Compare commits

..

1 Commits

Author SHA1 Message Date
Dolibot
ceada6c888 PHPStan > Update baseline 2025-10-05 12:08:48 +00:00
3633 changed files with 40909 additions and 108842 deletions

10
.gitattributes vendored
View File

@@ -39,20 +39,20 @@
# Export ignores to generate clean production tarballs
/build export-ignore
/dev export-ignore
/doc export-ignore
/test export-ignore
/.github export-ignore
/.phan export-ignore
/.tx export-ignore
.buildpath export-ignore
/build.xml export-ignore
.codeclimate.yml export-ignore
Dockerfile export-ignore
.dockerignore export-ignore
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
.mailmap export-ignore
.pre-commit-config.yaml export-ignore
.scrutinizer.yml export-ignore
.settings export-ignore
.travis.yml export-ignore
Dockerfile export-ignore
.tx export-ignore

View File

@@ -136,9 +136,9 @@ If your PR is a change on interface, you must also paste a screenshot showing th
#### Examples
<pre>
FIX|Fix #456 Short description (where #456 is number of bug fix, if an issue ID exists, or #xxx456 with xxx as the name of the VDP platform in lower case for security issues. The "Fix" must be in upper case to appear into ChangeLog)
FIX|Fix #456 Short description (where #456 is number of bug fix, if it exists. In upper case to appear into ChangeLog)
or
CLOSE|Close #456 Short description (where #456 is number of feature request, if it exists. The "Close" must be in upper case to appear into ChangeLog)
CLOSE|Close #456 Short description (where #456 is number of feature request, if it exists. In upper case to appear into ChangeLog)
or
NEW|New|QUAL|Qual|PERF|Perf Short description (In upper case to appear into ChangeLog, use this if you add a feature not tracked, otherwise use CLOSE #xxx)
or

View File

@@ -6,8 +6,6 @@ on:
pull_request:
types: [closed]
workflow_dispatch:
jobs:
cleanup:
runs-on: ubuntu-latest
@@ -18,7 +16,7 @@ jobs:
contents: read
steps:
- name: Check out code
uses: actions/checkout@v6
uses: actions/checkout@v5
- name: Cleanup
run: |
gh extension install actions/gh-actions-cache

View File

@@ -1,29 +0,0 @@
---
# This is a basic workflow to check the lock on major version (to lock some files on certified versions)
name: Check fileset lock
on: [push, pull_request]
concurrency:
group: check-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
checkmajorversion:
name: Check lock on fileset unalterable_files with generate_filelist_xml.php
runs-on: ubuntu-latest
# Do not run schedule on forks
if: |
github.repository == 'Dolibarr/dolibarr'
|| github.event.schedule == false
steps:
- uses: actions/checkout@v6
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.2
coverage: none # disable xdebug, pcov
- name: Run generate_filelist_xml.php
run: |
# shellcheck disable=2086
dev/build/generate_filelist_xml.php checklock=auto unalterable_files

View File

@@ -1,7 +1,6 @@
name: "CI-PULL-REQUEST"
on: [pull_request]
jobs:
pre-commit:
uses: ./.github/workflows/pre-commit.yml

View File

@@ -1,7 +1,6 @@
name: "CI-PUSH"
on: [push]
jobs:
pre-commit:
uses: ./.github/workflows/pre-commit.yml

View File

@@ -1,24 +0,0 @@
name: "CI-RELEASE"
on:
release:
types: [published]
jobs:
trigger-docker:
runs-on: ubuntu-latest
steps:
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ vars.RELEASE_DOCKER_ID }}
private-key: ${{ secrets.RELEASE_DOCKER_SECRET }}
- uses: peter-evans/repository-dispatch@v4
with:
token: ${{ steps.generate-token.outputs.token }}
repository: Dolibarr/dolibarr-docker
event-type: new-release
client-payload: '{"version": "${{ github.event.release.tag_name }}"}'

View File

@@ -33,7 +33,7 @@ jobs:
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v6
uses: actions/checkout@v5
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
@@ -47,7 +47,7 @@ jobs:
# Restore old cache
- name: Restore phpstan cache
id: cache
uses: actions/cache/restore@v5
uses: actions/cache/restore@v4
with:
path: ./.github/tmp
key: phpstan-cache-${{ env.PHP_VERSION }}-${{ env.CACHE_KEY_PART }}-${{

View File

@@ -1,45 +0,0 @@
# Action to prepare the github action
# Go on Dolibarr Organization - Settings - Developer settings - GitHub App (https://github.com/organizations/Dolibarr/settings/apps)
# Create an App: Enter a name + In Home page URL use https://github.com/Dolibarr/dolibarr + Disable webhook
# Set Permissions (see other app for list of permissions)
# Click on generate the private keys
# Click on Install application - choose the repository of the bot
# Go on Organisation - Secret and variables and create a secret PR_SECRET_KEY and copy the content of received private key. Choose the repository access to "Repository Dolibarr".
# Go on Organisation - Secret and variables and create a variable PR_APP_ID and copy the ID of the previously create ID. Choose the repository access to "Repository Dolibarr".
#
name: Set the tag with devcamp label during the session of a devcamp
on:
pull_request_target:
types: [opened]
permissions:
pull-requests: write
issues: write
jobs:
add-label-devcamp:
runs-on: ubuntu-latest
steps:
#- name: Install GitHub CLI
# run: sudo apt-get install gh
- name: Generate a token
id: generate-token
uses: actions/create-github-app-token@v2
with:
app-id: ${{ vars.PR_APP_ID }}
private-key: ${{ secrets.PR_SECRET_KEY }}
- name: Checkout repository
uses: actions/checkout@v4
- name: Assign label
env:
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
url: ${{ github.event.pull_request.html_url }}
run: |
echo "env.url=${{env.url}}"
gh pr edit "${{env.url}}" --add-label "Event: DevCamp 2025 XXX"

View File

@@ -1,7 +1,4 @@
---
# This is a basic workflow to check code with PHPSTAN tool
name: Phan
on:
# workflow called by the parent workflow ci.yml
workflow_call:
@@ -15,15 +12,15 @@ on:
concurrency:
group: phan-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
gh_event: ${{ inputs.gh_event || github.event_name }}
PHAN_CONFIG: dev/tools/phan/config.php
PHAN_BASELINE: dev/tools/phan/baseline.txt
PHAN_MIN_PHP: 7.2
PHAN_MIN_PHP: 7.0
PHAN_QUICK: ${{ github.event.schedule && '' || '--quick' }}
GITHUB_JSON: ${{ toJSON(github) }} # Helps in debugging Github Action
name: phan
jobs:
phan:
name: Run phan
@@ -33,7 +30,7 @@ jobs:
github.repository == 'Dolibarr/dolibarr'
|| github.event.schedule == false
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v5
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:

View File

@@ -1,7 +1,6 @@
---
# This is a basic workflow to check code with PHPSTAN tool
name: PHPStan
# Controls when the workflow will run
on:
# workflow called by the parent workflow ci.yml
@@ -14,9 +13,8 @@ on:
workflow_dispatch:
concurrency:
group: phpstan-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
group: stan-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
env:
gh_event: ${{ inputs.gh_event || github.event_name }}
CACHE_KEY_PART: ${{ ( inputs.gh_event == 'pull_request' || github.event_name == 'pull_request' ) && format('{0}-{1}', github.base_ref, github.head_ref) || github.ref_name }}
@@ -37,7 +35,7 @@ jobs:
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v6
- uses: actions/checkout@v5
# Get PHP and addons
- name: Setup PHP
id: setup-php
@@ -52,7 +50,7 @@ jobs:
# Restore old cache
- name: Restore phpstan cache
id: cache
uses: actions/cache/restore@v5
uses: actions/cache/restore@v4
with:
path: ./.github/tmp
key: phpstan-cache-${{ matrix.php-version }}-${{ env.CACHE_KEY_PART }}-${{
@@ -74,14 +72,14 @@ jobs:
# Save cache
- name: Save phpstan cache
uses: actions/cache/save@v5
uses: actions/cache/save@v4
if: ${{ success() || ( ! cancelled() && steps.cache.outputs.cache-hit != 'true' ) }}
with:
path: ./.github/tmp
key: phpstan-cache-${{ matrix.php-version }}-${{ env.CACHE_KEY_PART }}-${{
github.run_id }}
- name: Provide phpstan log as artifact
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v4
if: ${{ always() }}
with:
name: phpstan-srcrt

View File

@@ -1,6 +1,5 @@
---
name: pre-commit
on:
# workflow called by the parent workflow ci.yml
workflow_call:
@@ -17,7 +16,6 @@ concurrency:
cancel-in-progress: true
env:
gh_event: ${{ inputs.gh_event || github.event_name }}
jobs:
pre-commit:
runs-on: ubuntu-latest
@@ -30,7 +28,7 @@ jobs:
# if: false
# Checkout git sources to analyze
- uses: actions/checkout@v6
- uses: actions/checkout@v5
# Try to get the list of modified files into steps.changed-php.outputs.all_changed_files
#- name: Get changed files
@@ -75,7 +73,7 @@ jobs:
- run: python -m pip install pre-commit
# Restore previous cache of precommit
- uses: actions/cache/restore@v5
- uses: actions/cache/restore@v4
with:
path: ~/.cache/pre-commit/
key: pre-commit-4|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }}
@@ -109,10 +107,6 @@ jobs:
coverage: none # disable xdebug, pcov
tools: phpcs
# Install perltidy and perlcritic
- name: Install perltidy and perlcritic
run: sudo apt-get update && sudo apt-get install -y perltidy libperl-critic-perl
# Run all the precommit tools (defined into pre-commit-config.yaml).
# We can force exclusion of some of them here.
- name: Run pre-commit hooks
@@ -157,20 +151,20 @@ jobs:
ls -l ~/.cache/pre-commit/
- name: Convert Raw Log to Annotations
uses: mdeweerd/logToCheckStyle@v2025.11.2
uses: mdeweerd/logToCheckStyle@v2025.1.1
if: ${{ failure() }}
with:
in: ${{ env.RAW_LOG }}
# Save the precommit cache
- uses: actions/cache/save@v5
- uses: actions/cache/save@v4
if: ${{ ! cancelled() }}
with:
path: ~/.cache/pre-commit/
key: pre-commit-4|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }}
# Upload result log files of precommit into the Artifact shared store
- name: Provide log as artifact
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v4
if: ${{ ! cancelled() }}
with:
name: precommit-logs

View File

@@ -1,6 +1,5 @@
---
name: Win CI
# yamllint disable-line rule:truthy
on:
# workflow called by the parent workflow ci.yml
@@ -26,7 +25,6 @@ env:
PHP_INI_SCAN_DIR: C:\myphpini
CKEY: win-ci-2
GITHUB_JSON: ${{ toJSON(github) }} # Helps in debugging Github Action
jobs:
win-test:
strategy:
@@ -37,7 +35,7 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- name: Checkout code
uses: actions/checkout@v6
uses: actions/checkout@v5
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
@@ -57,9 +55,9 @@ jobs:
# Restore cache
- name: Restore cache
id: cache
uses: actions/cache/restore@v5
uses: actions/cache/restore@v4
env:
HASH: ${{ hashFiles('htdocs/install/**', 'htdocs/filefunc.inc.php', 'htdocs/version.inc.php') }}
HASH: ${{ hashFiles('htdocs/install/**', 'htdocs/filefunc.inc.php') }}
KEY_ROOT: ${{ matrix.os }}-${{ env.ckey }}-${{ matrix.php_version }}
with:
# See https://github.com/actions/cache/issues/1275#issuecomment-1925217178
@@ -167,13 +165,13 @@ jobs:
for /f "tokens=2 delims==" %%A in ('doskey /m:err') do EXIT /B %%A
- name: Convert Raw Log to Annotations
uses: mdeweerd/logToCheckStyle@v2025.11.2
uses: mdeweerd/logToCheckStyle@v2025.1.1
if: ${{ failure() }}
with:
in: ${{ env.PHPUNIT_LOG }}
- name: Provide dolibarr and phpunit logs as artifact
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v4
if: ${{ ! cancelled() }}
with:
name: win-ci-logs
@@ -187,7 +185,7 @@ jobs:
# Save cache
- name: Save cache
uses: actions/cache/save@v5
uses: actions/cache/save@v4
if: ${{ ! cancelled() }}
with:
# See https://github.com/actions/cache/issues/1275#issuecomment-1925217178

1
.gitignore vendored
View File

@@ -52,7 +52,6 @@ dev/build/node_modules/
node_modules/
vendor/
php-vendor
tmp/
#yarn

View File

@@ -1,9 +1,9 @@
---
exclude: (?x)^( htdocs/includes/ckeditor/.*|htdocs/public/includes/ckeditor/.*|(\.(?!github/workflows)[^/]*/.*))$
exclude: (?x)^( htdocs/includes/ckeditor/.*|(\.(?!github/workflows)[^/]*/.*))$
repos:
# Several miscellaneous checks and fix (on yaml files, end of files fix)
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
rev: v5.0.0
hooks:
# This hook tests the name of the branch and return an error if the name is
# 'develop' or an official version 'x.y'
@@ -60,13 +60,13 @@ repos:
# Gitleaks is a SAST tool for detecting and preventing hardcoded secrets like passwords, api keys, and tokens in git repos
- repo: https://github.com/gitleaks/gitleaks.git
rev: v8.29.0
rev: v8.24.0
hooks:
- id: gitleaks
# Check github actions
- repo: https://github.com/rhysd/actionlint
rev: v1.7.8
rev: v1.7.7
hooks:
- id: actionlint
@@ -137,8 +137,6 @@ repos:
files: \.(php)$
args: [--standard=dev/setup/codesniffer/ruleset.xml]
- id: php-cs
exclude: |
(?x)^(htdocs/includes/.*)$
files: \.(php)$
args:
[
@@ -193,7 +191,7 @@ repos:
# Check format of yaml files
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.37.1
rev: v1.36.2
hooks:
- id: yamllint
args:
@@ -246,7 +244,7 @@ repos:
# Check some shell scripts
- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.11.0.1
rev: v0.10.0.1
hooks:
- id: shellcheck
args: [-W, "100"]
@@ -274,22 +272,3 @@ repos:
|htdocs/install/pgsql/functions/functions.*\.sql
|htdocs/modulebuilder/template/sql/.*\.sql
)$
- repo: https://github.com/perltidy/perltidy
rev: '20250105.03'
hooks:
- id: perltidy
# virtualmin excuded - reason https://github.com/Dolibarr/dolibarr/pull/36370#issuecomment-3565101823
exclude: (?x)^
(dev/build/perl/virtualmin/dolibarr.pl
)$
args: [ --tabs, --nola ]
#- repo: https://github.com/henryykt/pre-commit-perl
# rev: v0.0.5
# hooks:
# - id: perlcritic
# # virtualmin excluded - reason https://github.com/Dolibarr/dolibarr/pull/36370#issuecomment-3565101823
# exclude: (?x)^
# (dev/build/perl/virtualmin/dolibarr.pl
# )$

View File

@@ -41,10 +41,10 @@ jobs:
include:
- stage: PHP min and max
if: type = push
php: '7.2'
php: '7.1'
env:
- DB=postgresql
- TRAVIS_PHP_VERSION=7.2
- TRAVIS_PHP_VERSION=7.1
- stage: PHP min and max
if: type = pull_request OR type = push
php: '8.4'
@@ -85,9 +85,6 @@ before_install:
if [ "$TRAVIS_PHP_VERSION" = '7.1' ]; then
sudo apt install unzip apache2 php7.1 php7.1-cli php7.1-curl php7.1-mysql php7.1-pgsql php7.1-gd php7.1-imap php7.1-intl php7.1-ldap php7.1-xml php7.1-mbstring php7.1-xml php7.1-zip libapache2-mod-php7.1
fi
if [ "$TRAVIS_PHP_VERSION" = '7.2' ]; then
sudo apt install unzip apache2 php7.2 php7.2-cli php7.2-curl php7.2-mysql php7.2-pgsql php7.2-gd php7.2-imap php7.2-intl php7.2-ldap php7.2-xml php7.2-mbstring php7.2-xml php7.2-zip libapache2-mod-php7.2
fi
if [ "$TRAVIS_PHP_VERSION" = '8.1' ]; then
sudo apt install unzip apache2 php8.1 php8.1-cli php8.1-curl php8.1-mysql php8.1-pgsql php8.1-gd php8.1-imap php8.1-intl php8.1-ldap php8.1-xml php8.1-mbstring php8.1-xml php8.1-zip libapache2-mod-php8.1
fi
@@ -112,8 +109,8 @@ before_install:
#ps fauxww | grep postgres
ls /etc/postgresql/13/main/
sudo sed -i -e '/local.*peer/s/postgres/all/' -e 's/peer\|md5/trust/g' /etc/postgresql/14/main/pg_hba.conf
sudo cat /etc/postgresql/14/main/pg_hba.conf
sudo sed -i -e '/local.*peer/s/postgres/all/' -e 's/peer\|md5/trust/g' /etc/postgresql/13/main/pg_hba.conf
sudo cat /etc/postgresql/13/main/pg_hba.conf
sudo service postgresql restart
@@ -134,9 +131,6 @@ install:
if [ "$TRAVIS_PHP_VERSION" = '7.1' ]; then
sudo update-alternatives --set php /usr/bin/php7.1
fi
if [ "$TRAVIS_PHP_VERSION" = '7.2' ]; then
sudo update-alternatives --set php /usr/bin/php7.2
fi
if [ "$TRAVIS_PHP_VERSION" = '8.1' ]; then
sudo update-alternatives --set php /usr/bin/php8.1
fi
@@ -535,9 +529,9 @@ script:
echo
- |
echo Show some debug info, like table content, or migration log from some versions
echo '\d llx_blockedlog' | psql 'postgresql://postgres:postgres@127.0.0.1:5432/travis'
cat $TRAVIS_BUILD_DIR/upgrade500600.log
echo Show some debug info like table content or log
#echo '\d llx_adherent' | psql 'postgresql://postgres:postgres@127.0.0.1:5432/travis'
cat $TRAVIS_BUILD_DIR/upgrade18001900.log
cat $TRAVIS_BUILD_DIR/upgrade19002000.log
echo
@@ -557,7 +551,6 @@ script:
php upgrade2.php 0.0.0 0.0.0 MAIN_MODULE_RECEPTION,MAIN_MODULE_RECRUITMENT >> $TRAVIS_BUILD_DIR/enablemodule.log
php upgrade2.php 0.0.0 0.0.0 MAIN_MODULE_KnowledgeManagement,MAIN_MODULE_EventOrganization,MAIN_MODULE_PARTNERSHIP >> $TRAVIS_BUILD_DIR/enablemodule.log
php upgrade2.php 0.0.0 0.0.0 MAIN_MODULE_EmailCollector >> $TRAVIS_BUILD_DIR/enablemodule.log
php upgrade2.php 0.0.0 0.0.0 MAIN_MODULE_BlockedLog >> $TRAVIS_BUILD_DIR/enablemodule.log
echo $?
cd -
set +e

401
ChangeLog
View File

@@ -6,407 +6,30 @@ English Dolibarr ChangeLog
For users:
----------
NEW: Need PHP 7.2 as minimum version
NEW: Module datapolicy moved as stable (for anonimization features)
NEW: #31723 - Improve project overview: Hide paid orders (#35524)
NEW: #35700 : Throw an error when validating a propal, order, supplier with a product no more in sale/purchase… (#35709)
NEW: Accountancy - Accounting by payment type (#34729)
NEW: Accountancy - Add accounting for discounts (#35977)
NEW: Accountancy - Add a protection on various payment for auxiliary account on general account not centralized (#35720)
NEW: Accountancy - Add field centralized on import/export (#35872)
NEW: Accountancy - Add hook on export filename (#35188)
NEW: Accountancy - Add reconcile on general accounting account - SQL part (#35994)
NEW: Accountancy - Analytical axis (SQL Structure) (#34738)
NEW: Accountancy - Manual input - Add script to greyed out subledger_account if general ledger is not centralized (#35855)
NEW: Accountancy - Transaction - Add verification on centralized account (#35824)
NEW: Accountancy - Various payment - Add script to greyed out subledger_account if general ledger is not centralized (#35842)
NEW: Add a boolean for lines in api and $properties (#34293)
NEW: Add accounting export mode for ISTEA (#36006)
NEW: add a limit to avoid too many answer in agenda view. Add warning if limit has been reached.
NEW: Add a page to edit http security headers of application (#34941)
NEW: Add auto-reference generation for tasks (like in project) in API (#35981)
NEW: Add column ref_ext and note_private for membership
NEW: Add column thirdparty ref_customer and ref_supplier in project list
NEW: Add column title in emailing and add more filters
NEW: add combining characters (accents, cedilla...) codes in dol_string_unaccent() (#35130)
NEW: add company date birth (SQL structure) (#34854) (UI) (#34861)
NEW: add conditional supplier price display (#35900)
NEW: Add configuration for default timesheet menu (#35805)
NEW: Add contact tab on product service (#35914)
NEW: Add directory navigation to Web Portal Shared Documents (#35443)
NEW: Added Messaging and agenda tabs on order and shipments (#34859)
NEW: Add event when installing a module in the security event list.
NEW: add extrafield option "empty on clone" (#34866)
NEW: add fields usage_opportunity, usage_task, usage_bill_time for project import (#35301)
NEW: Add filter on agenda event progression on agenda page
NEW: add free numbering module for members (#35636)
NEW: add global search for resource object (#36043)
NEW: add hidden const to get response header in geturlcontent function (#34781) (#34824)
NEW: add hook getListOfModels (#34626)
NEW: Add hook on calcula_price() and get_default_tva()
NEW: Add hooks in webportal (#35326)
NEW: add hook when printing new card button on thirdparty list (#36350)
NEW: add hourly rate in list of users
NEW: Add missing parameters for menus on webportal hook (#35550)
NEW: Add option PDF_PURCHASE_INVOICE_HIDE_VAT
NEW: Add option PROJECT_CAN_ALWAYS_LINK_TO_ALL_CUSTOMERS
NEW: Add option to create simple standalone shipment of non origin (#35651)
NEW: Add option to create standalone reception (#36134)
NEW: add private and public note on ticket (#35303)
NEW: add product_type field on fichinter (preparing subtotal) (#36196)
NEW: Add regions for CONGO, THE DEMOCRATIC REPUBLIC OF THE;CD (#36340)
NEW: ADD Send mail for reception / Delivery (#34829)
NEW: Add setup page to concat natively files on invoice PDF.
NEW: add shipping address to propal (#34441)
NEW: Add Sign feature on shipments (#34640)
NEW: Add sms reminder in reminder of agenda events (#35239)
NEW: Add SQL table for expensereport line extrafields support (#36251)
NEW: add supplier invoice, order and supplier order tag filter and bulk insert and statistics order and supplier order (#35399)
NEW: add supplier payment mail template (#35877)
NEW: add tags on proposals and supplier proposals and in statistics (#35553)
NEW: Add task categories 1/3 (#35848)
NEW: Add tasks card hooks (#35616)
NEW: Add the "Dispute status" in list of invoice.
NEW: add the option to not synchronize thirdparty <--> member (#36033)
NEW: Add the widget funnel of opportunities
NEW: Add tpl files for standalone shipment (#35624)
NEW: Add tpl loader for discounts.tpl.php (#34798)
NEW: Add Transfer Number (#35665)
NEW: Add Type, Description columns to Project Overview Expense Reports (#36214)
NEW: Add user permission for create/edit/delete supplier prices (#35940)
NEW: Allow omission of ODT template name when generating ODT and PDF (#35701)
NEW: Better navigation and report into database admin tools
NEW: Button to create a proposal and sale order from a contract always on
NEW: Can add info of main IT service provider in setup.
NEW: can admin payments extrafields (#34822)
NEW: Can drag and drop in BOM card
NEW: Can force_install_dolibarrpassword for automatic installation (#34537)
NEW: Can have a tooltip picto on title of column and keep autotruncation of label. Tooltip is show at begin of text.
NEW: Can show both currency code and symbol into the select of currency
NEW: Can sort on employee in holiday balance. Add link to go to history.
NEW: Can update value of timespent with last task hourly rate (#36018)
NEW: Can urlencode substitution variable of constants
NEW: Can view/list/edit the dispute status of an invoice
NEW: Change the path for the mailing files (#34878)
NEW: Constant ORDER_MASS_ACTION_BILLED_LINK_EXPEDITIONS (#34617)
NEW: const MENU_HIDE_EMAIL_TEMPLATES to hide email templates setup in Tools menu (#35739)
NEW: Create simple shipment of non origin (#35604)
NEW: Currency for the Democratic Republic of Congo added. (#36104)
NEW: Customized step in duration select (#34652)
NEW: Dashboard - Add option in ihm to disable MRP thumb (#36185)
NEW: date function related to holiday can accept country id in addition to country code
NEW: DEV Can set color of the on/off button.
NEW: Disable by default obfuscation methods and function in extrafields evaluable strings. Can re-enable with MAIN_ALLOW_OBFUSCATION_METHODS_IN_DOL_EVAL=1
NEW: Discount split more than two parts (#34782)
NEW: Display company logo on kanban view (#34520)
NEW: dol_sort_array can be used with 2 sorting criteria.
NEW: Enhanced layout feature for emailing
NEW: Enhance popup for image preview (show size in title, can restore small view, always show the Rotate button).
NEW: Enhance the system for warnings on module activation
NEW: execute hook addMoreActionsButtons on bank card (#35598)
NEW: extrafields: add field to link a field to a module (#34416)
NEW: Feature to merge duplicate members (#35308)
NEW: generate renewal proposal for contracts (#35120)
NEW: Holiday - Allow to specify a specific mail address from (#36184)
NEW: hook allowing external modules to replace the behavior of fetchObjectLinked() (#34724)
NEW: hooks `showInputExtraField` and `showOutputExtraField` to override ExtraFields::show(Input|Output)Field (#35496)
NEW: implement box on product and interventional index page (#34629)
NEW: import subscriptions (#35612)
NEW: Introduce getCurrency(). $conf is no more allowed into computed formulae.
NEW: Invert logic of default date in proposal/order/invoice creation: Need option to NOT autofill instead of the opposite.
NEW: line input multicurrency price with tax (#35064)
NEW: Major overhaul of DataPolicyCron and add Recruitment policy (#34704)
NEW: Make the public contact form with experimental status
NEW: Minimal version of PHP is now 7.2
NEW: More index for memberships table
NEW: More information on the user credential section
NEW: More webportal feature - Can add shared files and thirdparty documents (#35391)
NEW: New hook mergePdf (#34707)
NEW: On invoice, show also nb of credit notes notyet converted for consumption
NEW: Option to clone parent categories on variant creation (#35806)
NEW: Output of category tag is nicer for long subcategories.
NEW: Parent project column in list of projects (#36177)
NEW: Paymentok validate invoice if not already done (#35564)
NEW: PDF Show customer balance on invoice date (#34800)
NEW: possibility to define global entity in user param (#35908)
NEW: Add messaging and agenda features to proposals (#34883)
NEW: public and private note can be shown on contact list
NEW: Public donation page (#35565)
NEW: public pages donation, ticket and member use captcha setup (#35913)
NEW: Rework of the management of the card and fields on the web portal (#36076)
NEW: Save the BAN and RUM for SEPA into database not just file.
NEW: search all facture rec (#34563)
NEW: Show cron last result and output in info (#36028)
NEW: Show full date with seconds in the tooltip of date of event
NEW: Show the link to download the zip of a module on module setup
NEW: Show warning on banner when an email is not valid
NEW: The check file feature can limit check on unalterable files only
NEW: The flag "Dispute open" make the status in Red.
NEW: The PHP info is in a popup in install page.
NEW: update country list (#34865)
NEW: Update Incoterms to 2025 standards and add new terms (#36041)
NEW: Upgrade ACE editor to 1.43.12
NEW: User/Date in the Follow tab are more condensed.
NEW: We added a hook to allow us to modify the Prospect Customer drop down… (#25635)
NEW: Withholdingtax how VatRefund (#34649)
For developers:
---------------
NEW: Introducing the TRIGGER_PREFIX property to force developers to use unique triggerkey per business object, to limit code to business CRUD events and report warning when it is not.
NEW: add extraparams field in llx_categorie (#35975)
NEW: Add prepare() method to DoliDB class (rebuild) (#35249)
NEW: Add function to split a discount in 2 by API REST (#34786)
NEW: Add a new API "product lots" (#36243)
NEW: Add API for Holidays/Leaves
NEW: add api for members statistics (#35851)
NEW: add api List VAT (#35920)
NEW: add api_paiements.class.php (#34756)
NEW: document API builddoc product
NEW: Add contact management on project Api (#35459)
NEW: Add contact support on products in REST API (#35925)
NEW: Add country ID resolution from country code for thirdparty api (#36345)
NEW: Add getcontacts on api of interventional and proposal (#35589)
NEW: Add hook initialization for interventions API (#35203)
NEW: Add option API_ENABLE_COUNT_CALLS
NEW: Add thirdparty search on api list (#34634)
NEW: add timespent API endpoints for projects and tasks add also cascading assignment of contacts to tasks (#35897)
NEW: add upload api feature for shipment (#34639)
NEW: Allow creating contact via api with ISO code (#36322)
NEW: API endpoint for getting products in a warehouse (#35918)
NEW: API for getting, adding, deleting and/or modifying email templates (#35853)
NEW: API for handling mass mailing targets (#35603)
NEW: API GET endpoint for thirdparties types listing (c_typent) (#34751)
NEW: Api mass emailing (#35531)
NEW: API user/groups/ POST, PUT, DELETE + some hurl tests (#35903)
NEW: API User - Remove user from group (#35453)
NEW: Implement listTimespent method in api_projects.class.php (#36093)
NEW: qual fixes on api contract (#36066)
NEW: stock API GET movement (#36193)
NEW: action to clone ticket
* Introducing the TRIGGER_PREFIX property to force developers to use unique triggerkey per business object, limit also code to business CRUD events and identity when it is not.
WARNING:
--------
The following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
* The deprecated column "egroupware_id" has been dropped from table llx_user.
* The deprecated column egroupware_id has been dropped.
* The property $sumpayed (duplicated of $totalpaid), $sumdeposit (duplicate of $totaldeposits) and $sumcreditnote (duplicate of $totalcreditnotes) has
been removed (there are replaced with the property that was a duplication of (same for $sumpayed_multicurrency, $sumdeposit_multicurrency, $sumcreditnote_multicurrency).
* Parameters $maxlen and $notooltip of Contract have been inverted to follow the standard. It was breaking the common use of getNomUrl() but if you were
using the parameter maxlen (rare) by using the old signature, result may be just a tooltip that is no more visible when mous over the contract ref shown by your module.
* Removed array $MAP_ID_TO_CODE that was a duplicate of the array "array_flip($categ->MAP_ID)"
* Parameters $maxlen and $notooltip of Contract have been inverted to follow the standard. It was breaking the common use of getNomUrl() but if you were using the parameter
maxlen (rare) by using the old signature, result may be a tooltip that is no more visible on ref printed by you module.
* Removed array $MAP_ID_TO_CODE that was a duplicate of array "array_flip($categ->MAP_ID)"
* The signature of the Sale order ->cancel() method and shipment ->cancel() has been modified to introduce the $user param like for other methods that modify a status.
* Adding new "document generation templates" must be done by adding files into the mymodule/core/modules/xxx/doc directory. Adding files into custom directory with the
same path than the core path, without using a "mymodule" directory, is now forbidden.
* The directory theme/common/octicons has been removed. No resource was used by Dolibarrfrom this directory.
* The library timepicker.js has been removed. Was no more used by Dolibarr since a long time.
* Because of the new TRIGGER_PREFIX property, the triggers SUPPLIER_PRODUCT_BUYPRICE_XXX are renamed into PRODUCT_BUYPRICE_XXX.
* Function img_pdf() has been removed. Replace it with img_picto('', 'pdf') if you were using it.
* The method run_trigger() was deprecated 10+ years ago in favor of runTrigger(). It has been removed. Change your trigger file if you still use it.
* Property ->picto of module descriptors must contains the image extension if it is not a font awesome tag. Example: $this->picto="mymoduleimg.png";
* Stock movement API GET method output variable names has been harmonized with POST input parameter names
* Concatenation into computed property of extrafields is off by default. You can enable it from conf.php file by adding dol_concat to list of allowed function in $dolibarr_main_restrict_eval_methods,
For example: $dolibarr_main_restrict_eval_methods='getDolGlobalString,getDolGlobalInt,getDolCurrency,fetchNoCompute,hasRight,isModEnabled,isStringVarMatching,abs,min,max,round,dol_now,dol_concat,preg_match';
* Old variable $obj and $object are no more allowed into on the fly evaluated strings like computed or conditions on extrafields. Use $objectoffield to get current object
Also if you were using temporary variables int a computed extrafields, the nameot temporary variable must match $var123.
* The hidden constant MAIN_ALLOW_UNSECURED_SPECIAL_CHARS_IN_DOL_EVAL in database has been replaced with the
variable $dolibarr_main_allow_unsecured_special_chars_in_dol_eval into file conf/conf.php
* $conf use into "computed formulae" of etrafields is now deprecated (not yet forbidden). You can replace use of $conf->currency by the new method getCurrency() and $conf->global->xxx by getDolGlobalString('xxx').
* $user->rights->module->perms is also deprecated. You can use $user->hasRight() instead.
* The API endpoint /proposals/{id}/contact/{contactid}/{type}/{source} is now {id}/contact/{contactid}/{type} to match same behaviour than order and invoices.
* The API endpoint /interventions/{id}/reopen hase been removed in favor of /interventions/{id}/settodraft
* If the module geoipmaxmind is used, you must resubmit the geoip data file as it is now stored differently.
***** ChangeLog for 22.0.4 compared to 22.0.3 *****
FIX: $param is the 5th parameter of print_liste_field_titre ($moreparam) (#36250)
FIX: 17.0: perweek.php resets task progress to 0% when: (#36401)
FIX: 18.0: GETPOSTDATE and buildParamDate assumed HTTP param names 'minute' and 'second' instead of 'min' and 'sec'
FIX: 19.0 - attachments upload dir for invoices not always determined correctly (doesn't always take multi-entity into account) (#36302)
FIX: #33148 - partial payments are taken into account in EPC QR codes (#36338)
FIX: #33899 API Timespent Service Field
FIX: #35061
FIX: #35096 #36393 Add minimal fields required asthe class is used by
FIX: #35141 (#36390)
FIX: #35375 Accountancy - SQL error on empty filter account category
FIX: #35655 API Contract Creation Fails for Non-Admin Users in Version 22.0.2
FIX: #36090 Accountancy - Inconsistent date on various journal
FIX: #36149 (#36150)
FIX: #36310 Accountancy - Data - Wrong account labels (cache) on write bookkeeping action (#36410)
FIX: #36334 - reload invoice data before pdf-creation in process of generating a new member contribution (#36335)
FIX: #36347 (#36358)
FIX: #36368 - avoid overlaying of EPC-QR Code and payment information (#36369)
FIX: #36576 - date creation is empty on import
FIX: Accountancy - #36090 Inconsistent date on various journal
FIX: Accountancy - No limit on chart of account to define category on account
FIX: Accountancy - Not propose to write operation on draft asset
FIX: Accountancy - Problem calculating exercises with different tax periods on fixed assets
FIX: Accountancy - Problem calculating fiscal year with different periods on fixed assets
FIX: Accountancy - Reverse accounting account in depreciation expense entries for fixed assets
FIX: Accountancy - Verify fiscal year on last hour to enable the integration of asset entries
FIX: allow a situation with credit to be removed from cycle
FIX: API task getTimeSpent to actually return data
FIX: avoid php warning error (#36330), avoid php warnings (#36301), (#36411)
FIX: Can Validated Holidays When Negative Balance
FIX: Concat of PDF to invoices (#36329)
FIX: create API temp directory in Dolibarr API constructor
FIX: DA027383: permissions not checked on HRM evaluation card (#36328) (#36399)
FIX: do not force rowid to int (#36412)
FIX: Email Collector Module: manage error when imap_fetchstructure return false. Previously it generated warning and fatal error because the returned value was not of type class
FIX: empty origin type passed to addline when creating invoices from expeditions using massaction (confirm_createbills) (#36413)
FIX: expense report card: do not show bank account if user cannot see them
FIX: expense report card: use correct bank module designator for detection
FIX: Export of extrafield in organized events
FIX: fix #36401 (for v17.0) doesn't work in v18.0+ because of variable renaming
FIX: | Fixing addPayment /invoices/id/payments
FIX: getEntity use element instead table_element (#36405)
FIX: Implementation of multi-company compatibility with inventory/warehouse management
FIX: info on supplier payment card on v22 and payment link
FIX: keep user who validate proposal on update (#36257)
FIX: List is filtered on task status when it should not
FIX: Missing AND on fields filter on evaluation class
FIX: missing p.default_vat_code in product import profile.
FIX: Missing Product ref in Bom stats
FIX: Mo::deleteLine() - stock movement correction (#34733)
FIX: Multicompany compatibility with "project_task"
FIX: not remove value of others extra-fields on update extras action
FIX: Object should be cloned here (#36289)
FIX: PR#36401 fixed a missing GETPOSTISSET() but the check involves a variable ($taskid) that was renamed ($tmptaskid) in 18.0
FIX: (propal): Incorrect HT/TTC recalculation when editing proposal lines #36514
FIX: (propal): values lost when editing HT price
FIX: propal shipping and availability update (v18+)
FIX: re-create API temp dir after purging temp files
FIX: remove situation invoice from cycle
FIX: remove useless condition to create credit on situation invoice (#35786)
FIX: Search all for supplier proposals via object reference
FIX: Selection of email when prefilled from a template
FIX: SQL error for LIST_OF_QUALIFIED_INVOICES_LIMIT_DEFINED
FIX: subtotal feature button availability according setup
FIX: TakePOS Missing Thirdparty Id when getting more products (#36341)
FIX: (tasks): dates in gantt view
FIX: undefined variables on create invoice card from order (backport from v19) or shipment card (backport from v20)
FIX: use array_intersect instead in_array
FIX: warning on select
FIX: wrong $param parameter position (#36265)
SEC: 7ed0af2a138a34e7c7005b95c85ffc791976a6cf
SEC: empty commit for CI automata
SEC: FIX: #36430 permissions not checked on other tabs of HRM evaluation card
SEC: fix IDOR attack on employee evaluation. Missing permission test https://github.com/atm-florianm/dolibarr/commit/7ed0af2a138a34e7c7005b95c85ffc791976a6cf
SEC: permissions not checked on other tabs of HRM evaluation card
***** ChangeLog for 22.0.3 compared to 22.0.2 *****
FIX: 16.0: extrafield of type link to category causes SQL error in selectForFormsList() (#36074)
FIX: 20.0 ajax_constantonoff + FormSetup were ignoring custom css class (cssClass / $morecss) (#36039)
FIX: #33741 FIX: #35632
FIX: #35247 FIX: #35950 Using same option for landing page and home page
FIX: #35519 (security) missing check user rights (#35527)
FIX: #35520 FIX: #35522
FIX: #35568 (#35569)
FIX: #35573 FIX: #35241
FIX: #35634 (#35912)
FIX: #35766: Update buying price INT Float (#35769)
FIX: #35780
FIX: #35782
FIX: #35784
FIX: #35922 Lines of orders - Status filter unexpected beahavior (#35924)
FIX: #36025 Accountancy - Error when cloning directly from accounting entry (#36034)
FIX: #36046 enabling extrafieldmanaged to enable deletion of records from the llx_salay_extrafields table
FIX: #36113 (#36116)
FIX: access problem when label is used for next/prev (#35933)
FIX: Accountancy - Admin personalized report - Remove duplicate button (#35721)
FIX: Accountancy - General setup - Missing form on UpdateMask (#35735)
FIX: Accountancy - Missing subledger information on mass cloning (#35777)
FIX: Accountancy - Printing the subsidiary ledger returns the general ledger (#35719)
FIX: Accountancy - Print subledger balance return general balance (#35712)
FIX: Accountancy - Problem with general setup (#36067)
FIX: Accountancy - Return on wrong page on y/n button (#35978)
FIX: Add missing left join to filter by extrafields (#36092)
FIX: add possibility to override authoritative dns (#35699)
FIX: Allow decimals on services duration (#36031)
FIX: avoid link problem with employee list context (#36125)
FIX: avoid NULL value (#36126)
FIX: avoid php warning (#35756)
FIX: avoid php warning (#35953)
FIX: avoid php warnings (#35492)
FIX: Bad label for column title on multicurency
FIX: bad name for target import table (#35615)
FIX: broken feature ! (#35906)
FIX: Can approve holidays when negative balance (#36144)
FIX: categories: sql error in link extrafields targettings categories (#36236)
FIX: check if category module is enabled (#35770)
FIX: check if service is activated only for api product (#35911)
FIX: check if zip file of website exists (#35879)
FIX: Clear filter
FIX: clone of cron tasks
FIX: conflict between $user->id and $object->id (#36225)
FIX: create invoice from order using API and multi-entity (#35654)
FIX: day of ticket on takePOS. Backport 6abdb6e. (#35745)
FIX: Deletion of a donation. Button was disabled.
FIX: detection of setup not done with
FIX: dol_escape_htmltag in extrafields_view (#36136)
FIX: doubled display of PRoduct Stokable checkbox when STOCK_SUPPORTS_SERVICES on service edit card (#36138)
FIX: Email template fetching (#35738)
FIX: Error 500 on api if cache is on and directory does not exists
FIX: extra-field list depend on parent extra-filed list on direct edit (#35803)
FIX: filter on note lost when sorting company list
FIX: Hide AWP if product has no stock managed
FIX: Import/Export - Do not list imports or exports of Builder module backups of module descriptor files (#36192)
FIX: In shipment creation process, if product is not manage in stock, Dolibarr should not display a "low stock warning" (#36139)
FIX: in shippement creation with SHIPMENT_SUPPORTS_SERVICES and/or STOCK_DISALLOW_NEGATIVE_TRANSFER and/or stockable_product there are inconsistencies (#36140)
FIX: Invoice Situation - Octopus - Column offset for amounts greater than 5 digits (#36124)
FIX: Invoice Situation - Octopus - Shipping block overlap issue (#36122)
FIX: Invoice Situation - Octopus - Show remaintopay at bottom (#36121)
FIX: invoices payments on multicurrencies being converted as int (#35622)
FIX: Knowledge management - Button ReOpen show in draft mode (#36008)
FIX: Label shown when value is empty
FIX: late customer orders are not shown on start page (#36200)
FIX: link to sort of target email page
FIX: MAIN_AUTOFILL_DATE in supplier invoice display 01/01/1970 (#36087)
FIX: MAIN_SEE_SUBORDONATES sql request error (#35896)
FIX: Missing begin transaction, The status of customer was not
FIX: missing check if partership is enabled (#36169)
FIX: missing entity field (#36086)
FIX: missing entity filter (#35517)
FIX: missing entity filter (#35857)
FIX: missing entity filters + wrong widget name (#35873)
FIX: missing "printFieldListValue" hook (#35990)
FIX: missing prospect/customer category translation (#35814)
FIX: Must show unit price when price is not for quantity 1
FIX: muticompany compatibility (wrong sharing name) (#36013)
FIX: my previous fix was incompatible with Thomas' fix from PR#35590 (#35890)
FIX: no emails sent when closing a ticket (#35874)
FIX: notification email not sent : NOTIFICATION_EMAIL_FROM is replaced with MAIN_MAIL_EMAIL_FROM if it's empty (#35881)
FIX: notifications: correctly report email delivery errors (#35864)
FIX: not possible to search for billed and not billed supplier orders in the list (#35680)
FIX: Perf for bom select (#35871)
FIX: Performance Problem on load stats command (#35785)
FIX: pgsql: error when calculating depreciations (#34213)
FIX: php 8+ warnings when creating deposits (#35582)
FIX: prices must be HT in dolistore browser
FIX: product stock lists: prevent SQL error when filtering on physical stock (#36038)
FIX: resize iban column to support encryption (#36237)
FIX: Select correct approver when making a leave request for someone else (#36118)
FIX: Situation percent set as 0 when adding line on situation invoices (#35999)
Fix: sql error if LIST_OF_QUALIFIED_INVOICES_LIMIT_DEFINED is used (#36135)
FIX: sql syntax error (#35588)
FIX: Status if thirdparty not synchronized with status WON of
FIX: substitutions on subject of the sent email reminder of the event (#35621)
FIX: The IBAN into EPC qr code must use the default bank account if not
FIX: The order closing date was not filled in during the shipment validation (workflow module). (#36235)
FIX: The status of customer was not synchronized with opportunity status
FIX: thirdparty was never notified. Passing of contact ID information was not coherent. (#35590)
FIX: To have only the sender's entity when sending mail (#31053)
FIX: when creating a ticken on backend and adding a linked file, the 'notify thirdparty at creation' chackbox disappears. (#35595)
FIX: when display in view mode HTML extrafeilds content doubled (#36127)
FIX: Wrong cast on TVA rate when updating supplier order lines (#36106)
FIX: wrong check of hook return
FIX: wrong entity alias (#35821)
FIX: wrong entity filter (#35691)
FIX: wrong field name (#35728)
FIX: wrong getEntiy element name (#35771)
FIX: wrong number of categories by entity (#36111)
FIX: wrong socpeople id when multiple assigned + avoid php warnings (#35878)
* Adding new document templates must be done by adding files into the mymodule/core/modules/xxx/doc directory. Adding files into custom directory with the
same path than the core path without using a mymodule directory is now forbidden.
* The directory theme/common/octicons has been removed
* The library timepicker.js has been removed. Was not used by Dolibarr.
* Because of new TRIGGER_PREFIX property triggers SUPPLIER_PRODUCT_BUYPRICE_XXX are renamed to PRODUCT_BUYPRICE_XXX.
***** ChangeLog for 22.0.2 compared to 22.0.1 *****

View File

@@ -2,7 +2,7 @@
![Downloads per day](https://img.shields.io/sourceforge/dw/dolibarr.svg)
![Docker hub pulls](https://img.shields.io/docker/pulls/dolibarr/dolibarr.svg)
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/)
[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg?style=flat-square)](https://php.net/)
[![GitHub release](https://img.shields.io/github/v/release/Dolibarr/dolibarr)](https://github.com/Dolibarr/dolibarr)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5521/badge)](https://bestpractices.coreinfrastructure.org/projects/5521)

View File

@@ -5,19 +5,19 @@ This file contains some policies about the security reports on Dolibarr ERP CRM
## Supported Versions for security reports
Security report are valid only on any current stable version for the last 5 major versions (see https://dolibarr.org web site to get current stable version) or on development version (branch "develop" on https://github.com/Dolibarr/dolibarr).
Security report are valid only on current stable version (see https://dolibarr.org web site to get current stable version) or on development version (branch "develop" on https://github.com/Dolibarr/dolibarr).
## Reporting a Vulnerability
To report a vulnerability, for a private report, you can:
- Send your report as an issue on https://github.com/Dolibarr/dolibarr/issues or on GitHub Vulnerability Disclosure Program tool (VDP): https://github.com/Dolibarr/dolibarr/security/advisories (recommended)
- Send your report on Vulnerability Disclosure Program (VDP): Link will be updated soon (recommended for everybody)
<!--
- Send your report on Vulnerability Disclosure Program (VDP) [https://app.yogosha.com/cvd/dolibarr/10VxeNx6Ui3rSEhAgX63US](https://app.yogosha.com/cvd/dolibarr/10VxeNx6Ui3rSEhAgX63US) (recommended for everybody)
- Or if you have permissions, use GitHub security advisory at [https://github.com/Dolibarr/dolibarr/security/advisories/new](https://github.com/Dolibarr/dolibarr/security/advisories/new)
-->
- Or send an email to security@dolibarr.org with clear textual description of the report along with steps to reproduce the issue, include attachments such as screenshots or proof of concept code as necessary (in such a case, the issue may be created by the developer that will fix the vulnerability or the Release Manager).
- Or send an email to security@dolibarr.org with clear textual description of the report along with steps to reproduce the issue, include attachments such as screenshots or proof of concept code as necessary.
## Hunting vulnerabilities on Dolibarr
@@ -114,8 +114,3 @@ Scope is the web application (backoffice) and the APIs.
* Invalid or missing SPF (Sender Policy Framework) records (Incomplete or missing SPF/DKIM/DMARC)
* Physical or social engineering attempts or issues that require physical access to a victims computer/device
* Vulnerabilities of type XSS exploited by using javascript into a website page of the website module or by using php code into a website page (being able to set javascript or php code is the expected behaviour in the website module), except if the user does not have the permission to edit page or php code.
## Be informed of a new vulnerability
You can get more information on how to be informed on a new vulnerability on the page https://wiki.dolibarr.org/index.php/Security_information

View File

@@ -7,4 +7,3 @@
/dolibarr-*.zip
/*.exe
/html
/makepack-dolibarr.pl.bak

View File

@@ -30,3 +30,5 @@ services:
networks:
- internal-pod
- external-pod

View File

@@ -1,94 +1,54 @@
#!/usr/bin/perl
##no critic (InputOutput::RequireBriefOpen)
use strict;
use warnings;
#--------------------------------------------------------------------
# Start the generation of the development documentation with doxygen
#--------------------------------------------------------------------
# Determine the patho of this script
( my $DIR = $0 ) =~ s/([^\/\\]+)$//;
$DIR ||= '.';
($DIR=$0) =~ s/([^\/\\]+)$//;
$DIR||='.';
$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
my $OPTIONS = "";
$OPTIONS="";
#$OPTIONS="-d Preprocessor";
my $CONFFILE = "dolibarr-doxygen.doxyfile";
$CONFFILE="dolibarr-doxygen.doxyfile";
use Cwd;
my $dir = getcwd;
print "Current dir is: $dir\n";
#print "Running dir for doxygen must be: $DIR\n";
if ( !-s "dev/build/doxygen/$CONFFILE" ) {
print
"Error: current directory for building Dolibarr doxygen documentation is not correct.\n";
print "\n";
if (! -s "dev/build/doxygen/$CONFFILE")
{
print "Error: current directory for building Dolibarr doxygen documentation is not correct.\n";
print "\n";
print "Change your current directory then, to launch the script, run:\n";
print '> perl .\dolibarr-doxygen-build.pl (on Windows)' . "\n";
print '> perl ../dolibarr-doxygen-build.pl (on Linux or BSD)' . "\n";
sleep 4;
exit 1;
print '> perl .\dolibarr-doxygen-build.pl (on Windows)'."\n";
print '> perl ../dolibarr-doxygen-build.pl (on Linux or BSD)'."\n";
sleep 4;
exit 1;
}
my $SOURCE = ".";
$SOURCE=".";
# Get version $MAJOR, $MINOR and $BUILD
my $result = open( my $IN, "<", $SOURCE . "/htdocs/filefunc.inc.php" );
if ( !$result ) {
die "Error: Can't open descriptor file " . $SOURCE
. "/htdocs/filefunc.inc.php\n";
$result = open( IN, "< " . $SOURCE . "/htdocs/filefunc.inc.php" );
if ( !$result ) { die "Error: Can't open descriptor file " . $SOURCE . "/htdocs/filefunc.inc.php\n"; }
while (<IN>) {
if ( $_ =~ /define\('DOL_VERSION', '([\d\.a-z\-]+)'\)/ ) { $PROJVERSION = $1; break; }
}
my $PROJVERSION = "";
while (<$IN>) {
if ( $_ =~ /define\('DOL_VERSION', '([\d\.a-z\-]+)'\)/ ) {
$PROJVERSION = $1;
last;
}
}
close $IN;
close IN;
($MAJOR,$MINOR,$BUILD)=split(/\./,$PROJVERSION,3);
if ($MINOR eq '') { die "Error can't detect version into ".$SOURCE . "/htdocs/filefunc.inc.php"; }
if ( $PROJVERSION eq "" ) {
my $DOL_MAJOR_VERSION;
my $DOL_MINOR_VERSION;
my @VERSION_FILES = ( "filefunc.inc.php", "version.inc.php" );
foreach my $file (@VERSION_FILES) {
$result = open( my $IN, "<", $SOURCE . "/htdocs/$file" );
if ( !$result ) {
die "Error: Can't open descriptor file " . $SOURCE
. "/htdocs/$file\n";
}
while (<$IN>) {
if ( $_ =~ /define\('DOL_MAJOR_VERSION', '([\d\.a-z\-]+)'\)/ ) {
$DOL_MAJOR_VERSION = $1;
}
if ( $_ =~ /define\('DOL_MINOR_VERSION', '([\d\.a-z\-]+)'\)/ ) {
$DOL_MINOR_VERSION = $1;
}
}
close $IN;
}
$PROJVERSION = $DOL_MAJOR_VERSION . '.' . $DOL_MINOR_VERSION;
}
( my $MAJOR, my $MINOR, my $BUILD ) = split( /\./, $PROJVERSION, 3 );
if ( !defined($MINOR) || $MINOR eq '' ) {
die "Error can't detect version from " . $SOURCE
. "/htdocs/filefunc.inc.php";
}
$version=$MAJOR.".".$MINOR.".".$BUILD;
my $version = $MAJOR . "." . $MINOR . "." . $BUILD;
print "Running doxygen for version " . $version . ", please wait...\n";
print "cat dev/build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/" . $version
. "/' | doxygen $OPTIONS - 2>&1\n";
$result =
`cat dev/build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/$version/' | doxygen $OPTIONS - 2>&1`;
print "Running doxygen for version ".$version.", please wait...\n";
print "cat dev/build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/".$version."/' | doxygen $OPTIONS - 2>&1\n";
$result=`cat dev/build/doxygen/$CONFFILE | sed -e 's/x\.y\.z/$version/' | doxygen $OPTIONS - 2>&1`;
print $result;

View File

@@ -4,79 +4,85 @@
# on PHP source files before running Doxygen.
# \author Laurent Destailleur
#--------------------------------------------------------------------
## no critic (InputOutput::RequireBriefOpen)
use strict;
use warnings;
# Usage: dolibarr-doxygen-filter.pl pathtofilefromdolibarrroot
my $file = $ARGV[0];
if ( !$file ) {
$file=$ARGV[0];
if (! $file)
{
print "Usage: dolibarr-doxygen-filter.pl pathtofilefromdolibarrroot\n";
exit;
}
open( my $fh, "<", $file ) || die "Failed to open file $file";
while (<$fh>) {
if ( $_ =~ /\\version\s/i ) {
open(FILE,$file) || die "Failed to open file $file";
while (<FILE>)
{
if ($_ =~ /\\version\s/i)
{
$_ =~ s/\$Id://i;
$_ =~ s/(Exp|)\s\$$//i;
$_ =~ s/(\\version\s+)[^\s]+\s/$1/i;
$_ =~ s/(\w)\s(\w)/$1_$2/g;
}
$_ =~ s/exit\s*;/exit(0);/i;
my $i = 0;
my $len = length($_);
my $s = "";
my $insidequote = 0;
my $insidedquote = 0;
my $ignore = "";
while ( $i < $len ) {
my $c = substr( $_, $i, 1 );
if ( $c eq "\\" ) {
if ($insidequote) { $ignore = "'"; }
if ($insidedquote) { $ignore = "\""; }
$i=0;
$len=length($_);
$s="";
$insidequote=0;
$insidedquote=0;
$ignore="";
while ($i < $len)
{
$c=substr($_,$i,1);
if ($c eq "\\")
{
if ($insidequote) { $ignore="'"; };
if ($insidedquote) { $ignore="\""; };
}
else {
if ( $c eq "'" ) {
if ( !$insidedquote ) {
$c = "\"";
else
{
if ($c eq "'")
{
if (! $insidedquote)
{
$c="\"";
#print "X".$ignore;
if ( $ignore ne "'" ) {
if ($ignore ne "'")
{
#print "Z".$ignore;
$insidequote++;
if ( $insidequote == 2 ) {
$insidequote = 0;
if ($insidequote == 2)
{
$insidequote=0;
}
}
}
#print "X".$insidequote;
}
elsif ( $c eq "\"" ) {
elsif ($c eq "\"")
{
#print "Y".$insidequote;
if ($insidequote) {
$c = "'";
if ($insidequote)
{
$c="'";
}
else {
if ( $ignore ne "\"" ) {
else
{
if ($ignore ne "\"")
{
$insidedquote++;
if ( $insidedquote == 2 ) {
$insidedquote = 0;
if ($insidedquote == 2)
{
$insidedquote=0;
}
}
}
}
$ignore = "";
$ignore="";
}
$s .= $c;
$s.=$c;
$i++;
}
print $s;
}
close($fh);
close(FILE);

View File

@@ -1,7 +1,4 @@
#!/usr/bin/perl
use strict;
use warnings;
#--------------------------------------------------------------------
# Script to get version of a source file
# Does not work with cygwin cvs command on Windows.
@@ -10,18 +7,15 @@ use warnings;
# Usage: dolibarr-doxygen-getversion.pl pathtofilefromdolibarrroot
$file = $ARGV[0];
if ( !$file ) {
$file=$ARGV[0];
if (! $file)
{
print "Usage: dolibarr-doxygen-getversion.pl pathtofilefromdolibarrroot\n";
exit;
}
$commande =
'cvs status "'
. $file
. '" | sed -n \'s/^[ \]*Working revision:[ \t]*\([0-9][0-9\.]*\).*/\1/p\'';
$commande='cvs status "'.$file.'" | sed -n \'s/^[ \]*Working revision:[ \t]*\([0-9][0-9\.]*\).*/\1/p\'';
#print $commande;
$result = `$commande 2>&1`;
$result=`$commande 2>&1`;
print $result;

View File

@@ -43,5 +43,5 @@ DoliWampWillStartApacheMysql=Die DoliWamp-Installation wird nun starten oder Apa
OldVersionFoundAndMoveInNew=Eine alte Datenbankversion wurde gefunden und verschoben, um von der neuen Dolibarr-Version verwendet zu werden.
OldVersionFoundButFailedToMoveInNew=Eine alte Datenbankversion wurde gefunden, konnte jedoch nicht verschoben werden, um mit der neuen Dolibarr-Version verwendet zu werden.
DLLMissing=Your Windows installation is missing The "Microsoft Visual C++ Redistributable for Visual Studio 2017" component. Please install the 32-bit version (vc_redist.x86.exe) first (you can find it at https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#latest-supported-redistributable-version) and restart DoliWamp installation/upgrade after.
DLLMissing=Your Windows installation is missing The "Micrsoft Visual C++ Redistributable for Visual Studio 2017" component. Please install the 32-bit version (vcredist_x86.exe) first (you can find it at https://www.microsoft.com/en-us/download/) and restart DoliWamp installation/upgrade after.
ContinueAnyway=Fahren Sie trotzdem fort (der Installationsvorgang kann ohne diese Voraussetzung fehlschlagen).

View File

@@ -21,7 +21,7 @@ AppVerName=__FILENAMEEXEDOLIWAMP__
; Replace key with DoliWamp-x.x x or DoliWamp-x.x.x-alpha or DoliWamp-x.x.x-beta or DoliWamp-x.x.x-rc or DoliWamp-x.x.x
OutputBaseFilename=__FILENAMEEXEDOLIWAMP__
; ----- End of change
;OutputManifestFile=dev\build\doliwampbuild.log
;OutputManifestFile=build\doliwampbuild.log
; Define full path from which all relative path are defined
; You must modify this to put here your dolibarr root directory
SourceDir=..\..\..\..
@@ -48,28 +48,28 @@ ChangesEnvironment=no
CreateUninstallRegKey=yes
;UseSetupLdr=no
;UninstallDisplayIcon={app}\bidon
OutputDir=dev\build
OutputDir=build
ShowLanguageDialog=auto
ShowUndisplayableLanguages=no
LanguageDetectionMethod=uilanguage
;SignedUninstaller=yes
[Languages]
Name: "en"; MessagesFile: "compiler:Default.isl,dev\build\exe\doliwamp\Languages\MyEnglish.isl"
Name: "br"; MessagesFile: "compiler:Languages\Portuguese.isl,dev\build\exe\doliwamp\Languages\MyBrazilianPortuguese.isl"
Name: "ca"; MessagesFile: "compiler:Languages\Catalan.isl,dev\build\exe\doliwamp\Languages\MyCatalan.isl"
Name: "da"; MessagesFile: "compiler:Languages\Danish.isl,dev\build\exe\doliwamp\Languages\MyDanish.isl"
Name: "es"; MessagesFile: "compiler:Languages\Spanish.isl,dev\build\exe\doliwamp\Languages\MySpanish.isl"
Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl,dev\build\exe\doliwamp\Languages\MyDutch.isl"
Name: "fi"; MessagesFile: "compiler:Languages\Finnish.isl,dev\build\exe\doliwamp\Languages\MyFinnish.isl"
Name: "fr"; MessagesFile: "compiler:Languages\French.isl,dev\build\exe\doliwamp\Languages\MyFrench.isl"
Name: "ge"; MessagesFile: "compiler:Languages\German.isl,dev\build\exe\doliwamp\Languages\MyGerman.isl"
Name: "it"; MessagesFile: "compiler:Languages\Italian.isl,dev\build\exe\doliwamp\Languages\MyItalian.isl"
Name: "nb"; MessagesFile: "compiler:Languages\Norwegian.isl,dev\build\exe\doliwamp\Languages\MyNorwegian.isl"
Name: "po"; MessagesFile: "compiler:Languages\Polish.isl,dev\build\exe\doliwamp\Languages\MyPolish.isl"
Name: "pt"; MessagesFile: "compiler:Languages\Portuguese.isl,dev\build\exe\doliwamp\Languages\MyPortuguese.isl"
Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl,dev\build\exe\doliwamp\Languages\MyRussian.isl"
Name: "sv"; MessagesFile: "compiler:Languages\Slovenian.isl,dev\build\exe\doliwamp\Languages\MySlovenian.isl"
Name: "en"; MessagesFile: "compiler:Default.isl,build\exe\doliwamp\Languages\MyEnglish.isl"
Name: "br"; MessagesFile: "compiler:Languages\Portuguese.isl,build\exe\doliwamp\Languages\MyBrazilianPortuguese.isl"
Name: "ca"; MessagesFile: "compiler:Languages\Catalan.isl,build\exe\doliwamp\Languages\MyCatalan.isl"
Name: "da"; MessagesFile: "compiler:Languages\Danish.isl,build\exe\doliwamp\Languages\MyDanish.isl"
Name: "es"; MessagesFile: "compiler:Languages\Spanish.isl,build\exe\doliwamp\Languages\MySpanish.isl"
Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl,build\exe\doliwamp\Languages\MyDutch.isl"
Name: "fi"; MessagesFile: "compiler:Languages\Finnish.isl,build\exe\doliwamp\Languages\MyFinnish.isl"
Name: "fr"; MessagesFile: "compiler:Languages\French.isl,build\exe\doliwamp\Languages\MyFrench.isl"
Name: "ge"; MessagesFile: "compiler:Languages\German.isl,build\exe\doliwamp\Languages\MyGerman.isl"
Name: "it"; MessagesFile: "compiler:Languages\Italian.isl,build\exe\doliwamp\Languages\MyItalian.isl"
Name: "nb"; MessagesFile: "compiler:Languages\Norwegian.isl,build\exe\doliwamp\Languages\MyNorwegian.isl"
Name: "po"; MessagesFile: "compiler:Languages\Polish.isl,build\exe\doliwamp\Languages\MyPolish.isl"
Name: "pt"; MessagesFile: "compiler:Languages\Portuguese.isl,build\exe\doliwamp\Languages\MyPortuguese.isl"
Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl,build\exe\doliwamp\Languages\MyRussian.isl"
Name: "sv"; MessagesFile: "compiler:Languages\Slovenian.isl,build\exe\doliwamp\Languages\MySlovenian.isl"
[Tasks]
;Name: "autostart"; Description: "Automatically launch DoliWamp server on startup. If you check this option, Services will be installed as automatic. Otherwise, services will be installed as manual and will start and stop with the service manager."; GroupDescription: "Auto Start:" ;Flags: unchecked;
@@ -84,19 +84,19 @@ Name: "{app}\bin\apache\apache2.4.51\logs"
[Files]
; Stop/start
Source: "dev\build\exe\doliwamp\stopdoliwamp.bat"; DestDir: "{app}\"; Flags: ignoreversion; AfterInstall: close()
Source: "dev\build\exe\doliwamp\startdoliwamp.bat"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\install_services.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\uninstall_services.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\removefiles.bat"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\rundoliwamp.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\rundolihelp.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\rundoliadmin.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\mysqlinitpassword.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\mysqltestinstall.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\startdoliwamp_manual_donotuse.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\builddemosslfiles.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\UsedPort.exe"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "build\exe\doliwamp\stopdoliwamp.bat"; DestDir: "{app}\"; Flags: ignoreversion; AfterInstall: close()
Source: "build\exe\doliwamp\startdoliwamp.bat"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "build\exe\doliwamp\install_services.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "build\exe\doliwamp\uninstall_services.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "build\exe\doliwamp\removefiles.bat"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "build\exe\doliwamp\rundoliwamp.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "build\exe\doliwamp\rundolihelp.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "build\exe\doliwamp\rundoliadmin.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "build\exe\doliwamp\mysqlinitpassword.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "build\exe\doliwamp\mysqltestinstall.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "build\exe\doliwamp\startdoliwamp_manual_donotuse.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "build\exe\doliwamp\builddemosslfiles.bat.install"; DestDir: "{app}\"; Flags: ignoreversion;
Source: "build\exe\doliwamp\UsedPort.exe"; DestDir: "{app}\"; Flags: ignoreversion;
; Apache, Php, Mysql
; Put here path of Wampserver applications
@@ -117,16 +117,16 @@ Source: "scripts\*.*"; DestDir: "{app}\www\dolibarr\scripts"; Flags: ignoreversi
Source: "*.*"; DestDir: "{app}\www\dolibarr"; Flags: ignoreversion; Excludes: ".gitignore,.project,CVS\*,Thumbs.db,default.properties,install.lock"
; Config files
Source: "dev\build\exe\doliwamp\dolibarr.conf.install"; DestDir: "{app}\alias"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\httpd.conf.install"; DestDir: "{app}\bin\apache\apache2.4.51\conf"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\my.ini.install"; DestDir: "{app}\bin\mysql\mysql5.0.45"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\my.ini.install"; DestDir: "{app}\bin\mariadb\mariadb10.6.5"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\php.ini.install"; DestDir: "{app}\bin\php\php7.4.26"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\index.php.install"; DestDir: "{app}\www"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\install.forced.php.install"; DestDir: "{app}\www\dolibarr\htdocs\install"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\openssl.conf"; DestDir: "{app}"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\ca_demo_dolibarr.crt"; DestDir: "{app}"; Flags: ignoreversion;
Source: "dev\build\exe\doliwamp\ca_demo_dolibarr.key"; DestDir: "{app}"; Flags: ignoreversion;
Source: "build\exe\doliwamp\dolibarr.conf.install"; DestDir: "{app}\alias"; Flags: ignoreversion;
Source: "build\exe\doliwamp\httpd.conf.install"; DestDir: "{app}\bin\apache\apache2.4.51\conf"; Flags: ignoreversion;
Source: "build\exe\doliwamp\my.ini.install"; DestDir: "{app}\bin\mysql\mysql5.0.45"; Flags: ignoreversion;
Source: "build\exe\doliwamp\my.ini.install"; DestDir: "{app}\bin\mariadb\mariadb10.6.5"; Flags: ignoreversion;
Source: "build\exe\doliwamp\php.ini.install"; DestDir: "{app}\bin\php\php7.4.26"; Flags: ignoreversion;
Source: "build\exe\doliwamp\index.php.install"; DestDir: "{app}\www"; Flags: ignoreversion;
Source: "build\exe\doliwamp\install.forced.php.install"; DestDir: "{app}\www\dolibarr\htdocs\install"; Flags: ignoreversion;
Source: "build\exe\doliwamp\openssl.conf"; DestDir: "{app}"; Flags: ignoreversion;
Source: "build\exe\doliwamp\ca_demo_dolibarr.crt"; DestDir: "{app}"; Flags: ignoreversion;
Source: "build\exe\doliwamp\ca_demo_dolibarr.key"; DestDir: "{app}"; Flags: ignoreversion;
; Licence
Source: "COPYRIGHT"; DestDir: "{app}"; Flags: ignoreversion;

View File

@@ -26,7 +26,6 @@
if (!defined('NOREQUIREDB')) {
define('NOREQUIREDB', '1'); // Do not create database handler $db
}
define('NOREQUIREVIRTUALURL', 1);
$sapi_type = php_sapi_name();
$script_file = basename(__FILE__);
@@ -38,10 +37,6 @@ if (substr($sapi_type, 0, 3) == 'cgi') {
exit(1);
}
define('DOL_DOCUMENT_ROOT', dirname(dirname($path)).'/htdocs');
$algo = 'sha256';
require_once $path."../../htdocs/master.inc.php";
require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
@@ -53,27 +48,17 @@ require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php";
$includecustom = 0;
$includeconstants = array();
$buildzip = 0;
$release = '';
$checklock = '';
print '***** '.$script_file.' *****'."\n";
if (empty($argv[1])) {
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value] [buildzip=1]\n";
print "Usage: ".$script_file." checklock=auto[-mybuild]|x.y.z[-mybuild] unalterable_files\n";
print "\n";
print "Example: ".$script_file." release=6.0.0 includecustom=1 includeconstant=ES:CONST_XX_IS_ON includeconstant=all:MAILING_NO_USING_PHPMAIL:1\n";
print "\n";
print '***** '.$script_file.' *****'."\n";
print "Generate the file filelist-x.y.z[-mybuild].xml with signature of files. ";
print "The file always includes the 3 sections:\n";
print "This includes the 3 sections:\n";
print "- dolibarr_htdocs_dir\n";
print "- dolibarr_scripts_dir\n";
print "- dolibarr_unalterable_files (only files inside the scope of the unalterable module)\n";
print "and if a specific setup/parameter need to be included into the signature for check:\n";
print "- dolibarr_constants\n";
print "\n";
print "If used with parameter 'check_unalterable_files', it will validate that the signature generated is the samethan the one found into lockedfiles.txt";
print "\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value] [buildzip=1]\n";
print "Example: ".$script_file." release=6.0.0 includecustom=1 includeconstant=FR:INVOICE_CAN_ALWAYS_BE_REMOVED:0 includeconstant=all:MAILING_NO_USING_PHPMAIL:1\n";
exit(1);
}
@@ -87,14 +72,14 @@ while ($i < $argc) {
if (!empty($result["release"])) {
$release = $result["release"];
}
if (!empty($result["checklock"])) {
$checklock = $result["checklock"];
}
if (!empty($result["includecustom"])) {
$includecustom = $result["includecustom"];
}
if (preg_match('/unalterable_files/', strval($argv[$i]))) {
$checksource = 'unalterable_files';
if (!empty($result["includeconstant"])) {
$includeconstants[$i] = $result["includeconstant"];
}
if (!empty($result["buildzip"])) {
$buildzip = 1;
}
if (preg_match('/includeconstant=/', strval($argv[$i]))) {
$tmp = explode(':', $result['includeconstant'], 3); // $includeconstant has been set with previous parse_str()
@@ -104,16 +89,12 @@ while ($i < $argc) {
}
$includeconstants[$tmp[0]][$tmp[1]] = $tmp[2];
}
if (!empty($result["buildzip"])) {
$buildzip = 1;
}
$i++;
}
if (empty($release) && empty($checklock)) {
print "Error: Missing release or checklock parameter\n";
if (empty($release)) {
print "Error: Missing release parameter\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
print "Usage: ".$script_file." checklock=auto[-mybuild]|x.y.z[-mybuild] unalterable_files\n";
exit(2);
}
@@ -127,375 +108,325 @@ if ($tmpver[0] == 'auto') {
$release .= '-'.$tmpver[1];
}
}
// If release is auto, we take current version
$tmpver = explode('-', $checklock, 2);
if ($tmpver[0] == 'auto') {
$checklock = DOL_VERSION;
if (!empty($tmpver[1]) && $tmpver[0] == 'auto') {
$checklock .= '-'.$tmpver[1];
}
}
$checklockmajorversion = '';
if ($checklock) {
$checklockmajorversion = preg_replace('/-.*$/', '', $checklock);
$checklockmajorversion = preg_replace('/\..*/', '', $checklockmajorversion);
$checklockmajorversion .= '.0.0';
}
if ($release) {
if (empty($includecustom)) {
$tmpverbis = explode('-', $release, 2);
if (empty($tmpverbis[1])) {
if (DOL_VERSION != $tmpverbis[0] && $savrelease != 'auto') {
print 'Error: When parameter "includecustom" is not set and there is no suffix in release parameter, version declared into filefunc.in.php ('.DOL_VERSION.') must be exactly the same value than "release" parameter ('.$tmpverbis[0].')'."\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
print "\n";
exit(3);
}
} else {
$tmpverter = explode('-', DOL_VERSION, 2);
if ($tmpverter[0] != $tmpverbis[0]) {
print 'Error: When parameter "includecustom" is not set, version declared into filefunc.in.php ('.DOL_VERSION.') must have value without prefix ('.$tmpverter[0].') that is exact same value than "release" parameter ('.$tmpverbis[0].')'."\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
print "\n";
exit(4);
}
if (empty($includecustom)) {
$tmpverbis = explode('-', $release, 2);
if (empty($tmpverbis[1])) {
if (DOL_VERSION != $tmpverbis[0] && $savrelease != 'auto') {
print 'Error: When parameter "includecustom" is not set and there is no suffix in release parameter, version declared into filefunc.in.php ('.DOL_VERSION.') must be exact same value than "release" parameter ('.$tmpverbis[0].')'."\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
exit(3);
}
} else {
if (!preg_match('/'.preg_quote(DOL_VERSION, '/').'-/', $release)) {
print 'Error: When parameter "includecustom" is set, version declared into filefunc.inc.php ('.DOL_VERSION.') must be used with a suffix into "release" parameter (ex: '.DOL_VERSION.'-mydistrib).'."\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
print "\n";
exit(5);
$tmpverter = explode('-', DOL_VERSION, 2);
if ($tmpverter[0] != $tmpverbis[0]) {
print 'Error: When parameter "includecustom" is not set, version declared into filefunc.in.php ('.DOL_VERSION.') must have value without prefix ('.$tmpverter[0].') that is exact same value than "release" parameter ('.$tmpverbis[0].')'."\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
exit(4);
}
}
} else {
if (!preg_match('/'.preg_quote(DOL_VERSION, '/').'-/', $release)) {
print 'Error: When parameter "includecustom" is set, version declared into filefunc.inc.php ('.DOL_VERSION.') must be used with a suffix into "release" parameter (ex: '.DOL_VERSION.'-mydistrib).'."\n";
print "Usage: ".$script_file." release=auto[-mybuild]|x.y.z[-mybuild] [includecustom=1] [includeconstant=CC:MY_CONF_NAME:value]\n";
exit(5);
}
}
if ($checklock && empty($checksource)) {
print 'Error: When action "checklock" is set, second parameter must be the scope family to check, for example "unalterable_files"'."\n";
print "Usage: ".$script_file." checklock=auto[-mybuild]|x.y.z[-mybuild] unalterable_files\n";
print "\n";
print "Working on files into : ".DOL_DOCUMENT_ROOT."\n";
print "Release : ".$release."\n";
print "Include custom dir in signature : ".(empty($includecustom) ? 'no' : 'yes')."\n";
print "Include constants in signature : ".(empty($includeconstants) ? 'none' : '');
foreach ($includeconstants as $countrycode => $tmp) {
foreach ($tmp as $constname => $constvalue) {
print $constname.'='.$constvalue." ";
}
}
print "\n";
//$outputfile=dirname(__FILE__).'/../htdocs/install/filelist-'.$release.'.xml';
$outputdir = dirname(dirname(dirname(__FILE__))).'/htdocs/install';
print 'Delete current files '.$outputdir.'/filelist*.xml*'."\n";
dol_delete_file($outputdir.'/filelist*.xml*', 0, 1, 1);
$checksumconcat = array();
$outputfile = $outputdir.'/filelist-'.$release.'.xml';
$fp = fopen($outputfile, 'w');
if (empty($fp)) {
print 'Failed to open file '.$outputfile."\n";
exit(6);
}
if ($release) {
print "Working on files into : ".DOL_DOCUMENT_ROOT."\n";
print "Version of target release : ".$release."\n";
print "Include custom dir in signature : ".(empty($includecustom) ? 'no' : 'yes')."\n";
print "Include constants in signature : ".(empty($includeconstants) ? 'none' : '');
foreach ($includeconstants as $countrycode => $tmp) {
foreach ($tmp as $constname => $constvalue) {
print $constname.'='.$constvalue." ";
}
}
print "\n";
$gitcommit = 'seetag';
$branchname = preg_replace('/^(\d+\.\d+)\..*$/', '\1', $release); // Keep only x.y into x.y.z
$fileforgit = dirname(dirname(dirname(__FILE__))).'/.git/refs/heads/'.$branchname;
print "Try to get last commit ID from file ".$fileforgit."\n";
$fileforgitcontent = '';
if (file_exists($fileforgit)) {
$fileforgitcontent = file_get_contents($fileforgit);
}
if ($checklock) {
print "Working on files into : ".DOL_DOCUMENT_ROOT."\n";
print "Version to check in lockedfiles.txt : ".$checklockmajorversion."\n";
print "Check source : ".$checksource."\n";
}
if ($release) {
//$outputfile=dirname(__FILE__).'/../htdocs/install/filelist-'.$release.'.xml';
$outputdir = dirname(dirname(dirname(__FILE__))).'/htdocs/install';
print 'Delete current files '.$outputdir.'/filelist*.xml*'."\n";
dol_delete_file($outputdir.'/filelist*.xml*', 0, 1, 1);
if (empty($fileforgitcontent)) {
print "Failed to get the last commit ID. Are you on the branch for the release (branch name ".$branchname.") ?\n";
}
$gitcommit = trim($fileforgitcontent);
fputs($fp, '<?xml version="1.0" encoding="UTF-8" ?>'."\n");
fputs($fp, '<checksum_list version="'.$release.'" date="'.dol_print_date(dol_now(), 'dayhourrfc').'" generator="'.$script_file.'" gitcommit="'.$gitcommit.'">'."\n");
$needtoclose = 0;
// Build the XML file
if ($release) {
$checksumconcat = array();
$outputfile = $outputdir.'/filelist-'.$release.'.xml';
$fp = fopen($outputfile, 'w');
if (empty($fp)) {
print 'Failed to open file '.$outputfile."\n";
exit(7);
foreach ($includeconstants as $countrycode => $tmp) {
fputs($fp, '<dolibarr_constants country="'.$countrycode.'">'."\n");
foreach ($tmp as $constname => $constvalue) {
$valueforchecksum = (empty($constvalue) ? '0' : $constvalue);
$checksumconcat[] = $valueforchecksum;
fputs($fp, ' <constant name="'.$constname.'">'.$valueforchecksum.'</constant>'."\n");
}
$gitcommit = 'seetag';
$branchname = preg_replace('/^(\d+\.\d+)\..*$/', '\1', $release); // Keep only x.y into x.y.z
$fileforgit = dirname(dirname(dirname(__FILE__))).'/.git/refs/heads/'.$branchname;
print "Try to get last commit ID from file ".$fileforgit."\n";
$fileforgitcontent = '';
if (file_exists($fileforgit)) {
$fileforgitcontent = file_get_contents($fileforgit);
}
if (empty($fileforgitcontent)) {
print "Failed to get the last commit ID (are you on the branch for the release branch name ".$branchname." ?). We will use an empty value for gitcommit.\n";
}
$gitcommit = trim($fileforgitcontent);
fputs($fp, '<?xml version="1.0" encoding="UTF-8" ?>'."\n");
fputs($fp, '<checksum_list version="'.$release.'" date="'.dol_print_date(dol_now(), 'dayhourrfc').'" generator="'.$script_file.'" algo="'.$algo.'" gitcommit="'.$gitcommit.'">'."\n");
foreach ($includeconstants as $countrycode => $tmp) {
fputs($fp, '<dolibarr_constants country="'.$countrycode.'">'."\n");
foreach ($tmp as $constname => $constvalue) {
$valueforchecksum = (empty($constvalue) ? '0' : $constvalue);
$checksumconcat[] = $valueforchecksum;
fputs($fp, ' <constant name="'.$constname.'">'.$valueforchecksum.'</constant>'."\n");
}
fputs($fp, '</dolibarr_constants>'."\n\n");
}
fputs($fp, '<dolibarr_htdocs_dir includecustom="'.$includecustom.'">'."\n");
// Define qualified files (must be same than into generate_filelist_xml.php and in api_setup.class.php)
$regextoinclude = '\.(php|php3|php4|php5|phtml|phps|phar|inc|css|scss|html|xml|js|json|tpl|jpg|jpeg|png|gif|ico|sql|lang|txt|yml|bak|md|mp3|mp4|wav|mkv|z|gz|zip|rar|tar|less|svg|eot|woff|woff2|ttf|manifest)$';
$regextoexclude = '('.($includecustom ? '' : 'custom|').'documents|escpos-php\/doc|escpos-php\/example|escpos-php\/test|conf|install|dejavu-fonts-ttf-.*|public\/test|sabre\/sabre\/.*\/tests|Shared\/PCLZip|nusoap\/lib\/Mail|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
$files = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
$dir = '';
foreach ($files as $filetmp) {
$file = $filetmp['fullname'];
//$newdir = str_replace(dirname(__FILE__).'/../htdocs', '', dirname($file));
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$hashoffile = hash_file($algo, $file);
$checksumconcat[] = $hashoffile;
fputs($fp, ' <'.$algo.'file name="'.basename($file).'" size="'.filesize($file).'">'.$hashoffile.'</'.$algo.'file>'."\n");
}
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, '</dolibarr_htdocs_dir>'."\n");
asort($checksumconcat); // Sort list of checksum
$hashhtdocsdir = hash($algo, join(',', $checksumconcat));
fputs($fp, '<dolibarr_htdocs_dir_checksum>'."\n");
fputs($fp, $hashhtdocsdir."\n");
fputs($fp, '</dolibarr_htdocs_dir_checksum>'."\n\n");
// Add the checksum for the part in scripts
$checksumconcat = array();
fputs($fp, '<dolibarr_scripts_dir version="'.$release.'">'."\n");
$regextoinclude = '\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$';
$regextoexclude = '(custom|documents|conf|install)$'; // Exclude dirs
$files = dol_dir_list(dirname(__FILE__).'/../../scripts/', 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
$dir = '';
foreach ($files as $filetmp) {
$file = $filetmp['fullname'];
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
$newdir = str_replace(dirname(__FILE__).'/../../scripts', '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$hashoffile = hash_file($algo, $file);
$checksumconcat[] = $hashoffile;
fputs($fp, ' <'.$algo.'file name="'.basename($file).'" size="'.filesize($file).'">'.$hashoffile.'</'.$algo.'file>'."\n");
}
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, '</dolibarr_scripts_dir>'."\n");
asort($checksumconcat); // Sort list of checksum
$hashscriptsdir = hash($algo, join(',', $checksumconcat));
fputs($fp, '<dolibarr_scripts_dir_checksum>'."\n");
fputs($fp, $hashscriptsdir."\n");
fputs($fp, '</dolibarr_scripts_dir_checksum>'."\n\n");
fputs($fp, '</dolibarr_constants>'."\n\n");
}
fputs($fp, '<dolibarr_htdocs_dir includecustom="'.$includecustom.'">'."\n");
// Define qualified files (must be same than into generate_filelist_xml.php and in api_setup.class.php)
$regextoinclude = '\.(php|php3|php4|php5|phtml|phps|phar|inc|css|scss|html|xml|js|json|tpl|jpg|jpeg|png|gif|ico|sql|lang|txt|yml|bak|md|mp3|mp4|wav|mkv|z|gz|zip|rar|tar|less|svg|eot|woff|woff2|ttf|manifest)$';
$regextoexclude = '('.($includecustom ? '' : 'custom|').'documents|escpos-php\/doc|escpos-php\/example|escpos-php\/test|conf|install|dejavu-fonts-ttf-.*|public\/test|sabre\/sabre\/.*\/tests|Shared\/PCLZip|nusoap\/lib\/Mail|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
$files = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
$dir = '';
foreach ($files as $filetmp) {
$file = $filetmp['fullname'];
//$newdir = str_replace(dirname(__FILE__).'/../htdocs', '', dirname($file));
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$md5 = md5_file($file);
$checksumconcat[] = $md5;
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
}
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, '</dolibarr_htdocs_dir>'."\n");
asort($checksumconcat); // Sort list of checksum
fputs($fp, '<dolibarr_htdocs_dir_checksum>'."\n");
fputs($fp, md5(join(',', $checksumconcat))."\n");
fputs($fp, '</dolibarr_htdocs_dir_checksum>'."\n\n");
// Add the checksum for the part in scripts
$checksumconcat = array();
fputs($fp, '<dolibarr_script_dir version="'.$release.'">'."\n");
$regextoinclude = '\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$';
$regextoexclude = '(custom|documents|conf|install)$'; // Exclude dirs
$files = dol_dir_list(dirname(__FILE__).'/../../scripts/', 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
$dir = '';
foreach ($files as $filetmp) {
$file = $filetmp['fullname'];
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
$newdir = str_replace(dirname(__FILE__).'/../../scripts', '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$md5 = md5_file($file);
$checksumconcat[] = $md5;
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
}
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, '</dolibarr_script_dir>'."\n");
asort($checksumconcat); // Sort list of checksum
fputs($fp, '<dolibarr_script_dir_checksum>'."\n");
fputs($fp, md5(join(',', $checksumconcat))."\n");
fputs($fp, '</dolibarr_script_dir_checksum>'."\n\n");
// Add the checksum for the files into the scope of the unalterable system (record, read, export)
$checksumconcat = array();
if ($release) {
fputs($fp, '<dolibarr_unalterable_files version="'.$release.'">'."\n");
}
fputs($fp, '<dolibarr_unalterable_files version="'.$release.'">'."\n");
// Array of dir/files to include in the section
$arrayofunalterablefiles = array(
array('dir' => dirname(__FILE__).'/../../htdocs/', 'file' => 'version.inc.php'),
array('dir' => dirname(__FILE__).'/../../htdocs/blockedlog', 'file' => 'all', 'regextoinclude' => '(\.php|\.sql)$', 'regextoexclude' => ''),
array('dir' => dirname(__FILE__).'/../../htdocs/install/mysql/tables', 'file' => 'all', 'regextoinclude' => 'llx_blockedlog.*(\.php|\.sql)$', 'regextoexclude' => ''),
array('dir' => dirname(__FILE__).'/../../htdocs/core/triggers', 'file' => 'interface_50_modBlockedlog_ActionsBlockedLog.class.php'),
array('dir' => dirname(__FILE__).'/../../htdocs/core/class', 'file' => 'all', 'regextoinclude' => '(interfaces.class.php|commontrigger.class.php)$', 'regextoexclude' => ''),
array('dir' => dirname(__FILE__).'/../../htdocs/takepos', 'file' => 'receipt.php')
);
foreach ($arrayofunalterablefiles as $entry) {
if ($entry['file'] == 'all') {
$regextoinclude = $entry['regextoinclude'];
$regextoexclude = $entry['regextoexclude'];
$files = dol_dir_list($entry['dir'], 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
$dir = '';
foreach ($files as $filetmp) {
$file = $filetmp['fullname'];
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
$newdir = str_replace(dirname(__FILE__).'/../../htdocs', '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
if ($release) {
fputs($fp, ' </dir>'."\n");
}
$needtoclose = 0;
}
if ($release) {
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
}
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$hashoffile = hash_file($algo, $file);
$checksumconcat[] = $hashoffile;
if ($release) {
fputs($fp, ' <'.$algo.'file name="'.basename($file).'" size="'.filesize($file).'">'.$hashoffile.'</'.$algo.'file>'."\n");
}
}
}
$regextoinclude = '(\.php|\.sql)$';
$regextoexclude = ''; // Exclude dirs
$files = dol_dir_list(dirname(__FILE__).'/../../htdocs/blockedlog', 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
$dir = '';
foreach ($files as $filetmp) {
$file = $filetmp['fullname'];
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
$newdir = str_replace(dirname(__FILE__).'/../../htdocs', '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
if ($release) {
fputs($fp, ' </dir>'."\n");
}
$needtoclose = 0;
}
} else {
$file = $entry['dir'].'/'.$entry['file'];
$dir = '';
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
$newdir = str_replace(dirname(__FILE__).'/../../htdocs', '', dirname($file));
if (!file_exists($file)) {
print "Error file ".$file." does not exists.";
exit(1);
}
if ($newdir != $dir) {
if ($needtoclose) {
if ($release) {
fputs($fp, ' </dir>'."\n");
}
$needtoclose = 0;
}
if ($release) {
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
}
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$hashoffile = hash_file($algo, $file);
$checksumconcat[] = $hashoffile;
if ($release) {
fputs($fp, ' <'.$algo.'file name="'.basename($file).'" size="'.filesize($file).'">'.$hashoffile.'</'.$algo.'file>'."\n");
}
}
if ($needtoclose) {
if ($release) {
fputs($fp, ' </dir>'."\n");
}
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$md5 = md5_file($file);
$checksumconcat[] = $md5;
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
}
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
// Add the SQL file
$regextoinclude = 'llx_blockedlog.*(\.php|\.sql)$';
$regextoexclude = ''; // Exclude dirs
$files = dol_dir_list(dirname(__FILE__).'/../../htdocs/install/mysql/tables', 'files', 0, $regextoinclude, $regextoexclude, 'fullname');
foreach ($files as $filetmp) {
$file = $filetmp['fullname'];
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
$newdir = str_replace(dirname(__FILE__).'/../../htdocs', '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$md5 = md5_file($file);
$checksumconcat[] = $md5;
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
}
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
// Add the trigger file
$file = dirname(__FILE__).'/../../htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php';
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
$newdir = str_replace(dirname(__FILE__).'/../../htdocs', '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
$dir = $newdir;
$needtoclose = 1;
}
if (filetype($file) == "file") {
$md5 = md5_file($file);
$checksumconcat[] = $md5;
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
// Add the interfaces.class.php file
$file = dirname(__FILE__).'/../../htdocs/core/class/interfaces.class.php';
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
$newdir = str_replace(dirname(__FILE__).'/../../htdocs', '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
$dir = $newdir;
//$needtoclose = 1; // close will be done in next filethat is in same dir
}
if (filetype($file) == "file") {
$md5 = md5_file($file);
$checksumconcat[] = $md5;
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
// Add the commontrigger.class.php file
$file = dirname(__FILE__).'/../../htdocs/core/class/commontrigger.class.php';
$newdir = str_replace(DOL_DOCUMENT_ROOT, '', dirname($file));
$newdir = str_replace(dirname(__FILE__).'/../../htdocs', '', dirname($file));
if ($newdir != $dir) {
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, ' <dir name="'.$newdir.'">'."\n");
$dir = $newdir;
$needtoclose = 1;
}
$needtoclose = 1; // This is the last file
if (filetype($file) == "file") {
$md5 = md5_file($file);
$checksumconcat[] = $md5;
fputs($fp, ' <md5file name="'.basename($file).'" size="'.filesize($file).'">'.$md5.'</md5file>'."\n");
}
if ($needtoclose) {
fputs($fp, ' </dir>'."\n");
$needtoclose = 0;
}
fputs($fp, '</dolibarr_unalterable_files>'."\n");
asort($checksumconcat); // Sort list of checksum
$hashunalterable_files = hash($algo, join(',', $checksumconcat));
fputs($fp, '<dolibarr_unalterable_files_checksum>'."\n");
fputs($fp, md5(join(',', $checksumconcat))."\n");
fputs($fp, '</dolibarr_unalterable_files_checksum>'."\n\n");
if ($release) {
fputs($fp, '</dolibarr_unalterable_files>'."\n");
fputs($fp, '<dolibarr_unalterable_files_checksum>'."\n");
fputs($fp, $hashunalterable_files."\n");
fputs($fp, '</dolibarr_unalterable_files_checksum>'."\n\n");
// End of file
// End of file
fputs($fp, '</checksum_list>'."\n");
fclose($fp);
}
fputs($fp, '</checksum_list>'."\n");
fclose($fp);
print "\n";
if ($release) {
if (empty($buildzip)) {
print "File ".$outputfile." generated.\n";
print "Signature for htdocs files: ".$hashhtdocsdir."\n";
print "Signature for scripts files: ".$hashscriptsdir."\n";
print "Signature for the ".count($checksumconcat)." unalterable files: ".$hashunalterable_files."\n";
} else {
if ($buildzip == '1' || $buildzip == 'zip') {
$result = dol_compress_file($outputfile, $outputfile.'.zip', 'zip');
if ($result > 0) {
dol_delete_file($outputfile);
print "File ".$outputfile.".zip generated.\n";
}
} elseif ($buildzip == '2' || $buildzip == 'gz') {
$result = dol_compress_file($outputfile, $outputfile.'.gz', 'gz');
if ($result > 0) {
dol_delete_file($outputfile);
print "File ".$outputfile.".gz generated.\n";
}
if (empty($buildzip)) {
print "File ".$outputfile." generated\n";
} else {
if ($buildzip == '1' || $buildzip == 'zip') {
$result = dol_compress_file($outputfile, $outputfile.'.zip', 'zip');
if ($result > 0) {
dol_delete_file($outputfile);
print "File ".$outputfile.".zip generated\n";
}
} elseif ($buildzip == '2' || $buildzip == 'gz') {
$result = dol_compress_file($outputfile, $outputfile.'.gz', 'gz');
if ($result > 0) {
dol_delete_file($outputfile);
print "File ".$outputfile.".gz generated\n";
}
}
}
if ($checklock) {
print "Signature for unalterable files: ".$algo." ".$hashunalterable_files."\n";
$lockedfile = DOL_DOCUMENT_ROOT.'/../dev/lockedfiles.txt';
$checksuminlockedfile = '';
if (!file_exists($lockedfile)) {
print "Can't find the file ".$lockedfile.". No checksum to check\n";
} else {
// Now we check the content of lockedfiles.txt
$arraylocked = file($lockedfile);
foreach ($arraylocked as $line) {
$tmparray = preg_split("/\s+/", $line, 4);
if ($tmparray[0] == $checklockmajorversion && $tmparray[2] == $algo) {
$checksuminlockedfile = $tmparray[3];
}
}
if (empty($checksuminlockedfile)) {
print "The major version ".$checklockmajorversion." is not locked on the scope '".$checksource."' (file found but no matching entry found into dev/lockedfiles.txt).\n";
} elseif ($checksuminlockedfile != $hashunalterable_files) {
print "The major version ".$checklockmajorversion." is locked on scope '".$checksource."' to checksum ".$algo." ".$checksuminlockedfile."\n";
if ($checklockmajorversion != $checksource) {
print "The checksum now differs from the locked one, so we return an error.\n";
print "\n";
exit(10);
}
}
}
}
print "\n";
exit(0);

View File

@@ -1,5 +1,4 @@
#!/usr/bin/perl
## no critic (InputOutput::RequireBriefOpen)
#fetch Gravatars
use strict;
@@ -11,44 +10,39 @@ use Digest::MD5 qw(md5_hex);
my $size = 90;
my $output_dir = './avatars';
die("no .git repository found in current path\n") unless -r './.git';
die("no .git/ directory found in current path\n") unless -d './avatars';
mkdir($output_dir) unless -d $output_dir;
open( my $GITLOG, '-|', q/git log --pretty=format:"%ae|%an" --reverse/ )
or die("failed to read git-log: $!\n");
open(GITLOG, q/git log --pretty=format:"%ae|%an" |/) or die("failed to read git-log: $!\n");
my %processed_authors;
while (<$GITLOG>) {
chomp;
my ( $email, $author ) = split( /\|/, $_ );
while(<GITLOG>) {
chomp;
my($email, $author) = split(/\|/, $_);
next if $processed_authors{$author}++;
next if $processed_authors{$author}++;
my $author_image_file = $output_dir . '/' . $author . '.png';
my $author_image_file = $output_dir . '/' . $author . '.png';
#skip images we have
next if -e $author_image_file;
#skip images we have
next if -e $author_image_file;
#try and fetch image
#try and fetch image
my $grav_url =
"https://www.gravatar.com/avatar/"
. md5_hex( lc $email )
. "?d=404&size="
. $size;
my $grav_url = "http://www.gravatar.com/avatar/".md5_hex(lc $email)."?d=404&size=".$size;
warn "fetching image for '$author' $email ($grav_url)...\n";
warn "fetching image for '$author' $email ($grav_url)...\n";
my $rc = getstore( $grav_url, $author_image_file );
my $rc = getstore($grav_url, $author_image_file);
sleep(1);
sleep(1);
if ( $rc != 200 ) {
unlink($author_image_file);
next;
}
if($rc != 200) {
unlink($author_image_file);
next;
}
}
close $GITLOG;
close GITLOG;

File diff suppressed because it is too large Load Diff

View File

@@ -5,288 +5,223 @@
# \author (c)2005-2014 Laurent Destailleur <eldy@users.sourceforge.net>
# \contributor (c)2017 Nicolas ZABOURI <info@inovea-conseil.com>
#----------------------------------------------------------------------------
## no critic (InputOutput::ProhibitExplicitStdin,InputOutput::RequireBriefOpen)
use strict;
use warnings;
use Cwd;
use Term::ANSIColor;
$OWNER = "ldestailleur";
$GROUP = "ldestailleur";
$OWNER="ldestailleur";
$GROUP="ldestailleur";
@LISTETARGET = ("ZIP"); # Possible packages
%REQUIREMENTTARGET = ( # Tool requirement for each package
"TGZ" => "tar",
"ZIP" => "7z"
@LISTETARGET=("ZIP"); # Possible packages
%REQUIREMENTTARGET=( # Tool requirement for each package
"TGZ"=>"tar",
"ZIP"=>"7z"
);
%ALTERNATEPATH = ();
%ALTERNATEPATH=(
);
use vars qw/ $REVISION $VERSION /;
$REVISION = '1.0';
$VERSION = "3.5 (build $REVISION)";
$REVISION='1.0';
$VERSION="3.5 (build $REVISION)";
#------------------------------------------------------------------------------
# MAIN
#------------------------------------------------------------------------------
( $DIR = $0 ) =~ s/([^\/\\]+)$//;
( $PROG = $1 ) =~ s/\.([^\.]*)$//;
$Extension = $1;
$DIR ||= '.';
$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
($DIR=$0) =~ s/([^\/\\]+)$//; ($PROG=$1) =~ s/\.([^\.]*)$//; $Extension=$1;
$DIR||='.'; $DIR =~ s/([^\/\\])[\\\/]+$/$1/;
# Detect OS type
# --------------
if ( "$^O" =~ /linux/i || ( -d "/etc" && -d "/var" && "$^O" !~ /cygwin/i ) ) {
$OS = 'linux';
$CR = '';
}
elsif ( -d "/etc" && -d "/Users" ) { $OS = 'macosx'; $CR = ''; }
elsif ( "$^O" =~ /cygwin/i || "$^O" =~ /win32/i ) {
$OS = 'windows';
$CR = "\r";
}
if ( !$OS ) {
print "$PROG.$Extension was not able to detect your OS.\n";
if ("$^O" =~ /linux/i || (-d "/etc" && -d "/var" && "$^O" !~ /cygwin/i)) { $OS='linux'; $CR=''; }
elsif (-d "/etc" && -d "/Users") { $OS='macosx'; $CR=''; }
elsif ("$^O" =~ /cygwin/i || "$^O" =~ /win32/i) { $OS='windows'; $CR="\r"; }
if (! $OS) {
print "$PROG.$Extension was not able to detect your OS.\n";
print "Can't continue.\n";
print "$PROG.$Extension aborted.\n";
sleep 2;
sleep 2;
exit 1;
}
# Define buildroot
# ----------------
if ( $OS =~ /linux/ ) {
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "/tmp";
if ($OS =~ /linux/) {
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"/tmp";
}
if ( $OS =~ /macos/ ) {
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "/tmp";
if ($OS =~ /macos/) {
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"/tmp";
}
if ( $OS =~ /windows/ ) {
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "c:/temp";
$PROGPATH = $ENV{"ProgramFiles"};
if ($OS =~ /windows/) {
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"c:/temp";
$PROGPATH=$ENV{"ProgramFiles"};
}
if ( !$TEMP || !-d $TEMP ) {
print "Error: A temporary directory can not be find.\n";
print "Check that TEMP or TMP environment variable is set correctly.\n";
if (! $TEMP || ! -d $TEMP) {
print "Error: A temporary directory can not be find.\n";
print "Check that TEMP or TMP environment variable is set correctly.\n";
print "$PROG.$Extension aborted.\n";
sleep 2;
exit 2;
sleep 2;
exit 2;
}
$BUILDROOT = "$TEMP/dolibarr-buildroot";
$BUILDROOT="$TEMP/dolibarr-buildroot";
my $copyalreadydone = 0;
my $batch = 0;
for ( 0 .. @ARGV - 1 ) {
if ( $ARGV[$_] =~ /^-*target=(\w+)/i ) { $target = $1; $batch = 1; }
if ( $ARGV[$_] =~ /^-*desti=(.+)/i ) { $DESTI = $1; }
if ( $ARGV[$_] =~ /^-*prefix=(.+)/i ) {
$PREFIX = $1;
$FILENAMESNAPSHOT .= "-" . $PREFIX;
}
my $copyalreadydone=0;
my $batch=0;
for (0..@ARGV-1) {
if ($ARGV[$_] =~ /^-*target=(\w+)/i) { $target=$1; $batch=1; }
if ($ARGV[$_] =~ /^-*desti=(.+)/i) { $DESTI=$1; }
if ($ARGV[$_] =~ /^-*prefix=(.+)/i) {
$PREFIX=$1;
$FILENAMESNAPSHOT.="-".$PREFIX;
}
}
$SOURCE = "$DIR/../..";
$DESTI = "$SOURCE/dev/build";
if ( $ENV{"DESTIMODULES"} ) {
$DESTI = $ENV{"DESTIMODULES"};
} # Force output dir if env DESTIMODULES is defined
$NEWDESTI = $DESTI;
$SOURCE="$DIR/../..";
$DESTI="$SOURCE/dev/build";
if ($ENV{"DESTIMODULES"}) { $DESTI = $ENV{"DESTIMODULES"}; } # Force output dir if env DESTIMODULES is defined
$NEWDESTI=$DESTI;
print "Makepack for modules version $VERSION\n";
print "Source directory: $SOURCE\n";
print "Target directory: $NEWDESTI\n";
# Ask module
print
"Enter name for your module (mymodule, mywonderfullmodule, ... or 'all') : ";
my $PROJECTINPUT = <STDIN>;
print "Enter name for your module (mymodule, mywonderfulmondule, ... or 'all') : ";
$PROJECTINPUT=<STDIN>;
chomp($PROJECTINPUT);
print "Move to " . $DIR . " directory.\n";
print "Move to ".$DIR." directory.\n";
chdir($DIR);
my @PROJECTLIST = ();
if ( $PROJECTINPUT eq "all" ) {
opendir( my $DIR, $DIR ) or return;
local @rv = grep { /^makepack\-(.*)\.conf$/ } sort readdir($DIR);
closedir($DIR);
foreach my $xxx ( 0 .. @rv - 1 ) {
if ( $rv[$xxx] =~ /^makepack\-(.*)\.conf$/ ) {
@PROJECTLIST[$xxx] = $1;
}
}
my @PROJECTLIST=();
if ($PROJECTINPUT eq "all")
{
opendir(DIR, $DIR) || return;
local @rv = grep { /^makepack\-(.*)\.conf$/ } sort readdir(DIR);
closedir(DIR);
foreach my $xxx (0..@rv-1) {
if ($rv[$xxx] =~ /^makepack\-(.*)\.conf$/)
{
@PROJECTLIST[$xxx]=$1;
}
}
}
else {
@PROJECTLIST = ($PROJECTINPUT);
else
{
@PROJECTLIST=($PROJECTINPUT);
}
# Loop on each projects
foreach my $PROJECT (@PROJECTLIST) {
$PROJECTLC = lc($PROJECT);
$PROJECTLC=lc($PROJECT);
if ( !-f "makepack-" . $PROJECT . ".conf" ) {
print "Error: can't open conf file makepack-" . $PROJECT . ".conf\n";
if (! -f "makepack-".$PROJECT.".conf")
{
print "Error: can't open conf file makepack-".$PROJECT.".conf\n";
print "\n";
print "For help on building a module package, see web page\n";
print
"http://wiki.dolibarr.org/index.php/Module_development#Create_a_package_to_distribute_and_install_your_module\n";
print "http://wiki.dolibarr.org/index.php/Module_development#Create_a_package_to_distribute_and_install_your_module\n";
print "makepack-dolibarrmodule.pl aborted.\n";
sleep 2;
exit 2;
sleep 2;
exit 2;
}
# Get version $MAJOR, $MINOR and $BUILD
print "Version detected for module "
. $PROJECT
. " in file "
. $SOURCE
. "/htdocs/"
. $PROJECTLC
. "/core/modules/mod"
. ucfirst($PROJECT)
. ".class.php";
$result = open(
my $IN,
"<",
$SOURCE
. "/htdocs/"
. $PROJECTLC
. "/core/modules/mod"
. ucfirst($PROJECT)
. ".class.php"
);
$custom = false;
if ( !$result ) {
$result = open(
my $IN,
"<",
$SOURCE
. "/htdocs/custom/"
. $PROJECTLC
. "/core/modules/mod"
. ucfirst($PROJECT)
. ".class.php"
);
if ( !$result ) {
die "Error: Can't open descriptor file "
. $SOURCE
. "/htdocs/(or /htdocs/custom/)"
. $PROJECTLC
. "/core/modules/mod"
. ucfirst($PROJECT)
. ".class.php for reading.\n";
}
}
else {
$custom = true;
}
while (<$IN>) {
if ( $_ =~ /this->version\s*=\s*'([\d\.]+)'/ ) {
$PROJVERSION = $1;
break;
}
}
close $IN;
print $PROJVERSION. "\n";
print "Version detected for module ".$PROJECT." in file ".$SOURCE."/htdocs/".$PROJECTLC."/core/modules/mod".ucfirst($PROJECT).".class.php";
$result=open(IN,"<".$SOURCE."/htdocs/".$PROJECTLC."/core/modules/mod".ucfirst($PROJECT).".class.php");
$custom=false;
if (! $result) {
$result=open(IN,"<".$SOURCE."/htdocs/custom/".$PROJECTLC."/core/modules/mod".ucfirst($PROJECT).".class.php");
if (! $result) {
die "Error: Can't open descriptor file ".$SOURCE."/htdocs/(or /htdocs/custom/)".$PROJECTLC."/core/modules/mod".ucfirst($PROJECT).".class.php for reading.\n";
}else{
$custom = true;
}
}
while(<IN>)
{
if ($_ =~ /this->version\s*=\s*'([\d\.]+)'/) { $PROJVERSION=$1; break; }
}
close IN;
print $PROJVERSION."\n";
( $MAJOR, $MINOR, $BUILD ) = split( /\./, $PROJVERSION, 3 );
if ( $MINOR eq '' ) {
print "Enter value for minor version for module " . $PROJECT . ": ";
$MINOR = <STDIN>;
chomp($MINOR);
($MAJOR,$MINOR,$BUILD)=split(/\./,$PROJVERSION,3);
if ($MINOR eq '')
{
print "Enter value for minor version for module ".$PROJECT.": ";
$MINOR=<STDIN>;
chomp($MINOR);
}
$FILENAME = "$PROJECTLC";
$FILENAMETGZ =
"module_$PROJECTLC-$MAJOR.$MINOR" . ( $BUILD ne '' ? ".$BUILD" : "" );
$FILENAMEZIP =
"module_$PROJECTLC-$MAJOR.$MINOR" . ( $BUILD ne '' ? ".$BUILD" : "" );
if ( -d "/usr/src/redhat" ) {
# redhat
$RPMDIR = "/usr/src/redhat";
$FILENAME="$PROJECTLC";
$FILENAMETGZ="module_$PROJECTLC-$MAJOR.$MINOR".($BUILD ne ''?".$BUILD":"");
$FILENAMEZIP="module_$PROJECTLC-$MAJOR.$MINOR".($BUILD ne ''?".$BUILD":"");
if (-d "/usr/src/redhat") {
# redhat
$RPMDIR="/usr/src/redhat";
}
if ( -d "/usr/src/RPM" ) {
# mandrake
$RPMDIR = "/usr/src/RPM";
if (-d "/usr/src/RPM") {
# mandrake
$RPMDIR="/usr/src/RPM";
}
# Choose package targets
#-----------------------
$target = "ZIP"; # Dolibarr modules are this format
$CHOOSEDTARGET{ uc($target) } = 1;
$target="ZIP"; # Dolibarr modules are this format
$CHOOSEDTARGET{uc($target)}=1;
# Test if requirement is ok
#--------------------------
foreach my $target ( keys %CHOOSEDTARGET ) {
foreach my $req ( split( /[,\s]/, $REQUIREMENTTARGET{$target} ) ) {
foreach my $target (keys %CHOOSEDTARGET) {
foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target})) {
# Test
print "Test requirement for target $target: Search '$req'... ";
$ret=`"$req" 2>&1`;
$coderetour=$?; $coderetour2=$coderetour>>8;
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) {
# Not found error, we try in PROGPATH
$ret=`"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
$coderetour=$?; $coderetour2=$coderetour>>8;
$REQUIREMENTTARGET{$target}="$PROGPATH/$ALTERNATEPATH{$req}/$req";
}
# Test
print "Test requirement for target $target: Search '$req'... ";
$ret = `"$req" 2>&1`;
$coderetour = $?;
$coderetour2 = $coderetour >> 8;
if (
$coderetour != 0
&& (
(
$coderetour2 == 1
&& $OS =~ /windows/
&& $ret !~ /Usage/i
)
|| ( $coderetour2 == 127 && $OS !~ /windows/ )
)
&& $PROGPATH
)
{
# Not found error, we try in PROGPATH
$ret = `"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
$coderetour = $?;
$coderetour2 = $coderetour >> 8;
$REQUIREMENTTARGET{$target} =
"$PROGPATH/$ALTERNATEPATH{$req}/$req";
}
if (
$coderetour != 0
&& (
(
$coderetour2 == 1
&& $OS =~ /windows/
&& $ret !~ /Usage/i
)
|| ( $coderetour2 == 127 && $OS !~ /windows/ )
)
)
{
# Not found error
print
"Not found\nCan't build target $target. Requirement '$req' not found in PATH\n";
$CHOOSEDTARGET{$target} = -1;
last;
}
else {
# Pas erreur ou erreur autre que programme absent
print " Found " . $REQUIREMENTTARGET{$target} . "\n";
}
}
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/))) {
# Not found error
print "Not found\nCan't build target $target. Requirement '$req' not found in PATH\n";
$CHOOSEDTARGET{$target}=-1;
last;
} else {
# Pas erreur ou erreur autre que programme absent
print " Found ".$REQUIREMENTTARGET{$target}."\n";
}
}
}
print "\n";
# Check if there is at least one target to build
# Check if there is at least on target to build
#----------------------------------------------
$nboftargetok = 0;
$nboftargetneedbuildroot = 0;
$nboftargetneedcvs = 0;
foreach my $target ( keys %CHOOSEDTARGET ) {
if ( $CHOOSEDTARGET{$target} < 0 ) { next; }
if ( $target ne 'EXE' && $target ne 'EXEDOLIWAMP' ) {
$nboftargetok=0;
$nboftargetneedbuildroot=0;
$nboftargetneedcvs=0;
foreach my $target (keys %CHOOSEDTARGET) {
if ($CHOOSEDTARGET{$target} < 0) { next; }
if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP')
{
$nboftargetneedbuildroot++;
}
if ( $target eq 'SNAPSHOT' ) {
if ($target eq 'SNAPSHOT')
{
$nboftargetneedcvs++;
}
$nboftargetok++;
@@ -294,211 +229,178 @@ foreach my $PROJECT (@PROJECTLIST) {
if ($nboftargetok) {
# Update CVS if required
#-----------------------
if ($nboftargetneedcvs) {
print "Go to directory $SOURCE\n";
$olddir = getcwd();
chdir("$SOURCE");
print "Run cvs update -P -d\n";
$ret = `cvs update -P -d 2>&1`;
chdir("$olddir");
# Update CVS if required
#-----------------------
if ($nboftargetneedcvs)
{
print "Go to directory $SOURCE\n";
$olddir=getcwd();
chdir("$SOURCE");
print "Run cvs update -P -d\n";
$ret=`cvs update -P -d 2>&1`;
chdir("$olddir");
}
# Update buildroot if required
#-----------------------------
if ($nboftargetneedbuildroot) {
if ( !$copyalreadydone ) {
print "Delete directory $BUILDROOT\n";
$ret = `rm -fr "$BUILDROOT"`;
# Update buildroot if required
#-----------------------------
if ($nboftargetneedbuildroot)
{
if (! $copyalreadydone) {
print "Delete directory $BUILDROOT\n";
$ret=`rm -fr "$BUILDROOT"`;
mkdir "$BUILDROOT";
mkdir "$BUILDROOT/$PROJECTLC";
mkdir "$BUILDROOT";
mkdir "$BUILDROOT/$PROJECTLC";
print "Now, we will copy all files declared in the makepack-"
. $PROJECT
. ".conf into the directory $BUILDROOT\n";
print "Now, we will copy all files declared in the makepack-".$PROJECT.".conf into the directory $BUILDROOT\n";
open( my $IN2, "<", "makepack-" . $PROJECT . ".conf" )
or die "Error: Can't open conf file makepack-"
. $PROJECT
. ".conf for reading.\n";
while (<$IN2>) {
$entry = $_;
$result=open(IN,"<makepack-".$PROJECT.".conf");
if (! $result) { die "Error: Can't open conf file makepack-".$PROJECT.".conf for reading.\n"; }
while(<IN>)
{
$entry=$_;
if ( $entry =~ /^#/ ) { next; } # Do not process comments
if ($entry =~ /^#/) { next; } # Do not process comments
$entry =~ s/\n//;
if ( $entry =~ /^!(.*)$/ ) # Exclude so remove file/dir
{
print "Remove $BUILDROOT/$PROJECTLC/$1\n";
$ret = `rm -fr "$BUILDROOT/$PROJECTLC/"$1`;
if ( $? != 0 ) {
die
"Failed to delete a file to exclude declared into makepack-"
. $PROJECT
. ".conf file (Failed on the line "
. $entry . ")\n";
}
next;
}
if ($entry =~ /^!(.*)$/) # Exclude so remove file/dir
{
print "Remove $BUILDROOT/$PROJECTLC/$1\n";
$ret=`rm -fr "$BUILDROOT/$PROJECTLC/"$1`;
if ($? != 0) { die "Failed to delete a file to exclude declared into makepack-".$PROJECT.".conf file (Failed on the line ".$entry.")\n"; }
next;
}
$entry =~ /^(.*)\/[^\/]+/;
print "Create directory $BUILDROOT/$PROJECTLC/$1\n";
$ret = `mkdir -p "$BUILDROOT/$PROJECTLC/$1"`;
if ( $entry !~ /version\-/ ) {
print
"Copy $SOURCE/$entry into $BUILDROOT/$PROJECTLC/$entry\n";
$ret =
`cp -pr "$SOURCE/$entry" "$BUILDROOT/$PROJECTLC/$entry"`;
if ( $? != 0 ) {
die
"Failed to make copy of a file declared into makepack-"
. $PROJECT
. ".conf file (Failed on the line '"
. $entry . "')\n";
}
}
print "Create directory $BUILDROOT/$PROJECTLC/$1\n";
$ret=`mkdir -p "$BUILDROOT/$PROJECTLC/$1"`;
if ($entry !~ /version\-/)
{
print "Copy $SOURCE/$entry into $BUILDROOT/$PROJECTLC/$entry\n";
$ret=`cp -pr "$SOURCE/$entry" "$BUILDROOT/$PROJECTLC/$entry"`;
if ($? != 0) { die "Failed to make copy of a file declared into makepack-".$PROJECT.".conf file (Failed on the line '".$entry."')\n"; }
}
}
close $IN2;
close IN;
@timearray = localtime( time() );
$fulldate =
( $timearray[5] + 1900 ) . '-'
. ( $timearray[4] + 1 ) . '-'
. $timearray[3] . ' '
. $timearray[2] . ':'
. $timearray[1];
#open(VF,">$BUILDROOT/$PROJECTLC/dev/build/version-".$PROJECTLC.".txt");
#print "Create version file $BUILDROOT/$PROJECTLC/dev/build/version-".$PROJECTLC.".txt with date ".$fulldate."\n";
#$ret=`mkdir -p "$BUILDROOT/$PROJECTLC/dev/build"`;
#print VF "Version: ".$MAJOR.".".$MINOR.($BUILD ne ''?".$BUILD":"")."\n";
#print VF "Build : ".$fulldate."\n";
#close VF;
}
print "Clean $BUILDROOT\n";
$ret = `rm -fr $BUILDROOT/$PROJECTLC/.cache`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/.git`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/.project`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/.settings`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/index.php`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/dev/build/html`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/documents`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/document`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.mysql`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.old`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.postgres`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf*sav*`;
if ($custom) {
$ret =
`cp -r $BUILDROOT/$PROJECTLC/htdocs/custom/* $BUILDROOT/$PROJECTLC/htdocs/.`;
}
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/custom`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/htdocs/custom2`;
$ret = `rm -fr $BUILDROOT/$PROJECTLC/test`;
$ret =
`rm -fr $BUILDROOT/$PROJECTLC/Thumbs.db $BUILDROOT/$PROJECTLC/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/*/*/Thumbs.db`;
$ret =
`rm -fr $BUILDROOT/$PROJECTLC/CVS* $BUILDROOT/$PROJECTLC/*/CVS* $BUILDROOT/$PROJECTLC/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/*/*/CVS*`;
@timearray=localtime(time());
$fulldate=($timearray[5]+1900).'-'.($timearray[4]+1).'-'.$timearray[3].' '.$timearray[2].':'.$timearray[1];
#open(VF,">$BUILDROOT/$PROJECTLC/dev/build/version-".$PROJECTLC.".txt");
#print "Create version file $BUILDROOT/$PROJECTLC/dev/build/version-".$PROJECTLC.".txt with date ".$fulldate."\n";
#$ret=`mkdir -p "$BUILDROOT/$PROJECTLC/dev/build"`;
#print VF "Version: ".$MAJOR.".".$MINOR.($BUILD ne ''?".$BUILD":"")."\n";
#print VF "Build : ".$fulldate."\n";
#close VF;
}
print "Clean $BUILDROOT\n";
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.cache`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.git`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.project`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/.settings`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/index.php`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/dev/build/html`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/documents`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/document`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.mysql`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.old`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf.php.postgres`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/conf/conf*sav*`;
if ($custom) {
$ret=`cp -r $BUILDROOT/$PROJECTLC/htdocs/custom/* $BUILDROOT/$PROJECTLC/htdocs/.`;
}
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/custom`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/htdocs/custom2`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/test`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/Thumbs.db $BUILDROOT/$PROJECTLC/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/*/Thumbs.db $BUILDROOT/$PROJECTLC/*/*/*/*/Thumbs.db`;
$ret=`rm -fr $BUILDROOT/$PROJECTLC/CVS* $BUILDROOT/$PROJECTLC/*/CVS* $BUILDROOT/$PROJECTLC/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/*/CVS* $BUILDROOT/$PROJECTLC/*/*/*/*/*/CVS*`;
}
# Build package for each target
#------------------------------
foreach my $target ( keys %CHOOSEDTARGET ) {
if ( $CHOOSEDTARGET{$target} < 0 ) { next; }
# Build package for each target
#------------------------------
foreach my $target (keys %CHOOSEDTARGET) {
if ($CHOOSEDTARGET{$target} < 0) { next; }
print "\nBuild package for target $target\n";
print "\nBuild package for target $target\n";
if ( $target eq 'TGZ' ) {
$NEWDESTI = $DESTI;
if ( -d $DESTI . '/../modules' ) {
$NEWDESTI = $DESTI . '/../modules';
}
if ($target eq 'TGZ') {
$NEWDESTI=$DESTI;
if (-d $DESTI.'/../modules') { $NEWDESTI=$DESTI.'/../modules'; }
print "Remove target $FILENAMETGZ.tgz...\n";
unlink("$NEWDESTI/$FILENAMETGZ.tgz");
print "Compress $BUILDROOT/* into $FILENAMETGZ.tgz...\n";
$cmd =
"tar --exclude-vcs --exclude *.tgz --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$FILENAMETGZ.tgz\" .";
$ret = `$cmd`;
if ( $OS =~ /windows/i ) {
print
"Move $FILENAMETGZ.tgz to $NEWDESTI/$FILENAMETGZ.tgz\n";
$ret = `mv "$FILENAMETGZ.tgz" "$NEWDESTI/$FILENAMETGZ.tgz"`;
}
else {
$ret = `mv "$FILENAMETGZ.tgz" "$NEWDESTI/$FILENAMETGZ.tgz"`;
}
next;
}
print "Remove target $FILENAMETGZ.tgz...\n";
unlink("$NEWDESTI/$FILENAMETGZ.tgz");
print "Compress $BUILDROOT/* into $FILENAMETGZ.tgz...\n";
$cmd="tar --exclude-vcs --exclude *.tgz --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$FILENAMETGZ.tgz\" .";
$ret=`$cmd`;
if ($OS =~ /windows/i) {
print "Move $FILENAMETGZ.tgz to $NEWDESTI/$FILENAMETGZ.tgz\n";
$ret=`mv "$FILENAMETGZ.tgz" "$NEWDESTI/$FILENAMETGZ.tgz"`;
}
else
{
$ret=`mv "$FILENAMETGZ.tgz" "$NEWDESTI/$FILENAMETGZ.tgz"`;
}
next;
}
if ( $target eq 'ZIP' ) {
$NEWDESTI = $DESTI;
if ( -d $DESTI . '/../modules' ) {
$NEWDESTI = $DESTI . '/../modules';
}
if ($target eq 'ZIP') {
$NEWDESTI=$DESTI;
if (-d $DESTI.'/../modules') { $NEWDESTI=$DESTI.'/../modules'; }
print "Remove target $FILENAMEZIP.zip...\n";
unlink "$NEWDESTI/$FILENAMEZIP.zip";
print "Compress $FILENAMEZIP into $FILENAMEZIP.zip...\n";
print "Remove target $FILENAMEZIP.zip...\n";
unlink "$NEWDESTI/$FILENAMEZIP.zip";
print "Compress $FILENAMEZIP into $FILENAMEZIP.zip...\n";
print "Go to directory $BUILDROOT/$PROJECTLC\n";
$olddir = getcwd();
chdir("$BUILDROOT/$PROJECTLC");
$cmd = "7z a -r -tzip -mx $BUILDROOT/$FILENAMEZIP.zip *";
print $cmd. "\n";
$ret = `$cmd`;
chdir("$olddir");
print "Go to directory $BUILDROOT/$PROJECTLC\n";
$olddir=getcwd();
chdir("$BUILDROOT/$PROJECTLC");
$cmd= "7z a -r -tzip -mx $BUILDROOT/$FILENAMEZIP.zip *";
print $cmd."\n";
$ret= `$cmd`;
chdir("$olddir");
print "Move $FILENAMEZIP.zip to $NEWDESTI/$FILENAMEZIP.zip\n";
$ret =
`mv "$BUILDROOT/$FILENAMEZIP.zip" "$NEWDESTI/$FILENAMEZIP.zip"`;
$ret = `chown $OWNER:$GROUP "$NEWDESTI/$FILENAMEZIP.zip"`;
next;
}
print "Move $FILENAMEZIP.zip to $NEWDESTI/$FILENAMEZIP.zip\n";
$ret=`mv "$BUILDROOT/$FILENAMEZIP.zip" "$NEWDESTI/$FILENAMEZIP.zip"`;
$ret=`chown $OWNER:$GROUP "$NEWDESTI/$FILENAMEZIP.zip"`;
next;
}
if ( $target eq 'EXE' ) {
$NEWDESTI = $DESTI;
if ( -d $DESTI . '/../modules' ) {
$NEWDESTI = $DESTI . '/../modules';
}
if ($target eq 'EXE') {
$NEWDESTI=$DESTI;
if (-d $DESTI.'/../modules') { $NEWDESTI=$DESTI.'/../modules'; }
print "Remove target $FILENAMEEXE.exe...\n";
unlink "$NEWDESTI/$FILENAMEEXE.exe";
print "Compress into $FILENAMEEXE.exe by $FILENAMEEXE.nsi...\n";
$command =
"\"$REQUIREMENTTARGET{$target}\" /DMUI_VERSION_DOT=$MAJOR.$MINOR.$BUILD /X\"SetCompressor bzip2\" \"$SOURCE\\dev\\build\\exe\\$FILENAME.nsi\"";
print "$command\n";
$ret = `$command`;
print "Move $FILENAMEEXE.exe to $NEWDESTI\n";
rename( "$SOURCE\\dev\\build\\exe\\$FILENAMEEXE.exe",
"$NEWDESTI/$FILENAMEEXE.exe" );
next;
}
print "Remove target $FILENAMEEXE.exe...\n";
unlink "$NEWDESTI/$FILENAMEEXE.exe";
print "Compress into $FILENAMEEXE.exe by $FILENAMEEXE.nsi...\n";
$command="\"$REQUIREMENTTARGET{$target}\" /DMUI_VERSION_DOT=$MAJOR.$MINOR.$BUILD /X\"SetCompressor bzip2\" \"$SOURCE\\dev\\build\\exe\\$FILENAME.nsi\"";
print "$command\n";
$ret=`$command`;
print "Move $FILENAMEEXE.exe to $NEWDESTI\n";
rename("$SOURCE\\dev\\build\\exe\\$FILENAMEEXE.exe","$NEWDESTI/$FILENAMEEXE.exe");
next;
}
}
}
}
print "\n----- Summary -----\n";
foreach my $target ( keys %CHOOSEDTARGET ) {
if ( $CHOOSEDTARGET{$target} < 0 ) {
print "Package $target not built (bad requirement).\n";
}
else {
print "Package $target built successfully in $NEWDESTI\n";
}
foreach my $target (keys %CHOOSEDTARGET) {
if ($CHOOSEDTARGET{$target} < 0) {
print "Package $target not built (bad requirement).\n";
} else {
print "Package $target built successfully in $NEWDESTI\n";
}
}
}
if ( !$batch ) {
print "\nPress key to finish...";
my $WAITKEY = <STDIN>;
if (! $batch) {
print "\nPress key to finish...";
my $WAITKEY=<STDIN>;
}
0;

View File

@@ -4,294 +4,268 @@
# \brief Script to build a theme Package for Dolibarr
# \author (c)2005-2009 Laurent Destailleur <eldy@users.sourceforge.net>
#-----------------------------------------------------------------------------
## no critic (InputOutput::ProhibitExplicitStdin)
use strict;
use warnings;
use Cwd;
use Term::ANSIColor;
$PROJECT = "dolibarr";
$PROJECT="dolibarr";
@LISTETARGET = ("TGZ"); # Possible packages
%REQUIREMENTTARGET = ( # Tool requirement for each package
"TGZ" => "tar",
"ZIP" => "7z",
"RPM" => "rpmbuild",
"DEB" => "dpkg-buildpackage",
"EXE" => "makensis.exe"
@LISTETARGET=("TGZ"); # Possible packages
%REQUIREMENTTARGET=( # Tool requirement for each package
"TGZ"=>"tar",
"ZIP"=>"7z",
"RPM"=>"rpmbuild",
"DEB"=>"dpkg-buildpackage",
"EXE"=>"makensis.exe"
);
%ALTERNATEPATH = (
"7z" => "7-ZIP",
"makensis.exe" => "NSIS"
%ALTERNATEPATH=(
"7z"=>"7-ZIP",
"makensis.exe"=>"NSIS"
);
use vars qw/ $REVISION $VERSION /;
$REVISION = '1.11';
$VERSION = "1.0 (build $REVISION)";
$REVISION='1.11';
$VERSION="1.0 (build $REVISION)";
#------------------------------------------------------------------------------
# MAIN
#------------------------------------------------------------------------------
( $DIR = $0 ) =~ s/([^\/\\]+)$//;
( $PROG = $1 ) =~ s/\.([^\.]*)$//;
$Extension = $1;
$DIR ||= '.';
$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
($DIR=$0) =~ s/([^\/\\]+)$//; ($PROG=$1) =~ s/\.([^\.]*)$//; $Extension=$1;
$DIR||='.'; $DIR =~ s/([^\/\\])[\\\/]+$/$1/;
# Detect OS type
# --------------
if ( "$^O" =~ /linux/i || ( -d "/etc" && -d "/var" && "$^O" !~ /cygwin/i ) ) {
$OS = 'linux';
$CR = '';
}
elsif ( -d "/etc" && -d "/Users" ) { $OS = 'macosx'; $CR = ''; }
elsif ( "$^O" =~ /cygwin/i || "$^O" =~ /win32/i ) {
$OS = 'windows';
$CR = "\r";
}
if ( !$OS ) {
print "$PROG.$Extension was not able to detect your OS.\n";
if ("$^O" =~ /linux/i || (-d "/etc" && -d "/var" && "$^O" !~ /cygwin/i)) { $OS='linux'; $CR=''; }
elsif (-d "/etc" && -d "/Users") { $OS='macosx'; $CR=''; }
elsif ("$^O" =~ /cygwin/i || "$^O" =~ /win32/i) { $OS='windows'; $CR="\r"; }
if (! $OS) {
print "$PROG.$Extension was not able to detect your OS.\n";
print "Can't continue.\n";
print "$PROG.$Extension aborted.\n";
sleep 2;
sleep 2;
exit 1;
}
# Define buildroot
# ----------------
if ( $OS =~ /linux/ ) {
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "/tmp";
if ($OS =~ /linux/) {
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"/tmp";
}
if ( $OS =~ /macos/ ) {
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "/tmp";
if ($OS =~ /macos/) {
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"/tmp";
}
if ( $OS =~ /windows/ ) {
$TEMP = $ENV{"TEMP"} || $ENV{"TMP"} || "c:/temp";
$PROGPATH = $ENV{"ProgramFiles"};
if ($OS =~ /windows/) {
$TEMP=$ENV{"TEMP"}||$ENV{"TMP"}||"c:/temp";
$PROGPATH=$ENV{"ProgramFiles"};
}
if ( !$TEMP || !-d $TEMP ) {
print "Error: A temporary directory can not be find.\n";
print "Check that TEMP or TMP environment variable is set correctly.\n";
if (! $TEMP || ! -d $TEMP) {
print "Error: A temporary directory can not be find.\n";
print "Check that TEMP or TMP environment variable is set correctly.\n";
print "makepack-dolibarrtheme.pl aborted.\n";
sleep 2;
exit 2;
sleep 2;
exit 2;
}
$BUILDROOT = "$TEMP/dolibarr-buildroot";
$BUILDROOT="$TEMP/dolibarr-buildroot";
my $copyalreadydone = 0;
my $batch = 0;
my $copyalreadydone=0;
my $batch=0;
print "Makepack theme version $VERSION\n";
print "Enter name of theme(s) to package (separated with space): ";
$PROJECT = <STDIN>;
$PROJECT=<STDIN>;
chomp($PROJECT);
@PROJECTLIST = split( / /, $PROJECT );
$PROJECT = join( '', @PROJECTLIST );
@PROJECTLIST=split(/ /,$PROJECT);
$PROJECT=join('',@PROJECTLIST);
# Ask and set version $MAJOR and $MINOR
print "Enter value for version: ";
$PROJVERSION = <STDIN>;
$PROJVERSION=<STDIN>;
chomp($PROJVERSION);
( $MAJOR, $MINOR ) = split( /\./, $PROJVERSION, 2 );
if ( $MINOR eq '' ) {
($MAJOR,$MINOR)=split(/\./,$PROJVERSION,2);
if ($MINOR eq '')
{
print "Enter value for minor version: ";
$MINOR = <STDIN>;
$MINOR=<STDIN>;
chomp($MINOR);
}
$FILENAME = "$PROJECT";
$FILENAMETGZ = "theme_$PROJECT-$MAJOR.$MINOR";
$FILENAMEZIP = "theme_$PROJECT-$MAJOR.$MINOR";
if ( -d "/usr/src/redhat" ) {
$FILENAME="$PROJECT";
$FILENAMETGZ="theme_$PROJECT-$MAJOR.$MINOR";
$FILENAMEZIP="theme_$PROJECT-$MAJOR.$MINOR";
# redhat
$RPMDIR = "/usr/src/redhat";
if (-d "/usr/src/redhat") {
# redhat
$RPMDIR="/usr/src/redhat";
}
if ( -d "/usr/src/RPM" ) {
# mandrake
$RPMDIR = "/usr/src/RPM";
if (-d "/usr/src/RPM") {
# mandrake
$RPMDIR="/usr/src/RPM";
}
$SOURCE = "$DIR/../..";
$DESTI = "$SOURCE/build";
$SOURCE="$DIR/../..";
$DESTI="$SOURCE/build";
# Choose package targets
#-----------------------
$target = "ZIP"; # Packages uses this format
$target="ZIP"; # Packages uses this format
if ($target) {
$CHOOSEDTARGET{ uc($target) } = 1;
$CHOOSEDTARGET{uc($target)}=1;
}
else {
my $found = 0;
my $NUM_SCRIPT;
while ( !$found ) {
my $cpt = 0;
printf( " %d - %3s (%s)\n",
$cpt, "All", "Need " . join( ",", values %REQUIREMENTTARGET ) );
foreach my $target (@LISTETARGET) {
$cpt++;
printf( " %d - %3s (%s)\n",
$cpt, $target, "Need " . $REQUIREMENTTARGET{$target} );
}
my $found=0;
my $NUM_SCRIPT;
while (! $found) {
my $cpt=0;
printf(" %d - %3s (%s)\n",$cpt,"All","Need ".join(",",values %REQUIREMENTTARGET));
foreach my $target (@LISTETARGET) {
$cpt++;
printf(" %d - %3s (%s)\n",$cpt,$target,"Need ".$REQUIREMENTTARGET{$target});
}
# Are asked to select the file to move
print "Choose one package number or several separated with space: ";
$NUM_SCRIPT = <STDIN>;
chomp($NUM_SCRIPT);
if ( $NUM_SCRIPT =~ s/-//g ) {
# Do not do copy
$copyalreadydone = 1;
}
if ( $NUM_SCRIPT !~ /^[0-$cpt\s]+$/ ) {
print "This is not a valid package number list.\n";
$found = 0;
}
else {
$found = 1;
}
}
print "\n";
if ($NUM_SCRIPT) {
foreach my $num ( split( /\s+/, $NUM_SCRIPT ) ) {
$CHOOSEDTARGET{ $LISTETARGET[ $num - 1 ] } = 1;
}
}
else {
foreach my $key (@LISTETARGET) {
$CHOOSEDTARGET{$key} = 1;
}
}
# Are asked to select the file to move
print "Choose one package number or several separated with space: ";
$NUM_SCRIPT=<STDIN>;
chomp($NUM_SCRIPT);
if ($NUM_SCRIPT =~ s/-//g) {
# Do not do copy
$copyalreadydone=1;
}
if ($NUM_SCRIPT !~ /^[0-$cpt\s]+$/)
{
print "This is not a valid package number list.\n";
$found = 0;
}
else
{
$found = 1;
}
}
print "\n";
if ($NUM_SCRIPT) {
foreach my $num (split(/\s+/,$NUM_SCRIPT)) {
$CHOOSEDTARGET{$LISTETARGET[$num-1]}=1;
}
}
else {
foreach my $key (@LISTETARGET) {
$CHOOSEDTARGET{$key}=1;
}
}
}
# Test if requirement is ok
#--------------------------
foreach my $target ( keys %CHOOSEDTARGET ) {
foreach my $req ( split( /[,\s]/, $REQUIREMENTTARGET{$target} ) ) {
foreach my $target (keys %CHOOSEDTARGET) {
foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target})) {
# Test
print "Test requirement for target $target: Search '$req'... ";
$ret=`"$req" 2>&1`;
$coderetour=$?; $coderetour2=$coderetour>>8;
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) {
# Not found error, we try in PROGPATH
$ret=`"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
$coderetour=$?; $coderetour2=$coderetour>>8;
$REQUIREMENTTARGET{$target}="$PROGPATH/$ALTERNATEPATH{$req}/$req";
}
# Test
print "Test requirement for target $target: Search '$req'... ";
$ret = `"$req" 2>&1`;
$coderetour = $?;
$coderetour2 = $coderetour >> 8;
if (
$coderetour != 0
&& ( ( $coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i )
|| ( $coderetour2 == 127 && $OS !~ /windows/ ) )
&& $PROGPATH
)
{
# Not found error, we try in PROGPATH
$ret = `"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
$coderetour = $?;
$coderetour2 = $coderetour >> 8;
$REQUIREMENTTARGET{$target} = "$PROGPATH/$ALTERNATEPATH{$req}/$req";
}
if (
$coderetour != 0
&& ( ( $coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i )
|| ( $coderetour2 == 127 && $OS !~ /windows/ ) )
)
{
# Not found error
print
"Not found\nCan't build target $target. Requirement '$req' not found in PATH\n";
$CHOOSEDTARGET{$target} = -1;
last;
}
else {
# Pas erreur ou erreur autre que programme absent
print " Found " . $REQUIREMENTTARGET{$target} . "\n";
}
}
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/))) {
# Not found error
print "Not found\nCan't build target $target. Requirement '$req' not found in PATH\n";
$CHOOSEDTARGET{$target}=-1;
last;
} else {
# Pas erreur ou erreur autre que programme absent
print " Found ".$REQUIREMENTTARGET{$target}."\n";
}
}
}
print "\n";
# Check if there is at least on target to build
#----------------------------------------------
$nboftargetok = 0;
foreach my $target ( keys %CHOOSEDTARGET ) {
if ( $CHOOSEDTARGET{$target} < 0 ) { next; }
$nboftargetok++;
$nboftargetok=0;
foreach my $target (keys %CHOOSEDTARGET) {
if ($CHOOSEDTARGET{$target} < 0) { next; }
$nboftargetok++;
}
if ($nboftargetok) {
# Update buildroot
#-----------------
if ( !$copyalreadydone ) {
print "Delete directory $BUILDROOT\n";
$ret = `rm -fr "$BUILDROOT"`;
mkdir "$BUILDROOT";
mkdir "$BUILDROOT/htdocs";
mkdir "$BUILDROOT/htdocs/theme";
# Update buildroot
#-----------------
if (! $copyalreadydone) {
print "Delete directory $BUILDROOT\n";
$ret=`rm -fr "$BUILDROOT"`;
mkdir "$BUILDROOT";
mkdir "$BUILDROOT/htdocs";
mkdir "$BUILDROOT/htdocs/theme";
print "Copy $SOURCE into $BUILDROOT\n";
mkdir "$BUILDROOT";
foreach my $tmp (@PROJECTLIST) {
$ret =
`cp -pr "$SOURCE/htdocs/theme/$tmp" "$BUILDROOT/htdocs/theme"`;
print "Copy $SOURCE into $BUILDROOT\n";
mkdir "$BUILDROOT";
foreach my $tmp (@PROJECTLIST)
{
$ret=`cp -pr "$SOURCE/htdocs/theme/$tmp" "$BUILDROOT/htdocs/theme"`;
}
}
print "Clean $BUILDROOT\n";
$ret =
`rm -fr $BUILDROOT/htdocs/theme/$PROJECT/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/*/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/Thumbs.db`;
$ret =
`rm -fr $BUILDROOT/htdocs/theme/$PROJECT/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/*/*/CVS*`;
}
print "Clean $BUILDROOT\n";
$ret=`rm -fr $BUILDROOT/htdocs/theme/$PROJECT/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/*/Thumbs.db $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/Thumbs.db`;
$ret=`rm -fr $BUILDROOT/htdocs/theme/$PROJECT/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/*/CVS* $BUILDROOT/htdocs/theme/$PROJECT/*/*/*/*/*/CVS*`;
# Build package for each target
#------------------------------
foreach my $target ( keys %CHOOSEDTARGET ) {
if ( $CHOOSEDTARGET{$target} < 0 ) { next; }
print "\nBuild package for target $target\n";
# Build package for each target
#------------------------------
foreach my $target (keys %CHOOSEDTARGET) {
if ($CHOOSEDTARGET{$target} < 0) { next; }
if ( $target eq 'TGZ' ) {
unlink $FILENAMETGZ . tgz;
print "Compress $BUILDROOT/htdocs into $FILENAMETGZ.tgz...\n";
$cmd =
"tar --exclude-vcs --exclude-from \"$DESTI/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$FILENAMETGZ.tgz\" htdocs";
$ret = `$cmd`;
if ( $OS =~ /windows/i ) {
print "Move $FILENAMETGZ.tgz to $DESTI/$FILENAMETGZ.tgz\n";
$ret = `mv "$FILENAMETGZ.tgz" "$DESTI/$FILENAMETGZ.tgz"`;
}
next;
}
print "\nBuild package for target $target\n";
if ( $target eq 'ZIP' ) {
unlink $FILENAMEZIP . zip;
print "Compress $FILENAMETGZ into $FILENAMEZIP.zip...\n";
chdir("$BUILDROOT");
$ret = `7z a -r -tzip -mx $BUILDROOT/$FILENAMEZIP.zip htdocs`;
if ($target eq 'TGZ') {
unlink $FILENAMETGZ.tgz;
print "Compress $BUILDROOT/htdocs into $FILENAMETGZ.tgz...\n";
$cmd="tar --exclude-vcs --exclude-from \"$DESTI/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$FILENAMETGZ.tgz\" htdocs";
$ret=`$cmd`;
if ($OS =~ /windows/i) {
print "Move $FILENAMETGZ.tgz to $DESTI/$FILENAMETGZ.tgz\n";
$ret=`mv "$FILENAMETGZ.tgz" "$DESTI/$FILENAMETGZ.tgz"`;
}
next;
}
if ($target eq 'ZIP') {
unlink $FILENAMEZIP.zip;
print "Compress $FILENAMETGZ into $FILENAMEZIP.zip...\n";
chdir("$BUILDROOT");
$ret=`7z a -r -tzip -mx $BUILDROOT/$FILENAMEZIP.zip htdocs`;
print "Move $FILENAMEZIP.zip to $DESTI\n";
$ret = `mv "$FILENAMEZIP.zip" "$DESTI/$FILENAMEZIP.zip"`;
next;
}
$ret=`mv "$FILENAMEZIP.zip" "$DESTI/$FILENAMEZIP.zip"`;
next;
}
}
}
}
print "\n----- Summary -----\n";
foreach my $target ( keys %CHOOSEDTARGET ) {
if ( $CHOOSEDTARGET{$target} < 0 ) {
print "Package $target not built (bad requirement).\n";
}
else {
print "Package $target built successfully in $DESTI\n";
}
foreach my $target (keys %CHOOSEDTARGET) {
if ($CHOOSEDTARGET{$target} < 0) {
print "Package $target not built (bad requirement).\n";
} else {
print "Package $target built successfully in $DESTI\n";
}
}
if ( !$btach ) {
print "\nPress key to finish...";
my $WAITKEY = <STDIN>;
if (! $btach) {
print "\nPress key to finish...";
my $WAITKEY=<STDIN>;
}
0;

View File

@@ -112,14 +112,14 @@ We suppose the branch x.y has already been created during the beta (see previous
- Update version/info in ChangeLog, for this:
To generate a changelog of a **major new version** x.0.0 (from a repo on branch develop or x.y):
To generate a changelog of a **major new version** x.0.0 (from a repo on branch develop), you can do
```
cd ~/git/dolibarr
git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/changelogtocopy
```
To generate a changelog of a **intermediate new version** x.y.0 (from a repo on branch x.y);
To generate a changelog of a **intermediate new version** x.y.0 (from a repo on branch x.y), you can do
```
cd ~/git/dolibarr_x.y

View File

@@ -1,7 +1,7 @@
#----------------------------------------------------------------------------
# \file dolibarr.pl
# \brief Dolibarr script install for Virtualmin Pro
# \author (c)2009-2025 Regis Houssin <regis.houssin@inodbox.com>
# \author (c)2009-2020 Regis Houssin <regis.houssin@inodbox.com>
#----------------------------------------------------------------------------
@@ -30,15 +30,7 @@ return "Regis Houssin";
# script_dolibarr_versions()
sub script_dolibarr_versions
{
return ( "22.0.3", "21.0.4", "20.0.4", "19.0.4", "18.0.8", "17.0.4", "16.0.5" );
}
sub script_dolibarr_version_desc
{
local ($ver) = @_;
my ($major_ver) = $ver =~ /^(\d+)\..*/;
return $major_ver == 22 ? "$ver (Latest)" :
$major_ver == 18 ? "$ver (LTS)" : "$ver";
return ( "14.0.5", "13.0.5", "12.0.5", "11.0.5", "10.0.7", "9.0.4", "8.0.6", "7.0.5" );
}
sub script_dolibarr_release
@@ -46,11 +38,6 @@ sub script_dolibarr_release
return 2; # for mysqli fix
}
sub script_dolibarr_testable
{
return 1;
}
sub script_dolibarr_category
{
return "Commerce";
@@ -58,23 +45,14 @@ return "Commerce";
sub script_dolibarr_php_vers
{
return ( 7 );
return ( 5 );
}
sub script_dolibarr_php_vars
{
return ( [ 'memory_limit', '128M', '+' ] );
}
sub script_dolibarr_php_modules
{
local ($d, $ver, $phpver, $opts) = @_;
local ($dbtype, $dbname) = split(/_/, $opts->{'db'}, 2);
local @modules = ("xml", "mbstring", "gd", "iconv",
"curl", "intl", "zip");
push(@modules, ($dbtype eq "mysql" ? "mysql" : "pgsql"));
return @modules;
return $dbtype eq "mysql" ? ("mysql") : ("pgsql");
}
sub script_dolibarr_dbs
@@ -83,10 +61,34 @@ local ($d, $ver) = @_;
return ("mysql", "postgres");
}
sub script_dolibarr_php_fullver
# script_dolibarr_depends(&domain, version)
sub script_dolibarr_depends
{
local ($d, $ver, $sinfo) = @_;
return "7.1";
local ($d, $ver, $sinfo, $phpver) = @_;
local @rv;
if ($ver >= 3.6) {
# Check for PHP 5.3+
local $phpv = &get_php_version($phpver || 5, $d);
if (!$phpv) {
push(@rv, "Could not work out exact PHP version");
}
elsif ($phpv < 5.3) {
push(@rv, "Dolibarr requires PHP version 5.3 or later");
}
}
if ($ver >= 12.0) {
# Check for PHP 5.6+
local $phpv = &get_php_version($phpver || 5, $d);
if (!$phpv) {
push(@rv, "Could not work out exact PHP version");
}
elsif ($phpv < 5.6) {
push(@rv, "Dolibarr requires PHP version 5.6 or later");
}
}
return @rv;
}
# script_dolibarr_params(&domain, version, &upgrade-info)
@@ -193,7 +195,7 @@ local $dbpass = $dbtype eq "mysql" ? &mysql_pass($d) : &postgres_pass($d, 1);
local $dbphptype = $dbtype eq "mysql" && $version < 3.6 ? "mysql" :
$dbtype eq "mysql" ? "mysqli" : "pgsql";
local $dbhost = &get_database_host($dbtype, $d);
local $dberr = &check_script_db_connection($d, $dbtype, $dbname, $dbuser, $dbpass);
local $dberr = &check_script_db_connection($dbtype, $dbname, $dbuser, $dbpass);
return (0, "Database connection failed : $dberr") if ($dberr);
# Extract tar file to temp dir and copy to target
@@ -293,9 +295,6 @@ else {
[ "db_name", $dbname ],
[ "db_user", $dbuser ],
[ "db_pass", $dbpass ],
[ "db_prefix", 'llx_' ],
[ "db_port", '3306' ],
[ "selectlang", 'en_US' ],
[ "action", "set" ],
[ "main_force_https", $opts->{'forcehttps'} ],
[ "dolibarr_main_db_character_set", $charset ],
@@ -401,32 +400,24 @@ sub script_dolibarr_check_latest
{
local ($ver) = @_;
local @vers = &osdn_package_versions("dolibarr",
$ver >= 22.0 ? "dolibarr\\-(22\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 21.0 ? "dolibarr\\-(21\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 20.0 ? "dolibarr\\-(20\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 19.0 ? "dolibarr\\-(19\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 18.0 ? "dolibarr\\-(18\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 17.0 ? "dolibarr\\-(17\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 16.0 ? "dolibarr\\-(16\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 15.0 ? "dolibarr\\-(15\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 14.0 ? "dolibarr\\-(14\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 13.0 ? "dolibarr\\-(13\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 12.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 11.0 ? "dolibarr\\-(11\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 10.0 ? "dolibarr\\-(10\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 9.0 ? "dolibarr\\-(9\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 8.0 ? "dolibarr\\-(8\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 7.0 ? "dolibarr\\-(7\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 6.0 ? "dolibarr\\-(6\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 5.0 ? "dolibarr\\-(5\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 4.0 ? "dolibarr\\-(4\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.9 ? "dolibarr\\-(3\\.9\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.8 ? "dolibarr\\-(3\\.8\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.7 ? "dolibarr\\-(3\\.7\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.6 ? "dolibarr\\-(3\\.6\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.5 ? "dolibarr\\-(3\\.5\\.[0-9\\.]+)\\.tgz" :
$ver >= 2.9 ? "dolibarr\\-(2\\.9\\.[0-9\\.]+)\\.tgz" :
"dolibarr\\-(2\\.8\\.[0-9\\.]+)\\.tgz");
$ver >= 14.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 13.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 12.0 ? "dolibarr\\-(12\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 11.0 ? "dolibarr\\-(11\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 10.0 ? "dolibarr\\-(10\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 9.0 ? "dolibarr\\-(9\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 8.0 ? "dolibarr\\-(8\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 7.0 ? "dolibarr\\-(7\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 6.0 ? "dolibarr\\-(6\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 5.0 ? "dolibarr\\-(5\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 4.0 ? "dolibarr\\-(4\\.0\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.9 ? "dolibarr\\-(3\\.9\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.8 ? "dolibarr\\-(3\\.8\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.7 ? "dolibarr\\-(3\\.7\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.6 ? "dolibarr\\-(3\\.6\\.[0-9\\.]+)\\.tgz" :
$ver >= 3.5 ? "dolibarr\\-(3\\.5\\.[0-9\\.]+)\\.tgz" :
$ver >= 2.9 ? "dolibarr\\-(2\\.9\\.[0-9\\.]+)\\.tgz" :
"dolibarr\\-(2\\.8\\.[0-9\\.]+)\\.tgz");
return "Failed to find versions" if (!@vers);
return $ver eq $vers[0] ? undef : $vers[0];
}
@@ -441,26 +432,4 @@ sub script_dolibarr_passmode
return 2;
}
sub script_dolibarr_db_conn_desc
{
my $db_conn_desc =
{ 'conf/conf.php' =>
{
'dbpass' =>
{
'func' => 'php_quotemeta',
'func_params' => 1,
'replace' => [ '\$dolibarr_main_db_pass\s*=' =>
'$dolibarr_main_db_pass=\'$$sdbpass\';' ],
},
'dbuser' =>
{
'replace' => [ '\$dolibarr_main_db_user\s*=' =>
'$dolibarr_main_db_user=\'$$sdbuser\';' ],
},
}
};
return $db_conn_desc;
}
1;

File diff suppressed because it is too large Load Diff

View File

@@ -30,17 +30,27 @@ Alias /dolibarr /usr/share/dolibarr/htdocs
ErrorDocument 404 /public/error-404.php
# OPTIMIZE: To use cache on static pages (A259200 = 1 month).
# Note that you must also enable the module mod_expires.
#ExpiresActive On
#ExpiresByType image/x-icon A2592000
#ExpiresByType image/gif A2592000
#ExpiresByType image/png A2592000
#ExpiresByType image/jpeg A2592000
#ExpiresByType text/css A2592000
#ExpiresByType text/javascript A2592000
#ExpiresByType application/x-javascript A2592000
#ExpiresByType application/javascript A2592000
# OPTIMIZE: To use gzip compressed files (for Dolibarr already compressed files).
# Note that constant MAIN_OPTIMIZE_SPEED must have a value with bit 0 set.
#AddType text/javascript .jgz
#AddEncoding gzip .jgz
# OPTIMIZE: To use gzip compression (on the fly).
# Note that you must also enable the module mod_deflate.
# You can also set this with constant MAIN_OPTIMIZE_SPEED and bit 2 set.
#TODO
# OPTIMIZE: To use cache on static pages (A259200 = 1 month).
# Note that you must also enable the module mod_expires.
#ExpiresActive On
#ExpiresByType image/x-icon A2592000
#ExpiresByType image/gif A2592000
#ExpiresByType image/png A2592000
#ExpiresByType image/jpeg A2592000
#ExpiresByType text/css A2592000
#ExpiresByType text/javascript A2592000
#ExpiresByType application/x-javascript A2592000
#ExpiresByType application/javascript A2592000
</DirectoryMatch>

View File

@@ -1,6 +1,6 @@
This file describes the changes made on external libraries to fix some bugs, after they were included
in Dolibarr external vendor dir (htdocs/includes).
This file describes changes made on external libraries after being included
in Dolibarr root.
@@ -234,7 +234,7 @@ In htdocs/includes/tecnickcom/tcpdf/tcpdf.php
PHP TCPDI:
----------
Add file fpdf_tpl.php 1.2.3
Add file fpdf_tpl.php 1.2
Add file tcpdi.php

View File

@@ -1,4 +1,4 @@
README (english)
--------------------------------
This directory contains some sample files to test ldap command on command line.
They are used to help developmement and debugging of Dolibarr LDAP features.
They are used to help developmement and debugging of Dolibarr LDAP features.

View File

@@ -8,4 +8,4 @@
dn: ou=contacts,dc=my-domain,dc=com
objectClass: organizationalUnit
ou: contacts
ou: contacts

View File

@@ -24,5 +24,6 @@
# ldapsearch -h hostname -p 389 -x -D "cn=manager,o=somecompany.com" -w password -b "ou=people,dc=teclib,dc=infra"
# ldapsearch -h hostname -p 389 -x -D "cn=manager,o=somecompany.com" -w password -b "o=somecompany.com" "(objectclass=*)"
#
# Example to test a ldap search:
# Example to test a ldap search:
# ldapsearch -h hostname -p 389 -x -z 5 -b 'OU=Collaborateurs,OU=Utilisateurs,OU=MyCompany,DC=bocal,DC=lan' -D 'CN=UserAdmin,OU=Informatique,OU=Utilisateurs,OU=MyCompany,DC=bocal,DC=lan' -w password

View File

@@ -65,4 +65,4 @@ o9CFUO94RUiiEpmahN6IfgQXpQJUft9yuDseAluyCkKif5QkQA3IvwVYD2mv0R1uc9gY
fZt0uru+Tc93cnQQ82A5KVrVVvvahsyxtQFRMOgFLl8ct3wu6NVPyQPby9YUk2J4dpQr
R5X+bCaMew5mDNsdjMV95GesdhT3n3y32Az+XZsuecMoxePVX5S+GRSu/9XVL9Z+w7Ki
--468358388441498ebb24096bfda88a45--
--468358388441498ebb24096bfda88a45--

View File

@@ -46,4 +46,4 @@ Content-Transfer-Encoding: quoted-printable
... attach-file ...
--------------090104020208060008040809-- (end multipart/mixed)
--------------090104020208060008040809-- (end multipart/mixed)

View File

@@ -45,4 +45,4 @@ VEImZGI9b2Rvb192OCc+UGFydG5lciBBZ3JvbGFpdDwvYT48L3NtYWxsPjwvc3Bhbj4K
--===============8764907306434163361==--
--===============4543832834454763172==--
--===============4543832834454763172==--

View File

@@ -71,7 +71,7 @@ Content-Type: text/plain; charset="UTF-8"
adfsdfsdfds
--
--
Laurent.
------------------------------------------------------------------------------------
Twitter: https://www.twitter.com/eldy10

View File

@@ -3,3 +3,4 @@
Take a look at the dolibarr wiki page of Zapier module:
https://wiki.dolibarr.org/index.php?title=Module_Zapier

View File

@@ -1,25 +1,56 @@
{
"table_rowid" : "id",
"id" : 6764,
"type_id" : "5",
"type_code" : "AC_RDV",
"label" : "azerty",
"datep" : 1555365600,
"datef" : 1555538399,
"durationp" : 172799,
"fulldayevent" : 1,
"punctual" : 1,
"percentage" : "-1",
"transparency" : 1,
"priority" : 0,
"userassigned" : {
"1" : {
"id" : "1",
"transparency" : 1
}
},
"userownerid" : "1",
"fk_project" : 0,
"note" : "wxcvbn",
"duree" : 0
}
"table_rowid": "id",
"id": 6764,
"ref": null,
"type_id": "5",
"type_code": "AC_RDV",
"type": null,
"type_color": null,
"code": null,
"label": "azerty",
"datec": null,
"datem": null,
"authorid": null,
"usermodid": null,
"datep": 1555365600,
"datef": 1555538399,
"durationp": 172799,
"fulldayevent": 1,
"punctual": 1,
"percentage": "-1",
"location": "",
"transparency": 1,
"priority": 0,
"userassigned": {
"1": {
"id": "1",
"transparency": 1
}
},
"userownerid": "1",
"userdoneid": null,
"usertodo": null,
"userdone": null,
"socid": null,
"contactid": null,
"elementtype": "",
"icalname": null,
"icalcolor": null,
"actions": [],
"email_msgid": null,
"email_from": null,
"email_sender": null,
"email_to": null,
"email_tocc": null,
"email_tobcc": null,
"email_subject": null,
"errors_to": null,
"import_key": null,
"linkedObjectsIds": null,
"fk_project": 0,
"modelpdf": null,
"note_public": null,
"note_private": null,
"note": "wxcvbn",
"duree": 0
}

View File

@@ -46,8 +46,6 @@ passwd=$6
if [ "$confirm" != "confirm" ]
then
echo "----- $0 -----"
echo "Usage: initdemo.sh confirm "
echo " or"
echo "Usage: initdemo.sh confirm [mysqldump_dolibarr_x.x.x.sql database port login pass]"
exit
fi
@@ -58,8 +56,6 @@ command -v dialog >/dev/null 2>&1 || {
echo "Error: command dialog not found. On Linux, you can install it with: apt install dialog"
exit
}
DIALOG=${DIALOG:=dialog}
DIALOG="$DIALOG --ascii-lines"
# ----------------------------- if no params on command line
@@ -71,7 +67,8 @@ then
dumpfile=$(basename "$dumpfile")
# ----------------------------- input file
DIALOG=${DIALOG:=dialog}
DIALOG="$DIALOG --ascii-lines"
fichtemp=$(mktemp 2>/dev/null) || fichtemp=/tmp/test$$
# shellcheck disable=2064,2172
trap "rm -f $fichtemp" 0 1 2 5 15
@@ -88,6 +85,8 @@ then
rm "$fichtemp"
# ----------------------------- database name
DIALOG=${DIALOG:=dialog}
DIALOG="$DIALOG --ascii-lines"
fichtemp=$(mktemp 2>/dev/null) || fichtemp=/tmp/test$$
# shellcheck disable=2064,2172
trap "rm -f '$fichtemp'" 0 1 2 5 15
@@ -104,10 +103,13 @@ then
rm "$fichtemp"
# ---------------------------- database port
DIALOG=${DIALOG:=dialog}
fichtemp=$(mktemp 2>/dev/null) || fichtemp=/tmp/test$$
# shellcheck disable=2064,2172
trap "rm -f '$fichtemp'" 0 1 2 5 15
$DIALOG --title "Init Dolibarr with demo values" --clear --inputbox "Mysql port (ex: 3306):" 16 55 3306 2> "$fichtemp"
$DIALOG --title "Init Dolibarr with demo values" --clear \
--inputbox "Mysql port (ex: 3306):" 16 55 3306 2> "$fichtemp"
valret=$?
case $valret in
@@ -121,10 +123,13 @@ then
rm "$fichtemp"
# ---------------------------- compte admin mysql
DIALOG=${DIALOG:=dialog}
fichtemp=$(mktemp 2>/dev/null) || fichtemp=/tmp/test$$
# shellcheck disable=2064,2172
trap "rm -f '$fichtemp'" 0 1 2 5 15
$DIALOG --title "Init Dolibarr with demo values" --clear --inputbox "Mysql user login (ex: root):" 16 55 root 2> "$fichtemp"
$DIALOG --title "Init Dolibarr with demo values" --clear \
--inputbox "Mysql user login (ex: root):" 16 55 root 2> "$fichtemp"
valret=$?
case $valret in
@@ -138,10 +143,13 @@ then
rm "$fichtemp"
# ---------------------------- password admin mysql (root)
DIALOG=${DIALOG:=dialog}
fichtemp=$(mktemp 2>/dev/null) || fichtemp=/tmp/test$$
# shellcheck disable=2064,2172
trap "rm -f '$fichtemp'" 0 1 2 5 15
$DIALOG --title "Init Dolibarr with demo values" --clear --passwordbox "Password for Mysql user login :" 16 55 2> "$fichtemp"
$DIALOG --title "Init Dolibarr with demo values" --clear \
--passwordbox "Password for Mysql user login :" 16 55 2> "$fichtemp"
valret=$?
case $valret in
@@ -161,7 +169,9 @@ then
# ---------------------------- confirmation
$DIALOG --title "Init Dolibarr with demo values" --clear --yesno "Do you confirm ? \n Dump file : '$dumpfile' \n Dump dir : '$mydir' \n Document dir : '$documentdir' \n Mysql database : '$base' \n Mysql port : '$port' \n Mysql login: '$admin' \n Mysql password : --hidden--" 15 55
DIALOG=${DIALOG:=dialog}
$DIALOG --title "Init Dolibarr with demo values" --clear \
--yesno "Do you confirm ? \n Dump file : '$dumpfile' \n Dump dir : '$mydir' \n Document dir : '$documentdir' \n Mysql database : '$base' \n Mysql port : '$port' \n Mysql login: '$admin' \n Mysql password : --hidden--" 15 55
case $? in
0) echo "Ok, start process..." ;;
@@ -201,21 +211,26 @@ export documentdir
documentdir=$(< "$mydir/../../htdocs/conf/conf.php" grep '^\$dolibarr_main_data_root' | sed -e 's/$dolibarr_main_data_root=//' | sed -e 's/;//' | sed -e "s/'//g" | sed -e 's/"//g')
if [ "$documentdir" != "" ]
then
$DIALOG --title "Reset document directory" --clear --yesno "DELETE and recreate document directory '$documentdir/':" 16 55
"$DIALOG" --title "Reset document directory" --clear \
--inputbox "DELETE and recreate document directory '$documentdir/':" 16 55 n 2> "$fichtemp"
valret=$?
case $valret in
0)
# YES
echo "RECREATE $documentdir"
echo " rm -fr '$documentdir/'*"
rm -fr "${documentdir:?}/"* ;;
rep=$(cat "$fichtemp") ;;
1)
exit ;;
255)
exit ;;
esac
echo "rep=$rep"
if [ "$rep" = "y" ]; then
echo "rm -fr '$documentdir/'*"
rm -fr "${documentdir:?}/"*
fi
echo "cp -pr '$mydir/documents_demo/'* '$documentdir/'"
cp -pr "$mydir/documents_demo/"* "$documentdir/"

View File

@@ -64922,7 +64922,7 @@ INSERT INTO `llx_const` VALUES
(10436,'ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT',1,'-1','chaine',0,'','2023-01-24 11:09:30'),
(10437,'ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT',1,'-1','chaine',0,'','2023-01-24 11:09:30'),
(10615,'MAIN_ALLOW_SVG_FILES_AS_IMAGES',1,'1','chaine',1,'','2023-01-25 16:12:52'),
(10618,'MAIN_HOME',1,'<span style=\"font-size:11px;\">__(NoteSomeFeaturesAreDisabled)__</span>','chaine',0,'','2023-01-30 18:23:00'),
(10618,'MAIN_HOME',1,'__(NoteSomeFeaturesAreDisabled)__<br />\r\n__(SomeTranslationAreUncomplete)__','chaine',0,'','2023-01-30 18:23:00'),
(11246,'MEMBER_ENABLE_PUBLIC',1,'1','chaine',0,'','2023-02-09 13:31:03'),
(11247,'MEMBER_NEWFORM_AMOUNT',1,'20','chaine',0,'','2023-02-09 13:31:03'),
(11248,'MEMBER_MIN_AMOUNT',1,'15','chaine',0,'','2023-02-09 13:31:03'),
@@ -79915,7 +79915,7 @@ CREATE TABLE `llx_user` (
LOCK TABLES `llx_user` WRITE;
/*!40000 ALTER TABLE `llx_user` DISABLE KEYS */;
INSERT INTO `llx_user` VALUES
(1,'2012-07-08 13:20:11','2025-03-13 09:13:00',NULL,NULL,'aeinstein',0,'','',NULL,1,NULL,NULL,'$2y$10$lIvMb5RJjxqmd6OxnZLqvuLZGOXj3gxIQhZQUqcY8fQTyh0cTtUpa',NULL,NULL,'Einstein','Albert','','123456789','','','','aeinstein@example.com','','[]','',0,NULL,NULL,NULL,'','2017-10-05 08:32:44','2017-10-03 11:43:50',NULL,'',1,'alberteinstein.jpg',NULL,NULL,14,NULL,NULL,NULL,'','','',NULL,NULL,'aaaaff','',NULL,0,'',0,NULL,NULL,NULL,44.00000000,'man','',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,NULL,NULL),
(1,'2012-07-08 13:20:11','2025-03-13 09:13:00',NULL,NULL,'aeinstein',0,'','',NULL,1,NULL,NULL,'$2y$10$lIvMb5RJjxqmd6OxnZLqvuLZGOXj3gxIQhZQUqcY8fQTyh0cTtUpa',NULL,'demokey','Einstein','Albert','','123456789','','','','aeinstein@example.com','','[]','',0,NULL,NULL,NULL,'','2017-10-05 08:32:44','2017-10-03 11:43:50',NULL,'',1,'alberteinstein.jpg',NULL,NULL,14,NULL,NULL,NULL,'','','',NULL,NULL,'aaaaff','',NULL,0,'',0,NULL,NULL,NULL,44.00000000,'man','',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,NULL,NULL),
(2,'2012-07-08 13:54:48','2025-05-05 12:08:56',NULL,NULL,'demo',1,'','',NULL,1,NULL,NULL,'$2y$10$Hgawd0DFS2bgBiM6rJuAZ.ff250vlm111HVWBJQvRzRq5hNijLxam',NULL,NULL,'Doe','David','Trainee','09123123','','','','daviddoe@example.com','','[]','',0,NULL,NULL,NULL,'','2018-07-30 23:10:54','2018-07-30 23:04:17',NULL,'',1,'person9.jpeg',NULL,NULL,11,NULL,NULL,NULL,'','','',NULL,NULL,'','',NULL,0,'',0,NULL,NULL,NULL,35.00000000,'man','',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,NULL,NULL),
(3,'2012-07-11 16:18:59','2025-05-05 14:48:17',NULL,NULL,'pcurie',1,'','',NULL,1,NULL,NULL,'$2y$10$Hgawd0DFS2bgBiM6rJuAZ.ff250vlm111HVWBJQvRzRq5hNijLxam',NULL,NULL,'Curie','Pierre','','','','','','pcurie@example.com','','[]','',0,NULL,NULL,2,'','2014-12-21 17:38:55',NULL,NULL,'',1,'dolicloud_avent_saas.png',NULL,NULL,14,NULL,NULL,NULL,'','','',NULL,NULL,'','',NULL,0,'',0,NULL,NULL,NULL,39.00000000,'','',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,NULL,NULL),
(4,'2015-01-23 17:52:27','2025-05-05 14:48:18',NULL,NULL,'bbookkeeper',1,'','',NULL,1,NULL,NULL,'$2y$10$Hgawd0DFS2bgBiM6rJuAZ.ff250vlm111HVWBJQvRzRq5hNijLxam',NULL,NULL,'Bookkeeper','Bob','Bookkeeper','','','','','bbookkeeper@example.com','','{\"skype\":\"skypebbookkeeper\"}','',0,17,6,NULL,'','2015-02-25 10:18:41','2015-01-23 17:53:20',NULL,'',1,'person8.jpeg',NULL,NULL,11,NULL,NULL,NULL,'','','',NULL,NULL,'','',NULL,0,'',0,NULL,NULL,NULL,16.00000000,'man','',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'',NULL,NULL,NULL),

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +0,0 @@
---- Locked files -----
This file is the list of the signatures of some set of files locked to block a commit if files are tried to be modified for a given version.
It is used by the CI or the script to check and guarantee that no change is done on a given scope of files.
Version Scope Algo Signature (generated by dev/build/generate_filelist_xml.php) that must remain unchanged for this couple version/scope
x.0.0 unalterable_files sha256 123456

View File

@@ -1,3 +0,0 @@
/dolibarr_schema.mwb.bak
/dolibarr_schema.mwb.sav.mwb
/dolibarr_schema.mwb.sav.mwb.bak

View File

@@ -1,2 +1,2 @@
This directory contains the file with the graphical database structure.
It can be read with MySQL Workbench software.
It can be read with MySQL Workbench software.

View File

@@ -2,5 +2,5 @@ EORI
https://en.wikipedia.org/wiki/EORI_number
in Dolibarr avaiable since v13
in Dolibarr avaiable since v13
- it is set to field 'profid5'

View File

@@ -18,3 +18,5 @@ Et ça marche à linverse avec un fournisseur sauf que lon est en 775000 a
Un compte comptable de Tiers vente = Acount Receivable
Un compte comptable de Tiers achat = Acount Payable

View File

@@ -3,3 +3,4 @@ Address format
https://bitboost.com/ref/international-address-formats.html#Formats
https://www.upu.int/en/Postal-Solutions/Programmes-Services/Addressing-Solutions

View File

@@ -117,3 +117,5 @@ IBAN : FR54 3000 4031 2800 032T 56H9 125
Division :
3000403128000322956179125152754 / 97 =
3000403128000322956179125152753 reste 1.

View File

@@ -1,4 +1,4 @@
NACE
NACE
https://ec.europa.eu/eurostat/ramon/nomenclatures/index.cfm?TargetUrl=LST_CLS_DLD&StrNom=NACE_REV2&StrLanguageCode=EN&StrLayoutCode=

View File

@@ -3,7 +3,7 @@
# The list is updated whenever a change to the official code list in ISO 3166-1 is effected by the ISO 3166/MA.
# It lists 240 official short names and code elements. One line of text contains one entry.
# A country name and its code element are separated by a semicolon (;).
# https://www.iso.org/iso-3166-country-codes.html
# https://www.iso.org/iso-3166-country-codes.html
# https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes
# ISO-3166: https://en.wikipedia.org/wiki/ISO_3166-1

View File

@@ -136,4 +136,4 @@
<xsd:element name="regionCode" type="xsd:string"/>
<xsd:element name="date" type="xsd:date"/>
<xsd:element name="time" type="xsd:time"/>
</xsd:schema>
</xsd:schema>

View File

@@ -52,12 +52,12 @@ GUARANI GN AMERINDIAN
GUJARATI GU INDIAN
HAUSA HA NEGRO-AFRICAN
HEBREW HE SEMITIC [*Changed 1989 from original ISO 639:1988, IW]
HEBREW HE SEMITIC [*Changed 1989 from original ISO 639:1988, IW]
HINDI HI INDIAN
HUNGARIAN HU FINNO-UGRIC
ICELANDIC IS GERMANIC
INDONESIAN ID OCEANIC/INDONESIAN [*Changed 1989 from original ISO 639:1988, IN]
INDONESIAN ID OCEANIC/INDONESIAN [*Changed 1989 from original ISO 639:1988, IN]
INTERLINGUA IA INTERNATIONAL AUX.
INTERLINGUE IE INTERNATIONAL AUX.
INUKTITUT IU [ ]
@@ -159,7 +159,7 @@ WOLOF WO NEGRO-AFRICAN
XHOSA XH NEGRO-AFRICAN
YIDDISH YI GERMANIC [*Changed 1989 from original ISO 639:1988, JI]
YIDDISH YI GERMANIC [*Changed 1989 from original ISO 639:1988, JI]
YORUBA YO NEGRO-AFRICAN
ZHUANG ZA [ ]
@@ -211,7 +211,7 @@ GALICIAN GL ROMANCE
GUARANI GN AMERINDIAN
GUJARATI GU INDIAN
HAUSA HA NEGRO-AFRICAN
HEBREW HE SEMITIC [*Changed 1989 from original ISO 639:1988, IW]
HEBREW HE SEMITIC [*Changed 1989 from original ISO 639:1988, IW]
HINDI HI INDIAN
CROATIAN HR SLAVIC
HUNGARIAN HU FINNO-UGRIC
@@ -219,7 +219,7 @@ ARMENIAN HY INDO-EUROPEAN (OTHER)
INTERLINGUA IA INTERNATIONAL AUX.
INTERLINGUE IE INTERNATIONAL AUX.
INUPIAK IK ESKIMO
INDONESIAN ID OCEANIC/INDONESIAN [*Changed 1989 from original ISO 639:1988, IN]
INDONESIAN ID OCEANIC/INDONESIAN [*Changed 1989 from original ISO 639:1988, IN]
ICELANDIC IS GERMANIC
ITALIAN IT ROMANCE
INUKTITUT IU [ ]
@@ -304,7 +304,7 @@ VIETNAMESE VI ASIAN
VOLAPUK VO INTERNATIONAL AUX.
WOLOF WO NEGRO-AFRICAN
XHOSA XH NEGRO-AFRICAN
YIDDISH YI GERMANIC [*Changed 1989 from original ISO 639:1988, JI]
YIDDISH YI GERMANIC [*Changed 1989 from original ISO 639:1988, JI]
YORUBA YO NEGRO-AFRICAN
ZHUANG ZA [ ]
CHINESE ZH ASIAN
@@ -362,7 +362,7 @@ GERMAN DE GERMANIC
ICELANDIC IS GERMANIC
NORWEGIAN NO GERMANIC
SWEDISH SV GERMANIC
YIDDISH YI GERMANIC [*Changed 1989 from original ISO 639:1988, JI]
YIDDISH YI GERMANIC [*Changed 1989 from original ISO 639:1988, JI]
AFAN (OROMO) OM HAMITIC
AFAR AA HAMITIC
@@ -420,7 +420,7 @@ YORUBA YO NEGRO-AFRICAN
ZULU ZU NEGRO-AFRICAN
FIJI FJ OCEANIC/INDONESIAN
INDONESIAN ID OCEANIC/INDONESIAN [*Changed 1989 from original ISO 639:1988, IN]
INDONESIAN ID OCEANIC/INDONESIAN [*Changed 1989 from original ISO 639:1988, IN]
JAVANESE JV OCEANIC/INDONESIAN
MALAGASY MG OCEANIC/INDONESIAN
MALAY MS OCEANIC/INDONESIAN
@@ -444,7 +444,7 @@ SPANISH ES ROMANCE
AMHARIC AM SEMITIC
ARABIC AR SEMITIC
HEBREW HE SEMITIC [*Changed 1989 from original ISO 639:1988, IW]
HEBREW HE SEMITIC [*Changed 1989 from original ISO 639:1988, IW]
MALTESE MT SEMITIC
TIGRINYA TI SEMITIC

View File

@@ -5,4 +5,4 @@ terms
(fr) TVA = Taxe sur la Valeur Ajouté
(es) NIF / CIF
(de) USt / MwSt = UmsatzSteuer / Mehrwertsteuer
(it) IVA
(it) IVA

View File

@@ -5,6 +5,6 @@ https://www.taxrates.cc/index.html
https://en.wikipedia.org/wiki/List_of_countries_by_tax_rates
For India: VAT=IGST / CGST=Localtax1 / SGST=Localtax2
see:
see:
https://cleartax.in/s/what-is-sgst-cgst-igst
https://www.mastersindia.co/blog/what-is-cgst-sgst-igst-and-ugst/

View File

@@ -3,4 +3,4 @@ README (English)
If your web hosting does not allow you to place the folder "documents" outside
the site root, add the htaccess.txt in the root directory of
folder "documents" by renaming it into .htaccess
folder "documents" by renaming it into .htaccess

View File

@@ -1,7 +1,7 @@
[PHP]
; ************************
: Need a special php.ini to allow usage of
: Need a special php.ini to allow usage of
; ************************
;;;;;;;;;;;;;;;;;;;

View File

@@ -7,7 +7,7 @@
*/</template><template autoinsert="true" context="phpcomment" deleted="false" description="Comment for created constructors" enabled="true" id="org.eclipse.php.ui.editor.templates.php.codetemplates.constructorcomment" name="constructorcomment">/**
* ${tags}
*/</template><template autoinsert="true" context="phpcomment" deleted="false" description="Comment for created PHP files" enabled="true" id="org.eclipse.php.ui.editor.templates.php.codetemplates.filecomment" name="filecomment">/**
*
*
*/
</template><template autoinsert="true" context="phpcomment" deleted="false" description="Comment for created types" enabled="true" id="org.eclipse.php.ui.editor.templates.php.codetemplates.typecomment" name="typecomment">/**
* @author ${user}
@@ -47,7 +47,7 @@ ${cursor}</template><template autoinsert="false" context="php" deleted="false" d
case ${value}:
${cursor};
break;
default:
;
break;
@@ -66,21 +66,21 @@ ${cursor}</template><template autoinsert="false" context="php" deleted="false" d
</template><template autoinsert="false" context="php" deleted="false" description="lambda function statement (closure)" enabled="true" id="org.eclipse.php.ui.editor.templates.php.closure" name="closure">function (${parameters}) use (${lexical_variables}) {
${cursor};
}
</template><template autoinsert="false" context="php" deleted="false" description="class statement" enabled="true" id="org.eclipse.php.ui.editor.templates.php.cls" name="cls">class ${class_name}
</template><template autoinsert="false" context="php" deleted="false" description="class statement" enabled="true" id="org.eclipse.php.ui.editor.templates.php.cls" name="cls">class ${class_name}
{
function ${function_name}()
function ${function_name}()
{
${cursor};
}
}
</template><template autoinsert="false" context="php" deleted="false" description="class statement" enabled="true" id="org.eclipse.php.ui.editor.templates.php.class" name="class">class ${class_name}
</template><template autoinsert="false" context="php" deleted="false" description="class statement" enabled="true" id="org.eclipse.php.ui.editor.templates.php.class" name="class">class ${class_name}
{
function ${function_name}()
function ${function_name}()
{
${cursor};
}
}
</template><template autoinsert="false" context="php" deleted="false" description="if statement" enabled="true" id="org.eclipse.php.ui.editor.templates.php.if" name="if">if (${condition})
</template><template autoinsert="false" context="php" deleted="false" description="if statement" enabled="true" id="org.eclipse.php.ui.editor.templates.php.if" name="if">if (${condition})
{
${cursor};
}
@@ -115,7 +115,7 @@ if (${dollar}${dirh}) {
${cursor};
}
</template><template autoinsert="false" context="php" deleted="false" description="Trap code output" enabled="true" id="org.eclipse.php.ui.editor.templates.php.my_gc" name="my_gc">ob_start();
${cursor};
${dollar}${contents} = ob_get_contents();
@@ -142,4 +142,4 @@ ${cursor}
&lt;/body&gt;
&lt;/noframes&gt;
&lt;/frameset&gt;
&lt;/html&gt;</template></templates>
&lt;/html&gt;</template></templates>

View File

@@ -33,7 +33,7 @@ do
result1=$?
if [ "$result1" != "0" ]
if [ "x$result1" != "x0" ]
then
echo "Fix the error before commit." 1>&2
exit 1
@@ -56,10 +56,10 @@ then
result2=$?
if [ "$result2" != "0" ]
if [ "x$result2" != "x0" ]
then
# Fix standard errors
if [ "$AUTOFIX" != "0" ]
if [ "x$AUTOFIX" != "x0" ]
then
# shellcheck disable=2086,2090
"${DIRPHPCS}phpcbf" -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true $FILES

View File

@@ -9,4 +9,4 @@ cs_re:red:.*ERR.*
cs_re:white,yellow:.*WARNING.*
cs_re:green,yellow:.*NOTICE.*
cs_re:green:.*INFO.*
cs_re:white:.*DEBUG.*
cs_re:white:.*DEBUG.*

View File

@@ -44,10 +44,10 @@ function save_db_cache() (
# DETERMINE VERSION
cd "${TRAVIS_BUILD_DIR}/htdocs/install" || exit 1
# Get the target version from the version.inc.php file
target_version=$(sed -n "s/.*define('DOL_\\(MAJOR_\\)\\?VERSION',[[:space:]]*'\\([0-9.]*\\).*/\\2/p" ../version.inc.php) ; echo $target_version
# Get the target version from the filefunc.inc.php file
target_version=$(sed -n "s/.*define('DOL_VERSION',[[:space:]]*'\\([0-9.]*\\).*/\\1/p" ../filefunc.inc.php) ; echo $target_version
# Default in case that failed
target_version=${target_version:=22.0.0}
target_version=${target_version:=20.0.0}
# Sequence of versions for upgrade process (to be completed)
VERSIONS=("3.5.0" "3.6.0" "3.7.0" "3.8.0" "3.9.0")

View File

@@ -16,4 +16,4 @@ xdebug.show_local_vars=off
xdebug.profiler_output_dir=/var/tmp
xdebug.profiler_append=0
Then xdebug profiling can be enabled by adding XDEBUG_PROFILE=1 on URL.
Then xdebug profiling can be enabled by adding XDEBUG_PROFILE=1 on URL.

View File

@@ -1 +1 @@
Files and tools of a skeleton to build a module were moved into htdocs/modulebuilder/template
Files and tools of a skeleton to build a module were moved into htdocs/modulebuilder/template

View File

@@ -1,31 +0,0 @@
README (English)
--------------------------------
##############
RapidAPI
##############
RapidAPI for Mac is a full-featured HTTP client that let's you test and describe the APIs you build or consume.
It has a beautiful native macOS interface to compose requests, inspect server responses, generate client code and export API definitions.
https://paw.cloud/
@@@
(@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@%
@@@@@@, @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,
@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
(@@@@@@( @@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@* @@@@@@@@@@@. /@@@@@@@@@@@@@@@@@(
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@* @@@@@@@@@@@. @@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ /@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@# @@@@@@@@@@@ @@@@@@@@@@@@&
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ &@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ &@@@@@@@@@@@@@@@@@@@@/
@@@@@@@@@@@@@@@@@@@@@@@@@@& .@@@@@@@@@@@ &@@@@@@@@@@@@@@@@@@/
(@@@@@@@@@@@@@@@@@@@@@@@ .@@@@@@@@@@@ &@@@@@@@@@@@@@@@(
@@@@@ @@@@@ .@@@@@@@@@@@ @@@@@@@@@@@*

View File

@@ -61,7 +61,7 @@ if (empty($argv[1])) {
$outputpath = $argv[1];
$outputdir = dirname($outputpath);
$outputfile = basename($outputpath);
$outputfilerss = preg_replace('/\.\w+$/i', '', $outputfile).'-security.rss'; // Replace the .html by -security.rss
$outputfilerss = preg_replace('/\.\w+$/i', '', $outputfile).'-security.rss';
if (!is_dir($outputdir)) {
print 'Error: dir '.$outputdir.' does not exists or is not writable'."\n";
@@ -124,14 +124,14 @@ $urlgit = 'https://github.com/Dolibarr/dolibarr/blob/develop/';
$output_arrproj = array();
$output_arrdep = array();
if ($dirscc != 'disabled') {
$commandcheck = ($dirscc ? $dirscc.'/' : '').'scc . --exclude-dir=htdocs/custom,htdocs/includes,htdocs/public/includes,htdocs/theme/common/fontawesome-5,htdocs/public/theme/common/fontawesome-5 --cocomo-project-type semi-detached';
$commandcheck = ($dirscc ? $dirscc.'/' : '').'scc . --exclude-dir=htdocs/custom,htdocs/includes,htdocs/public/includes,htdocs/theme/common/fontawesome-5,htdocs/public/theme/common/fontawesome-5';
print 'Execute SCC to count lines of code in project: '.$commandcheck."\n";
$resexecproj = 0;
exec($commandcheck, $output_arrproj, $resexecproj);
// Count lines of code of dependencies
$commandcheck = ($dirscc ? $dirscc.'/' : '').'scc htdocs/includes htdocs/public/includes htdocs/theme/common/fontawesome-5 htdocs/public/theme/common/fontawesome-5 --cocomo-project-type semi-detached';
$commandcheck = ($dirscc ? $dirscc.'/' : '').'scc htdocs/includes htdocs/public/includes htdocs/theme/common/fontawesome-5 htdocs/public/theme/common/fontawesome-5';
print 'Execute SCC to count lines of code in dependencies: '.$commandcheck."\n";
$resexecdep = 0;
exec($commandcheck, $output_arrdep, $resexecdep);
@@ -221,13 +221,13 @@ foreach (array('proj', 'dep') as $source) {
$arrayofmetrics[$source]['Bytes'] = $reg[1];
}
if (preg_match('/^(.*)\s+([\d,]+)\s+([\d,]+)\s+([\d,]+)\s+([\d,]+)\s+([\d,]+)\s+([\d,]+)$/', $line, $reg)) {
$arrayoflineofcode[$source][$reg[1]]['Files'] = str_replace(array(',', ' '), array('', ''), $reg[2]);
$arrayoflineofcode[$source][$reg[1]]['Lines'] = str_replace(array(',', ' '), array('', ''), $reg[3]);
$arrayoflineofcode[$source][$reg[1]]['Blanks'] = str_replace(array(',', ' '), array('', ''), $reg[4]);
$arrayoflineofcode[$source][$reg[1]]['Comments'] = str_replace(array(',', ' '), array('', ''), $reg[5]);
$arrayoflineofcode[$source][$reg[1]]['Code'] = str_replace(array(',', ' '), array('', ''), $reg[6]);
$arrayoflineofcode[$source][$reg[1]]['Complexity'] = str_replace(array(',', ' '), array('', ''), $reg[7]);
if (preg_match('/^(.*)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$/', $line, $reg)) {
$arrayoflineofcode[$source][$reg[1]]['Files'] = $reg[2];
$arrayoflineofcode[$source][$reg[1]]['Lines'] = $reg[3];
$arrayoflineofcode[$source][$reg[1]]['Blanks'] = $reg[4];
$arrayoflineofcode[$source][$reg[1]]['Comments'] = $reg[5];
$arrayoflineofcode[$source][$reg[1]]['Code'] = $reg[6];
$arrayoflineofcode[$source][$reg[1]]['Complexity'] = $reg[7];
}
}
@@ -271,7 +271,7 @@ $nbofmonth = 6;
$delay = (3600 * 24 * 30 * $nbofmonth);
$arrayofalerts = array();
$commandcheck = "git log --all --shortstat --no-renames --use-mailmap --pretty=".escapeshellarg('format:%cI;%H;%aN;%aE;%ce;%s')." --since=".escapeshellarg(dol_print_date(dol_now() - $delay, '%Y-%m-%d'))." | grep -i -E ".escapeshellarg("(#ghsa|#yogosha|CVE|Sec:|Sec |^Sec$)");
$commandcheck = "git log --all --shortstat --no-renames --use-mailmap --pretty=".escapeshellarg('format:%cI;%H;%aN;%aE;%ce;%s')." --since=".escapeshellarg(dol_print_date(dol_now() - $delay, '%Y-%m-%d'))." | grep -i -E ".escapeshellarg("(#yogosha|CVE|Sec:|Sec |Sec$)");
print 'Execute git log to get commits related to security: '.$commandcheck."\n";
$output_arrglpu = array();
$resexecglpu = 0;
@@ -280,12 +280,12 @@ foreach ($output_arrglpu as $valgitlog) { // The most recent lines are first.
// Parse the line to split interesting data
$tmpval = cleanVal2($valgitlog);
if (preg_match('/(#ghsa|#yogosha|CVE[\s\-]*\d|Sec:|Sec\s|^Sec$)/i', $tmpval['title'])) { // Recommended git comment: "Fix #..."
if (preg_match('/(#yogosha|CVE[\s\-]*\d|Sec:|Sec\s|Sec$)/i', $tmpval['title'])) { // Recommended git comment: "Sec: Fix #..."
$alreadyfound = '';
$alreadyfoundcommitid = '';
foreach ($arrayofalerts as $val) { // Loop on already found alerts
if ($val['issueidvdp'] && $val['issueidvdp'] == $tmpval['issueidvdp']) { // Already in list
$alreadyfound = 'vdp';
if ($val['issueidyogosha'] && $val['issueidyogosha'] == $tmpval['issueidyogosha']) { // Already in list
$alreadyfound = 'yogosha';
$alreadyfoundcommitid = $val['commitid'];
break;
}
@@ -742,19 +742,19 @@ $html .= '</div>';
$html .= '</section>'."\n";
// Project value (COCOMO Model, use Basic / Semi-detached
// Project value
$html .= '<section class="chapter" id="projectvalue">'."\n";
$html .= '<h2><span class="fas fa-dollar-sign pictofixedwidth"></span>Project value</h2>'."\n";
$html .= '<div class="boxallwidth">'."\n";
$html .= '<div class="box inline-box back1">';
$html .= 'COCOMO value<br><span class="small opacitymedium">(Basic/Semi-detached model)</span><br>';
$html .= 'COCOMO value<br><span class="small opacitymedium">(Basic organic model)</span><br>';
$html .= '<b>$'.formatNumber((empty($arraycocomo['proj']['currency']) ? 0 : $arraycocomo['proj']['currency']) + (empty($arraycocomo['dep']['currency']) ? 0 : $arraycocomo['dep']['currency']), 2).'</b>';
$html .= '</div>';
if (array_key_exists('proj', $arraycocomo)) {
$html .= '<div class="box inline-box back2">';
$html .= 'COCOMO effort<br><span class="small opacitymedium">(Basic/Semi-detached model)</span><br>';
$html .= 'COCOMO effort<br><span class="small opacitymedium">(Basic organic model)</span><br>';
$html .= '<b>'.formatNumber($arraycocomo['proj']['people'] * $arraycocomo['proj']['effort'] + $arraycocomo['dep']['people'] * $arraycocomo['dep']['effort']);
$html .= ' months people</b>';
$html .= '</div>';
@@ -841,10 +841,10 @@ $html .= '<h2><span class="fas fa-code pictofixedwidth"></span>'.$title_security
$html .= '<div class="boxallwidth">'."\n";
$html .= '<div class="div-table-responsive">'."\n";
$html .= '<table class="list_technical_debt centpercent">'."\n";
$html .= '<tr class="trgroup"><td>Commit ID</td><td>Date</td><td style="white-space: nowrap">Reported on a<br>VDP (GHSA, Yogosha...)</td><td style="white-space: nowrap">Reported on<br>GitHub issues</td><td style="white-space: nowrap"><a href="https://www.cve.org/CVERecord/SearchResults?query=dolibarr">Reported on<br>CVE</a></td><td>Title</td><td>Branch of fix</td></tr>'."\n";
$html .= '<tr class="trgroup"><td>Commit ID</td><td>Date</td><td style="white-space: nowrap">Reported on<br>Yogosha</td><td style="white-space: nowrap">Reported on<br>GIT</td><td style="white-space: nowrap"><a href="https://www.cve.org/CVERecord/SearchResults?query=dolibarr">Reported on<br>CVE</a></td><td>Title</td><td>Branch of fix</td></tr>'."\n";
foreach ($arrayofalerts as $key => $alert) {
$cve = '';
$vdp = empty($alert['issueidvdp']) ? '' : $alert['issueidvdp'];
$yogosha = empty($alert['issueidyogosha']) ? '' : $alert['issueidyogosha'];
$arrayofalerts[$key]['url_commit'] = 'https://github.com/Dolibarr/dolibarr/commit/'.$alert['commitid'];
if (!empty($alert['issueid'])) {
$arrayofalerts[$key]['url_issue'] = 'https://github.com/Dolibarr/dolibarr/issues/'.$alert['issueid'];
@@ -853,7 +853,7 @@ foreach ($arrayofalerts as $key => $alert) {
$cve = preg_replace('/\s+/', '-', trim($alert['issueidcve']));
$arrayofalerts[$key]['url_cve'] = 'https://nvd.nist.gov/vuln/detail/CVE-'.$cve;
}
$arrayofalerts[$key]['title'] = ($project ? "[".$project."] " : "").'Security alert - '.($vdp ? ' VDP #'.$vdp.' - ' : '').($cve ? 'CVE-'.$cve.' - ' : '');
$arrayofalerts[$key]['title'] = ($project ? "[".$project."] " : "").'Security alert - '.($yogosha ? ' Yogosha #'.$yogosha.' - ' : '').($cve ? 'CVE-'.$cve.' - ' : '');
$arrayofalerts[$key]['title'] .= 'Fix committed as: '.dol_trunc($alert['commitid'], 8);
$arrayofalerts[$key]['description'] = '<![CDATA[Security alert<br>';
@@ -880,11 +880,13 @@ foreach ($arrayofalerts as $key => $alert) {
$html .= preg_replace('/T.*$/', '', $alert['created_at']);
$html .= '</td>';
// VDP ID
// Yogosha ID
$html .= '<td style="white-space: nowrap">';
if (!empty($alert['issueidvdp'])) {
$html .= '#vdp'.$alert['issueidvdp'];
$arrayofalerts[$key]['description'] .= "\n<br>".'VDP ID #'.$alert['issueidvdp'];
if (!empty($alert['issueidyogosha'])) {
//$html .= '<a target="_blank" href="https://yogosha.com?'.$alert['issueidyogosha'].'">';
$html .= '#yogosha'.$alert['issueidyogosha'];
$arrayofalerts[$key]['description'] .= "\n<br>".'Yogosha ID #'.$alert['issueidyogosha'];
//$html .= '</a>';
} else {
//$html .= '<span class="opacitymedium">public issue</span>';
}
@@ -930,7 +932,7 @@ $html .= '</div>';
$html .= '</div>';
$html .= '<br>';
$html .= 'Note:Search is done in git repository on regex string "#ghsa|#yogosha|CVE[\s\-]*\d|Sec:|Sec |^Sec\s" (not case sensitive)<br>';
$html .= 'Note:Search is done in git repository on regex string "#yogosha|CVE[\s\-]*\d|Sec:|Sec\s" (not case sensitive)<br>';
$html .= 'You can use this URL for RSS notifications: <a href="/'.$outputfilerss.'">'.$outputfilerss.'</a><br><br>';
$html .= '</section>';
@@ -971,18 +973,6 @@ if ($fh) {
}
fwrite($fh, '</image>'."\n");
// Loop on arrayofalert to remove alerts that are on develop
foreach ($arrayofalerts as $tmpkey => $alert) {
$arrayuniquetmp = array_unique($alert['branch']);
if (count($arrayuniquetmp) == 1 && in_array('develop', $arrayuniquetmp)) {
// The alert has been fixed into develop only, so we discard it for RSS alert
print 'The alert with key '.$tmpkey.' is fixed into branch develop only, so we discard it for RSS'."\n";
unset($arrayofalerts[$tmpkey]);
}
}
// Loop on array of alerts on stable branches
foreach ($arrayofalerts as $alert) {
$alert['url_commit'] = 'https://github.com/Dolibarr/dolibarr/commit/'.$alert['commitid'];
@@ -1145,7 +1135,7 @@ function cleanVal2($val)
$tmpval['commitid'] = $tmp[1];
$tmpval['url'] = '';
$tmpval['issueid'] = '';
$tmpval['issueidvdp'] = '';
$tmpval['issueidyogosha'] = '';
$tmpval['issueidcve'] = '';
$tmpval['title'] = array_key_exists(5, $tmp) ? preg_replace('/\.$/', '', $tmp[5]) : '';
$tmpval['created_at'] = array_key_exists(0, $tmp) ? $tmp[0] : '';
@@ -1159,10 +1149,7 @@ function cleanVal2($val)
$tmpval['issueidcve'] = preg_replace('/^\-/', '', preg_replace('/\s+/', '-', trim($reg[1])));
}
if (preg_match('/#yogosha(\d+)/i', $tmpval['title'], $reg)) {
$tmpval['issueidvdp'] = $reg[1];
}
if (preg_match('/#ghsa([a-z\-\d]+)/i', $tmpval['title'], $reg)) {
$tmpval['issueidvdp'] = $reg[1];
$tmpval['issueidyogosha'] = $reg[1];
}
return $tmpval;

View File

@@ -11,386 +11,351 @@
# Pour les cles autoincrement: rowid integer AUTO_INCREMENT PRIMARY KEY,
# Mettre les index dans fichier.key.sql
#------------------------------------------------------------------------------
## no critic (InputOutput::ProhibitExplicitStdin,InputOutput::RequireBriefOpen)
use Data::Dumper;
use Getopt::Long;
use strict;
use warnings;
use vars qw/ $DIR $PROG $Extension $SOURCE $DESTI %filelist $stop /;
# command line options
my ( $opt_debug, $opt_help );
my( $opt_debug, $opt_help);
# general values
my ( $out, $size );
my ($out, $size);
# variables for constructing pre-create-table entities
my $create_sql = ''; # if empty we are not making a create statement
my $create_index = ''; # if empty we are not making a create statement
my %enum_datafield = (); # holds enumeration choices
my ( @column_values, $enum_column, $seq );
my $table = "";
my $create_sql=''; # if empty we are not making a create statement
my $create_index=''; # if empty we are not making a create statement
my %enum_datafield=(); # holds enumeration choices
my (@column_values,$enum_column, $seq);
my $table="";
#------------------------------------------------------------------------------
# MAIN
#------------------------------------------------------------------------------
( $DIR = $0 ) =~ s/([^\/\\]+)$//;
( $PROG = $1 ) =~ s/\.([^\.]*)$//;
$Extension = $1;
$DIR ||= '.';
$DIR =~ s/([^\/\\])[\\\/]+$/$1/;
($DIR=$0) =~ s/([^\/\\]+)$//; ($PROG=$1) =~ s/\.([^\.]*)$//; $Extension=$1;
$DIR||='.'; $DIR =~ s/([^\/\\])[\\\/]+$/$1/;
$SOURCE = "$DIR/install/mysql/tables";
$DESTI = "$DIR/install/pgsql/tables";
$SOURCE="$DIR/install/mysql/tables";
$DESTI="$DIR/install/pgsql/tables";
# Recherche tous les fichiers .sql
opendir( my $dir, $SOURCE );
foreach my $file ( readdir($dir) ) {
if ( $file =~ /\.sql$/ && -f "$SOURCE/$file" ) {
print "Found file $file\n";
$filelist{$file} = 1;
}
}
closedir($dir);
opendir(DIR, $SOURCE);
foreach my $file (readdir(DIR)) {
if ($file =~ /\.sql$/ && -f "$SOURCE/$file") {
print "Found file $file\n";
$filelist{$file}=1;
}
}
closedir(DIR);
# Boucle sur tous les fichiers de SOURCE
#---------------------------------------
foreach my $file ( keys %filelist ) {
foreach my $file (keys %filelist) {
local $ARGV[0] = "$SOURCE/$file";
local $ARGV[1] = "$DESTI/$file";
$ARGV[0]="$SOURCE/$file";
$ARGV[1]="$DESTI/$file";
print "Convert file $ARGV[0] into $ARGV[1]\n";
print "Convert file $ARGV[0] into $ARGV[1]\n";
# MySQL to PostgreSQL dump file converter
#
# For usage: perl mysql2pgsql.perl --help
#
# homepage: http://www.rot13.org/~dpavlin/projects.html
# 1999-12-15 DbP -- Dobrica Pavlinusic <dpavlin@rot13.org>
# 1999-12-26 DbP don't make serial from auto_increment, create all manually
# (to set start value right)
# 2000-01-11 DbP now creates sequences with correct value
# 2000-04-25 DbP import into CVS (at cvs.linux.hr)
# 2001-01-29 tpo -- Tomas Pospisek <tpo@sourcepole.ch>:
# 1) make script comply to usage:
# 2) make script output to STDOUT instead of STERR
# 3) change verbosity behaveour
# 4) add debug option
# see rest of changelog at http://cvs.linux.hr/cvsweb.cgi/sql/mysql2pgsql
# 2003-12-16 jsp -- Joe Speigle <joe.speigle@jklh.us>:
# converts: s/\) *Type=MyISAM;/);/i, enum data type -> references,
# auto_increment->sequences
# 2004-01-13 jsp -- moved project to gborg; both the above declined ownership
# 2004-06-29 converts: year(4), year(2)
# homepage: gborg.postgresql.org
# MySQL to PostgreSQL dump file converter
#
# For usage: perl mysql2pgsql.perl --help
#
# homepage: http://www.rot13.org/~dpavlin/projects.html
# 1999-12-15 DbP -- Dobrica Pavlinusic <dpavlin@rot13.org>
# 1999-12-26 DbP don't make serial from auto_increment, create all manually
# (to set start value right)
# 2000-01-11 DbP now creates sequences with correct value
# 2000-04-25 DbP import into CVS (at cvs.linux.hr)
# 2001-01-29 tpo -- Tomas Pospisek <tpo@sourcepole.ch>:
# 1) make script comply to usage:
# 2) make script output to STDOUT instead of STERR
# 3) change verbosity behaveour
# 4) add debug option
# see rest of changelog at http://cvs.linux.hr/cvsweb.cgi/sql/mysql2pgsql
# 2003-12-16 jsp -- Joe Speigle <joe.speigle@jklh.us>:
# converts: s/\) *Type=MyISAM;/);/i, enum data type -> references,
# auto_increment->sequences
# 2004-01-13 jsp -- moved project to gborg; both the above declined ownership
# 2004-06-29 converts: year(4), year(2)
# homepage: gborg.postgresql.org
GetOptions( "debug", "help" );
GetOptions("debug", "help");
my $DEBUG = $opt_debug || 0;
my $HELP = $opt_help || 0;
my $DEBUG = $opt_debug || 0;
my $HELP = $opt_help || 0;
if ( ($HELP) || !defined( $ARGV[0] ) || !defined( $ARGV[1] ) ) {
print
"Usage: perl $0 {--verbose|--help|--debug} mysql_dump_file.sql pg_dump_file.sql\n";
print "\t* OPTIONS\n";
print
"\t--verbose tees to pg_dump_file.sql and STDOUT during conversion\n";
print "\t--debug does ?? \n";
print "\t--help prints this message \n";
print "\t* REQUIRED ARGUMENTS\n";
if ( defined( $ARGV[0] ) ) {
print "\tmysql_dump_file.sql ($ARGV[0])\n";
}
else {
print "\tmysql_dump_file.sql (undefined)\n";
}
if ( defined( $ARGV[1] ) ) {
print "\tpg_dump_file.sql ($ARGV[1])\n";
}
else {
print "\tpg_dump_file.sql (undefined)\n";
}
exit 1;
}
open( my $in, "<", "$ARGV[0]" )
|| die "can't open mysql dump file $ARGV[0]";
open( my $out, ">", "$ARGV[1]" ) || die "can't open pg dump file $ARGV[1]";
print $out "-- Generated by $PROG\n";
print $out "-- (c) 2004, PostgreSQL Inc.\n";
print $out "-- (c) 2005, Laurent Destailleur.\n";
print $out "\n";
if (($HELP) || ! defined($ARGV[0]) || ! defined($ARGV[1])) {
print "Usage: perl $0 {--verbose|--help|--debug} mysql_dump_file.sql pg_dump_file.sql\n";
print "\t* OPTIONS\n";
print "\t--verbose tees to pg_dump_file.sql and STDOUT during conversion\n";
print "\t--debug does ?? \n";
print "\t--help prints this message \n";
print "\t* REQUIRED ARGUMENTS\n";
if (defined ($ARGV[0])) {
print "\tmysql_dump_file.sql ($ARGV[0])\n";
} else {
print "\tmysql_dump_file.sql (undefined)\n";
}
if (defined ($ARGV[1])) {
print "\tpg_dump_file.sql ($ARGV[1])\n";
} else {
print "\tpg_dump_file.sql (undefined)\n";
}
exit 1;
}
# Output for create table and create index
sub output_create {
open(IN,"<$ARGV[0]") || die "can't open mysql dump file $ARGV[0]";
open(OUT,">$ARGV[1]") || die "can't open pg dump file $ARGV[1]";
print OUT "-- Generated by $PROG\n";
print OUT "-- (c) 2004, PostgreSQL Inc.\n";
print OUT "-- (c) 2005, Laurent Destailleur.\n";
print OUT "\n";
# If command ends with "xxx,);", we change to "xxx);"
$create_sql =~ s/,(\s*)\);/$1\);/m;
# Output for create table and create index
sub output_create {
# If command ends with "xxx,);", we change to "xxx);"
$create_sql =~ s/,(\s*)\);/$1\);/m;
# If command ends with "xxx, -- yyy );", we change to "xxx -- yyy);"
$create_sql =~ s/,(\s*\-\-[^\)\n]*)(\s*)\);/$1\n\);/m;
# If command ends with "xxx, -- yyy );", we change to "xxx -- yyy);"
$create_sql =~ s/,(\s*\-\-[^\)\n]*)(\s*)\);/$1\n\);/m;
print OUT $create_sql;
if ($create_index) {
print OUT "\n";
print OUT $create_index;
}
}
print $out $create_sql;
if ($create_index) {
print $out "\n";
print $out $create_index;
}
return;
}
# Reset when moving from each "create table" to "insert" part of dump
sub reset_vars() {
$create_sql="";
$create_index="";
%enum_datafield=();
$enum_column='';
}
# Reset when moving from each "create table" to "insert" part of dump
sub reset_vars() {
$create_sql = "";
$create_index = "";
%enum_datafield = ();
$enum_column = '';
return;
}
# Boucle sur contenu fichier source
#----------------------------------
while (<$in>) {
# Boucle sur contenu fichier source
#----------------------------------
while(<IN>) {
# comments or empty lines
if (/^-- \$Id/) {
$_ =~ s/\$//g;
print $out $_;
if (/^-- \$Id/) {
$_ =~ s/\$//g;
print OUT $_;
next;
}
# comments or empty lines
if ( /^#/ || /^$/ || /^--/ ) {
print $out $_;
next;
}
if (/^USE\s*([^;]*);/) {
print $out "\\c " . $1;
next;
}
if ( $create_sql ne "" )
{ # we are inside create table statement so let's process datatypes
if (/^#/ || /^$/ || /^--/) {
print OUT $_;
next;
}
if (/^USE\s*([^;]*);/) {
print OUT "\\c ". $1;
next;
}
if ($create_sql ne "") { # we are inside create table statement so let's process datatypes
if (/\);/i) { # end of create table sequence
$create_sql =~ s/,$//g; # strip last , inside create table
&output_create;
&reset_vars();
next;
if (/\);/i) { # end of create table sequence
$create_sql =~ s/,$//g; # strip last , inside create table
&output_create;
&reset_vars();
next;
# LDR Added "innodb" and "engine"
}
elsif (/(ISAM|innodb)/i) { # end of create table sequence
s/\) *type=(MyISAM|innodb);/);/i;
s/\) *engine=(MyISAM|innodb);/);/i;
$create_sql =~ s/,$//g; # strip last , inside create table
$create_sql .= $_;
&output_create;
&reset_vars();
next;
}
# LDR Added "innodb" and "engine"
}
elsif (/(ISAM|innodb)/i) { # end of create table sequence
s/\) *type=(MyISAM|innodb);/);/i;
s/\) *engine=(MyISAM|innodb);/);/i;
$create_sql =~ s/,$//g; # strip last , inside create table
$create_sql .= $_;
&output_create;
&reset_vars();
next;
}
# enum -> check
if (/([\w\"]*)\s+enum\s*\(((?:['"][\?\w]+['"]\s*,)+['"][\?\w]+['"])\)(.*)$/i) {
$enum_column=$1;
$enum_datafield{$enum_column}=$2; # 'abc','def', ...
my $suite=$3;
my $maxlength=0;
foreach my $enum (split(',',$enum_datafield{$enum_column})) {
$enum =~ s/[\"\']//g;
if ($maxlength<length($enum)) { $maxlength=length($enum); }
}
$enum_datafield{$enum_column} =~ s/\"/\'/g;
$_ = qq~ $enum_column CHAR($maxlength) CHECK ($enum_column IN ($enum_datafield{$enum_column})) $suite\n~;
# int, auto_increment -> serial
} elsif (/^[\s\t]*(\w*)\s*.*int.*auto_increment/i) {
$seq = qq~${table}_${1}_seq~;
s/[\s\t]*([a-zA-Z_0-9]*)\s*.*int.*auto_increment[^,]*/ $1 SERIAL PRIMARY KEY/ig;
$create_sql.=$_;
next;
# int type conversion
} elsif (/(\w*)int\(\d+\)/i) {
$size=$1;
$size =~ tr [A-Z] [a-z];
if ($size eq "tiny" || $size eq "small") {
$out = "int2";
} elsif ($size eq "big") {
$out = "int8";
} else {
$out = "int4";
}
s/\w*int\(\d+\)/$out/g;
}
# tinyint -> smallint
elsif (/tinyint/i) {
s/tinyint/smallint/g;
}
# enum -> check
if (
/([\w\"]*)\s+enum\s*\(((?:['"][\?\w]+['"]\s*,)+['"][\?\w]+['"])\)(.*)$/i
)
{
$enum_column = $1;
$enum_datafield{$enum_column} = $2; # 'abc','def', ...
my $suite = $3;
my $maxlength = 0;
foreach my $enum ( split( ',', $enum_datafield{$enum_column} ) )
{
$enum =~ s/[\"\']//g;
if ( $maxlength < length($enum) ) {
$maxlength = length($enum);
}
}
$enum_datafield{$enum_column} =~ s/\"/\'/g;
$_ =
qq~ $enum_column CHAR($maxlength) CHECK ($enum_column IN ($enum_datafield{$enum_column})) $suite\n~;
# nuke unsigned
s/(int\w+|smallint)\s+unsigned/$1/gi;
# int, auto_increment -> serial
}
elsif (/^[\s\t]*(\w*)\s*.*int.*auto_increment/i) {
$seq = qq~${table}_${1}_seq~;
s/[\s\t]*([a-zA-Z_0-9]*)\s*.*int.*auto_increment[^,]*/ $1 SERIAL PRIMARY KEY/ig;
$create_sql .= $_;
next;
# int type conversion
}
elsif (/(\w*)int\(\d+\)/i) {
$size = $1;
$size =~ tr [A-Z] [a-z];
if ( $size eq "tiny" || $size eq "small" ) {
$out = "int2";
}
elsif ( $size eq "big" ) {
$out = "int8";
}
else {
$out = "int4";
}
s/\w*int\(\d+\)/$out/g;
}
# blob -> text
s/\w*blob/text/gi;
# tinyint -> smallint
elsif (/tinyint/i) {
s/tinyint/smallint/g;
}
# tinytext/mediumtext -> text
s/tinytext/text/gi;
s/mediumtext/text/gi;
# nuke unsigned
s/(int\w+|smallint)\s+unsigned/$1/gi;
# char -> varchar
# PostgreSQL would otherwise pad with spaces as opposed
# to MySQL! Your user interface may depend on this!
s/(\s+)char/${1}varchar/gi;
# blob -> text
s/\w*blob/text/gi;
# nuke date representation (not supported in PostgreSQL)
s/datetime default '[^']+'/datetime/i;
s/date default '[^']+'/datetime/i;
s/time default '[^']+'/datetime/i;
# tinytext/mediumtext -> text
s/tinytext/text/gi;
s/mediumtext/text/gi;
# change not null datetime field to null valid ones
# (to support remapping of "zero time" to null
s/datetime not null/datetime/i;
s/datetime/timestamp/i;
# char -> varchar
# PostgreSQL would otherwise pad with spaces as opposed
# to MySQL! Your user interface may depend on this!
s/(\s+)char/${1}varchar/gi;
# nuke size of timestamp
s/timestamp\([^)]*\)/timestamp/i;
# nuke date representation (not supported in PostgreSQL)
s/datetime default '[^']+'/datetime/i;
s/date default '[^']+'/datetime/i;
s/time default '[^']+'/datetime/i;
# double -> numeric
s/^double/numeric/i;
s/(\s*)double/${1}numeric/i;
# change not null datetime field to null valid ones
# (to support remapping of "zero time" to null
s/datetime not null/datetime/i;
s/datetime/timestamp/i;
# float -> numeric
s/^float/numeric/i;
s/(\s*)float/${1}numeric/i;
# nuke size of timestamp
s/timestamp\([^)]*\)/timestamp/i;
# unique key(field1,field2)
if (/unique key\s*\((\w+\s*,\s*\w+)\)/i) {
s/unique key\s*\((\w+\s*,\s*\w+)\)/UNIQUE\($1\)/i;
$create_sql.=$_;
next;
}
# unique index(field1,field2)
if (/unique index\s*\((\w+\s*,\s*\w+)\)/i) {
s/unique index\s*\((\w+\s*,\s*\w+)\)/UNIQUE\($1\)/i;
$create_sql.=$_;
next;
}
# double -> numeric
s/^double/numeric/i;
s/(\s*)double/${1}numeric/i;
# unique key [name] (field)
if (/unique key\s*(\w*)\s*\((\w+)\)/i) {
s/unique key\s*(\w*)\s*\((\w+)\)/UNIQUE\($2\)/i;
my $idxname=($1?"$1":"idx_${table}_$2");
$create_sql.=$_;
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
next;
}
# unique index [name] (field)
if (/unique index\s*(\w*)\s*\((\w+)\)/i) {
s/unique index\s*(\w*)\s*\((\w+)\)/UNIQUE\($2\)/i;
my $idxname=($1?"$1":"idx_${table}_$2");
$create_sql.=$_;
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
next;
}
# unique (field) et unique (field1, field2 ...)
if (/unique\s*\(([\w,\s]+)\)/i) {
s/unique\s*\(([\w,\s]+)\)/UNIQUE\($1\)/i;
my $fieldlist="$1";
my $idxname="idx_${table}_${fieldlist}";
$idxname =~ s/\W/_/g; $idxname =~ tr/_/_/s;
$create_sql.=$_;
$create_index .= "CREATE INDEX $idxname ON $table ($fieldlist);\n";
next;
}
# float -> numeric
s/^float/numeric/i;
s/(\s*)float/${1}numeric/i;
# index(field)
if (/index\s*(\w*)\s*\((\w+)\)/i) {
my $idxname=($1?"$1":"idx_${table}_$2");
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
next;
}
# unique key(field1,field2)
if (/unique key\s*\((\w+\s*,\s*\w+)\)/i) {
s/unique key\s*\((\w+\s*,\s*\w+)\)/UNIQUE\($1\)/i;
$create_sql .= $_;
next;
}
# primary key
if (/\bkey\b/i && !/^\s+primary key\s+/i) {
s/KEY(\s+)[^(]*(\s+)/$1 UNIQUE $2/i; # hack off name of the non-primary key
}
# unique index(field1,field2)
if (/unique index\s*\((\w+\s*,\s*\w+)\)/i) {
s/unique index\s*\((\w+\s*,\s*\w+)\)/UNIQUE\($1\)/i;
$create_sql .= $_;
next;
}
# key(xxx)
if (/key\s*\((\w+)\)/i) {
my $idxname="idx_${table}_$1";
$create_index .= "CREATE INDEX $idxname ON $table ($1);\n";
next;
}
# unique key [name] (field)
if (/unique key\s*(\w*)\s*\((\w+)\)/i) {
s/unique key\s*(\w*)\s*\((\w+)\)/UNIQUE\($2\)/i;
my $idxname = ( $1 ? "$1" : "idx_${table}_$2" );
$create_sql .= $_;
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
next;
}
# Quote column names
s/(^\s*)([^\s\-\(]+)(\s*)/$1"$2"$3/gi if (!/\bkey\b/i);
# unique index [name] (field)
if (/unique index\s*(\w*)\s*\((\w+)\)/i) {
s/unique index\s*(\w*)\s*\((\w+)\)/UNIQUE\($2\)/i;
my $idxname = ( $1 ? "$1" : "idx_${table}_$2" );
$create_sql .= $_;
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
next;
}
# Remap columns with names of existing system attribute
if (/"oid"/i) {
s/"oid"/"_oid"/g;
print STDERR "WARNING: table $table uses column \"oid\" which is renamed to \"_oid\"\nYou should fix application manually! Press return to continue.";
my $wait=<STDIN>;
}
s/oid/_oid/i if (/key/i && /oid/i); # fix oid in key
$create_sql.=$_;
} # END of if ($create_sql ne "") i.e. were inside create table statement so processed datatypes
else { # not inside create table
#---- fix data in inserted data: (from MS world)
# FIX: disabled for now
if (00 && /insert into/i) {
s!\x96!-!g; # --
s!\x93!"!g; # ``
s!\x94!"!g; # ''
s!\x85!... !g; # \ldots
s!\x92!`!g;
}
# unique (field) et unique (field1, field2 ...)
if (/unique\s*\(([\w,\s]+)\)/i) {
s/unique\s*\(([\w,\s]+)\)/UNIQUE\($1\)/i;
my $fieldlist = "$1";
my $idxname = "idx_${table}_${fieldlist}";
$idxname =~ s/\W/_/g;
$idxname =~ tr/_/_/s;
$create_sql .= $_;
$create_index .=
"CREATE INDEX $idxname ON $table ($fieldlist);\n";
next;
}
# fix dates '0000-00-00 00:00:00' (should be null)
s/'0000-00-00 00:00:00'/null/gi;
s/'0000-00-00'/null/gi;
s/'00:00:00'/null/gi;
s/([12]\d\d\d)([01]\d)([0-3]\d)([0-2]\d)([0-6]\d)([0-6]\d)/'$1-$2-$3 $4:$5:$6'/;
# index(field)
if (/index\s*(\w*)\s*\((\w+)\)/i) {
my $idxname = ( $1 ? "$1" : "idx_${table}_$2" );
$create_index .= "CREATE INDEX $idxname ON $table ($2);\n";
next;
}
if (/create\s+table\s+(\w+)/i) {
$create_sql = $_;
/create\s*table\s*(\w+)/i;
$table=$1 if (defined($1));
} else {
print OUT $_;
}
} # end of if inside create_table
} # END while(<IN>)
# primary key
if ( /\bkey\b/i && !/^\s+primary key\s+/i ) {
s/KEY(\s+)[^(]*(\s+)/$1 UNIQUE $2/i
; # hack off name of the non-primary key
}
# key(xxx)
if (/key\s*\((\w+)\)/i) {
my $idxname = "idx_${table}_$1";
$create_index .= "CREATE INDEX $idxname ON $table ($1);\n";
next;
}
# Quote column names
s/(^\s*)([^\s\-\(]+)(\s*)/$1"$2"$3/gi if ( !/\bkey\b/i );
# Remap columns with names of existing system attribute
if (/"oid"/i) {
s/"oid"/"_oid"/g;
print STDERR
"WARNING: table $table uses column \"oid\" which is renamed to \"_oid\"\nYou should fix application manually! Press return to continue.";
my $wait = <STDIN>;
}
s/oid/_oid/i if ( /key/i && /oid/i ); # fix oid in key
$create_sql .= $_;
} # END of if ($create_sql ne "") i.e. were inside create table statement so processed datatypes
else { # not inside create table
#---- fix data in inserted data: (from MS world)
# FIX: disabled for now
if ( 00 && /insert into/i ) {
s!\x96!-!g; # --
s!\x93!"!g; # ``
s!\x94!"!g; # ''
s!\x85!... !g; # \ldots
s!\x92!`!g;
}
# fix dates '0000-00-00 00:00:00' (should be null)
s/'0000-00-00 00:00:00'/null/gi;
s/'0000-00-00'/null/gi;
s/'00:00:00'/null/gi;
s/([12]\d\d\d)([01]\d)([0-3]\d)([0-2]\d)([0-6]\d)([0-6]\d)/'$1-$2-$3 $4:$5:$6'/;
if (/create\s+table\s+(\w+)/i) {
$create_sql = $_;
/create\s*table\s*(\w+)/i;
$table = $1 if ( defined($1) );
}
else {
print $out $_;
}
} # end of if inside create_table
} # END while(<IN>)
close $in;
close $out;
close IN;
close OUT;
}
print "\n";
print "Build " . ( scalar keys %filelist ) . " file(s).\n";
print "Build ".(scalar keys %filelist)." file(s).\n";
print "\n";
print "Press a key to finish...\n";
$stop = <STDIN>;
$stop=<STDIN>;
0;

View File

@@ -128,3 +128,5 @@ for f in ${TFile[@]}; do
done
done

View File

@@ -12,24 +12,19 @@ cp "$0" /tmp/github_commits_perversion.sh
TEMP_DIR=/tmp/git
DOL_GIT="$TEMP_DIR/dolibarr"
if ! git rev-parse ; then
echo "/tmp/git/dolibarr is not a git repo. Delete $TEMP_DIR"
echo "Delete $TEMP_DIR"
rm -fr "$TEMP_DIR"
echo "Create '$TEMP_DIR' and cd to it"
mkdir -p "$TEMP_DIR"
mkdir "$TEMP_DIR"
cd "$TEMP_DIR" || exit
git clone https://github.com/Dolibarr/dolibarr.git
cd "${DOL_GIT}" || exit
else
echo "/tmp/git/dolibarr is a git repo."
mkdir -p ${DOL_GIT}
if [ -r "${DOL_GIT}" ] ; then
echo git worktree remove "${DOL_GIT}"
git worktree remove "${DOL_GIT}"
rm -rf "${DOL_GIT}" >& /dev/null
fi
echo git worktree add --force "${DOL_GIT}" develop
git worktree add --force "${DOL_GIT}" develop
cd "$DOL_GIT" || exit
git pull
@@ -37,14 +32,11 @@ fi
# Determine release to check
Releases=("3.9" "4.0" "5.0" "6.0" "7.0" "8.0" "9.0" "10.0" "11.0" "12.0" "13.0" "14.0" "15.0" "16.0" "17.0" "18.0" "19.0" "20.0" "21.0" "22.0")
target_version=$(sed -n "s/.*define('DOL_VERSION',[[:space:]]*'\\([0-9]*\\.[0-9]*\\).*/\\1/p" htdocs/version.inc.php)
Releases=("3.9" "4.0" "5.0" "6.0" "7.0" "8.0" "9.0" "10.0" "11.0" "12.0" "13.0" "14.0" "15.0" "16.0" "17.0" "18.0" "19.0" "20.0")
target_version=$(sed -n "s/.*define('DOL_VERSION',[[:space:]]*'\\([0-9]*\\.[0-9]*\\).*/\\1/p" htdocs/filefunc.inc.php)
# Default target version in case getting it from filefunc.inc failed
target_version=${target_version:=23}
echo "Last version to test target_version = $target_version";
target_version=${target_version:=20.0}
# Setup loop to append required versions
target_major=${target_version%%.*}
@@ -98,9 +90,8 @@ do
done
# Clean up git directory if it is a worktree
#if [ "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" ] ; then
# cd "$TEMP_DIR" || exit
# git -C "$DOL_GIT" worktree remove "$DOL_GIT"
#fi
if [ "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" ] ; then
cd "$TEMP_DIR" || exit
git -C "$DOL_GIT" worktree remove "$DOL_GIT"
fi
exit

View File

@@ -1,10 +1,8 @@
#!/bin/bash
# Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
# Borrowed from https://gist.github.com/lgiraudel/6065155
# Inplace mode added by Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
# shellcheck disable=2003,2006,2034,2046,2086,2166,2268,2327,2328
# shellcheck disable=2003,2006,2034,2046,2086,2166,2268
PROGNAME=${0##*/}
INPUT=''

View File

@@ -9,31 +9,34 @@
*/
return [
// # Issue statistics:
// PhanUndeclaredProperty : 410+ occurrences
// PhanTypeMismatchArgument : 65+ occurrences
// PhanUndeclaredGlobalVariable : 60+ occurrences
// PhanTypeMismatchArgumentNullable : 20+ occurrences
// PhanTypeMismatchProperty : 20+ occurrences
// PhanUndeclaredProperty : 420+ occurrences
// PhanTypeMismatchProperty : 100+ occurrences
// PhanTypeMismatchArgument : 70+ occurrences
// PhanUndeclaredGlobalVariable : 70+ occurrences
// PhanTypeMismatchArgumentNullable : 40+ occurrences
// PhanTypeInvalidDimOffset : 15+ occurrences
// PhanTypeMismatchDimFetch : 10+ occurrences
// PhanTypeArraySuspiciousNull : 5 occurrences
// PhanTypeMismatchDimFetch : 15+ occurrences
// PhanUndeclaredMethod : 9 occurrences
// PhanPossiblyUndeclaredGlobalVariable : 6 occurrences
// PhanTypeArraySuspiciousNull : 6 occurrences
// PhanTypeComparisonFromArray : 6 occurrences
// PhanTypeExpectedObjectPropAccess : 5 occurrences
// PhanUndeclaredMethod : 5 occurrences
// PhanTypeMismatchArgumentProbablyReal : 5 occurrences
// PhanPluginDuplicateArrayKey : 4 occurrences
// PhanPluginUndeclaredVariableIsset : 2 occurrences
// PhanPossiblyUndeclaredGlobalVariable : 2 occurrences
// PhanTypeMismatchArgumentProbablyReal : 2 occurrences
// PhanParamTooMany : 1 occurrence
// PhanParamTooMany : 3 occurrences
// PhanPluginUndeclaredVariableIsset : 3 occurrences
// PhanPossiblyUndeclaredVariable : 1 occurrence
// PhanTypeExpectedObjectPropAccessButGotNull : 1 occurrence
// PhanTypeMismatchReturn : 1 occurrence
// Currently, file_suppressions and directory_suppressions are the only supported suppressions
'file_suppressions' => [
'htdocs/bookcal/class/availabilities.class.php' => ['PhanUndeclaredMethod', 'PhanUndeclaredProperty'],
'htdocs/bookcal/class/calendar.class.php' => ['PhanUndeclaredMethod', 'PhanUndeclaredProperty'],
'htdocs/categories/viewcat.php' => ['PhanUndeclaredProperty'],
'htdocs/comm/action/index.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchProperty'],
'htdocs/comm/action/pertype.php' => ['PhanTypeExpectedObjectPropAccess'],
'htdocs/comm/action/peruser.php' => ['PhanTypeMismatchArgument'],
'htdocs/comm/action/pertype.php' => ['PhanTypeComparisonFromArray', 'PhanTypeExpectedObjectPropAccess', 'PhanTypeMismatchDimFetch'],
'htdocs/comm/action/peruser.php' => ['PhanTypeComparisonFromArray', 'PhanTypeMismatchArgument'],
'htdocs/comm/card.php' => ['PhanTypeMismatchArgument'],
'htdocs/comm/mailing/index.php' => ['PhanUndeclaredProperty'],
'htdocs/comm/mailing/targetemailing.php' => ['PhanUndeclaredProperty'],
@@ -51,6 +54,7 @@ return [
'htdocs/compta/clients.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/compta/facture/card-rec.php' => ['PhanTypeMismatchArgument'],
'htdocs/compta/facture/card.php' => ['PhanUndeclaredProperty'],
'htdocs/compta/facture/class/api_invoices.class.php' => ['PhanTypeMismatchArgumentProbablyReal'],
'htdocs/compta/facture/class/facture-rec.class.php' => ['PhanUndeclaredProperty'],
'htdocs/compta/facture/class/facture.class.php' => ['PhanUndeclaredProperty'],
'htdocs/compta/localtax/card.php' => ['PhanUndeclaredGlobalVariable'],
@@ -67,18 +71,20 @@ return [
'htdocs/compta/tva/class/paymentvat.class.php' => ['PhanUndeclaredProperty'],
'htdocs/compta/tva/clients.php' => ['PhanTypeArraySuspiciousNull', 'PhanTypeInvalidDimOffset', 'PhanTypeMismatchArgument'],
'htdocs/compta/tva/index.php' => ['PhanTypeMismatchArgument'],
'htdocs/compta/tva/quadri_detail.php' => ['PhanTypeMismatchArgument'],
'htdocs/core/actions_addupdatedelete.inc.php' => ['PhanUndeclaredProperty'],
'htdocs/compta/tva/quadri_detail.php' => ['PhanTypeArraySuspiciousNull', 'PhanTypeInvalidDimOffset', 'PhanTypeMismatchArgument'],
'htdocs/contrat/card.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/core/actions_addupdatedelete.inc.php' => ['PhanTypeMismatchDimFetch', 'PhanUndeclaredProperty'],
'htdocs/core/actions_massactions.inc.php' => ['PhanUndeclaredProperty'],
'htdocs/core/actions_sendmails.inc.php' => ['PhanUndeclaredProperty'],
'htdocs/core/actions_sendmails.inc.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
'htdocs/core/ajax/ajaxdirtree.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchProperty', 'PhanUndeclaredGlobalVariable'],
'htdocs/core/ajax/selectobject.php' => ['PhanTypeMismatchArgumentNullable'],
'htdocs/core/class/CMailFile.class.php' => ['PhanTypeMismatchArgument'],
'htdocs/core/class/canvas.class.php' => ['PhanUndeclaredMethod'],
'htdocs/core/class/canvas.class.php' => ['PhanParamTooMany', 'PhanUndeclaredMethod'],
'htdocs/core/class/ccountry.class.php' => ['PhanUndeclaredProperty'],
'htdocs/core/class/cgenericdic.class.php' => ['PhanUndeclaredProperty'],
'htdocs/core/class/commonobject.class.php' => ['PhanParamTooMany', 'PhanTypeMismatchArgument', 'PhanUndeclaredProperty'],
'htdocs/core/class/commonpeople.class.php' => ['PhanUndeclaredProperty'],
'htdocs/core/class/conf.class.php' => ['PhanTypeMismatchProperty'],
'htdocs/core/class/conf.class.php' => ['PhanTypeMismatchArgumentNullableInternal', 'PhanTypeMismatchProperty'],
'htdocs/core/class/ctyperesource.class.php' => ['PhanUndeclaredProperty'],
'htdocs/core/class/dolgraph.class.php' => ['PhanUndeclaredProperty'],
'htdocs/core/class/emailsenderprofile.class.php' => ['PhanUndeclaredProperty'],
@@ -100,6 +106,7 @@ return [
'htdocs/core/menus/standard/auguria.lib.php' => ['PhanTypeMismatchArgument'],
'htdocs/core/modules/asset/mod_asset_advanced.php' => ['PhanUndeclaredProperty'],
'htdocs/core/modules/bom/mod_bom_advanced.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'],
'htdocs/core/modules/cheque/doc/pdf_blochet.class.php' => ['PhanTypeMismatchArgumentProbablyReal'],
'htdocs/core/modules/cheque/modules_chequereceipts.php' => ['PhanTypeMismatchArgument'],
'htdocs/core/modules/commande/doc/pdf_einstein.modules.php' => ['PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'],
'htdocs/core/modules/commande/doc/pdf_eratosthene.modules.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'],
@@ -115,8 +122,10 @@ return [
'htdocs/core/modules/facture/doc/pdf_octopus.modules.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'],
'htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php' => ['PhanTypeMismatchArgumentNullable'],
'htdocs/core/modules/holiday/mod_holiday_immaculate.php' => ['PhanTypeMismatchArgument'],
'htdocs/core/modules/hrm/doc/pdf_standard_evaluation.modules.php' => ['PhanUndeclaredProperty'],
'htdocs/core/modules/hrm/mod_evaluation_advanced.php' => ['PhanUndeclaredProperty'],
'htdocs/core/modules/import/import_csv.modules.php' => ['PhanPossiblyUndeclaredVariable'],
'htdocs/core/modules/import/import_csv.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchProperty'],
'htdocs/core/modules/import/import_xlsx.modules.php' => ['PhanTypeMismatchProperty'],
'htdocs/core/modules/member/modules_cards.php' => ['PhanTypeMismatchArgument'],
'htdocs/core/modules/mrp/doc/pdf_vinci.modules.php' => ['PhanUndeclaredProperty'],
'htdocs/core/modules/mrp/mod_mo_advanced.php' => ['PhanUndeclaredProperty'],
@@ -134,6 +143,7 @@ return [
'htdocs/core/modules/supplier_proposal/doc/pdf_aurore.modules.php' => ['PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'],
'htdocs/core/modules/supplier_proposal/doc/pdf_zenith.modules.php' => ['PhanTypeMismatchArgumentNullable', 'PhanTypeMismatchDimFetch', 'PhanTypeMismatchProperty', 'PhanUndeclaredProperty'],
'htdocs/core/modules/syslog/mod_syslog_file.php' => ['PhanPluginDuplicateArrayKey'],
'htdocs/core/modules/user/doc/doc_generic_user_odt.modules.php' => ['PhanTypeMismatchArgumentNullable'],
'htdocs/core/modules/workstation/mod_workstation_advanced.php' => ['PhanUndeclaredProperty'],
'htdocs/core/multicompany_page.php' => ['PhanTypeMismatchArgument'],
'htdocs/core/tpl/extrafields_view.tpl.php' => ['PhanUndeclaredProperty'],
@@ -142,16 +152,25 @@ return [
'htdocs/core/tpl/objectline_view.tpl.php' => ['PhanUndeclaredProperty'],
'htdocs/core/tpl/passwordreset.tpl.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/core/tpl/resource_view.tpl.php' => ['PhanUndeclaredProperty'],
'htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php' => ['PhanUndeclaredProperty'],
'htdocs/core/triggers/interface_50_modAgenda_ActionsAuto.class.php' => ['PhanUndeclaredProperty'],
'htdocs/delivery/class/delivery.class.php' => ['PhanUndeclaredProperty'],
'htdocs/don/admin/donation.php' => ['PhanUndeclaredMethod'],
'htdocs/don/class/don.class.php' => ['PhanParamTooMany'],
'htdocs/don/document.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/don/info.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/don/list.php' => ['PhanTypeMismatchProperty'],
'htdocs/don/note.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/emailcollector/class/emailcollector.class.php' => ['PhanUndeclaredProperty'],
'htdocs/eventorganization/class/conferenceorboothattendee.class.php' => ['PhanUndeclaredMethod', 'PhanUndeclaredProperty'],
'htdocs/eventorganization/conferenceorbooth_list.php' => ['PhanTypeMismatchArgument'],
'htdocs/eventorganization/core/actions_massactions_mail.inc.php' => ['PhanUndeclaredProperty'],
'htdocs/expedition/card.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
'htdocs/expedition/class/expedition.class.php' => ['PhanUndeclaredProperty'],
'htdocs/expensereport/card.php' => ['PhanUndeclaredProperty'],
'htdocs/expensereport/class/expensereport.class.php' => ['PhanTypeMismatchArgument'],
'htdocs/expensereport/class/expensereport.class.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchArgumentNullable'],
'htdocs/expensereport/payment/info.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/externalsite/frames.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/fichinter/card-rec.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/fichinter/class/api_interventions.class.php' => ['PhanUndeclaredProperty'],
'htdocs/fichinter/class/fichinterrec.class.php' => ['PhanUndeclaredProperty'],
@@ -159,7 +178,7 @@ return [
'htdocs/fourn/class/fournisseur.commande.class.php' => ['PhanUndeclaredProperty'],
'htdocs/fourn/commande/card.php' => ['PhanUndeclaredProperty'],
'htdocs/fourn/facture/card-rec.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
'htdocs/fourn/facture/card.php' => ['PhanTypeMismatchArgument'],
'htdocs/fourn/facture/card.php' => ['PhanTypeMismatchArgument', 'PhanTypeMismatchProperty'],
'htdocs/fourn/facture/rapport.php' => ['PhanTypeMismatchArgument'],
'htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'],
'htdocs/holiday/card_group.php' => ['PhanTypeMismatchArgument'],
@@ -181,6 +200,7 @@ return [
'htdocs/loan/document.php' => ['PhanUndeclaredProperty'],
'htdocs/loan/note.php' => ['PhanUndeclaredProperty'],
'htdocs/loan/payment/payment.php' => ['PhanUndeclaredProperty'],
'htdocs/mrp/class/mo.class.php' => ['PhanTypeMismatchProperty'],
'htdocs/mrp/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'],
'htdocs/multicurrency/class/api_multicurrencies.class.php' => ['PhanTypeMismatchArgument'],
'htdocs/multicurrency/class/multicurrency.class.php' => ['PhanTypeExpectedObjectPropAccess'],
@@ -197,7 +217,7 @@ return [
'htdocs/product/reassort.php' => ['PhanTypeExpectedObjectPropAccessButGotNull'],
'htdocs/product/stock/info.php' => ['PhanUndeclaredProperty'],
'htdocs/product/stock/list.php' => ['PhanUndeclaredProperty'],
'htdocs/product/stock/movement_list.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanUndeclaredProperty'],
'htdocs/product/stock/movement_list.php' => ['PhanPluginUndeclaredVariableIsset', 'PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
'htdocs/product/stock/productlot_card.php' => ['PhanUndeclaredProperty'],
'htdocs/product/stock/stats/commande_fournisseur.php' => ['PhanUndeclaredProperty'],
'htdocs/product/stock/stats/expedition.php' => ['PhanUndeclaredProperty'],
@@ -210,7 +230,10 @@ return [
'htdocs/projet/tasks.php' => ['PhanTypeMismatchArgument'],
'htdocs/projet/tasks/time.php' => ['PhanTypeInvalidDimOffset', 'PhanUndeclaredProperty'],
'htdocs/projet/tasks/tpl/linkedobjectblock.tpl.php' => ['PhanUndeclaredProperty'],
'htdocs/public/eventorganization/subscriptionok.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/public/members/new.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/public/payment/newpayment.php' => ['PhanUndeclaredProperty'],
'htdocs/public/payment/paymentok.php' => ['PhanTypeMismatchArgumentProbablyReal'],
'htdocs/public/project/suggestbooth.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
'htdocs/public/project/suggestconference.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
'htdocs/public/project/viewandvote.php' => ['PhanUndeclaredGlobalVariable'],
@@ -231,7 +254,7 @@ return [
'htdocs/recruitment/recruitmentjobposition_card.php' => ['PhanUndeclaredProperty'],
'htdocs/recruitment/recruitmentjobposition_document.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
'htdocs/recruitment/recruitmentjobposition_note.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
'htdocs/salaries/payment_salary.php' => ['PhanUndeclaredProperty'],
'htdocs/salaries/paiement_salary.php' => ['PhanUndeclaredProperty'],
'htdocs/salaries/virement_request.php' => ['PhanUndeclaredProperty'],
'htdocs/societe/ajax/company.php' => ['PhanUndeclaredProperty'],
'htdocs/societe/class/societe.class.php' => ['PhanTypeMismatchProperty'],
@@ -239,6 +262,7 @@ return [
'htdocs/supplier_proposal/card.php' => ['PhanUndeclaredGlobalVariable', 'PhanUndeclaredProperty'],
'htdocs/supplier_proposal/class/api_supplier_proposals.class.php' => ['PhanUndeclaredProperty'],
'htdocs/supplier_proposal/class/supplier_proposal.class.php' => ['PhanUndeclaredProperty'],
'htdocs/takepos/index.php' => ['PhanPluginUndeclaredVariableIsset'],
'htdocs/takepos/invoice.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'],
'htdocs/takepos/split.php' => ['PhanPluginUndeclaredVariableIsset'],
'htdocs/ticket/card.php' => ['PhanUndeclaredProperty'],
@@ -249,9 +273,11 @@ return [
'htdocs/user/class/usergroup.class.php' => ['PhanUndeclaredProperty'],
'htdocs/variants/tpl/productattributevalueline_edit.tpl.php' => ['PhanUndeclaredProperty'],
'htdocs/variants/tpl/productattributevalueline_view.tpl.php' => ['PhanUndeclaredProperty'],
'htdocs/viewimage.php' => ['PhanUndeclaredMethod'],
'htdocs/webhook/class/target.class.php' => ['PhanUndeclaredMethod'],
'htdocs/webhook/target_card.php' => ['PhanUndeclaredGlobalVariable'],
'htdocs/webportal/admin/setup.php' => ['PhanTypeMismatchArgument'],
'htdocs/webportal/class/html.formcardwebportal.class.php' => ['PhanTypeMismatchArgument', 'PhanUndeclaredProperty'],
'htdocs/webportal/class/html.formlistwebportal.class.php' => ['PhanUndeclaredProperty'],
'htdocs/webportal/class/webportalpropal.class.php' => ['PhanUndeclaredProperty'],
'htdocs/webservices/server_project.php' => ['PhanUndeclaredProperty'],

View File

@@ -1,22 +1,20 @@
<?php
/* Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
*/
/* PHP 7.0 */
$finder = (new PhpCsFixer\Finder())
->in(__DIR__)
->exclude([
'core/includes',
'custom',
'documents',
'doctemplates',
'vendor',
'install/doctemplates',
'htdocs/custom',
'htdocs/includes',
'htdocs/install/doctemplates',
])
->notPath('vendor');
->in(__DIR__)
->exclude([
'core/includes',
'custom',
'documents',
'doctemplates',
'vendor',
'install/doctemplates',
'htdocs/custom',
'htdocs/includes',
'htdocs/install/doctemplates',
])
->notPath('vendor');
/* PHP 7.4+ */
@@ -45,11 +43,8 @@ return (new PhpCsFixer\Config())
// So we use target PHP70 for the moment.
'@PHP70Migration' => true,
//'@PHP71Migration' => true,
// Avoid adding public to const (incompatible with PHP 7.0):
'visibility_required' => ['elements' => ['property', 'method']],
// Replace deprecated 'visibility_required'
'modifier_keywords' => ['elements' => ['property', 'method']],
// Avoid adding public to const (incompatible with PHP 7.0):
'visibility_required' => ['elements'=>['property', 'method']],
//'strict_param' => true,
//'array_syntax' => ['syntax' => 'short'],
@@ -64,4 +59,5 @@ return (new PhpCsFixer\Config())
->setIndent("\t")
// All files MUST use the Unix LF line ending only
// https://www.php-fig.org/psr/psr-12/#22-files
->setLineEnding("\n");
->setLineEnding("\n")
;

View File

@@ -1,5 +1,4 @@
parameters:
phpVersion: 80200 # PHP 8.2
tmpDir: ./.github/tmp
parallel:
# Commented some of the settings, reminding the defaults:
@@ -47,15 +46,12 @@ parameters:
- htdocs/includes/tecnickcom/*
- htdocs/includes/webklex/*
- htdocs/core/class/lessc.class.php
# checkAlwaysTrueCheckTypeFunctionCall: false
# checkAlwaysTrueInstanceof: false
# checkAlwaysTrueStrictComparison: false
polluteScopeWithLoopInitialAssignments: false
polluteScopeWithAlwaysIterableForeach: false
checkAlwaysTrueCheckTypeFunctionCall: false
checkAlwaysTrueInstanceof: false
checkAlwaysTrueStrictComparison: false
checkClassCaseSensitivity: true
checkFunctionArgumentTypes: true
checkFunctionNameCase: true
checkInternalClassCaseSensitivity: true
checkArgumentsPassedByReference: true
checkMaybeUndefinedVariables: true
checkNullables: false
@@ -65,6 +61,8 @@ parameters:
reportMaybes: false
reportMaybesInMethodSignatures: false
reportStaticMethodSignatures: false
polluteScopeWithLoopInitialAssignments: true
polluteScopeWithAlwaysIterableForeach: true
reportMagicMethods: false
reportMagicProperties: false
treatPhpDocTypesAsCertain: false

View File

@@ -1,2 +1,2 @@
/test.php
/vendor
/vendor

View File

@@ -36,3 +36,4 @@ then
wmctrl -i -r $1 -e 0,0,0,$width,$height
echo Size of windows $1 modified to $width x $height
fi

View File

@@ -93,3 +93,5 @@ if __name__ == '__main__':
options, arguments = parser.parse_args()
sys.argv[:] = arguments
main(options, arguments)

View File

@@ -1,4 +1,4 @@
Test to migrate Dolibarr to namespace "Dolibarr".
Script bbb.php is a script of an external module with current code writing.
It must works after migration.
It must works after migration.

View File

@@ -14,7 +14,7 @@ https://www.transifex.com/dolibarr-association/dolibarr/dashboard/
Installation of Transifex Client:
---------------------------------
for Linux OS
to install or to update transifex client:
to install or to update transifex client:
sudo pip install --upgrade transifex-client

View File

@@ -108,16 +108,6 @@ ACCOUNTING_VAT_BUY_REVERSE_CHARGES_DEBIT
ACCOUNTING_VAT_PAY_ACCOUNT
ACCOUNTING_VAT_SOLD_ACCOUNT
ADHERENT_SUBSCRIPTION_ACCOUNTINGACCOUNT
ACCOUNTING_LT1_BUY_ACCOUNT
ACCOUNTING_LT2_BUY_ACCOUNT
ACCOUNTING_LT1_BUY_REVERSE_CHARGES_CREDIT
ACCOUNTING_LT2_BUY_REVERSE_CHARGES_CREDIT
ACCOUNTING_LT1_PAY_ACCOUNT
ACCOUNTING_LT2_PAY_ACCOUNT
ACCOUNTING_LT1_PAY_REVERSE_CHARGES_CREDIT
ACCOUNTING_LT2_PAY_REVERSE_CHARGES_CREDIT
ACCOUNTING_LT1_SOLD_ACCOUNT
ACCOUNTING_LT2_SOLD_ACCOUNT
AI_API_MODEL_AUDIO
AI_API_MODEL_IMAGE

View File

@@ -130,6 +130,7 @@ AvailabilityType
BAN
BI
BOMs
Back
Bad value for email, email was not verified by Google
Bad value for returned userinfo[aud]
Bad value for returned userinfo[exp]. Token expired.
@@ -145,6 +146,8 @@ Barcode
BarcodeDesc
BarcodeStickersMask
BillOfMaterialsLine
BlockLogNeedAmountsValue
BlockLogNeedElement
BlockedLogAuthorityNeededToStoreYouFingerprintsInNonAlterableRemote
BlockedLogAuthorityUrl
BlockedLogSetup
@@ -172,6 +175,7 @@ Child of
ClassNotFound
Clear
ClickToDial
Clients
Clone
CloneAffectation
CloneChanges
@@ -257,6 +261,7 @@ Dictionaries
DictionaryEmpty
DictionaryNameUpdated
Directory
DisabledByOptionADD_UNSPLASH_LOGIN_BACKGROUND
Document
Documentation
Dolibarr
@@ -321,6 +326,7 @@ ErrorFailedToGetListOfNotificationsToSend
ErrorFailedToLoadBankAccount
ErrorFailedToLoadDiscount
ErrorFailedToSetNewPassword
ErrorFaviconMustBeASquaredImage
ErrorFileNameInvalid
ErrorImportOfChartLimitedToCurrentChart
ErrorMAIN_ROUNDING_RULE_TOTCanMAIN_MAX_DECIMALS_TOT
@@ -397,6 +403,7 @@ Filename
FilteredFrom
Flashy
ForcedByGlobalSetup
Form for public lead registration has not been enabled
Free
FreeLegalTextOnReceptions
FrequencyPer_
@@ -619,6 +626,7 @@ Poll
Posts
PredefinedInterventional
PrevRangeToThisRange
PreviousFingerprint
Print
PrintDriver
PrintModule
@@ -798,6 +806,7 @@ TicketTypeShort
TimeOnly
Timezone
ToGetBack
ToPay
Token
Tooltip
TooltipEditAndRevertStockMovement

View File

@@ -65,3 +65,4 @@ fi
echo Think to launch also:
echo "> dev/tools/fixaltlanguages.sh fix all"
#echo "For v11: Replace also regex \(.*(sponge|cornas|eratosthene|cyan).*\) with '' on *.lang files"

View File

@@ -19,4 +19,4 @@ But if you are looking for other resources (downloads, documentation, addons, ..
* <a href="https://www.dolistore.com">DoliStore (official addons/plugins market place)</a><br>
</body>
</html>
</html>

View File

@@ -8,14 +8,14 @@ Download / Herunterladen
* Dolibarr ERP/CRM kann man über die offizielle Dolibarr Website
https://www.dolibarr.org/downloads
https://www.dolibarr.org/downloads
oder direkt bei Sourceforge
https://sourceforge.net/projects/dolibarr/files/
herunterladen.
@@ -26,10 +26,10 @@ Installation / Hilfe
* Für eine kurze Einleitung schau in die README.md Datei im Hauptverzeichnis.
* Umfangreiche Dokumentationen sind im Dolibarr Wiki zu finden:
https://wiki.dolibarr.org/index.php/Hauptseite
* eine Deutsche Community bietet der Dolibarr e.V. unter
https://www.dolibarr.de/
https://wiki.dolibarr.org/index.php/Hauptseite
* eine Deutsche Community bietet der Dolibarr e.V. unter
https://www.dolibarr.de/
@@ -38,6 +38,8 @@ Installation / Hilfe
Zusatzmodule
------------------------------------
* Die meisten externen Module/Themen sind über den offiziellen DoliStore verfügbar:
* Die meisten externen Module/Themen sind über den offiziellen DoliStore verfügbar:
https://www.dolistore.com/de/

1
htdocs/.gitignore vendored
View File

@@ -21,6 +21,7 @@
/cabinetmed*
/webmail*
/conf/conf.php
/subtotal*
/abricot*
/nomenclature*
/of/

View File

@@ -3,7 +3,7 @@
* Copyright (C) 2013-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2016-2018 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -431,7 +431,7 @@ if ($resql) {
$newcardbutton = dolGetButtonTitle($langs->trans('Addanaccount'), '', 'fa fa-plus-circle', DOL_URL_ROOT.'/accountancy/admin/card.php?action=create', '', $permissiontoadd);
print '<form method="POST" id="searchFormList" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
}
@@ -788,11 +788,11 @@ if ($resql) {
if (!empty($arrayfields['aa.reconcilable']['checked'])) {
print '<td class="center">';
if (empty($obj->reconcilable)) {
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=enable&page='.$page.'&mode=1&token='.newToken().'">';
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=enable&mode=1&token='.newToken().'">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '</a>';
} else {
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=disable&page='.$page.'&mode=1&token='.newToken().'">';
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=disable&mode=1&token='.newToken().'">';
print img_picto($langs->trans("Activated"), 'switch_on');
print '</a>';
}
@@ -806,11 +806,11 @@ if ($resql) {
if (!empty($arrayfields['aa.centralized']['checked'])) {
print '<td class="center">';
if (empty($obj->centralized)) {
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=enable&page='.$page.'&mode=2&token='.newToken().'">';
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=enable&mode=2&token='.newToken().'">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '</a>';
} else {
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=disable&page='.$page.'&mode=2&token='.newToken().'">';
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=disable&mode=2&token='.newToken().'">';
print img_picto($langs->trans("Activated"), 'switch_on');
print '</a>';
}
@@ -824,11 +824,11 @@ if ($resql) {
if (!empty($arrayfields['aa.active']['checked'])) {
print '<td class="center">';
if (empty($obj->active)) {
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=enable&page='.$page.'&mode=0&token='.newToken().'">';
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=enable&mode=0&token='.newToken().'">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '</a>';
} else {
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=disable&page='.$page.'&mode=0&token='.newToken().'">';
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$obj->rowid.'&action=disable&mode=0&token='.newToken().'">';
print img_picto($langs->trans("Activated"), 'switch_on');
print '</a>';
}

View File

@@ -329,7 +329,7 @@ print load_fiche_titre($titre, $linkback, 'title_accountancy');
// Confirmation de la suppression de la ligne
if ($action == 'delete') {
print $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['page'=> $page, 'sortfield' => $sortfield, 'sortorder' => $sortorder, 'rowid' => $rowid, 'code' => $code, 'id' => $id]), $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1);
print $form->formconfirm($_SERVER["PHP_SELF"].'?'.($page ? 'page='.urlencode((string) ($page)).'&' : '').'sortfield='.urlencode((string) ($sortfield)).'&sortorder='.urlencode((string) ($sortorder)).'&rowid='.urlencode((string) ($rowid)).'&code='.urlencode((string) ($code)).'&id='.urlencode((string) ($id)), $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_delete', '', 0, 1);
}
@@ -577,34 +577,19 @@ if ($resql) {
}
}
// $url = $_SERVER["PHP_SELF"].'?token='.newToken().($page ? '&page='.$page : '').'&sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')).'&code='.(!empty($obj->code) ? urlencode($obj->code) : '');
// $url .= '&'.$param.'&';
$query = [];
// decode and add param to query
parse_str($param, $query);
$query = array_merge($query, [
'action' => '',
'page' => $page,
'sortfield' => $sortfield,
'sortorder' => $sortorder,
'rowid' => (!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')),
'code' => $obj->code,
]);
$url = $_SERVER["PHP_SELF"].'?token='.newToken().($page ? '&page='.$page : '').'&sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')).'&code='.(!empty($obj->code) ? urlencode($obj->code) : '');
$url .= '&'.$param.'&';
// Active
print '<td class="center nowrap">';
$query['action'] = $acts[$obj->active];
print '<a href="'.dolBuildUrl($_SERVER["PHP_SELF"], $query, true).'">'.$actl[$obj->active].'</a>';
print '<a href="'.$url.'action='.$acts[$obj->active].'">'.$actl[$obj->active].'</a>';
print "</td>";
// Modify link
$query['action'] = 'edit';
print '<td class="center"><a class="reposition editfielda" href="'.dolBuildUrl($_SERVER["PHP_SELF"], $query, true).'">'.img_edit().'</a></td>';
print '<td class="center"><a class="reposition editfielda" href="'.$url.'action=edit&token='.newToken().'">'.img_edit().'</a></td>';
// Delete link
$query['action'] = 'delete';
print '<td class="center"><a href="'.dolBuildUrl($_SERVER["PHP_SELF"], $query, true).'">'.img_delete().'</a></td>';
print '<td class="center"><a href="'.$url.'action=delete&token='.newToken().'">'.img_delete().'</a></td>';
print "</tr>\n";
}

View File

@@ -1,7 +1,7 @@
<?php
/* Copyright (C) 2004-2023 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2011-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
/* Copyright (C) 2004-2023 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2011-2024 Alexandre Spangaro <aspangaro@easya.solutions>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -465,7 +465,9 @@ $paramwithsearch = $param;
if ($sortorder) {
$paramwithsearch .= '&sortorder='.urlencode($sortorder);
}
$paramwithsearch .= '&sortfield='.urlencode($sortfield);
if ($sortfield) {
$paramwithsearch .= '&sortfield='.urlencode($sortfield);
}
if (GETPOST('from', 'alpha')) {
$paramwithsearch .= '&from='.urlencode(GETPOST('from', 'alpha'));
}
@@ -823,7 +825,9 @@ if ($resql) {
}
}
$url = $_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')).'&code='.(!empty($obj->code) ? urlencode($obj->code) : '');
$url .= '&'.$param;
if ($param) {
$url .= '&'.$param;
}
$url .= '&';
$canbemodified = $iserasable;
@@ -905,6 +909,7 @@ if ($resql) {
print '<td class="center" class="nowrap">';
if ($canbedisabled) {
print '<a class="reposition" href="'.$url.'action='.urlencode($acts[$obj->active]).'&token='.newToken().'">'.$actl[$obj->active].'</a>';
print '<a class="reposition" href="'.$url.'action='.$acts[$obj->active].'&token='.newToken().'">'.$actl[$obj->active].'</a>';
} else {
print $langs->trans("AlwaysActive");
}

View File

@@ -7,7 +7,6 @@
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2025 Vincent de Grandporé <vincent@de-grandpre.quebec>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -103,20 +102,9 @@ $list_account[] = 'ACCOUNTING_VAT_BUY_ACCOUNT';
$list_account[] = 'ACCOUNTING_VAT_PAY_ACCOUNT';
$list_account[] = 'ACCOUNTING_LT1_SOLD_ACCOUNT';
$list_account[] = 'ACCOUNTING_LT1_BUY_ACCOUNT';
$list_account[] = 'ACCOUNTING_LT1_PAY_ACCOUNT';
$list_account[] = 'ACCOUNTING_LT2_SOLD_ACCOUNT';
$list_account[] = 'ACCOUNTING_LT2_BUY_ACCOUNT';
$list_account[] = 'ACCOUNTING_LT2_PAY_ACCOUNT';
if (getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
$list_account[] = 'ACCOUNTING_VAT_BUY_REVERSE_CHARGES_CREDIT';
$list_account[] = 'ACCOUNTING_VAT_BUY_REVERSE_CHARGES_DEBIT';
$list_account[] = 'ACCOUNTING_LT1_BUY_REVERSE_CHARGES_CREDIT';
$list_account[] = 'ACCOUNTING_LT1_BUY_REVERSE_CHARGES_DEBIT';
$list_account[] = 'ACCOUNTING_LT2_BUY_REVERSE_CHARGES_CREDIT';
$list_account[] = 'ACCOUNTING_LT2_BUY_REVERSE_CHARGES_DEBIT';
}
if (isModEnabled('bank')) {
$list_account[] = 'ACCOUNTING_ACCOUNT_TRANSFER_CASH';
@@ -136,11 +124,6 @@ if (isModEnabled('loan')) {
$list_account[] = 'LOAN_ACCOUNTING_ACCOUNT_INSURANCE';
}
$list_account[] = 'ACCOUNTING_ACCOUNT_SUSPENSE';
if (isModEnabled('invoice') || isModEnabled('supplier_invoice')) {
$list_account[] = '---Discounts---';
$list_account[] = 'ACCOUNTING_ACCOUNT_DISCOUNT_GRANTED';
$list_account[] = 'ACCOUNTING_ACCOUNT_DISCOUNT_RECEIVED';
}
if (isModEnabled('societe')) {
$list_account[] = '---Deposits---';
}
@@ -297,14 +280,8 @@ foreach ($list_account as $key) {
print img_picto('', 'service', 'class="pictofixedwidth"');
} elseif (preg_match('/^ACCOUNTING_VAT_PAY_ACCOUNT/', $key)) {
print img_picto('', 'payment_vat', 'class="pictofixedwidth"');
} elseif (preg_match('/^ACCOUNTING_LT1_PAY_ACCOUNT/', $key)) {
print img_picto('', 'payment_vat', 'class="pictofixedwidth"');
} elseif (preg_match('/^ACCOUNTING_LT2_PAY_ACCOUNT/', $key)) {
print img_picto('', 'payment_vat', 'class="pictofixedwidth"');
} elseif (preg_match('/^ACCOUNTING_VAT/', $key)) {
print img_picto('', 'vat', 'class="pictofixedwidth"');
} elseif (preg_match('/^ACCOUNTING_LT/', $key)) {
print img_picto('', 'vat', 'class="pictofixedwidth"');
} elseif (preg_match('/^ACCOUNTING_ACCOUNT_CUSTOMER/', $key)) {
print img_picto('', 'bill', 'class="pictofixedwidth"');
} elseif (preg_match('/^LOAN_ACCOUNTING_ACCOUNT/', $key)) {

View File

@@ -202,7 +202,7 @@ if ($result) {
if (getDolGlobalString('ACCOUNTANCY_FISCALYEAR_DEFAULT') == (int) $fiscalyearstatic->ref) {
print img_picto($langs->trans("Default"), 'on');
} else {
print '<a class="reposition" href="'.dolBuildUrl($_SERVER["PHP_SELF"], ['action' => 'setdefault', 'value' => $fiscalyearstatic->ref, 'label'=>$fiscalyearstatic->label], true).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("SetAsDefault"), 'off').'</a>';
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?action=setdefault&token='.newToken().'&value='.urlencode($fiscalyearstatic->ref).'&label='.urlencode($fiscalyearstatic->label).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("SetAsDefault"), 'off').'</a>';
}
print '</td>';

View File

@@ -1,5 +1,5 @@
<?php
/* Copyright (C) 2014-2026 Alexandre Spangaro <alexandre@inovea-conseil.com>
/* Copyright (C) 2014-2024 Alexandre Spangaro <aspangaro@easya.solutions>
* Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
*
@@ -46,7 +46,7 @@ $ref = GETPOST('ref', 'alpha');
$action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
$cancel = GETPOST('cancel', 'alpha');
$cancel = GETPOST('cancel', 'aZ09');
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : str_replace('_', '', basename(dirname(__FILE__)).basename(__FILE__, '.php')); // To manage different context of search
$backtopage = GETPOST('backtopage', 'alpha'); // if not set, a default page will be used
$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha'); // if not set, $backtopage will be used
@@ -202,7 +202,7 @@ llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-accountancy page-fis
if ($action == 'create') {
print load_fiche_titre($title, '', 'object_'.$object->picto);
print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="add">';
@@ -211,9 +211,7 @@ if ($action == 'create') {
print '<table class="border centpercent tableforfieldcreate">'."\n";
// Label
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Label").'</td><td>';
print '<input name="label" size="32" value="'.GETPOST('label', 'alpha').'">';
print '</td></tr>';
print '<tr><td class="titlefieldcreate fieldrequired">'.$langs->trans("Label").'</td><td><input name="label" size="32" value="'.GETPOST('label', 'alpha').'"></td></tr>';
// Date start
print '<tr><td class="fieldrequired">'.$langs->trans("DateStart").'</td><td>';
@@ -259,7 +257,6 @@ if (($id || $ref) && $action == 'edit') {
print '<form method="POST" name="update" action="'.$_SERVER["PHP_SELF"].'">'."\n";
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="update">';
print '<input type="hidden" name="status" value="' . $object->status . '">';
print '<input type="hidden" name="id" value="'.$object->id.'">';
if ($backtopage) {
print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
@@ -337,7 +334,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
// ------------------------------------------------------------
$linkback = '<a href="'.DOL_URL_ROOT.'/accountancy/admin/fiscalyear.php?restore_lastsearch_values=1">'.$langs->trans("BackToList").'</a>';
dol_banner_tab($object, 'label', $linkback, 1, 'label', 'label', $morehtmlref);
dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
print '<div class="fichecenter">';
@@ -345,12 +342,6 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
print '<div class="underbanner clearboth"></div>';
print '<table class="border centpercent tableforfield">'."\n";
// Id
print "<tr>";
print '<td class="titlefield">'.$langs->trans("Id").'</td><td>';
print $object->id;
print '</td></tr>';
// Label
print '<tr><td class="tdtop">';
print $form->editfieldkey("Label", 'label', $object->label, $object, 0, 'alpha:32');

View File

@@ -8,7 +8,7 @@
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2017 Laurent Destailleur <eldy@destailleur.fr>
* Copyright (C) 2021 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -69,6 +69,7 @@ $formSetup = new FormSetup($db);
// Main options
$formSetup->newItem('BANK_DISABLE_DIRECT_INPUT')->setAsYesNo();
$formSetup->newItem('ACCOUNTANCY_COMBO_FOR_AUX')->setAsYesNo();
$item = $formSetup->newItem('ACCOUNTING_MANAGE_ZERO')->setAsYesNo();
@@ -176,27 +177,20 @@ if ($action == 'updatemode') {
}
}
if ($action == 'update') {
if ($action == 'update2') {
$error = 0;
foreach ($list as $constname) {
$constvalue = GETPOST($constname, 'alpha');
if (!dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) {
$error++;
}
}
if (!$error) {
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
} else {
if ($error) {
setEventMessages($langs->trans("Error"), null, 'errors');
}
}
if ($action == 'update_binding') {
$error = 0;
// option in section binding
foreach ($list_binding as $constname) {
$constvalue = GETPOST($constname, 'alpha');
@@ -209,39 +203,16 @@ if ($action == 'update_binding') {
}
}
if (!$error) {
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
} else {
setEventMessages($langs->trans("Error"), null, 'errors');
}
}
if ($action == 'update_advanced') {
$error = 0;
// options in section other
if (GETPOSTISSET('ACCOUNTING_LETTERING_NBLETTERS')) {
if (!dolibarr_set_const($db, 'ACCOUNTING_LETTERING_NBLETTERS', GETPOST('ACCOUNTING_LETTERING_NBLETTERS'), 'chaine', 0, '', $conf->entity)) {
$error++;
}
}
if (!$error) {
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
} else {
setEventMessages($langs->trans("Error"), null, 'errors');
}
}
if ($action == 'update_export') {
$error = 0;
// Export options
$modelcsv = GETPOSTINT('ACCOUNTING_EXPORT_MODELCSV');
// reload
$configuration = $accountancyexport->getTypeConfig();
$listparam = $configuration['param'];
if (!empty($modelcsv)) {
if (!dolibarr_set_const($db, 'ACCOUNTING_EXPORT_MODELCSV', $modelcsv, 'chaine', 0, '', $conf->entity)) {
$error++;
@@ -272,6 +243,12 @@ if ($action == 'update_export') {
}
}
if (!$error) {
// reload
$configuration = $accountancyexport->getTypeConfig();
$listparam = $configuration['param'];
}
if (!$error) {
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
} else {
@@ -335,34 +312,6 @@ if ($action == 'setdisablebindingonexpensereports') {
}
}
if ($action == 'setdisabletransferonassets') {
$setdisabletransferonassets = GETPOSTINT('value');
$res = dolibarr_set_const($db, "ACCOUNTING_DISABLE_TRANSFER_ON_ASSETS", $setdisabletransferonassets, 'yesno', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;
}
if (!$error) {
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
} else {
setEventMessages($langs->trans("Error"), null, 'mesgs');
}
}
if ($action == 'setdisabletransferondiscounts') {
$setdisabletransferondiscounts = GETPOSTINT('value');
$res = dolibarr_set_const($db, "ACCOUNTING_DISABLE_TRANSFER_ON_DISCOUNTS", $setdisabletransferondiscounts, 'yesno', 0, '', $conf->entity);
if (!($res > 0)) {
$error++;
}
if (!$error) {
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
} else {
setEventMessages($langs->trans("Error"), null, 'mesgs');
}
}
if ($action == 'setenablelettering') {
$setenablelettering = GETPOSTINT('value');
$res = dolibarr_set_const($db, "ACCOUNTING_ENABLE_LETTERING", $setenablelettering, 'yesno', 0, '', $conf->entity);
@@ -506,19 +455,20 @@ if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 1) {
print '</form>';
print '<br><br>';
print '<br><br><br>';
}
// Show form main options
// Show form for main parameters
print $formSetup->generateOutput(true);
print '<br><br>';
print '<br><br><br>';
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="update_binding">';
print '<input type="hidden" name="action" value="update2">';
print '<input type="hidden" name="page_y" value="">';
// Binding params
@@ -596,32 +546,6 @@ if (getDolGlobalString('ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS')) {
}
print '</tr>';
print '<tr class="oddeven">';
print '<td>'.$langs->trans("ACCOUNTING_DISABLE_TRANSFER_ON_ASSETS").'</td>';
if (getDolGlobalString('ACCOUNTING_DISABLE_TRANSFER_ON_ASSETS')) {
print '<td class="right"><a class="reposition" href="'.$_SERVER['PHP_SELF'].'?token='.newToken().'&action=setdisabletransferonassets&value=0">';
print img_picto($langs->trans("Activated"), 'switch_on', '', 0, 0, 0, '', 'warning');
print '</a></td>';
} else {
print '<td class="right"><a class="reposition" href="'.$_SERVER['PHP_SELF'].'?token='.newToken().'&action=setdisabletransferonassets&value=1">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '</a></td>';
}
print '</tr>';
print '<tr class="oddeven">';
print '<td>'.$langs->trans("ACCOUNTING_DISABLE_TRANSFER_ON_DISCOUNTS").'</td>';
if (getDolGlobalString('ACCOUNTING_DISABLE_TRANSFER_ON_DISCOUNTS')) {
print '<td class="right"><a class="reposition" href="'.$_SERVER['PHP_SELF'].'?token='.newToken().'&action=setdisabletransferondiscounts&value=0">';
print img_picto($langs->trans("Activated"), 'switch_on', '', 0, 0, 0, '', 'warning');
print '</a></td>';
} else {
print '<td class="right"><a class="reposition" href="'.$_SERVER['PHP_SELF'].'?token='.newToken().'&action=setdisabletransferondiscounts&value=1">';
print img_picto($langs->trans("Disabled"), 'switch_off');
print '</a></td>';
}
print '</tr>';
if (!getDolGlobalString('ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS')) {
print '<tr class="oddeven">';
print '<td>'.$langs->trans("ACCOUNTANCY_ER_DATE_RECORD").'</td>';
@@ -653,11 +577,12 @@ print '</tr>';
print '</table>';
print '</div>';
print '<div class="center"><input type="submit" class="button button-edit reposition" name="button" value="'.dol_escape_htmltag($langs->trans('Save')).'"></div>';
print '</form>';
print '<div class="center"><input type="submit" class="button reposition" value="'.dol_escape_htmltag($langs->trans('Save')).'" name="button"></div>';
// Show numbering options
print '<br><br>';
print '<br><br><br>';
// Accountancy Numbering model
$dirmodels = array_merge(array('/'), $conf->modules_parts['models']);
@@ -769,17 +694,13 @@ foreach ($arrayofmodules as $module) {
}
print '</table>';
print '</div>';
print '</form>';
// Show advanced options
print '<br><br>';
print '<br><br><br>';
// Advanced params
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="update_advanced">';
print '<input type="hidden" name="page_y" value="">';
print '<div class="div-table-responsive-no-min">';
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
@@ -818,7 +739,7 @@ if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING')) {
print '<input class="flat right" name="ACCOUNTING_LETTERING_NBLETTERS" id="ACCOUNTING_LETTERING_NBLETTERS" value="' . $nbletter . '" type="number" step="1" min="2" max="3" >' . "\n";
print '</tr>';
// Auto matching when transfer in accountancy is realized
// Auto Lettering when transfer in accountancy is realized
print '<tr class="oddeven">';
print '<td>';
print $form->textwithpicto($langs->trans("ACCOUNTING_ENABLE_AUTOLETTERING"), $langs->trans("ACCOUNTING_ENABLE_AUTOLETTERING_DESC")) . '</td>';
@@ -867,17 +788,12 @@ print '</div>';
print '<div class="center"><input type="submit" class="button button-edit reposition" name="button" value="'.$langs->trans('Save').'"></div>';
print '</form>';
print '<br><br>';
print '<br><br><br>';
// Export options
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="update_export">';
print '<input type="hidden" name="page_y" value="">';
print "\n".'<script type="text/javascript">'."\n";
print 'jQuery(document).ready(function () {'."\n";
@@ -923,6 +839,8 @@ print ' });'."\n";
print '})'."\n";
print '</script>'."\n";
// Main Options
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td colspan="2">'.$langs->trans('ExportOptions').'</td>';
@@ -984,6 +902,7 @@ if ($num2) {
print '<div class="center"><input type="submit" class="button reposition" value="'.dol_escape_htmltag($langs->trans('Save')).'" name="button"></div>';
print '</form>';
// End of page

View File

@@ -6,7 +6,7 @@
* Copyright (C) 2015 Ari Elbaz (elarifr) <github@accedinfo.com>
* Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -28,14 +28,6 @@
* \brief To define accounting account on product / service
*/
require '../../main.inc.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Societe $mysoc
* @var Translate $langs
* @var User $user
*/
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formaccounting.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcategory.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
@@ -47,6 +39,15 @@ require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
/**
* @var Conf $conf
* @var DoliDB $db
* @var HookManager $hookmanager
* @var Societe $mysoc
* @var Translate $langs
* @var User $user
*/
// Load translation files required by the page
$langs->loadLangs(array("companies", "compta", "accountancy", "products"));
@@ -202,7 +203,7 @@ if ($action == 'update' && $permissiontobind) {
$ko = 0;
$msg = '';
$sql = '';
if (in_array($accounting_product_mode, $accounting_product_modes)) {
if (!empty($toselect) && in_array($accounting_product_mode, $accounting_product_modes)) { // @phpstan-ignore-line Bug phpstan thinking that empty(array()) is always true
$accounting = new AccountingAccount($db);
$arrayofdifferentselectedvalues = array();
@@ -466,9 +467,9 @@ if ($resql) {
if ($search_current_account_valid && $search_current_account_valid != '-1') {
$param .= "&search_current_account_valid=".urlencode($search_current_account_valid);
}
// if ($accounting_product_mode) { // can't be empty see line 91-93
$param .= '&accounting_product_mode='.urlencode($accounting_product_mode);
// }
if ($accounting_product_mode) {
$param .= '&accounting_product_mode='.urlencode($accounting_product_mode);
}
print '<form action="'.$_SERVER["PHP_SELF"].'" method="post">';
if ($optioncss != '') {

View File

@@ -1,6 +1,6 @@
<?php
/* Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -680,7 +680,9 @@ if ($resql) {
}
}
$url = $_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')).'&code='.(!empty($obj->code) ? urlencode($obj->code) : '');
$url .= '&'.$param;
if ($param) {
$url .= '&'.$param;
}
$url .= '&';
$canbemodified = $iserasable;

View File

@@ -2,7 +2,7 @@
/* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
* Copyright (C) 2013-2024 Alexandre Spangaro <aspangaro@easya.solutions>
* Copyright (C) 2016-2018 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
*
* This program is free software; you can redistribute it and/or modify
@@ -336,7 +336,7 @@ if ($resql) {
// List of mass actions available
$arrayofmassactions = array();
print '<form method="POST" id="searchFormList" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
print '<form method="POST" id="searchFormList" action="'.$_SERVER["PHP_SELF"].'">';
if ($optioncss != '') {
print '<input type="hidden" name="optioncss" value="'.$optioncss.'">';
}

Some files were not shown because too many files have changed in this diff Show More