Compare commits

..

33 Commits

Author SHA1 Message Date
Laurent Destailleur
c0911e55c8 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2026-02-12 18:57:51 +01:00
Laurent Destailleur
2f584530ce Doc 2026-02-12 18:04:16 +01:00
Eric - CAP-REL
7f38769d62 NEW Can request and force user to change its password (#37196)
* force user to change password : redirect to user card on login

* force user to change password : redirect to user card on login

* redirect to a dedicated page

* bad old idea : self change passwd on user card + edit mode and rights: it makes a hole on security check

* only apply on dolibarr auth mode context

* only on dolibarr auth mode context

* Fix force_pass_change SQL assignment logic

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-02-12 17:35:03 +01:00
hansemschnokeloch
6a9d4c5ca9 Error handling methods for commonobject (#37201) 2026-02-12 16:42:55 +01:00
MDW
f8e609b3b3 Qual: Update spelling (#37199)
* Qual: Update spelling for pre-select variants

# Qual: Update spelling for pre-select variants

In English, preselect is without the hyphen.  Update text and made some translations
related to preselect.

* Qual: Update composant to component and/or adequate translation.

# Qual: Update composant to component and/or adequate translation.

"Composant(s)" was mostly referenced in french file/class comments.
Updated

* Qual: Fix misspellings related to "criteria"

# Qual: Fix misspellings related to "criteria"

* Qual: Fix produt misspellings

# Qual: Fix produt misspellings

Change 'produt' to 'product'.

* Qual: Update French comments with "composants"

#Qual: Update French comments with "composants"

- Translating French comments to English (avoid codespell notice)

* Qual: Fixed typo 'bad practive' to 'bad practice'

# Qual: Fixed typo 'bad practive' to 'bad practice'

* Qual: Update phan.yml to exclude specific files from analysis

- Added file exclusion pattern to match phan configuration
- Added check for empty file list to avoid unnecessary phan execution

* Qual: Update file filtering in phan.yml workflow

The change updates the file filtering process in the phan.yml workflow to correctly redirect the output of the grep command to a temporary file.

* Qual: Ignore $systemfunction always exists

---------

Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-02-12 16:29:11 +01:00
intelliking
d5cc1d7754 fix: Remove HTML from accounting menu tooltips in eldy theme (#37203)
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-02-12 16:28:05 +01:00
Joris Le Blansch
b1d60ec82b CLOSE #37190 ODT Templates for thirdparties - Birthday is returned in epoch format (#37198)
Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
2026-02-12 16:27:30 +01:00
Laurent Destailleur
bada2c29df Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2026-02-12 15:19:27 +01:00
Laurent Destailleur
7b453994d8 Fix CI 2026-02-12 15:18:31 +01:00
MDW
8436004ce6 qual: Update PHPStan workflow to run on all files in integration (#37207)
The PHPStan workflow has been updated to run on all files in integration branches.
2026-02-12 15:14:03 +01:00
Laurent Destailleur
ed0b3a6f4d css 2026-02-12 01:40:00 +01:00
Laurent Destailleur
d092852768 Merge branch '23.0' of git@github.com:Dolibarr/dolibarr.git into develop 2026-02-12 00:39:28 +01:00
Laurent Destailleur
f23e6b541a Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into 23.0 2026-02-12 00:38:48 +01:00
Laurent Destailleur
1a83124ca6 FIX closing an deposit invoice when payment was too high. 2026-02-12 00:38:04 +01:00
Laurent Destailleur
718f318089 Fix error when setup not complete. 2026-02-11 22:53:55 +01:00
Laurent Destailleur
de948fad37 Merge branch 'develop' of git@github.com:Dolibarr/dolibarr.git into develop 2026-02-11 21:17:35 +01:00
Laurent Destailleur
b6f9a62a65 Merge branch '23.0' of git@github.com:Dolibarr/dolibarr.git into develop 2026-02-11 21:17:28 +01:00
Laurent Destailleur
a139ab1b20 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into 23.0 2026-02-11 21:17:08 +01:00
hansemschnokeloch
09b69a178b Typo fix (#37195) 2026-02-11 21:15:41 +01:00
github-actions[bot]
e199ef7cae PHPStan > Update baseline (#37197)
Co-authored-by: Dolibot <dolibarr-bot@users.noreply.github.com>
2026-02-11 21:15:15 +01:00
MDW
358a4883c6 Qual: Fix ambigious redirect error on Phan workflow (#37200)
# Qual: Fix ambigious redirect error on Phan workflow

Rewrote the shell command that is supposed to suppress a file contents
but is flagged by the environment.
2026-02-11 21:13:08 +01:00
Laurent Destailleur
fa55a2987a Doc 2026-02-11 21:10:27 +01:00
Laurent Destailleur
9743441127 Merge branch '23.0' of git@github.com:Dolibarr/dolibarr.git into 23.0 2026-02-11 21:07:06 +01:00
Laurent Destailleur
da6de62ad9 Fix log 2026-02-11 20:37:57 +01:00
Laurent Destailleur
1de655faaa Merge branch '23.0' of git@github.com:Dolibarr/dolibarr.git into 23.0 2026-02-11 18:46:34 +01:00
Laurent Destailleur
44fcbb4c18 Merge branch '22.0' of git@github.com:Dolibarr/dolibarr.git into 23.0 2026-02-11 18:46:21 +01:00
Laurent Destailleur
7a1a00e5d3 Complete examplefor tooltip to setup a virtual host 2026-02-11 18:44:15 +01:00
Laurent Destailleur
bf9e154deb Fix init ref 2026-02-11 18:07:37 +01:00
Laurent Destailleur
094e42fd4f Fix init ref 2026-02-11 18:03:03 +01:00
Laurent Destailleur
5846921e37 Sec: Can init a page with php content without permission for php content
edition (reported by phdwg1410)
2026-02-11 17:53:09 +01:00
Laurent Destailleur
d87b93cebd Fix missing br 2026-02-11 16:46:16 +01:00
Laurent Destailleur
ff63da5fac Fix phan 2026-02-11 15:08:13 +01:00
Laurent Destailleur
bd65974d56 Fix phan 2026-02-11 15:07:19 +01:00
47 changed files with 585 additions and 368 deletions

View File

@@ -64,18 +64,24 @@ jobs:
env: env:
ALL_CHANGED_FILES: ${{ steps.changed-php.outputs.all_changed_files }} ALL_CHANGED_FILES: ${{ steps.changed-php.outputs.all_changed_files }}
# shellcheck disable=2086 # shellcheck disable=2086
FILE_CHANGE_LIST: /tmp/phan-changed.lst FILE_CHANGED_LIST: /tmp/phan-changed.lst
run: | run: |
# shellcheck disable=2086 # shellcheck disable=2086
if [ "${{ github.ref_name }}" == "develop" ] || [[ "${{ github.ref_name }}" == *.0 ]]|| [[ "${{ github.head_ref }}" == *"phan_full"* ]] ; then if [ "${{ github.ref_name }}" == "develop" ] || [[ "${{ github.ref_name }}" == *.0 ]]|| [[ "${{ github.head_ref }}" == *"phan_full"* ]] ; then
echo phan $PHAN_QUICK -k "$PHAN_CONFIG" -B "$PHAN_BASELINE" --analyze-twice --minimum-target-php-version "$PHAN_MIN_PHP" --output-mode=checkstyle -o _phan.xml echo phan $PHAN_QUICK -k "$PHAN_CONFIG" -B "$PHAN_BASELINE" --analyze-twice --minimum-target-php-version "$PHAN_MIN_PHP" --output-mode=checkstyle -o _phan.xml
phan $PHAN_QUICK -k "$PHAN_CONFIG" -B "$PHAN_BASELINE" --analyze-twice --minimum-target-php-version "$PHAN_MIN_PHP" --output-mode=checkstyle -o _phan.xml phan $PHAN_QUICK -k "$PHAN_CONFIG" -B "$PHAN_BASELINE" --analyze-twice --minimum-target-php-version "$PHAN_MIN_PHP" --output-mode=checkstyle -o _phan.xml
else else
> $FILE_CHANGED_LIST echo -n "" > "$FILE_CHANGED_LIST"
for f in $ALL_CHANGED_FILES; do echo "$f" >> $FILE_CHANGED_LIST; done for f in $ALL_CHANGED_FILES; do echo "$f" >> "$FILE_CHANGED_LIST"; done
cat $FILE_CHANGED_LIST # Must exclude same files as in phan configuration
echo phan --file-list $FILE_CHANGED_LIST $PHAN_QUICK -k "$PHAN_CONFIG" -B "$PHAN_BASELINE" --analyze-twice --minimum-target-php-version "$PHAN_MIN_PHP" --output-mode=checkstyle -o _phan.xml grep -v -E '^htdocs/(custom/|.*/canvas/.*/tpl/.*.tpl.php|admin/tools/ui/|includes/(nusoap/|restler/|stripe/)|conf/conf.php|modulebuilder/template/|[^h].*/.*)$' "$FILE_CHANGED_LIST"> "$FILE_CHANGED_LIST".tmp
phan --file-list $FILE_CHANGED_LIST $PHAN_QUICK -k "$PHAN_CONFIG" -B "$PHAN_BASELINE" --analyze-twice --minimum-target-php-version "$PHAN_MIN_PHP" --output-mode=checkstyle -o _phan.xml mv "$FILE_CHANGED_LIST".tmp "$FILE_CHANGED_LIST"
if [ ! -s "$FILE_CHANGED_LIST" ] ; then
echo "All changed files are excluded for phan"
else
echo phan --file-list "$FILE_CHANGED_LIST" $PHAN_QUICK -k "$PHAN_CONFIG" -B "$PHAN_BASELINE" --analyze-twice --minimum-target-php-version "$PHAN_MIN_PHP" --output-mode=checkstyle -o _phan.xml
phan --file-list "$FILE_CHANGED_LIST" $PHAN_QUICK -k "$PHAN_CONFIG" -B "$PHAN_BASELINE" --analyze-twice --minimum-target-php-version "$PHAN_MIN_PHP" --output-mode=checkstyle -o _phan.xml
fi
fi fi
- name: Add results to PR as Github notices - name: Add results to PR as Github notices

View File

@@ -89,16 +89,28 @@ jobs:
# Run PHPStan # Run PHPStan
- name: Run PHPStan - name: Run PHPStan
id: phpstan id: phpstan
if: "! cancelled() && steps.changed-php.outputs.any_changed == 'true'" # Proceed when:
# - the action is not cancelled
# AND
# - the branch is an integration branch (no merge), or,
# - the merge from branch contains 'phpstan_full', or,
# - there are changes in PHP files.
if: ${{ ! cancelled() && (github.ref_name == 'develop' || github.ref_name == 'refs/heads/develop' || endsWith(github.ref_name, '.0') || contains(github.head_ref, 'phpstan_full') || steps.changed-php.outputs.any_changed == 'true') }}
env: env:
ALL_CHANGED_FILES: ${{ steps.changed-php.outputs.all_changed_files }} ALL_CHANGED_FILES: ${{ steps.changed-php.outputs.all_changed_files }}
# shellcheck disable=2086 # shellcheck disable=2086
run: | run: |
# shellcheck disable=2086 # shellcheck disable=2086
> /tmp/phpstan-files.txt > /tmp/phpstan-files.txt
echo "$ALL_CHANGED_FILES" >> /tmp/phpstan-files.txt if [ "${{ github.ref_name }}" == "develop" ] || [[ "${{ github.ref_name }}" == *.0 ]]|| [[ "${{ github.head_ref }}" == *"phpstan_full"* ]] ; then
cat /tmp/phpstan-files.txt # Run on all files in integration branch
phpstan -vvv analyse --error-format=checkstyle --memory-limit 7G -a dev/build/phpstan/bootstrap_action.php ${ALL_CHANGED_FILES} | tee _stan.xml | cs2pr --graceful-warnings phpstan -vvv analyse --error-format=checkstyle --memory-limit 7G -a dev/build/phpstan/bootstrap_action.php | tee _stan.xml | cs2pr --graceful-warnings
else
echo "$ALL_CHANGED_FILES" >> /tmp/phpstan-files.txt
cat /tmp/phpstan-files.txt
phpstan -vvv analyse --error-format=checkstyle --memory-limit 7G -a dev/build/phpstan/bootstrap_action.php ${ALL_CHANGED_FILES} | tee _stan.xml | cs2pr --graceful-warnings
fi
# continue-on-error: true # continue-on-error: true
# Save cache # Save cache

View File

@@ -60,7 +60,7 @@
Require all granted Require all granted
</Directory> </Directory>
# You may also want to allow access to everyone to wrappers for api, document, viewimage, manifest and public json/img # You may also want to allow access to everyone to wrappers for api, document, viewimage, manifest and public json/img files
# but if you can avoid it, it is better. # but if you can avoid it, it is better.
<Files /home/admin/wwwroot/dolibarr/htdocs/api/index.php> <Files /home/admin/wwwroot/dolibarr/htdocs/api/index.php>
AuthType None AuthType None

View File

@@ -1,6 +1,6 @@
<?php <?php
/* Copyright (C) 2013-2022 Laurent Destailleur <eldy@users.sourceforge.net> /* Copyright (C) 2013-2022 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024-2025 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 * This program is free software; you can redistribute it and/or modify
@@ -40,8 +40,9 @@ require '../../main.inc.php';
* @var string $dolibarr_main_restrict_ip * @var string $dolibarr_main_restrict_ip
* @var string $dolibarr_main_db_pass * @var string $dolibarr_main_db_pass
* @var string $dolibarr_main_db_encrypted_pass * @var string $dolibarr_main_db_encrypted_pass
* @var string|string[] $dolibarr_main_stream_to_disable * @var string $dolibarr_website_allow_custom_php
* @var string $dolibarr_nocsrfcheck * @var string $dolibarr_nocsrfcheck
* @var string|string[] $dolibarr_main_stream_to_disable
*/ */
require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/memory.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
@@ -154,7 +155,26 @@ if (getDolGlobalString('MAIN_SECURITY_SHOW_MORE_INFO')) {
print '<br>'; print '<br>';
print "<strong>PHP disable_functions</strong>: "; print "<strong>PHP disable_functions</strong>: ";
$arrayoffunctionsdisabled = explode(',', ini_get('disable_functions')); // The original value is...
$disablefunctionorign = '';
$phparray = phpinfo_array();
foreach ($phparray as $key => $value) {
foreach ($value as $keyparam => $keyvalue) {
if ($keyparam == 'disable_functions') {
if (!empty($keyvalue['master'])) {
$disablefunctionorign = $keyvalue['master'];
break;
}
}
}
}
/*
if (empty($disablefunctionorign)) {
$disablefunctionorign = ini_get('disable_functions'); // Not always the real value
}
*/
$arrayoffunctionsdisabled = explode(',', $disablefunctionorign);
$arrayoffunctionstodisable = explode(',', 'dl,apache_note,apache_setenv,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,show_source,virtual'); $arrayoffunctionstodisable = explode(',', 'dl,apache_note,apache_setenv,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,show_source,virtual');
//$arrayoffunctionstodisable[] = 'stream_wrapper_restore'; //$arrayoffunctionstodisable[] = 'stream_wrapper_restore';
//$arrayoffunctionstodisable[] = 'stream_wrapper_register'; //$arrayoffunctionstodisable[] = 'stream_wrapper_register';
@@ -368,13 +388,11 @@ if (empty($dolibarr_main_prod)) {
} }
print '<br>'; print '<br>';
print '<strong>$dolibarr_nocsrfcheck</strong>: '.(empty($dolibarr_nocsrfcheck) ? '0' : $dolibarr_nocsrfcheck);
if (!empty($dolibarr_nocsrfcheck)) { if (!empty($dolibarr_nocsrfcheck)) {
print '<strong>$dolibarr_nocsrfcheck</strong>: '.(empty($dolibarr_nocsrfcheck) ? '0' : $dolibarr_nocsrfcheck);
print ' &nbsp; &nbsp;'.img_picto('', 'error').' '.$langs->trans("IfYouAreOnAProductionSetThis", 0); print ' &nbsp; &nbsp;'.img_picto('', 'error').' '.$langs->trans("IfYouAreOnAProductionSetThis", 0);
} else { print '<br>';
print ' &nbsp; &nbsp; <span class="opacitymedium">('.$langs->trans("Recommended").': 0)</span>';
} }
print '<br>';
print '<strong>$dolibarr_main_restrict_ip</strong>: '; print '<strong>$dolibarr_main_restrict_ip</strong>: ';
if (empty($dolibarr_main_restrict_ip)) { if (empty($dolibarr_main_restrict_ip)) {
@@ -385,24 +403,46 @@ if (empty($dolibarr_main_restrict_ip)) {
} }
print '<br>'; print '<br>';
print '<strong>$dolibarr_main_restrict_os_commands</strong>: '; print '<strong>$dolibarr_main_restrict_os_commands</strong>: ';
if (empty($dolibarr_main_restrict_os_commands)) { if (empty($dolibarr_main_restrict_os_commands)) {
print $langs->trans("None"); print $langs->trans("None");
} else { } else {
print $dolibarr_main_restrict_os_commands; print $dolibarr_main_restrict_os_commands;
} }
print ' &nbsp; &nbsp; <span class="opacitymedium">('.$langs->trans("RecommendedValueIs", 'mysqldump, mysql, pg_dump, pg_restore, mariadb, mariadb-dump, clamdscan').')</span>'; print ' &nbsp; &nbsp; <span class="opacitymedium">('.$langs->trans("RecommendedValueIs", 'mariadb-dump, mariadb, mysqldump, mysql, pg_dump, pg_restore, clamdscan').')</span>';
print '<br>'; print '<br>';
print '<strong>$dolibarr_main_restrict_eval_methods</strong>: '; print '<strong>$dolibarr_main_restrict_eval_methods</strong>: ';
if (empty($dolibarr_main_restrict_eval_methods)) { if (empty($dolibarr_main_restrict_eval_methods)) {
print $langs->trans("None"); print $langs->trans("None");
} else { } else {
print $dolibarr_main_restrict_eval_methods; print $dolibarr_main_restrict_eval_methods;
} }
print ' &nbsp; &nbsp; <span class="opacitymedium">('.$langs->trans("RecommendedValueIs", 'getDolGlobalString,getDolGlobalInt,getDolCurrency,getDolEntity,getDolDBType,fetchNoCompute,hasRight,isAdmin,isModEnabled,isStringVarMatching,abs,min,max,round,dol_now,dol_concat,preg_match').')</span>'; print ' &nbsp; &nbsp; <span class="opacitymedium">('.$langs->trans("RecommendedValueIs", 'getDolGlobalString, getDolGlobalInt, getDolCurrency, getDolEntity, getDolDBType, fetchNoCompute, hasRight, isAdmin, isModEnabled, isStringVarMatching, abs, min, max, round, dol_now, dol_concat, preg_match').')</span>';
print '<br>'; print '<br>';
print '<strong>$dolibarr_website_allow_custom_php</strong>: ';
if (!empty($dolibarr_website_allow_custom_php) && $dolibarr_website_allow_custom_php == 2) {
print img_picto('', 'warning').' ';
}
if (empty($dolibarr_website_allow_custom_php)) {
print '0';
} else {
print $dolibarr_website_allow_custom_php;
}
print ' &nbsp; &nbsp; <span class="opacitymedium">(';
if (isModEnabled('website')) {
print $langs->trans("RecommendedValueIs", '0 if you don\'t include PHP in your websites, else 1');
} else {
print $langs->trans("RecommendedValueIs", '0');
}
print ')</span>';
print '<br>';
if (!getDolGlobalString('SECURITY_DISABLE_TEST_ON_OBFUSCATED_CONF')) { if (!getDolGlobalString('SECURITY_DISABLE_TEST_ON_OBFUSCATED_CONF')) {
print '<strong>$dolibarr_main_db_pass</strong>: '; print '<strong>$dolibarr_main_db_pass</strong>: ';
if (!empty($dolibarr_main_db_pass) && empty($dolibarr_main_db_encrypted_pass)) { if (!empty($dolibarr_main_db_pass) && empty($dolibarr_main_db_encrypted_pass)) {

View File

@@ -1,6 +1,7 @@
<?php <?php
/* /*
* Copyright (C) 2024 Anthony Damhet <a.damhet@progiseize.fr> * Copyright (C) 2024 Anthony Damhet <a.damhet@progiseize.fr>
* Copyright (C) 2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program and files/directory inner it is free software: you can * This program and files/directory inner it is free software: you can
* redistribute it and/or modify it under the terms of the * redistribute it and/or modify it under the terms of the
@@ -100,9 +101,9 @@ $documentation->showSidebar(); ?>
</div> </div>
<?php <?php
$lines = array( $lines = array(
'<span class="spannature paddinglarge marginrightonly nonature-back valignmiddle"><label for="prospectinput" class="valignmiddle"><span class="valignmiddle">Prospect</span><input id="prospectinput" class="flat checkforselect marginleftonly valignmiddle" type="checkbox" name="prospect" value="1" checked></label></span>', '<span class="spannature paddinglarge marginrightonly nonature-back valignmiddle"><label for="prospectinput" class="valignmiddle"><span class="valignmiddle">Prospect</span><input id="prospectinput" class="flat checkforselect marginleftonly valignmiddle" type="checkbox" name="prospect" value="1" checked></label></span>',
'<span class="spannature paddinglarge marginrightonly nonature-back valignmiddle"><label for="customerinput" class="valignmiddle"><span class="valignmiddle">Customer</span><input id="customerinput" class="flat checkforselect marginleftonly valignmiddle" type="checkbox" name="customer" value="1" checked></label></span>', '<span class="spannature paddinglarge marginrightonly nonature-back valignmiddle"><label for="customerinput" class="valignmiddle"><span class="valignmiddle">Customer</span><input id="customerinput" class="flat checkforselect marginleftonly valignmiddle" type="checkbox" name="customer" value="1" checked></label></span>',
'<span class="spannature paddinglarge marginrightonly nonature-back valignmiddle"><label for="supplierinput" class="valignmiddle"><span class="valignmiddle">Supplier</span><input id="supplierinput" class="flat checkforselect marginleftonly valignmiddle" type="checkbox" name="supplier" value="1" checked></label></span>', '<span class="spannature paddinglarge marginrightonly nonature-back valignmiddle"><label for="supplierinput" class="valignmiddle"><span class="valignmiddle">Supplier</span><input id="supplierinput" class="flat checkforselect marginleftonly valignmiddle" type="checkbox" name="supplier" value="1" checked></label></span>',
); );
echo $documentation->showCode($lines); ?> echo $documentation->showCode($lines); ?>
@@ -114,8 +115,8 @@ $documentation->showSidebar(); ?>
</div> </div>
<?php <?php
$lines = array( $lines = array(
'<input type="radio" id="idforradioinput1" name="radioinput" value="value1"><label for="idforradioinput1" class="marginrightonly"> Radio Input 1</label>', '<input type="radio" id="idforradioinput1" name="radioinput" value="value1"><label for="idforradioinput1" class="marginrightonly"> Radio Input 1</label>',
'<input type="radio" id="idforradioinput2" name="radioinput" value="value2"><label for="idforradioinput2" class="marginrightonly"> Radio Input 2</label>' '<input type="radio" id="idforradioinput2" name="radioinput" value="value2"><label for="idforradioinput2" class="marginrightonly"> Radio Input 2</label>'
); );
echo $documentation->showCode($lines); ?> echo $documentation->showCode($lines); ?>
</div> </div>
@@ -141,36 +142,36 @@ $documentation->showSidebar(); ?>
</div> </div>
<?php <?php
$lines = array( $lines = array(
'<?php', '<?php',
'', '',
'/**', '/**',
' * Function selectarray', ' * Function selectarray',
' *', ' *',
' * @param string $htmlname Name of html select area. Try to start name with "multi" or "search_multi" if this is a multiselect,', ' * @param string $htmlname Name of html select area. Try to start name with "multi" or "search_multi" if this is a multiselect,',
' * @param array $array Array like array(key => value) or array(key=>array(\'label\'=>..., \'data-...\'=>..., \'disabled\'=>..., \'css\'=>...)),', ' * @param array $array Array like array(key => value) or array(key=>array(\'label\'=>..., \'data-...\'=>..., \'disabled\'=>..., \'css\'=>...)),',
' * @param string|string[]|int $id Preselected key or array of preselected keys for multiselect. Use \'ifone\' to autoselect record if there is only one record.,', ' * @param string|string[]|int $id Preselected key or array of preselected keys for multiselect. Use \'ifone\' to autoselect record if there is only one record.,',
' * @param int<0,1>|string $show_empty 0 no empty value allowed, 1 or string to add an empty value into list (If 1: key is -1 and value is \'\' or "&nbsp;", If \'Placeholder string\': key is -1 and value is the string), <0 to add an empty value with key that is this value.,', ' * @param int<0,1>|string $show_empty 0 no empty value allowed, 1 or string to add an empty value into list (If 1: key is -1 and value is \'\' or "&nbsp;", If \'Placeholder string\': key is -1 and value is the string), <0 to add an empty value with key that is this value.,',
' * @param int<0,1> $key_in_label 1 to show key into label with format "[key] value",', ' * @param int<0,1> $key_in_label 1 to show key into label with format "[key] value",',
' * @param int<0,1> $value_as_key 1 to use value as key,', ' * @param int<0,1> $value_as_key 1 to use value as key,',
' * @param string $moreparam Add more parameters onto the select tag. For example "style=\"width: 95%\"" to avoid select2 component to go over parent container,', ' * @param string $moreparam Add more parameters onto the select tag. For example "style=\"width: 95%\"" to avoid select2 component to go over parent container,',
' * @param int<0,1> $translate 1=Translate and encode value,', ' * @param int<0,1> $translate 1=Translate and encode value,',
' * @param int $maxlen Length maximum for labels,', ' * @param int $maxlen Length maximum for labels,',
' * @param int<0,1> $disabled Html select box is disabled,', ' * @param int<0,1> $disabled Html select box is disabled,',
' * @param string $sort \'ASC\' or \'DESC\' = Sort on label, \'\' or \'NONE\' or \'POS\' = Do not sort, we keep original order,', ' * @param string $sort \'ASC\' or \'DESC\' = Sort on label, \'\' or \'NONE\' or \'POS\' = Do not sort, we keep original order,',
' * @param string $morecss Add more class to css styles,', ' * @param string $morecss Add more class to css styles,',
' * @param int $addjscombo Add js combo,', ' * @param int $addjscombo Add js combo,',
' * @param string $moreparamonempty Add more param on the empty option line. Not used if show_empty not set,', ' * @param string $moreparamonempty Add more param on the empty option line. Not used if show_empty not set,',
' * @param int $disablebademail 1=Check if a not valid email, 2=Check string \'---\', and if found into value, disable and colorize entry,', ' * @param int $disablebademail 1=Check if a not valid email, 2=Check string \'---\', and if found into value, disable and colorize entry,',
' * @param int $nohtmlescape No html escaping (not recommended, use \'data-html\' if you need to use label with HTML content).,', ' * @param int $nohtmlescape No html escaping (not recommended, use \'data-html\' if you need to use label with HTML content).,',
' * @return string HTML select string.,', ' * @return string HTML select string.,',
' */', ' */',
'', '',
'// Select with empty value', '// Select with empty value',
'print $form->selectarray(\'htmlnameselectwithemptyvalue\', $values, \'idselectwithemptyvalue\', 1, 0, 0, \'\', 0, 0, 0, \'\', \'minwidth200\');', 'print $form->selectarray(\'htmlnameselectwithemptyvalue\', $values, \'idselectwithemptyvalue\', 1, 0, 0, \'\', 0, 0, 0, \'\', \'minwidth200\');',
'', '',
'// Select within empty value', '// Select within empty value',
'print $form->selectarray(\'htmlnameselectwithinemptyvalue\', $values, \'idnameselectwithinemptyvalue\', 0,0, 0, \'\', 0, 0, 0, \'\', \'minwidth200\');', 'print $form->selectarray(\'htmlnameselectwithinemptyvalue\', $values, \'idnameselectwithinemptyvalue\', 0,0, 0, \'\', 0, 0, 0, \'\', \'minwidth200\');',
); );
echo $documentation->showCode($lines, 'php'); ?> echo $documentation->showCode($lines, 'php'); ?>
@@ -187,29 +188,29 @@ $documentation->showSidebar(); ?>
</div> </div>
<?php <?php
$lines = array( $lines = array(
'<?php', '<?php',
'', '',
'/**', '/**',
' * Show a multiselect form from an array. WARNING: Use this only for short lists.', ' * Show a multiselect form from an array. WARNING: Use this only for short lists.',
' *', ' *',
' * @param string $htmlname Name of select', ' * @param string $htmlname Name of select',
' * @param array<string,string|array{id:string,label:string,color:string,picto:string,labelhtml:string}> $array Array(key=>value) or Array(key=>array(\'id\'=>key, \'label\'=>value, \'color\'=> , \'picto\'=> , \'labelhtml\'=> ))', ' * @param array<string,string|array{id:string,label:string,color:string,picto:string,labelhtml:string}> $array Array(key=>value) or Array(key=>array(\'id\'=>key, \'label\'=>value, \'color\'=> , \'picto\'=> , \'labelhtml\'=> ))',
' * @param string[] $selected Array of keys preselected', ' * @param string[] $selected Array of keys preselected',
' * @param int<0,1> $key_in_label 1 to show key like in "[key] value"', ' * @param int<0,1> $key_in_label 1 to show key like in "[key] value"',
' * @param int<0,1> $value_as_key 1 to use value as key', ' * @param int<0,1> $value_as_key 1 to use value as key',
' * @param string $morecss Add more css style', ' * @param string $morecss Add more css style',
' * @param int<0,1> $translate Translate and encode value', ' * @param int<0,1> $translate Translate and encode value',
' * @param int|string $width Force width of select box. May be used only when using jquery couch. Example: 250, \'95%\'', ' * @param int|string $width Force width of select box. May be used only when using jquery couch. Example: 250, \'95%\'',
' * @param string $moreattrib Add more options on select component. Example: \'disabled\'', ' * @param string $moreattrib Add more options on select component. Example: \'disabled\'',
' * @param string $elemtype Type of element we show (\'category\', ...). Will execute a formatting function on it. To use in readonly mode if js component support HTML formatting.', ' * @param string $elemtype Type of element we show (\'category\', ...). Will execute a formatting function on it. To use in readonly mode if js component support HTML formatting.',
' * @param string $placeholder String to use as placeholder', ' * @param string $placeholder String to use as placeholder',
' * @param int<-1,1> $addjscombo Add js combo', ' * @param int<-1,1> $addjscombo Add js combo',
' * @return string HTML multiselect string', ' * @return string HTML multiselect string',
' * @see selectarray(), selectArrayAjax(), selectArrayFilter()', ' * @see selectarray(), selectArrayAjax(), selectArrayFilter()',
' */', ' */',
'', '',
'// Multiselect', '// Multiselect',
'print $form->multiselectarray(\'categories\', $values, GETPOST(\'categories\', \'array\'), 0, 0, \'minwidth200\', 0, 0);' 'print $form->multiselectarray(\'categories\', $values, GETPOST(\'categories\', \'array\'), 0, 0, \'minwidth200\', 0, 0);'
); );
echo $documentation->showCode($lines, 'php'); ?> echo $documentation->showCode($lines, 'php'); ?>
@@ -232,41 +233,41 @@ $documentation->showSidebar(); ?>
</div> </div>
<?php <?php
$lines = array( $lines = array(
'<?php', '<?php',
'/**', '/**',
' * Show a HTML widget to input a date or combo list for day, month, years and optionally hours and minutes.,', ' * Show a HTML widget to input a date or combo list for day, month, years and optionally hours and minutes.,',
' * Fields are preselected with :,', ' * Fields are preselected with :,',
' * - set_time date (must be a local PHP server timestamp or string date with format \'YYYY-MM-DD\' or \'YYYY-MM-DD HH:MM\'),', ' * - set_time date (must be a local PHP server timestamp or string date with format \'YYYY-MM-DD\' or \'YYYY-MM-DD HH:MM\'),',
' * - local date in user area, if set_time is \'\' (so if set_time is \'\', output may differs when done from two different location),', ' * - local date in user area, if set_time is \'\' (so if set_time is \'\', output may differs when done from two different location),',
' * - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1),', ' * - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1),',
' *', ' *',
' * @param integer|string $set_time Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, \'\' to use current date with 00:00 hour (Parameter \'empty\' must be 0 or 2).,', ' * @param integer|string $set_time Preselected date (must be a local PHP server timestamp), -1 to keep date not preselected, \'\' to use current date with 00:00 hour (Parameter \'empty\' must be 0 or 2).,',
' * @param string $prefix Prefix for fields name,', ' * @param string $prefix Prefix for fields name,',
' * @param int $h 1 or 2=Show also hours (2=hours on a new line), -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 or 4 (4=hours on a new line)=Show hour always empty,', ' * @param int $h 1 or 2=Show also hours (2=hours on a new line), -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 or 4 (4=hours on a new line)=Show hour always empty,',
' * @param int $m 1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty,', ' * @param int $m 1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty,',
' * @param int $empty 0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only,', ' * @param int $empty 0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only,',
' * @param string $form_name Not used,', ' * @param string $form_name Not used,',
' * @param int<0,1> $d 1=Show days, month, years,', ' * @param int<0,1> $d 1=Show days, month, years,',
' * @param int<0,2> $addnowlink Add a link "Now", 1 with server time, 2 with local computer time,', ' * @param int<0,2> $addnowlink Add a link "Now", 1 with server time, 2 with local computer time,',
' * @param int<0,1> $disabled Disable input fields,', ' * @param int<0,1> $disabled Disable input fields,',
' * @param int|string $fullday When a checkbox with id #fullday is checked, hours are set with 00:00 (if value if \'fulldaystart\') or 23:59 (if value is \'fulldayend\'),', ' * @param int|string $fullday When a checkbox with id #fullday is checked, hours are set with 00:00 (if value if \'fulldaystart\') or 23:59 (if value is \'fulldayend\'),',
' * @param string $addplusone Add a link "+1 hour". Value must be name of another selectDate field.,', ' * @param string $addplusone Add a link "+1 hour". Value must be name of another selectDate field.,',
' * @param int|string|array<string,mixed> $adddateof Add a link "Date of ..." using the following date. Must be array(array(\'adddateof\' => ..., \'labeladddateof\' => ...)),', ' * @param int|string|array<string,mixed> $adddateof Add a link "Date of ..." using the following date. Must be array(array(\'adddateof\' => ..., \'labeladddateof\' => ...)),',
' * @param string $openinghours Specify hour start and hour end for the select ex 8,20,', ' * @param string $openinghours Specify hour start and hour end for the select ex 8,20,',
' * @param int $stepminutes Specify step for minutes between 1 and 30,', ' * @param int $stepminutes Specify step for minutes between 1 and 30,',
' * @param string $labeladddateof Label to use for the $adddateof parameter. Deprecated. Used only when $adddateof is not an array.,', ' * @param string $labeladddateof Label to use for the $adddateof parameter. Deprecated. Used only when $adddateof is not an array.,',
' * @param string $placeholder Placeholder,', ' * @param string $placeholder Placeholder,',
' * @param \'auto\'|\'gmt\'|\'tzserver\'|\'tzuserrel\' $gm \'auto\' (for backward compatibility, avoid this), \'gmt\' or \'tzserver\' or \'tzuserrel\',', ' * @param \'auto\'|\'gmt\'|\'tzserver\'|\'tzuserrel\' $gm \'auto\' (for backward compatibility, avoid this), \'gmt\' or \'tzserver\' or \'tzuserrel\',',
' * @param string $calendarpicto URL of the icon/image used to display the calendar,', ' * @param string $calendarpicto URL of the icon/image used to display the calendar,',
' * @return string Html for selectDate,', ' * @return string Html for selectDate,',
' * @see form_date(), select_month(), select_year(), select_dayofweek(),', ' * @see form_date(), select_month(), select_year(), select_dayofweek(),',
' */', ' */',
'', '',
'// Date Select', '// Date Select',
'print $form->selectDate();', 'print $form->selectDate();',
'', '',
'// Date Select with hours', '// Date Select with hours',
'print $form->selectDate(\'\', \'re2\', 1, 1, 1);' 'print $form->selectDate(\'\', \'re2\', 1, 1, 1);'
); );
echo $documentation->showCode($lines, 'php'); ?> echo $documentation->showCode($lines, 'php'); ?>
@@ -281,29 +282,29 @@ $documentation->showSidebar(); ?>
</div> </div>
<?php <?php
$lines = array( $lines = array(
'<?php', '<?php',
'/**', '/**',
' * Create an object to build an HTML area to edit a large string content', ' * Create an object to build an HTML area to edit a large string content',
' *', ' *',
' * @param string $htmlname HTML name of WYSIWYG field', ' * @param string $htmlname HTML name of WYSIWYG field',
' * @param string $content Content of WYSIWYG field', ' * @param string $content Content of WYSIWYG field',
' * @param int|string $width Width in pixel of edit area (auto by default)', ' * @param int|string $width Width in pixel of edit area (auto by default)',
' * @param int $height Height in pixel of edit area (200px by default)', ' * @param int $height Height in pixel of edit area (200px by default)',
' * @param string $toolbarname Name of bar set to use (\'Full\', \'dolibarr_notes[_encoded]\', \'dolibarr_details[_encoded]\'=the less featured, \'dolibarr_mailings[_encoded]\', \'dolibarr_readonly\')', ' * @param string $toolbarname Name of bar set to use (\'Full\', \'dolibarr_notes[_encoded]\', \'dolibarr_details[_encoded]\'=the less featured, \'dolibarr_mailings[_encoded]\', \'dolibarr_readonly\')',
' * @param string $toolbarlocation Deprecated. Not used', ' * @param string $toolbarlocation Deprecated. Not used',
' * @param bool $toolbarstartexpanded Bar is visible or not at start', ' * @param bool $toolbarstartexpanded Bar is visible or not at start',
' * @param bool|int $uselocalbrowser Enabled to add links to local object with local browser. If false, only external images can be added in content.', ' * @param bool|int $uselocalbrowser Enabled to add links to local object with local browser. If false, only external images can be added in content.',
' * @param bool|int|string $okforextendededitor 1 or True=Allow usage of extended editor tool if qualified (like ckeditor). If \'textarea\', force use of simple textarea. If \'ace\', force use of Ace.', ' * @param bool|int|string $okforextendededitor 1 or True=Allow usage of extended editor tool if qualified (like ckeditor). If \'textarea\', force use of simple textarea. If \'ace\', force use of Ace.',
' * Warning: If you use \'ace\', don\'t forget to also include ace.js in page header. Also, the button "save" must have class="buttonforacesave"', ' * Warning: If you use \'ace\', don\'t forget to also include ace.js in page header. Also, the button "save" must have class="buttonforacesave"',
' * @param int $rows Size of rows for textarea tool', ' * @param int $rows Size of rows for textarea tool',
' * @param string $cols Size of cols for textarea tool (textarea number of cols \'70\' or percent \'x%\')', ' * @param string $cols Size of cols for textarea tool (textarea number of cols \'70\' or percent \'x%\')',
' * @param int<0,1> $readonly 0=Read/Edit, 1=Read only', ' * @param int<0,1> $readonly 0=Read/Edit, 1=Read only',
' * @param array{x?:string,y?:string,find?:string} $poscursor Array for initial cursor position array(\'x\'=>x, \'y\'=>y).', ' * @param array{x?:string,y?:string,find?:string} $poscursor Array for initial cursor position array(\'x\'=>x, \'y\'=>y).',
' * array(\'find\'=> \'word\') can be used to go to line were the word has been found', ' * array(\'find\'=> \'word\') can be used to go to line were the word has been found',
' */', ' */',
'', '',
'$doleditor = new DolEditor(\'desc\', GETPOST(\'desc\', \'restricthtml\'), \'\', 160, \'dolibarr_details\', \'\', false, true, getDolGlobalString(\'FCKEDITOR_ENABLE_DETAILS\'), ROWS_4, \'90%\');', '$doleditor = new DolEditor(\'desc\', GETPOST(\'desc\', \'restricthtml\'), \'\', 160, \'dolibarr_details\', \'\', false, true, getDolGlobalString(\'FCKEDITOR_ENABLE_DETAILS\'), ROWS_4, \'90%\');',
'print $form->multiselectarray(\'categories\', $values, GETPOST(\'categories\', \'array\'), 0, 0, \'minwidth200\', 0, 0);' 'print $form->multiselectarray(\'categories\', $values, GETPOST(\'categories\', \'array\'), 0, 0, \'minwidth200\', 0, 0);'
); );
echo $documentation->showCode($lines, 'php'); ?> echo $documentation->showCode($lines, 'php'); ?>
</div> </div>
@@ -316,14 +317,14 @@ $documentation->showSidebar(); ?>
<?php <?php
$containerCssSelector = '#demo-search-filter-tool-container-01'; $containerCssSelector = '#demo-search-filter-tool-container-01';
print $form->getSearchFilterToolInput( print $form->getSearchFilterToolInput(
$containerCssSelector. ' .search-item', $containerCssSelector. ' .search-item',
'', '',
'', '',
['attr' => [ ['attr' => [
'data-counter-target' => $containerCssSelector. ' .counter', 'data-counter-target' => $containerCssSelector. ' .counter',
'data-no-item-target' => $containerCssSelector. ' .search-tool-no-results', 'data-no-item-target' => $containerCssSelector. ' .search-tool-no-results',
], ],
] ]
); );
?> ?>
@@ -349,57 +350,57 @@ $documentation->showSidebar(); ?>
</div> </div>
<?php <?php
$lines = array( $lines = array(
'<div class="search-tool-container">', '<div class="search-tool-container">',
' <input ', ' <input ',
' type="search"', ' type="search"',
' name=""', ' name=""',
' autofocus="" <?php // To use only if search is in top of page ?> ', ' autofocus="" <?php // To use only if search is in top of page ?> ',
' value=""', ' value=""',
' class="search-tool-input" <?php // optional for js filter you can use custom class ?> ', ' class="search-tool-input" <?php // optional for js filter you can use custom class ?> ',
' placeholder="Search"', ' placeholder="Search"',
' autocomplete="off"', ' autocomplete="off"',
' data-search-tool-target="#demo-filter .search-item" <?php // required for js filter ?> ', ' data-search-tool-target="#demo-filter .search-item" <?php // required for js filter ?> ',
' data-counter-target="#demo-filter .counter" <?php // optional for js filter ?> ', ' data-counter-target="#demo-filter .counter" <?php // optional for js filter ?> ',
' data-no-item-target="#demo-filter .search-tool-no-results" <?php // optional for js filter ?> ', ' data-no-item-target="#demo-filter .search-tool-no-results" <?php // optional for js filter ?> ',
' >', ' >',
'</div>', '</div>',
'<div id="demo-filter">', '<div id="demo-filter">',
' <p>Counter : <strong class="counter">4</strong></p>', ' <p>Counter : <strong class="counter">4</strong></p>',
' <ul>', ' <ul>',
' <li class="search-item">France</li>', ' <li class="search-item">France</li>',
' <li class="search-item">Italy</li>', ' <li class="search-item">Italy</li>',
' <li class="search-item">Germany</li>', ' <li class="search-item">Germany</li>',
' <li class="search-item">Spain</li>', ' <li class="search-item">Spain</li>',
' </ul>', ' </ul>',
' <div class="search-tool-no-results hidden-search-result" >No results</div>', ' <div class="search-tool-no-results hidden-search-result" >No results</div>',
'</div>', '</div>',
); );
echo $documentation->showCode($lines, 'php'); echo $documentation->showCode($lines, 'php');
$lines = array( $lines = array(
'<?php', '<?php',
'print $form->getSearchFilterToolInput(', 'print $form->getSearchFilterToolInput(',
' \'#demo-filter .search-item\',', ' \'#demo-filter .search-item\',',
' \'search-tools-input\',', ' \'search-tools-input\',',
' [\'attr\' => [', ' [\'attr\' => [',
' \'data-no-item-target\' => \'#demo-filter .search-tool-no-results\', ', ' \'data-no-item-target\' => \'#demo-filter .search-tool-no-results\', ',
' \'data-counter-target\' => \'#demo-filter .counter\', ', ' \'data-counter-target\' => \'#demo-filter .counter\', ',
' ],', ' ],',
' ]', ' ]',
'); ', '); ',
'?>', '?>',
'', '',
'<div id="demo-filter">', '<div id="demo-filter">',
' <p>Counter : <strong class="counter">4</strong></p>', ' <p>Counter : <strong class="counter">4</strong></p>',
' <ul>', ' <ul>',
' <li class="search-item">France</li>', ' <li class="search-item">France</li>',
' <li class="search-item">Italy</li>', ' <li class="search-item">Italy</li>',
' <li class="search-item">Germany</li>', ' <li class="search-item">Germany</li>',
' <li class="search-item">Spain</li>', ' <li class="search-item">Spain</li>',
' </ul>', ' </ul>',
' <div class="search-tool-no-results hidden-search-result" >No results</div>', ' <div class="search-tool-no-results hidden-search-result" >No results</div>',
'</div>', '</div>',
); );
echo $documentation->showCode($lines, 'php'); echo $documentation->showCode($lines, 'php');

View File

@@ -1,7 +1,7 @@
<?php <?php
/* Copyright (C) 2016-2017 Laurent Destailleur <eldy@users.sourceforge.net> /* Copyright (C) 2016-2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr> * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -101,6 +101,7 @@ if (empty($action)) {
* Actions * Actions
*/ */
// None
/* /*

View File

@@ -1395,6 +1395,7 @@ class ActionComm extends CommonObject
/** /**
* Load all objects with filters. * Load all objects with filters.
* This is used by the showactions used into the main tab of objects to show the last n actions.
* @TODO WARNING: This make a fetch on all records instead of making one request with a join, like done into show_actions_done. * @TODO WARNING: This make a fetch on all records instead of making one request with a join, like done into show_actions_done.
* *
* @param int $socid Filter by thirdparty * @param int $socid Filter by thirdparty

View File

@@ -1,7 +1,7 @@
<?php <?php
/* Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro> /* Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2019-2025 Frédéric France <frederic.france@free.fr> * Copyright (C) 2019-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -51,9 +51,9 @@ class FormAdvTargetEmailing extends Form
} }
/** /**
* Affiche un champs select contenant une liste * Display a select field with a list
* *
* @param string[] $selected_array à preselectionner * @param string[] $selected_array To preselect elements
* @param string $htmlname select field * @param string $htmlname select field
* @return string select field * @return string select field
*/ */

View File

@@ -588,21 +588,21 @@ if ($socid > 0) {
$facturestatic->id = $obj->fk_facture_source; $facturestatic->id = $obj->fk_facture_source;
$facturestatic->ref = $obj->ref; $facturestatic->ref = $obj->ref;
$facturestatic->type = $obj->type; $facturestatic->type = $obj->type;
print preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $obj->description).' '.$facturestatic->getNomURl(1); print preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $obj->description).'<br>'.$facturestatic->getNomURl(1);
print '</td>'; print '</td>';
} elseif (preg_match('/\(DEPOSIT\)/', $obj->description)) { } elseif (preg_match('/\(DEPOSIT\)/', $obj->description)) {
print '<td class="tdoverflowmax100">'; print '<td class="tdoverflowmax100">';
$facturestatic->id = $obj->fk_facture_source; $facturestatic->id = $obj->fk_facture_source;
$facturestatic->ref = $obj->ref; $facturestatic->ref = $obj->ref;
$facturestatic->type = $obj->type; $facturestatic->type = $obj->type;
print preg_replace('/\(DEPOSIT\)/', $langs->trans("InvoiceDeposit"), $obj->description).' '.$facturestatic->getNomURl(1); print preg_replace('/\(DEPOSIT\)/', $langs->trans("InvoiceDeposit"), $obj->description).'<br>'.$facturestatic->getNomURl(1);
print '</td>'; print '</td>';
} elseif (preg_match('/\(EXCESS RECEIVED\)/', $obj->description)) { } elseif (preg_match('/\(EXCESS RECEIVED\)/', $obj->description)) {
print '<td class="tdoverflowmax100">'; print '<td class="tdoverflowmax100">';
$facturestatic->id = $obj->fk_facture_source; $facturestatic->id = $obj->fk_facture_source;
$facturestatic->ref = $obj->ref; $facturestatic->ref = $obj->ref;
$facturestatic->type = $obj->type; $facturestatic->type = $obj->type;
print preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("ExcessReceived"), $obj->description).' '.$facturestatic->getNomURl(1); print preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("ExcessReceived"), $obj->description).'<br>'.$facturestatic->getNomURl(1);
print '</td>'; print '</td>';
} else { } else {
print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($obj->description).'">'; print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($obj->description).'">';
@@ -886,21 +886,21 @@ if ($socid > 0) {
$facturefournstatic->id = $obj->fk_invoice_supplier_source; $facturefournstatic->id = $obj->fk_invoice_supplier_source;
$facturefournstatic->ref = $obj->ref; $facturefournstatic->ref = $obj->ref;
$facturefournstatic->type = $obj->type; $facturefournstatic->type = $obj->type;
print preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $obj->description).' '.$facturefournstatic->getNomURl(1); print preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $obj->description).'<br>'.$facturefournstatic->getNomURl(1);
print '</td>'; print '</td>';
} elseif (preg_match('/\(DEPOSIT\)/', $obj->description)) { } elseif (preg_match('/\(DEPOSIT\)/', $obj->description)) {
print '<td class="tdoverflowmax100">'; print '<td class="tdoverflowmax100">';
$facturefournstatic->id = $obj->fk_invoice_supplier_source; $facturefournstatic->id = $obj->fk_invoice_supplier_source;
$facturefournstatic->ref = $obj->ref; $facturefournstatic->ref = $obj->ref;
$facturefournstatic->type = $obj->type; $facturefournstatic->type = $obj->type;
print preg_replace('/\(DEPOSIT\)/', $langs->trans("InvoiceDeposit"), $obj->description).' '.$facturefournstatic->getNomURl(1); print preg_replace('/\(DEPOSIT\)/', $langs->trans("InvoiceDeposit"), $obj->description).'<br>'.$facturefournstatic->getNomURl(1);
print '</td>'; print '</td>';
} elseif (preg_match('/\(EXCESS PAID\)/', $obj->description)) { } elseif (preg_match('/\(EXCESS PAID\)/', $obj->description)) {
print '<td class="tdoverflowmax100">'; print '<td class="tdoverflowmax100">';
$facturefournstatic->id = $obj->fk_invoice_supplier_source; $facturefournstatic->id = $obj->fk_invoice_supplier_source;
$facturefournstatic->ref = $obj->ref; $facturefournstatic->ref = $obj->ref;
$facturefournstatic->type = $obj->type; $facturefournstatic->type = $obj->type;
print preg_replace('/\(EXCESS PAID\)/', $langs->trans("ExcessPaid"), $obj->description).' '.$facturefournstatic->getNomURl(1); print preg_replace('/\(EXCESS PAID\)/', $langs->trans("ExcessPaid"), $obj->description).'<br>'.$facturefournstatic->getNomURl(1);
print '</td>'; print '</td>';
} else { } else {
print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($obj->description).'">'; print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($obj->description).'">';
@@ -1234,21 +1234,21 @@ if ($socid > 0) {
$facturestatic->id = $obj->fk_facture_source; $facturestatic->id = $obj->fk_facture_source;
$facturestatic->ref = $obj->invoice_source_ref; $facturestatic->ref = $obj->invoice_source_ref;
$facturestatic->type = $obj->type; $facturestatic->type = $obj->type;
print preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $obj->description).' '.$facturestatic->getNomURl(1); print preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $obj->description).'<br>'.$facturestatic->getNomURl(1);
print '</td>'; print '</td>';
} elseif (preg_match('/\(DEPOSIT\)/', $obj->description)) { } elseif (preg_match('/\(DEPOSIT\)/', $obj->description)) {
print '<td class="tdoverflowmax100">'; print '<td class="tdoverflowmax100">';
$facturestatic->id = $obj->fk_facture_source; $facturestatic->id = $obj->fk_facture_source;
$facturestatic->ref = $obj->invoice_source_ref; $facturestatic->ref = $obj->invoice_source_ref;
$facturestatic->type = $obj->type; $facturestatic->type = $obj->type;
print preg_replace('/\(DEPOSIT\)/', $langs->trans("InvoiceDeposit"), $obj->description).' '.$facturestatic->getNomURl(1); print preg_replace('/\(DEPOSIT\)/', $langs->trans("InvoiceDeposit"), $obj->description).'<br>'.$facturestatic->getNomURl(1);
print '</td>'; print '</td>';
} elseif (preg_match('/\(EXCESS RECEIVED\)/', $obj->description)) { } elseif (preg_match('/\(EXCESS RECEIVED\)/', $obj->description)) {
print '<td class="tdoverflowmax100">'; print '<td class="tdoverflowmax100">';
$facturestatic->id = $obj->fk_facture_source; $facturestatic->id = $obj->fk_facture_source;
$facturestatic->ref = $obj->invoice_source_ref; $facturestatic->ref = $obj->invoice_source_ref;
$facturestatic->type = $obj->type; $facturestatic->type = $obj->type;
print preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("Invoice"), $obj->description).' '.$facturestatic->getNomURl(1); print preg_replace('/\(EXCESS RECEIVED\)/', $langs->trans("Invoice"), $obj->description).'<br>'.$facturestatic->getNomURl(1);
print '</td>'; print '</td>';
} else { } else {
print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($obj->description).'">'; print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($obj->description).'">';
@@ -1404,21 +1404,21 @@ if ($socid > 0) {
$facturefournstatic->id = $obj->fk_invoice_supplier_source; $facturefournstatic->id = $obj->fk_invoice_supplier_source;
$facturefournstatic->ref = $obj->invoice_source_ref; $facturefournstatic->ref = $obj->invoice_source_ref;
$facturefournstatic->type = $obj->type; $facturefournstatic->type = $obj->type;
print preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $obj->description).' '.$facturefournstatic->getNomURl(1); print preg_replace('/\(CREDIT_NOTE\)/', $langs->trans("CreditNote"), $obj->description).'<br>'.$facturefournstatic->getNomURl(1);
print '</td>'; print '</td>';
} elseif (preg_match('/\(DEPOSIT\)/', $obj->description)) { } elseif (preg_match('/\(DEPOSIT\)/', $obj->description)) {
print '<td class="tdoverflowmax100">'; print '<td class="tdoverflowmax100">';
$facturefournstatic->id = $obj->fk_invoice_supplier_source; $facturefournstatic->id = $obj->fk_invoice_supplier_source;
$facturefournstatic->ref = $obj->invoice_source_ref; $facturefournstatic->ref = $obj->invoice_source_ref;
$facturefournstatic->type = $obj->type; $facturefournstatic->type = $obj->type;
print preg_replace('/\(DEPOSIT\)/', $langs->trans("InvoiceDeposit"), $obj->description).' '.$facturefournstatic->getNomURl(1); print preg_replace('/\(DEPOSIT\)/', $langs->trans("InvoiceDeposit"), $obj->description).'<br>'.$facturefournstatic->getNomURl(1);
print '</td>'; print '</td>';
} elseif (preg_match('/\(EXCESS PAID\)/', $obj->description)) { } elseif (preg_match('/\(EXCESS PAID\)/', $obj->description)) {
print '<td class="tdoverflowmax100">'; print '<td class="tdoverflowmax100">';
$facturefournstatic->id = $obj->fk_invoice_supplier_source; $facturefournstatic->id = $obj->fk_invoice_supplier_source;
$facturefournstatic->ref = $obj->invoice_source_ref; $facturefournstatic->ref = $obj->invoice_source_ref;
$facturefournstatic->type = $obj->type; $facturefournstatic->type = $obj->type;
print preg_replace('/\(EXCESS PAID\)/', $langs->trans("Invoice"), $obj->description).' '.$facturefournstatic->getNomURl(1); print preg_replace('/\(EXCESS PAID\)/', $langs->trans("Invoice"), $obj->description).'<br>'.$facturefournstatic->getNomURl(1);
print '</td>'; print '</td>';
} else { } else {
print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($obj->description).'">'; print '<td class="tdoverflowmax100" title="'.dol_escape_htmltag($obj->description).'">';

View File

@@ -1058,8 +1058,12 @@ if (empty($reshook)) {
$error = 0; $error = 0;
if ($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_SITUATION) {
// If we're on a standard invoice, we have to get excess received to create a discount in TTC without VAT // Create a discount that is the amount of the excess received
if ($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_SITUATION
|| $object->type == Facture::TYPE_DEPOSIT) {
// If we have an excess received that need to create a discount in TTC without VAT
$discount->description = '(EXCESS RECEIVED)';
// Total payments // Total payments
$sql = 'SELECT SUM(pf.amount) as total_paiements'; $sql = 'SELECT SUM(pf.amount) as total_paiements';
@@ -1091,17 +1095,28 @@ if (empty($reshook)) {
dol_print_error($db); dol_print_error($db);
} }
$discount->amount_ht = $discount->amount_ttc = $total_paiements + $total_creditnote_and_deposit - $object->total_ttc; $discount->amount_ttc = price2num($total_paiements + $total_creditnote_and_deposit - $object->total_ttc, 'MT');
$discount->amount_tva = 0; $discount->amount_tva = 0;
$discount->amount_ht = $discount->amount_ttc;
$discount->tva_tx = 0; $discount->tva_tx = 0;
$discount->vat_src_code = ''; $discount->vat_src_code = '';
$result = $discount->create($user); if ($discount->amount_ttc > 0) {
if ($result < 0) { $result = $discount->create($user);
$error++; if ($result < 0) {
$error++;
}
} }
} }
// Create a discount that is the amount of the invoice
if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT) { if ($object->type == Facture::TYPE_CREDIT_NOTE || $object->type == Facture::TYPE_DEPOSIT) {
if ($object->type == Facture::TYPE_CREDIT_NOTE) {
$discount->description = '(CREDIT_NOTE)';
} else {
$discount->description = '(DEPOSIT)';
}
foreach ($amount_ht as $tva_tx => $xxx) { foreach ($amount_ht as $tva_tx => $xxx) {
if ($object->type == Facture::TYPE_CREDIT_NOTE) { if ($object->type == Facture::TYPE_CREDIT_NOTE) {
$discount->amount_ht = -((float) $amount_ht[$tva_tx]); $discount->amount_ht = -((float) $amount_ht[$tva_tx]);
@@ -1152,18 +1167,14 @@ if (empty($reshook)) {
} }
if (empty($error)) { if (empty($error)) {
if ($object->type != Facture::TYPE_DEPOSIT) { // Set invoice as paid
// Set invoice as paid $result = $object->setPaid($user); // We can close the invoice. Even if we got an excess received, it is now into discounts.
$result = $object->setPaid($user); if ($result >= 0) {
if ($result >= 0) { $object->fetch($object->id); // Reload properties
$object->fetch($object->id); // Reload properties
$db->commit();
} else {
setEventMessages($object->error, $object->errors, 'errors');
$db->rollback();
}
} else {
$db->commit(); $db->commit();
} else {
setEventMessages($object->error, $object->errors, 'errors');
$db->rollback();
} }
} else { } else {
setEventMessages($discount->error, $discount->errors, 'errors'); setEventMessages($discount->error, $discount->errors, 'errors');
@@ -6734,11 +6745,11 @@ if ($action == 'create') {
) { ) {
print '<a class="butAction classfortooltip'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=converttoreduc&token='.newToken().'" title="'.dol_escape_htmltag($langs->trans("ConfirmConvertToReduc2")).'">'.$langs->trans('ConvertToReduc').'</a>'; print '<a class="butAction classfortooltip'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=converttoreduc&token='.newToken().'" title="'.dol_escape_htmltag($langs->trans("ConfirmConvertToReduc2")).'">'.$langs->trans('ConvertToReduc').'</a>';
} }
// For down payment invoice (deposit)
// For down payment invoice (deposit)
if ($object->type == Facture::TYPE_DEPOSIT && $usercancreate && $object->status > Facture::STATUS_DRAFT && empty($discount->id)) { if ($object->type == Facture::TYPE_DEPOSIT && $usercancreate && $object->status > Facture::STATUS_DRAFT && empty($discount->id)) {
// We can close a down payment only if paid amount is same than amount of down payment (by definition). We can bypass this if hidden and unstable option DEPOSIT_AS_CREDIT_AVAILABLE_EVEN_UNPAID is set. // We can close a down payment only if paid amount is same than amount of down payment (by definition). We can bypass this if hidden and unstable option DEPOSIT_AS_CREDIT_AVAILABLE_EVEN_UNPAID is set.
if (price2num($object->total_ttc, 'MT') == price2num($sumofpaymentall, 'MT') || getDolGlobalInt('DEPOSIT_AS_CREDIT_AVAILABLE_EVEN_UNPAID') || ($object->type == Facture::STATUS_ABANDONED && in_array($object->close_code, array('bankcharge', 'discount_vat', 'other')))) { if (price2num($object->total_ttc, 'MT') <= price2num($sumofpaymentall, 'MT') || getDolGlobalInt('DEPOSIT_AS_CREDIT_AVAILABLE_EVEN_UNPAID') || ($object->type == Facture::STATUS_ABANDONED && in_array($object->close_code, array('bankcharge', 'discount_vat', 'other')))) {
print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=converttoreduc&token='.newToken().'">'.$langs->trans('ConvertToReduc').'</a>'; print '<a class="butAction'.($conf->use_javascript_ajax ? ' reposition' : '').'" href="'.$_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=converttoreduc&token='.newToken().'">'.$langs->trans('ConvertToReduc').'</a>';
} else { } else {
print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("AmountPaidMustMatchAmountOfDownPayment").'">'.$langs->trans('ConvertToReduc').'</span>'; print '<span class="butActionRefused classfortooltip" title="'.$langs->trans("AmountPaidMustMatchAmountOfDownPayment").'">'.$langs->trans('ConvertToReduc').'</span>';

View File

@@ -960,7 +960,7 @@ class Tva extends CommonObject
$return .= ' | <span class="opacitymedium">'.$langs->trans("Amount").'</span> : <span class="info-box-label amount">'.price($this->amount).'</span>'; $return .= ' | <span class="opacitymedium">'.$langs->trans("Amount").'</span> : <span class="info-box-label amount">'.price($this->amount).'</span>';
} }
if (property_exists($this, 'type_payment')) { if (property_exists($this, 'type_payment')) {
$return .= '<br><span class="opacitymedium">'.$langs->trans("Payement").'</span> : <span class="info-box-label">'.$this->type_payment.'</span>'; $return .= '<br><span class="opacitymedium">'.$langs->trans("Payment").'</span> : <span class="info-box-label">'.$this->type_payment.'</span>';
} }
if (property_exists($this, 'datev')) { if (property_exists($this, 'datev')) {
$return .= '<br><span class="opacitymedium">'.$langs->trans("DateEnd").'</span> : <span class="info-box-label" >'.dol_print_date($this->datev).'</span>'; $return .= '<br><span class="opacitymedium">'.$langs->trans("DateEnd").'</span> : <span class="info-box-label" >'.dol_print_date($this->datev).'</span>';

View File

@@ -218,16 +218,6 @@ $dolibarr_main_dolcrypt_key='';
$dolibarr_main_instance_unique_id='84b5bc91f83b56e458db71e0adac2b62'; $dolibarr_main_instance_unique_id='84b5bc91f83b56e458db71e0adac2b62';
// $dolibarr_website_allow_custom_php
// ================================
// By default for security purpose, it is not possible to add or edit PHP dynamic content into a website (even if user has permission for this). To be able
// to edit PHP content in website page, you must first allow this globally by setting this parameter to 1.
// Default value: 0
// Examples:
// $dolibarr_website_allow_custom_php = 1;
//
$dolibarr_website_allow_custom_php = 0;
//################## //##################
// Login // Login
@@ -366,10 +356,9 @@ $dolibarr_main_restrict_ip='';
// //
$dolibarr_nocsrfcheck='0'; $dolibarr_nocsrfcheck='0';
// dolibarr_nocsrfcheck // dolibarr_api_count_always_enabled
// ==================== // =================================
// This parameter can be used to disable CSRF protection. // Set this value to 1 so disabling the count of each API call will not be possible from the admin setup pages.
// This might be required for debug purpose or if you access Dolibarr behind a proxy that make bad URL rewriting, to avoid false alarms.
// In most cases, you should always keep this to 0. // In most cases, you should always keep this to 0.
// Default value: 0 // Default value: 0
// Possible values: 0 or 1 (API is always enabled, can't be disabled from admin setup) // Possible values: 0 or 1 (API is always enabled, can't be disabled from admin setup)
@@ -410,19 +399,18 @@ $dolibarr_cron_allow_cli='0';
// //
// $dolibarr_main_stream_to_disable = array('compress.zlib', 'compress.bzip2', 'ftp', 'ftps', 'glob', 'data', 'expect', 'ogg', 'rar', 'zip', 'zlib'); // $dolibarr_main_stream_to_disable = array('compress.zlib', 'compress.bzip2', 'ftp', 'ftps', 'glob', 'data', 'expect', 'ogg', 'rar', 'zip', 'zlib');
// MAIN_ANTIVIRUS_COMMAND (as a constant) // $dolibarr_website_allow_custom_php
// ====================== // ==================================
// Force a value for the antivirus command line tool so setup for admin user interface has no effect. // By default for security purpose, it is not possible to add or edit PHP dynamic content into a website (even if user has permission for this). To be able
// Default value: '' // to edit PHP content in website page, you must first allow this globally, by setting this parameter to 1 or 2.
// Example: '/usr/bin/clamdscan'; // 0 will disallow use of dynamic PHP inside the website features. Only HTML and js will be possible.
// define('MAIN_ANTIVIRUS_COMMAND', '/usr/bin/clamdscan'); // 1 will allow custom PHP inside website features, but only if dangerous PHP system functions are disabled (using the PHP disable_functions parameter)
// 2 will allow custom PHP inside website features even if your PHP setup does not protect you against dangerous system calls (this may be dangerous if you don't have a RCE protection like SELnux or Apparmor).
// Default value: '0'
// Examples: '0', '1' or '2'
// $dolibarr_website_allow_custom_php='0';
// MAIN_ANTIVIRUS_PARAM (as a constant)
// ====================
// Force a value for the antivirus parameters on command line so setup for admin user interface has no effect.
// Default value: ''
// Example: '--fdpass';
// define('MAIN_ANTIVIRUS_PARAM', '--fdpass');
// php_session_save_handler // php_session_save_handler
// ======================== // ========================
@@ -446,6 +434,20 @@ $dolibarr_cron_allow_cli='0';
// $force_install_lockinstall='440'; // $force_install_lockinstall='440';
// MAIN_ANTIVIRUS_COMMAND (as a constant)
// ======================
// Force a value for the antivirus command line tool so setup for admin user interface has no effect.
// Default value: ''
// Example: '/usr/bin/clamdscan';
// define('MAIN_ANTIVIRUS_COMMAND', '/usr/bin/clamdscan');
// MAIN_ANTIVIRUS_PARAM (as a constant)
// ====================
// Force a value for the antivirus parameters on command line so setup for admin user interface has no effect.
// Default value: ''
// Example: '--fdpass';
// define('MAIN_ANTIVIRUS_PARAM', '--fdpass');
//################## //##################
// Other // Other

View File

@@ -7,7 +7,7 @@
* Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com> * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2019-2025 Frédéric France <frederic.france@free.fr> * Copyright (C) 2019-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2025 Joachim Kueter <git-jk@bloxera.com> * Copyright (C) 2025 Joachim Kueter <git-jk@bloxera.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@@ -334,7 +334,7 @@ class CMailFile
// TODO Exclude viewimage used for the read tracker ? // TODO Exclude viewimage used for the read tracker ?
$dolibarr_main_data_root_images = $dolibarr_main_data_root; $dolibarr_main_data_root_images = $dolibarr_main_data_root;
if ((int) $conf->entity !== 1) { if ((int) $conf->entity !== 1) {
$dolibarr_main_data_root_images.='/'.$conf->entity.'/'; $dolibarr_main_data_root_images .= '/'.$conf->entity.'/';
} }
$findimg = $this->findHtmlImages($dolibarr_main_data_root_images.'/medias'); $findimg = $this->findHtmlImages($dolibarr_main_data_root_images.'/medias');
if ($findimg < 0) { if ($findimg < 0) {
@@ -2284,7 +2284,7 @@ class CMailFile
$arrayaddress = (!empty($address) ? explode(',', $address) : array()); $arrayaddress = (!empty($address) ? explode(',', $address) : array());
// Boucle sur chaque composant de l'address // Loop over every component of the address
$i = 0; $i = 0;
foreach ($arrayaddress as $val) { foreach ($arrayaddress as $val) {
$regs = array(); $regs = array();
@@ -2352,7 +2352,7 @@ class CMailFile
$arrayaddress = explode(',', $address); $arrayaddress = explode(',', $address);
// Boucle sur chaque composant de l'address // Loop over every component of the address
foreach ($arrayaddress as $val) { foreach ($arrayaddress as $val) {
$regs = array(); $regs = array();
if (preg_match('/^(.*)<(.*)>$/i', trim($val), $regs)) { if (preg_match('/^(.*)<(.*)>$/i', trim($val), $regs)) {

View File

@@ -560,7 +560,7 @@ abstract class CommonDocGenerator
public function get_substitutionarray_contact($object, $outputlangs, $array_key = 'object') public function get_substitutionarray_contact($object, $outputlangs, $array_key = 'object')
{ {
// phpcs:enable // phpcs:enable
global $conf, $extrafields; global $extrafields;
if (empty($object->country) && !empty($object->country_code)) { if (empty($object->country) && !empty($object->country_code)) {
$object->country = $outputlangs->transnoentitiesnoconv("Country".$object->country_code); $object->country = $outputlangs->transnoentitiesnoconv("Country".$object->country_code);
@@ -585,13 +585,14 @@ abstract class CommonDocGenerator
$array_key.'_country' => $object->country, $array_key.'_country' => $object->country,
$array_key.'_poste' => $object->poste, $array_key.'_poste' => $object->poste,
$array_key.'_socid' => $object->socid, $array_key.'_socid' => $object->socid,
$array_key.'_statut' => $object->statut, $array_key.'_statut' => $object->statut ? $object->statut : $object->status,
$array_key.'_code' => $object->code, $array_key.'_code' => $object->code,
$array_key.'_email' => $object->email, $array_key.'_email' => $object->email,
$array_key.'_phone_pro' => $object->phone_pro, $array_key.'_phone_pro' => $object->phone_pro,
$array_key.'_phone_perso' => $object->phone_perso, $array_key.'_phone_perso' => $object->phone_perso,
$array_key.'_phone_mobile' => $object->phone_mobile, $array_key.'_phone_mobile' => $object->phone_mobile,
$array_key.'_fax' => $object->fax, $array_key.'_fax' => $object->fax,
$array_key.'_birthday_locale' => (!empty($object->birthday) ? dol_print_date($object->birthday, 'day', false, $outputlangs) : ''),
$array_key.'_birthday' => $object->birthday, $array_key.'_birthday' => $object->birthday,
$array_key.'_default_lang' => $object->default_lang, $array_key.'_default_lang' => $object->default_lang,
$array_key.'_note_public' => $object->note_public, $array_key.'_note_public' => $object->note_public,

View File

@@ -11722,4 +11722,29 @@ abstract class CommonObject
return true; return true;
} }
} }
/**
* Set the error message for the object without logging it.
*
* @param string $message the error message
* @return void
*/
public function setErrorWithoutLog($message)
{
$this->error = $message;
$this->errors[] = $message;
}
/**
* Set the error message for the object and log it.
*
* @param string $message the error message
* @param int<0,7> $loglevel the log level
* @return void
*/
public function setErrorWithLog($message, $loglevel = LOG_ERR)
{
$this->setErrorWithoutLog($message);
dol_syslog($message, $loglevel);
}
} }

View File

@@ -23,7 +23,7 @@
* Copyright (C) 2018 Josep Lluis Amador <joseplluis@lliuretic.cat> * Copyright (C) 2018 Josep Lluis Amador <joseplluis@lliuretic.cat>
* Copyright (C) 2023 Joachim Kueter <git-jk@bloxera.com> * Copyright (C) 2023 Joachim Kueter <git-jk@bloxera.com>
* Copyright (C) 2023 Nick Fragoulis * Copyright (C) 2023 Nick Fragoulis
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr> * Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr>
* Copyright (C) 2026 Lenin Rivas <lenin.rivas777@gmail.com> * Copyright (C) 2026 Lenin Rivas <lenin.rivas777@gmail.com>
* *
@@ -1387,7 +1387,7 @@ class Form
* *
* @param int|string $selected Preselected ID * @param int|string $selected Preselected ID
* @param string $htmlname Name of field in form * @param string $htmlname Name of field in form
* @param string $filter Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here. Example: ((s.client:IN:1,3) AND (s.status:=:1)). Do not use a filter coming from input of users. * @param string $filter Optional filter criteria. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here. Example: ((s.client:IN:1,3) AND (s.status:=:1)). Do not use a filter coming from input of users.
* @param string|int<1,1> $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty') * @param string|int<1,1> $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty')
* @param int<0,1> $showtype Show third party type in combolist (customer, prospect or supplier) * @param int<0,1> $showtype Show third party type in combolist (customer, prospect or supplier)
* @param int<0,1> $forcecombo Force to load all values and output a standard combobox (with no beautification) * @param int<0,1> $forcecombo Force to load all values and output a standard combobox (with no beautification)
@@ -1482,7 +1482,7 @@ class Form
* @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container
* @param string $htmlid Html id to use instead of htmlname * @param string $htmlid Html id to use instead of htmlname
* @param string $selected_input_value Value of preselected input text (for use with ajax) * @param string $selected_input_value Value of preselected input text (for use with ajax)
* @param string $filter Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here. Example: ((s.client:IN:1,3) AND (s.status:=:1)). Do not use a filter coming from input of users. * @param string $filter Optional filter criteria. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here. Example: ((s.client:IN:1,3) AND (s.status:=:1)). Do not use a filter coming from input of users.
* @return int|string Return integer <0 if KO, HTML with select string if OK. * @return int|string Return integer <0 if KO, HTML with select string if OK.
*/ */
public function select_contact($socid, $selected = '', $htmlname = 'contactid', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $morecss = '', $nokeyifsocid = true, $showsoc = 0, $forcecombo = 0, $events = array(), $moreparam = '', $htmlid = '', $selected_input_value = '', $filter = '') public function select_contact($socid, $selected = '', $htmlname = 'contactid', $showempty = 0, $exclude = '', $limitto = '', $showfunction = 0, $morecss = '', $nokeyifsocid = true, $showsoc = 0, $forcecombo = 0, $events = array(), $moreparam = '', $htmlid = '', $selected_input_value = '', $filter = '')
@@ -1552,7 +1552,7 @@ class Form
* *
* @param string $selected Preselected type * @param string $selected Preselected type
* @param string $htmlname Name of field in form * @param string $htmlname Name of field in form
* @param string $filter Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>] are allowed here, example: 's.rowid <> x' * @param string $filter Optional filter criteria. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>] are allowed here, example: 's.rowid <> x'
* If you need parenthesis, use the Universal Filter Syntax, example: '(s.client:in:1,3)' * If you need parenthesis, use the Universal Filter Syntax, example: '(s.client:in:1,3)'
* Do not use a filter coming from input of users. * Do not use a filter coming from input of users.
* @param string|int<0,1> $showempty Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty') * @param string|int<0,1> $showempty Add an empty field (Can be '1' or text to use on empty line like 'SelectThirdParty')
@@ -1823,7 +1823,7 @@ class Form
* @param string $htmlid Html id to use instead of htmlname * @param string $htmlid Html id to use instead of htmlname
* @param bool $multiple add [] in the name of element and add 'multiple' attribute * @param bool $multiple add [] in the name of element and add 'multiple' attribute
* @param integer $disableifempty Set tag 'disabled' on select if there is no choice * @param integer $disableifempty Set tag 'disabled' on select if there is no choice
* @param string $filter Optional filters criteras. You must use the USF (Universal Search Filter) syntax, example: '(s.client:in:1,3)' * @param string $filter Optional filter criteria. You must use the USF (Universal Search Filter) syntax, example: '(s.client:in:1,3)'
* Do not use a filter coming from input of users. * Do not use a filter coming from input of users.
* @return int|string|array<int,array{key:int,value:string,label:string,labelhtml:string}> Return integer <0 if KO, HTML with select string if OK. * @return int|string|array<int,array{key:int,value:string,label:string,labelhtml:string}> Return integer <0 if KO, HTML with select string if OK.
*/ */
@@ -2094,7 +2094,7 @@ class Form
* *
* @param string $selected Id Fixed reduction preselected * @param string $selected Id Fixed reduction preselected
* @param string $htmlname Name of the form field * @param string $htmlname Name of the form field
* @param string $filter Optional filter critreria * @param string $filter Optional filter criteria
* @param int $socid Id of thirdparty * @param int $socid Id of thirdparty
* @param int $maxvalue Max value for lines that can be selected * @param int $maxvalue Max value for lines that can be selected
* @return int Return number of qualifed lines in list * @return int Return number of qualifed lines in list
@@ -4464,7 +4464,7 @@ class Form
* *
* @param int $productid Id of product * @param int $productid Id of product
* @param string $htmlname Name of HTML field * @param string $htmlname Name of HTML field
* @param int $selected_supplier Pre-selected supplier if more than 1 result * @param int $selected_supplier Preselected supplier if more than 1 result
* @return string * @return string
*/ */
public function select_product_fourn_price($productid, $htmlname = 'productfournpriceid', $selected_supplier = 0) public function select_product_fourn_price($productid, $htmlname = 'productfournpriceid', $selected_supplier = 0)
@@ -4706,8 +4706,8 @@ class Form
/** /**
* Return the list of type of delay available. * Return the list of type of delay available.
* *
* @param ''|int $selected Id du type de delais pre-selectionne * @param ''|int $selected Id for preselected delay typ
* @param string $htmlname Nom de la zone select * @param string $htmlname Name for the selected zone
* @param string|int<0,1> $filtertype To add a filter * @param string|int<0,1> $filtertype To add a filter
* @param int<0,1> $addempty Add empty entry * @param int<0,1> $addempty Add empty entry
* @param string $morecss More CSS * @param string $morecss More CSS
@@ -5180,8 +5180,8 @@ class Form
/** /**
* Selection HT or TTC * Selection HT or TTC
* *
* @param string $selected Id pre-selectionne * @param string $selected Preselected Id
* @param string $htmlname Nom de la zone select * @param string $htmlname Name of the selected zone
* @param int $addjscombo Add js combo * @param int $addjscombo Add js combo
* @return string Code of HTML select to chose tax or not * @return string Code of HTML select to chose tax or not
*/ */
@@ -5627,7 +5627,7 @@ class Form
} }
if (!empty($addentrynone)) { if (!empty($addentrynone)) {
$out .= '<option value="-2"'.($selected == -2 ? ' selected="selected"': '').' data-html="'.dolPrintHTMLForAttribute('<span class="opacitymedium">'.$langs->trans("None").'</span>').'">'.$langs->trans("None").'</option>'; $out .= '<option value="-2"'.($selected == -2 ? ' selected="selected"' : '').' data-html="'.dolPrintHTMLForAttribute('<span class="opacitymedium">'.$langs->trans("None").'</span>').'">'.$langs->trans("None").'</option>';
} }
$out .= "</select>"; $out .= "</select>";
@@ -6627,7 +6627,7 @@ class Form
* Form select for rule for lines dates * Form select for rule for lines dates
* *
* @param string $page Page * @param string $page Page
* @param string $selected Id condition pre-selectionne * @param string $selected Preselected Id
* @param string $htmlname Name of select html field * @param string $htmlname Name of select html field
* @param int $addempty Add empty entry * @param int $addempty Add empty entry
* @param int $nooutput No print is done. String is returned. * @param int $nooutput No print is done. String is returned.
@@ -6673,7 +6673,7 @@ class Form
* Show a form to select a delivery delay * Show a form to select a delivery delay
* *
* @param string $page Page * @param string $page Page
* @param string $selected Id condition pre-selectionne * @param string $selected Preselected I for condition
* @param string $htmlname Name of select html field * @param string $htmlname Name of select html field
* @param int<0,1> $addempty Add an empty entry * @param int<0,1> $addempty Add an empty entry
* @return void * @return void
@@ -6705,7 +6705,7 @@ class Form
* List found into table c_input_reason loaded by loadCacheInputReason * List found into table c_input_reason loaded by loadCacheInputReason
* *
* @param string $page Page * @param string $page Page
* @param string $selected Id condition pre-selectionne * @param string $selected Preselected Id for condition
* @param string $htmlname Name of select html field * @param string $htmlname Name of select html field
* @param int $addempty Add empty entry * @param int $addempty Add empty entry
* @param string $morecss More CSS * @param string $morecss More CSS
@@ -6829,7 +6829,7 @@ class Form
* Show form with payment mode * Show form with payment mode
* *
* @param string $page Page * @param string $page Page
* @param string $selected Id mode pre-selectionne * @param string $selected Preselected Id for mode
* @param string $htmlname Name of select html field * @param string $htmlname Name of select html field
* @param string $filtertype To filter on field type in llx_c_paiement ('CRDT' or 'DBIT' or array('code'=>xx,'label'=>zz)) * @param string $filtertype To filter on field type in llx_c_paiement ('CRDT' or 'DBIT' or array('code'=>xx,'label'=>zz))
* @param int<-1,1> $active Active or not, -1 = all * @param int<-1,1> $active Active or not, -1 = all
@@ -6875,7 +6875,7 @@ class Form
* Show form with transport mode * Show form with transport mode
* *
* @param string $page Page * @param string $page Page
* @param int|'' $selected Id mode pre-select * @param int|'' $selected Id mode preselect
* @param string $htmlname Name of select html field * @param string $htmlname Name of select html field
* @param int<-1,1> $active Active or not, -1 = all * @param int<-1,1> $active Active or not, -1 = all
* @param int<0,1> $addempty 1=Add empty entry * @param int<0,1> $addempty 1=Add empty entry
@@ -6907,7 +6907,7 @@ class Form
* Show form with multicurrency code * Show form with multicurrency code
* *
* @param string $page Page * @param string $page Page
* @param string $selected code pre-selectionne * @param string $selected Preselected code
* @param string $htmlname Name of select html field * @param string $htmlname Name of select html field
* @return void * @return void
*/ */
@@ -7088,7 +7088,7 @@ class Form
* *
* @param string $page Page * @param string $page Page
* @param Societe $societe Filter on third party * @param Societe $societe Filter on third party
* @param string $selected Id contact pre-selectionne * @param string $selected Preselected contact Id
* @param string $htmlname Name of HTML select. If 'none', we just show contact link. * @param string $htmlname Name of HTML select. If 'none', we just show contact link.
* @return void * @return void
*/ */
@@ -7132,7 +7132,7 @@ class Form
* @param string $page Page * @param string $page Page
* @param string $selected Id preselected * @param string $selected Id preselected
* @param string $htmlname Name of HTML select * @param string $htmlname Name of HTML select
* @param string $filter Optional filters criteras. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here (example: 's.rowid <> x', 's.client IN (1,3)'). Do not use a filter coming from input of users. * @param string $filter Optional filter criteria. WARNING: To avoid SQL injection, only few chars [.a-z0-9 =<>()] are allowed here (example: 's.rowid <> x', 's.client IN (1,3)'). Do not use a filter coming from input of users.
* @param string|int<0,1> $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty') * @param string|int<0,1> $showempty Add an empty field (Can be '1' or text key to use on empty line like 'SelectThirdParty')
* @param int<0,1> $showtype Show third party type in combolist (customer, prospect or supplier) * @param int<0,1> $showtype Show third party type in combolist (customer, prospect or supplier)
* @param int<0,1> $forcecombo Force to use combo box * @param int<0,1> $forcecombo Force to use combo box
@@ -7254,7 +7254,7 @@ class Form
* @param string $selected Preselected currency code * @param string $selected Preselected currency code
* @param string $htmlname Name of HTML select list * @param string $htmlname Name of HTML select list
* @param integer $useempty 1=Add empty line * @param integer $useempty 1=Add empty line
* @param string $filter Optional filters criteras (example: 'code <> x', ' in (1,3)'). Do not use external string here. * @param string $filter Optional filter criteria (example: 'code <> x', ' in (1,3)'). Do not use external string here.
* @param bool $excludeConfCurrency false = If company current currency not in table, we add it into list. Should always be available. * @param bool $excludeConfCurrency false = If company current currency not in table, we add it into list. Should always be available.
* true = we are in currency_rate update , we don't want to see conf->currency in select * true = we are in currency_rate update , we don't want to see conf->currency in select
* @param string $morecss More css * @param string $morecss More css
@@ -7537,7 +7537,7 @@ class Form
$num = count($arrayofvatrates); $num = count($arrayofvatrates);
if ($num > 0) { if ($num > 0) {
// Define the vat rate to pre-select (if defaulttx not forced so is -1 or '') // Define the vat rate to preselect (if defaulttx not forced so is -1 or '')
if ($defaulttx < 0 || dol_strlen($defaulttx) == 0) { if ($defaulttx < 0 || dol_strlen($defaulttx) == 0) {
// Define a default thirdparty to use if the seller or buyer is not defined // Define a default thirdparty to use if the seller or buyer is not defined
$tmpthirdparty = new Societe($this->db); $tmpthirdparty = new Societe($this->db);
@@ -7659,7 +7659,7 @@ class Form
* - local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location) * - local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location)
* - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1) * - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1)
* *
* @param integer|string $set_time Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2). * @param integer|string $set_time Preselected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2).
* @param string $prefix Prefix for fields name * @param string $prefix Prefix for fields name
* @param int $h 1 or 2=Show also hours (2=hours on a new line), -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show hour always empty * @param int $h 1 or 2=Show also hours (2=hours on a new line), -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show hour always empty
* @param int $m 1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty * @param int $m 1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty
@@ -7696,8 +7696,8 @@ class Form
* - local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location) * - local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location)
* - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1) * - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1)
* *
* @param int|'' $set_time Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2). * @param int|'' $set_time Preselected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2).
* @param integer|string $set_time_end Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2). * @param integer|string $set_time_end Preselected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2).
* @param string $prefix Prefix for fields name * @param string $prefix Prefix for fields name
* @param int<0,2> $empty 0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only * @param int<0,2> $empty 0=Fields required, 1=Empty inputs are allowed, 2=Empty inputs are allowed for hours only
* @param int $forcenewline Force new line between the 2 dates. * @param int $forcenewline Force new line between the 2 dates.
@@ -7723,7 +7723,7 @@ class Form
* - local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location) * - local date in user area, if set_time is '' (so if set_time is '', output may differs when done from two different location)
* - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1) * - Empty (fields empty), if set_time is -1 (in this case, parameter empty must also have value 1)
* *
* @param int|'' $set_time Pre-selected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2). Using a "string date" is deprecated and excluded from the param type. * @param int|'' $set_time Preselected date (must be a local PHP server timestamp), -1 to keep date not preselected, '' to use current date with 00:00 hour (Parameter 'empty' must be 0 or 2). Using a "string date" is deprecated and excluded from the param type.
* @param string $prefix Prefix for fields name * @param string $prefix Prefix for fields name
* @param int $h 1 or 2=Show also hours (2=hours on a new line), -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 or 4 (4=hours on a new line)=Show hour always empty * @param int $h 1 or 2=Show also hours (2=hours on a new line), -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 or 4 (4=hours on a new line)=Show hour always empty
* @param int $m 1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty * @param int $m 1=Show also minutes, -1 has same effect but hour and minutes are prefilled with 23:59 if date is empty, 3 show minutes always empty
@@ -7787,7 +7787,7 @@ class Form
} }
} }
// Analysis of the pre-selection date // Analysis of the preselected date
$reg = array(); $reg = array();
$shour = ''; $shour = '';
$smin = ''; $smin = '';
@@ -10763,7 +10763,7 @@ class Form
* Return an html string with a select combo box to choose yes or no * Return an html string with a select combo box to choose yes or no
* *
* @param string $htmlname Name of html select field * @param string $htmlname Name of html select field
* @param string|int<min,1> $value Pre-selected value * @param string|int<min,1> $value Preselected value
* @param int<0,1> $option 0 return yes/no, 1 return 1/0 * @param int<0,1> $option 0 return yes/no, 1 return 1/0
* @param bool|int<0,1> $disabled true or false * @param bool|int<0,1> $disabled true or false
* @param int<0,1> $useempty 1=Add empty line * @param int<0,1> $useempty 1=Add empty line

View File

@@ -4,7 +4,7 @@
* Copyright (C) 2015 Ari Elbaz (elarifr) <github@accedinfo.com> * Copyright (C) 2015 Ari Elbaz (elarifr) <github@accedinfo.com>
* Copyright (C) 2016 Marcos García <marcosgdf@gmail.com> * Copyright (C) 2016 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2016-2025 Alexandre Spangaro <alexandre@inovea-conseil.com> * Copyright (C) 2016-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr> * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@@ -624,7 +624,7 @@ class FormAccounting extends Form
* @param string $htmlname Name of HTML select object * @param string $htmlname Name of HTML select object
* @param int $option option (0: aggregate by general account or 1: aggregate by subaccount) * @param int $option option (0: aggregate by general account or 1: aggregate by subaccount)
* @param int $useempty Show empty value in list * @param int $useempty Show empty value in list
* @param string $filter optional filters criteria * @param string $filter Optional filter criteria
* @param int $nooutput No print output. Return it only. * @param int $nooutput No print output. Return it only.
* @return void|string * @return void|string
*/ */

View File

@@ -3,7 +3,7 @@
* Copyright (C) 2010-2012 Regis Houssin <regis.houssin@inodbox.com> * Copyright (C) 2010-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2010-2018 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2010-2018 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr> * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -396,7 +396,7 @@ class FormActions
/** /**
* Output html select list of type of event * Output html select list of type of event
* *
* @param string[]|string $selected Type pre-selected (can be 'manual', 'auto' or 'AC_xxx'). Can be an array too. * @param string[]|string $selected Type preselected (can be 'manual', 'auto' or 'AC_xxx'). Can be an array too.
* @param string $htmlname Name of select field * @param string $htmlname Name of select field
* @param string $excludetype A type to exclude ('systemauto', 'system', '') * @param string $excludetype A type to exclude ('systemauto', 'system', '')
* @param int<-2,1> $onlyautoornot 1=Group all type AC_XXX into 1 line AC_MANUAL. 0=Keep details of type, -1=Keep details and add a combined line "All manual", -2=Combined line is disabled (not implemented yet) * @param int<-2,1> $onlyautoornot 1=Group all type AC_XXX into 1 line AC_MANUAL. 0=Keep details of type, -1=Keep details and add a combined line "All manual", -2=Combined line is disabled (not implemented yet)

View File

@@ -3,7 +3,7 @@
* Copyright (C) 2005-2011 Regis Houssin <regis.houssin@inodbox.com> * Copyright (C) 2005-2011 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2007 Patrick Raguin <patrick.raguin@gmail.com> * Copyright (C) 2007 Patrick Raguin <patrick.raguin@gmail.com>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr> * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -56,7 +56,7 @@ class FormAdmin
/** /**
* Return html select list with available languages (key='en_US', value='United States' for example) * Return html select list with available languages (key='en_US', value='United States' for example)
* *
* @param string|string[] $selected Language pre-selected. Can be an array if $multiselect is 1. * @param string|string[] $selected Language preselected. Can be an array if $multiselect is 1.
* @param string $htmlname Name of HTML select * @param string $htmlname Name of HTML select
* @param int<0,1> $showauto Show 'auto' choice * @param int<0,1> $showauto Show 'auto' choice
* @param string[] $filter Array of keys to exclude in list (opposite of $onlykeys) * @param string[] $filter Array of keys to exclude in list (opposite of $onlykeys)
@@ -86,7 +86,7 @@ class FormAdmin
$langs_available = $langs->get_available_languages(DOL_DOCUMENT_ROOT, 12, 0, $mainlangonly); $langs_available = $langs->get_available_languages(DOL_DOCUMENT_ROOT, 12, 0, $mainlangonly);
// If empty value is not allowed and the language to select is not inside the list of available language and we must find // If empty value is not allowed and the language to select is not inside the list of available language and we must find
// an alternative of the language code to pre-select (to avoid to have first element in list pre-selected). // an alternative of the language code to preselect (to avoid to have first element in list preselected).
if ($selected && empty($showempty)) { if ($selected && empty($showempty)) {
if (!is_array($selected) && !array_key_exists($selected, $langs_available)) { if (!is_array($selected) && !array_key_exists($selected, $langs_available)) {
$tmparray = explode('_', $selected); $tmparray = explode('_', $selected);
@@ -303,7 +303,7 @@ class FormAdmin
/** /**
* Return combo list of available menu families * Return combo list of available menu families
* *
* @param string $selected Menu pre-selected * @param string $selected Menu preselected
* @param string $htmlname Name of html select * @param string $htmlname Name of html select
* @param string[] $dirmenuarray Directories to scan * @param string[] $dirmenuarray Directories to scan
* @return void * @return void
@@ -381,8 +381,8 @@ class FormAdmin
/** /**
* Return a HTML select list of timezones * Return a HTML select list of timezones
* *
* @param string $selected Menu pre-selectionnee * @param string $selected Preselected Menu
* @param string $htmlname Nom de la zone select * @param string $htmlname Name of the selected zone
* @return void * @return void
*/ */
public function select_timezone($selected, $htmlname) public function select_timezone($selected, $htmlname)
@@ -434,7 +434,7 @@ class FormAdmin
/** /**
* Return html select list with available languages (key='en_US', value='United States' for example) * Return html select list with available languages (key='en_US', value='United States' for example)
* *
* @param string $selected Paper format pre-selected * @param string $selected Paper format preselected
* @param string $htmlname Name of HTML select field * @param string $htmlname Name of HTML select field
* @param string $filter Value to filter on code * @param string $filter Value to filter on code
* @param int $showempty Add empty value * @param int $showempty Add empty value

View File

@@ -2,7 +2,7 @@
/* Copyright (C) 2007-2012 Regis Houssin <regis.houssin@inodbox.com> /* Copyright (C) 2007-2012 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2008-2012 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2008-2012 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr> * Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
/** /**
* \file htdocs/core/class/html.formbarcode.class.php * \file htdocs/core/class/html.formbarcode.class.php
* \brief Fichier de la class des functions predefinie de composants html * \brief File for class to manage barcode HTML
*/ */
@@ -55,7 +55,7 @@ class FormBarCode
/** /**
* Return HTML select with list of bar code generators * Return HTML select with list of bar code generators
* *
* @param int $selected Id code pre-selected * @param int $selected Id code preselected
* @param array<string,string> $barcodelist Array of barcodes generators * @param array<string,string> $barcodelist Array of barcodes generators
* @param int $code_id Id du code barre * @param int $code_id Id du code barre
* @param string $idForm Id of html form, ex id="idform" * @param string $idForm Id of html form, ex id="idform"
@@ -113,7 +113,7 @@ class FormBarCode
/** /**
* Print form to select type of barcode * Print form to select type of barcode
* *
* @param int $selected Id code pre-selected * @param int $selected Id code preselected
* @param string $htmlname Name of HTML select field * @param string $htmlname Name of HTML select field
* @param int $useempty Display empty value in list * @param int $useempty Display empty value in list
* @return void * @return void
@@ -128,7 +128,7 @@ class FormBarCode
/** /**
* Return html form to select type of barcode * Return html form to select type of barcode
* *
* @param int $selected Id code pre-selected * @param int $selected Id code preselected
* @param string $htmlname Name of HTML select field * @param string $htmlname Name of HTML select field
* @param int $useempty Display empty value in select * @param int $useempty Display empty value in select
* @return string * @return string

View File

@@ -1,7 +1,7 @@
<?php <?php
/* Copyright (C) 2020 Tobias Sekan <tobias.sekan@startmail.com> /* Copyright (C) 2020 Tobias Sekan <tobias.sekan@startmail.com>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr> * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -36,7 +36,7 @@ class FormCategory extends Form
* Return a HTML filter box for a list filter view * Return a HTML filter box for a list filter view
* *
* @param string $type The categorie type (e.g Categorie::TYPE_WAREHOUSE) * @param string $type The categorie type (e.g Categorie::TYPE_WAREHOUSE)
* @param array<int|string> $preSelected A list with the elements that should pre-selected * @param array<int|string> $preSelected A list with the elements that should preselected
* @param string $morecss More CSS * @param string $morecss More CSS
* @param int<-1,1> $searchCategoryProductOperator Used only if $multiselect is 1. Set to 0 or 1 to enable the checkbox to search with a or (0=not preselected, 1=preselected), -1=Checkbox never shown. * @param int<-1,1> $searchCategoryProductOperator Used only if $multiselect is 1. Set to 0 or 1 to enable the checkbox to search with a or (0=not preselected, 1=preselected), -1=Checkbox never shown.
* @param int<0,1> $multiselect 0 or 1 * @param int<0,1> $multiselect 0 or 1
@@ -108,7 +108,7 @@ class FormCategory extends Form
* Prints a select form for products categories * Prints a select form for products categories
* TODO Remove this. We should already have a generic method to get list of product category. * TODO Remove this. We should already have a generic method to get list of product category.
* *
* @param int $selected Id category pre-selection * @param int $selected Id category preselection
* @param string $htmlname Name of HTML field * @param string $htmlname Name of HTML field
* @param int $showempty Add an empty field * @param int $showempty Add an empty field
* @return int|null * @return int|null

View File

@@ -5,7 +5,7 @@
* Copyright (C) 2017 Rui Strecht <rui.strecht@aliartalentos.com> * Copyright (C) 2017 Rui Strecht <rui.strecht@aliartalentos.com>
* Copyright (C) 2020 Open-Dsi <support@open-dsi.fr> * Copyright (C) 2020 Open-Dsi <support@open-dsi.fr>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr> * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -642,7 +642,7 @@ class FormCompany extends Form
* *
* @param object $object Object we try to find contacts * @param object $object Object we try to find contacts
* @param string $var_id Name of id field * @param string $var_id Name of id field
* @param int $selected Pre-selected third party * @param int $selected Preselected third party
* @param string $htmlname Name of HTML form * @param string $htmlname Name of HTML form
* @param int[] $limitto Disable answers that are not id in this array list * @param int[] $limitto Disable answers that are not id in this array list
* @param int $forceid This is to force another object id than object->id * @param int $forceid This is to force another object id than object->id
@@ -1129,7 +1129,7 @@ class FormCompany extends Form
* @param string $page Page * @param string $page Page
* @param string $selected Id preselected * @param string $selected Id preselected
* @param string $htmlname Name of HTML select * @param string $htmlname Name of HTML select
* @param string $filter optional filters criteras * @param string $filter Optional filter criteria
* @param int<0,1> $nooutput No print output. Return it only. * @param int<0,1> $nooutput No print output. Return it only.
* @return void|string * @return void|string
* @phpstan-return ($nooutput is 1 ? string : void) * @phpstan-return ($nooutput is 1 ? string : void)

View File

@@ -1,7 +1,7 @@
<?php <?php
/* /*
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro> * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2025-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -20,7 +20,7 @@
/** /**
* \file htdocs/core/class/html.formcron.class.php * \file htdocs/core/class/html.formcron.class.php
* \brief Fichier de la class des functions predefinie de composants html cron * \brief File for class to manage the building of cron form components
*/ */

View File

@@ -1,6 +1,6 @@
<?php <?php
/* Copyright (c) 2015-2019 Laurent Destailleur <eldy@users.sourceforge.net> /* Copyright (c) 2015-2019 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 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 * This program is free software; you can redistribute it and/or modify
@@ -20,12 +20,12 @@
/** /**
* \file htdocs/core/class/html.formmargin.class.php * \file htdocs/core/class/html.formmargin.class.php
* \ingroup core * \ingroup core
* \brief Fichier de la class des functions predefinie de composants html autre * \brief File of the class to manage "other" html components
*/ */
/** /**
* Class permettant la generation de composants html autre * Class to manage "other" html components
* Only common components are here. * Only common components are here.
*/ */
class FormMargin class FormMargin

View File

@@ -11,7 +11,7 @@
* Copyright (C) 2007 Patrick Raguin <patrick.raguin@gmail.com> * Copyright (C) 2007 Patrick Raguin <patrick.raguin@gmail.com>
* Copyright (C) 2019 Thibault FOUCART <support@ptibogxiv.net> * Copyright (C) 2019 Thibault FOUCART <support@ptibogxiv.net>
* Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr> * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -30,12 +30,12 @@
/** /**
* \file htdocs/core/class/html.formother.class.php * \file htdocs/core/class/html.formother.class.php
* \ingroup core * \ingroup core
* \brief Fichier de la class des functions predefinie de composants html autre * \brief File for the class of other predefined html components
*/ */
/** /**
* Class permettant la generation de composants html autre * Class to help generate other html components
* Only common components are here. * Only common components are here.
*/ */
class FormOther class FormOther
@@ -140,9 +140,9 @@ class FormOther
/** /**
* Return HTML select list of export models * Return HTML select list of export models
* *
* @param string $selected Id modele pre-selectionne * @param string $selected Id of the preselected model
* @param string $htmlname Nom de la zone select * @param string $htmlname Name of the selected zone
* @param string $type Type des modeles recherches * @param string $type Type of the desired models
* @param int $useempty Show an empty value in list * @param int $useempty Show an empty value in list
* @param int $fk_user User we want templates * @param int $fk_user User we want templates
* @return void * @return void
@@ -202,9 +202,9 @@ class FormOther
/** /**
* Return list of export models * Return list of export models
* *
* @param string $selected Id modele pre-selectionne * @param string $selected Id of the preselected model
* @param string $htmlname Nom de la zone select * @param string $htmlname Name of the selected zone
* @param string $type Type des modeles recherches * @param string $type Type of the desired models
* @param int $useempty Show an empty value in list * @param int $useempty Show an empty value in list
* @param int $fk_user User that has created the template * @param int $fk_user User that has created the template
* @return void * @return void
@@ -364,7 +364,7 @@ class FormOther
/** /**
* Return a HTML select list to select a percent * Return a HTML select list to select a percent
* *
* @param integer $selected Percentage pre-selectionne * @param int $selected Preselected percentage
* @param string $htmlname Name of HTML combo list * @param string $htmlname Name of HTML combo list
* @param int $disabled Disabled or not * @param int $disabled Disabled or not
* @param int $increment Increment value * @param int $increment Increment value
@@ -655,7 +655,7 @@ class FormOther
/** /**
* Return list of project and tasks * Return list of project and tasks
* *
* @param int $selectedtask Pre-selected task * @param int $selectedtask Preselected task
* @param int $projectid Project id * @param int $projectid Project id
* @param string $htmlname Name of html select * @param string $htmlname Name of html select
* @param int $modeproject 1 to restrict on projects owned by user * @param int $modeproject 1 to restrict on projects owned by user
@@ -830,7 +830,7 @@ class FormOther
/** /**
* Output a HTML code to select a color * Output a HTML code to select a color
* *
* @param string $set_color Pre-selected color * @param string $set_color Preselected color
* @param string $prefix Name of HTML field * @param string $prefix Name of HTML field
* @param string $form_name Deprecated. Not used. * @param string $form_name Deprecated. Not used.
* @param int $showcolorbox 1=Show color code and color box, 0=Show only color code * @param int $showcolorbox 1=Show color code and color box, 0=Show only color code
@@ -848,7 +848,7 @@ class FormOther
/** /**
* Output a HTML code to select a color. Field will return an hexa color like '334455'. * Output a HTML code to select a color. Field will return an hexa color like '334455'.
* *
* @param string $set_color Pre-selected color with format '#......' * @param string $set_color Preselected color with format '#......'
* @param string $prefix Name of HTML field * @param string $prefix Name of HTML field
* @param null|'' $form_name Deprecated. Not used. * @param null|'' $form_name Deprecated. Not used.
* @param int $showcolorbox 1=Show color code and color box, 0=Show only color code * @param int $showcolorbox 1=Show color code and color box, 0=Show only color code
@@ -1553,7 +1553,7 @@ class FormOther
* Return an html string with a select combo box to choose yes or no * Return an html string with a select combo box to choose yes or no
* *
* @param string $htmlname Name of html select field * @param string $htmlname Name of html select field
* @param string $value Pre-selected value * @param string $value Preselected value
* @param int $option 0 return automatic/manual, 1 return 1/0 * @param int $option 0 return automatic/manual, 1 return 1/0
* @param bool $disabled true or false * @param bool $disabled true or false
* @param int $useempty 1=Add empty line * @param int $useempty 1=Add empty line

View File

@@ -3,7 +3,7 @@
* Copyright (C) 2015 Marcos García <marcosgdf@gmail.com> * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2018 Charlene Benke <charlie@patas-monkey.com> * Copyright (C) 2018 Charlene Benke <charlie@patas-monkey.com>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr> * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Benjamin Falière <benjamin.faliere@altairis.fr> * Copyright (C) 2024 Benjamin Falière <benjamin.faliere@altairis.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@@ -949,7 +949,7 @@ class FormProjets extends Form
* @param ''|int $percent_value percentage of the opportunity * @param ''|int $percent_value percentage of the opportunity
* @param string $htmlname_status name of HTML element for status select * @param string $htmlname_status name of HTML element for status select
* @param string $htmlname_percent name of HTML element for percent input * @param string $htmlname_percent name of HTML element for percent input
* @param string $filter optional filters criteras * @param string $filter Optional filter criteria
* @param int<0,1> $nooutput No print output. Return it only. * @param int<0,1> $nooutput No print output. Return it only.
* @return void|string * @return void|string
*/ */

View File

@@ -5,7 +5,7 @@
* Copyright (C) 2021 Juanjo Menent <jmenent@2byte.es> * Copyright (C) 2021 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2021 Alexandre Spangaro <aspangaro@open-dsi.fr> * Copyright (C) 2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
* Copyright (C) 2023-2025 Charlene Benke <charlene.r@patas-monkey.com> * Copyright (C) 2023-2025 Charlene Benke <charlene.r@patas-monkey.com>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Irvine FLEITH <irvine.fleith@atm-consulting.fr> * Copyright (C) 2024 Irvine FLEITH <irvine.fleith@atm-consulting.fr>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@@ -57,7 +57,7 @@ class FormTicket
public $track_id; public $track_id;
/** /**
* @var string Email $trackid. Used also for the $keytoavoidconflict to name session vars to upload files. * @var string Email. Used also for the to name session vars to upload files.
*/ */
public $trackid; public $trackid;
@@ -90,7 +90,7 @@ class FormTicket
public $withemail; public $withemail;
/** /**
* @var int<0,1> $withsubstit Show substitution array * @var int<0,1> Show substitution array
*/ */
public $withsubstit; public $withsubstit;
@@ -180,8 +180,7 @@ class FormTicket
/** /**
* * @var array<string,string> Substitutions
* @var array<string,string> $substit Substitutions
*/ */
public $substit = array(); public $substit = array();
/** /**
@@ -227,7 +226,6 @@ class FormTicket
} }
/** /**
*
* Check required fields * Check required fields
* *
* @param array<string, array<string, string>> $fields Array of fields to check * @param array<string, array<string, string>> $fields Array of fields to check
@@ -962,7 +960,7 @@ class FormTicket
/** /**
* Return html list of ticket analytic codes * Return html list of ticket analytic codes
* *
* @param string $selected Id pre-selected category * @param string $selected Id preselected category
* @param string $htmlname Name of select component * @param string $htmlname Name of select component
* @param string $filtertype To filter on some properties in llx_c_ticket_category ('public = 1'). This parameter must not come from input of users. * @param string $filtertype To filter on some properties in llx_c_ticket_category ('public = 1'). This parameter must not come from input of users.
* @param int $format 0 = id+label, 1 = code+code, 2 = code+label, 3 = id+code * @param int $format 0 = id+label, 1 = code+code, 2 = code+label, 3 = id+code
@@ -1318,7 +1316,7 @@ class FormTicket
/** /**
* Return html list of ticket severitys (priorities) * Return html list of ticket severitys (priorities)
* *
* @param string $selected Id severity pre-selected * @param string $selected Id severity preselected
* @param string $htmlname Name of the select area * @param string $htmlname Name of the select area
* @param string $filtertype To filter on field type in llx_c_ticket_severity (array('code'=>xx,'label'=>zz)) * @param string $filtertype To filter on field type in llx_c_ticket_severity (array('code'=>xx,'label'=>zz))
* @param int $format 0 = id+label, 1 = code+code, 2 = code+label, 3 = id+code * @param int $format 0 = id+label, 1 = code+code, 2 = code+label, 3 = id+code

View File

@@ -1,7 +1,7 @@
<?php <?php
/* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net> /* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr> * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -33,7 +33,7 @@
*/ */
function dolStripPhpCode($str, $replacewith = '') function dolStripPhpCode($str, $replacewith = '')
{ {
$str = str_replace('<?=', '<?php echo', $str); // replace a bad practive $str = str_replace('<?=', '<?php echo', $str); // replace a bad practice
$newstr = ''; $newstr = '';

View File

@@ -1865,7 +1865,7 @@ function get_left_menu_accountancy($mainmenu, &$newmenu, $usemenuhider = 1, $lef
} }
$key = $langs->trans("AccountingJournalType".$objp->nature); // $objp->nature is 1, 2, 3 ... $key = $langs->trans("AccountingJournalType".$objp->nature); // $objp->nature is 1, 2, 3 ...
$transferlabel = (($objp->nature && $key != "AccountingJournalType".$objp->nature) ? $key.($journallabelwithoutspan != $key ? ' '.$journallabel : '') : $journallabel); $transferlabel = (($objp->nature && $key != "AccountingJournalType".$objp->nature) ? $key.($journallabelwithoutspan != $key ? ' '.$journallabelwithoutspan : '') : $journallabelwithoutspan);
if (getDolGlobalString('ACCOUNTING_MODE') == 'RECETTES-DEPENSES') { if (getDolGlobalString('ACCOUNTING_MODE') == 'RECETTES-DEPENSES') {
$journalNaturePrefixUrl = 'treasury'; $journalNaturePrefixUrl = 'treasury';

View File

@@ -1,6 +1,7 @@
<?php <?php
/* Copyright (C) 2017-2024 Laurent Destailleur <eldy@users.sourceforge.net> /* Copyright (C) 2017-2024 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr> * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -100,7 +101,7 @@ if (!empty($pageid) && $pageid > 0) {
} }
} }
if (empty($srclang)) { if (empty($srclang)) {
$srclang= 'auto'; $srclang = 'auto';
} }
$weblangs->setDefaultLang($srclang); $weblangs->setDefaultLang($srclang);
@@ -160,7 +161,7 @@ if (!defined('USEDOLIBARRSERVER') && !defined('USEDOLIBARREDITOR')) {
} }
$hookmanager->initHooks(array("main")); $hookmanager->initHooks(array("main"));
$parameters = array('contentsecuritypolicy'=>$contentsecuritypolicy, 'mode'=>'reportonly'); $parameters = array('contentsecuritypolicy' => $contentsecuritypolicy, 'mode' => 'reportonly');
$result = $hookmanager->executeHooks('setContentSecurityPolicy', $parameters); // Note that $action and $object may have been modified by some hooks $result = $hookmanager->executeHooks('setContentSecurityPolicy', $parameters); // Note that $action and $object may have been modified by some hooks
if ($result > 0) { if ($result > 0) {
$contentsecuritypolicy = $hookmanager->resPrint; // Replace CSP $contentsecuritypolicy = $hookmanager->resPrint; // Replace CSP
@@ -193,7 +194,7 @@ if (!defined('USEDOLIBARRSERVER') && !defined('USEDOLIBARREDITOR')) {
} }
$hookmanager->initHooks(array("main")); $hookmanager->initHooks(array("main"));
$parameters = array('contentsecuritypolicy'=>$contentsecuritypolicy, 'mode'=>'active'); $parameters = array('contentsecuritypolicy' => $contentsecuritypolicy, 'mode' => 'active');
$result = $hookmanager->executeHooks('setContentSecurityPolicy', $parameters); // Note that $action and $object may have been modified by some hooks $result = $hookmanager->executeHooks('setContentSecurityPolicy', $parameters); // Note that $action and $object may have been modified by some hooks
if ($result > 0) { if ($result > 0) {
$contentsecuritypolicy = $hookmanager->resPrint; // Replace CSP $contentsecuritypolicy = $hookmanager->resPrint; // Replace CSP
@@ -303,6 +304,40 @@ $prefix = dol_getprefix('');
$sessionname = 'DOLSESSID_'.$prefix; $sessionname = 'DOLSESSID_'.$prefix;
//$savsessionid = $_COOKIE[$sessionname]; //$savsessionid = $_COOKIE[$sessionname];
// Add a protection if custom PHP is not allowed or allowed with conditions
global $dolibarr_website_allow_custom_php;
if (!empty($dolibarr_website_allow_custom_php) && $dolibarr_website_allow_custom_php == 1) {
$systemfunctions = array("exec", "passthru", "shell_exec", "system", "popen", "proc_open");
foreach ($systemfunctions as $systemfunction) {
//print ini_get('disable_functions').'<br>';
//print exec("ls");
// @phpstan-ignore-next-line
if (function_exists($systemfunction)) {
print '<center><br><br>';
print 'Website features are protected to be disabled if the PHP system functions ('.implode(',', $systemfunctions).') are not disabled for the website context.<br>';
print 'The value "'.$systemfunction.'" has NOT been found into the <b>current disable_functions</b>=<br>';
print '<textarea cols="100" rows="5">';
print ini_get('disable_functions'); // Warning, the real value may not be this one.Only the master initial value from php.ini is effective, not the local value set at virtualhost.
//print (implode(', ', explode(',', (string) ini_get('disable_functions'))));
print '</textarea>';
print '<br><br>';
print 'You can fix this by changing setup of your PHP ini (changing this in a virtual host with php_admin_value is not effective):<br>';
print 'disable_functions="exec,passthru,shell_exec,system,popen,proc_open,..."<br>';
print 'but WARNING, this may also break features for:<br>';
print '- cron tasks calling command line tools.<br>';
print '- and for the backup feature running the database dump tool.<br>';
print '- and for the command line antivirus check ran when uploading a file.<br>';
print '<br>';
print 'If you don\'t use this 3 feature, change your php.ini, if you need at least one, you can bypass this protection by setting $dolibarr_website_allow_custom_php to 2 in your dolibarr config file.';
print '</center>';
exit; // Stop here to PHP later won't be executed
}
}
}
$_COOKIE[$sessionname] = 'obfuscatedcookie'; $_COOKIE[$sessionname] = 'obfuscatedcookie';
unset($conf->file->instance_unique_id); unset($conf->file->instance_unique_id);

View File

@@ -498,7 +498,7 @@ if ($object->id > 0 || !empty($object->ref)) {
// Linked documents // Linked documents
// @phpstan-ignore-next-line // @phpstan-ignore-next-line
if (($objectsrc instanceOf Commande) && $object->origin_object->id && isModEnabled('order')) { if (($objectsrc instanceof Commande) && $object->origin_object->id && isModEnabled('order')) {
print '<tr><td>'; print '<tr><td>';
print $langs->trans("RefOrder").'</td>'; print $langs->trans("RefOrder").'</td>';
print '<td colspan="3">'; print '<td colspan="3">';
@@ -507,7 +507,7 @@ if ($object->id > 0 || !empty($object->ref)) {
print '</tr>'; print '</tr>';
} }
// @phpstan-ignore-next-line // @phpstan-ignore-next-line
if (($objectsrc instanceOf Propal) && $object->origin_object->id && isModEnabled("propal")) { if (($objectsrc instanceof Propal) && $object->origin_object->id && isModEnabled("propal")) {
print '<tr><td>'; print '<tr><td>';
print $langs->trans("RefProposal").'</td>'; print $langs->trans("RefProposal").'</td>';
print '<td colspan="3">'; print '<td colspan="3">';
@@ -600,7 +600,7 @@ if ($object->id > 0 || !empty($object->ref)) {
$db->free($resql); $db->free($resql);
} }
if ($objectsrc instanceOf Commande) { if ($objectsrc instanceof Commande) {
//$sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, SUM(l.qty) as qty,"; //$sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, l.ref AS sref, SUM(l.qty) as qty,";
$sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, '' AS sref, l.qty as qty,"; $sql = "SELECT l.rowid, l.fk_product, l.subprice, l.remise_percent, '' AS sref, l.qty as qty,";
$sql .= " p.ref, p.label, p.tobatch, p.fk_default_warehouse, p.barcode, p.stockable_product"; $sql .= " p.ref, p.label, p.tobatch, p.fk_default_warehouse, p.barcode, p.stockable_product";
@@ -952,7 +952,7 @@ if ($object->id > 0 || !empty($object->ref)) {
$dispatch_line_batch_current = null; $dispatch_line_batch_current = null;
if (!empty($objd->batch_list)) { if (!empty($objd->batch_list)) {
$dispatch_line_batch_count = count($objd->batch_list); $dispatch_line_batch_count = count($objd->batch_list);
// if only one batch found, this batch is pre-selected // if only one batch found, this batch is preselected
if ($dispatch_line_batch_count == 1) { if ($dispatch_line_batch_count == 1) {
$dispatch_line_batch_current = current($objd->batch_list); $dispatch_line_batch_current = current($objd->batch_list);
} }

View File

@@ -108,8 +108,8 @@ PaymentConditions=Payment Terms
PaymentConditionsShort=Payment Terms PaymentConditionsShort=Payment Terms
PaymentAmount=Payment amount PaymentAmount=Payment amount
PaymentHigherThanReminderToPay=Payment higher than reminder to pay PaymentHigherThanReminderToPay=Payment higher than reminder to pay
HelpPaymentHigherThanReminderToPay=Attention, the payment amount of one or more bills is higher than the outstanding amount to pay. <br> Edit your entry, otherwise confirm and consider creating a credit note for the excess received for each overpaid invoice. HelpPaymentHigherThanReminderToPay=Attention, the payment amount of one or more bills is higher than the outstanding amount to pay. <br> Edit your entry, otherwise confirm and consider converting the amount of each overpaid invoice into an available discount for the customer.
HelpPaymentHigherThanReminderToPaySupplier=Attention, the payment amount of one or more bills is higher than the outstanding amount to pay. <br> Edit your entry, otherwise confirm and consider creating a credit note for the excess paid for each overpaid invoice. HelpPaymentHigherThanReminderToPaySupplier=Attention, the payment amount of one or more bills is higher than the outstanding amount to pay. <br> Edit your entry, otherwise confirm and consider converting the amount of each overpaid invoice into an available discount for you.
ClassifyPaid=Classify 'Paid' ClassifyPaid=Classify 'Paid'
ClassifyUnPaid=Classify 'Unpaid' ClassifyUnPaid=Classify 'Unpaid'
ClassifyPaidPartially=Classify 'Paid partially' ClassifyPaidPartially=Classify 'Paid partially'

View File

@@ -229,6 +229,7 @@ UserGroups=User groups
NoUserGroupDefined=No user group defined NoUserGroupDefined=No user group defined
Password=Password Password=Password
PasswordRetype=Repeat your password PasswordRetype=Repeat your password
YouMustChangeYourPassword=You must change your password before continuing.
NoteSomeFeaturesAreDisabled=Note that a lot of features/modules are disabled in this demonstration. NoteSomeFeaturesAreDisabled=Note that a lot of features/modules are disabled in this demonstration.
YourUserFile=Your user file YourUserFile=Your user file
Name=Name Name=Name
@@ -1217,6 +1218,7 @@ Civility=Title of courtesy
AffectTag=Assign a Tag AffectTag=Assign a Tag
AffectUser=Assign a User AffectUser=Assign a User
SetSupervisor=Set the supervisor SetSupervisor=Set the supervisor
ForcePasswordChange=Force password change at next login
CreateExternalUser=Create external user CreateExternalUser=Create external user
ConfirmAffectTag=Bulk Tag Assignment ConfirmAffectTag=Bulk Tag Assignment
ConfirmAffectUser=Bulk User Assignment ConfirmAffectUser=Bulk User Assignment
@@ -1225,10 +1227,12 @@ ContactRoles=Contact roles
ProjectRole=Role assigned on each project/opportunity ProjectRole=Role assigned on each project/opportunity
TasksRole=Role assigned on each task (if used) TasksRole=Role assigned on each task (if used)
ConfirmSetSupervisor=Bulk Supervisor Set ConfirmSetSupervisor=Bulk Supervisor Set
ConfirmForcePasswordChange=Force Password Change
ConfirmUpdatePrice=Choose a increase/decrease price rate ConfirmUpdatePrice=Choose a increase/decrease price rate
ConfirmAffectTagQuestion=Are you sure you want to assign tags to the %s selected record(s)? ConfirmAffectTagQuestion=Are you sure you want to assign tags to the %s selected record(s)?
ConfirmAffectUserQuestion=Are you sure you want to assign users to the %s selected record(s)? ConfirmAffectUserQuestion=Are you sure you want to assign users to the %s selected record(s)?
ConfirmSetSupervisorQuestion=Are you sure you want to set supervisor to the %s selected record(s)? ConfirmSetSupervisorQuestion=Are you sure you want to set supervisor to the %s selected record(s)?
ConfirmForcePasswordChangeQuestion=Are you sure you want to force password change at next login for the %s selected user(s)?
ConfirmUpdatePriceQuestion=Are you sure you want to update the price of the %s selected record(s)? ConfirmUpdatePriceQuestion=Are you sure you want to update the price of the %s selected record(s)?
CategTypeNotFound=No tag type found for type of records CategTypeNotFound=No tag type found for type of records
SupervisorNotFound=Supervisor not found SupervisorNotFound=Supervisor not found

View File

@@ -1103,6 +1103,24 @@ if (!defined('NOLOGIN')) {
} }
} }
// Check if user must change password at next login
if (!empty($user->force_pass_change) && $dol_authmode == 'dolibarr') {
// redirect to a simple page with only one action is possible : change your password
$allowedpages = array('/user/changepassword.php', '/user/logout.php');
$currentpage = $_SERVER['PHP_SELF'];
$isallowed = false;
foreach ($allowedpages as $page) {
if (preg_match('/'.preg_quote($page, '/').'$/', $currentpage)) {
$isallowed = true;
break;
}
}
if (!$isallowed) {
header('Location: '.DOL_URL_ROOT.'/user/changepassword.php?id='.$user->id);
exit;
}
}
// If user admin, we force the rights-based modules // If user admin, we force the rights-based modules
if ($user->admin) { if ($user->admin) {
$user->rights->user->user->lire = 1; $user->rights->user->user->lire = 1;

View File

@@ -748,7 +748,7 @@ print $form->selectarray("PRODUIT_DESC_IN_FORM", $arrayofchoices, getDolGlobalIn
print '</td>'; print '</td>';
print '</tr>'; print '</tr>';
// Activate propal merge produt card // Activate propal merge product card
/* Kept as hidden feature only. PRODUIT_PDF_MERGE_PROPAL can be added manually. Still did not understand how this feature works. /* Kept as hidden feature only. PRODUIT_PDF_MERGE_PROPAL can be added manually. Still did not understand how this feature works.
print '<tr class="oddeven">'; print '<tr class="oddeven">';

View File

@@ -3,7 +3,7 @@
* Copyright (C) 2019-2025 Frédéric France <frederic.france@free.fr> * Copyright (C) 2019-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2022 Ferran Marcet <fmarcet@2byte.es> * Copyright (C) 2022 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2023 William Mead <william.mead@manchenumerique.fr> * Copyright (C) 2023 William Mead <william.mead@manchenumerique.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -75,7 +75,7 @@ class FormResource
* *
* @param int|int[] $selected Preselected resource id * @param int|int[] $selected Preselected resource id
* @param string $htmlname Name of field in form * @param string $htmlname Name of field in form
* @param string $filter Optional filters criteria (example: 's.rowid <> x') * @param string $filter Optional filter criteria (example: 's.rowid <> x')
* @param int<0,1> $showempty Add an empty field * @param int<0,1> $showempty Add an empty field
* @param int<0,1> $showtype Show third party type in combo list (customer, prospect or supplier) * @param int<0,1> $showtype Show third party type in combo list (customer, prospect or supplier)
* @param int<0,1> $forcecombo Force to use combo box * @param int<0,1> $forcecombo Force to use combo box

View File

@@ -391,7 +391,7 @@ class dolReceiptPrinter extends Printer
/** /**
* Form to Select type printer * Form to Select type printer
* *
* @param string $selected Id printer type pre-selected * @param string $selected Id printer type preselected
* @param string $htmlname select html name * @param string $htmlname select html name
* @return int 0 if OK; >0 if KO * @return int 0 if OK; >0 if KO
*/ */
@@ -416,7 +416,7 @@ class dolReceiptPrinter extends Printer
/** /**
* Form to Select Profile printer * Form to Select Profile printer
* *
* @param string $selected Id printer profile pre-selected * @param string $selected Id printer profile preselected
* @param string $htmlname select html name * @param string $htmlname select html name
* @return int 0 if OK; >0 if KO * @return int 0 if OK; >0 if KO
*/ */

View File

@@ -3,7 +3,7 @@
* Copyright (C) 2018 Andreu Bisquerra <jove@bisquerra.com> * Copyright (C) 2018 Andreu Bisquerra <jove@bisquerra.com>
* Copyright (C) 2021 Nicolas ZABOURI <info@inovea-conseil.com> * Copyright (C) 2021 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2022-2023 Christophe Battarel <christophe.battarel@altairis.fr> * Copyright (C) 2022-2023 Christophe Battarel <christophe.battarel@altairis.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024-2025 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 * This program is free software; you can redistribute it and/or modify
@@ -292,7 +292,7 @@ if (empty($reshook)) {
dol_syslog('Sale without lines'); dol_syslog('Sale without lines');
dol_htmloutput_errors($langs->trans("NoLinesToBill", "TakePos"), [], 1); dol_htmloutput_errors($langs->trans("NoLinesToBill", "TakePos"), [], 1);
} elseif (isModEnabled('stock') && !isModEnabled('productbatch') && $allowstockchange) { } elseif (isModEnabled('stock') && !isModEnabled('productbatch') && $allowstockchange) {
// Validation of invoice with change into stock when produt/lot module is NOT enabled and stock change NOT disabled. // Validation of invoice with change into stock when product/lot module is NOT enabled and stock change NOT disabled.
// The case for isModEnabled('productbatch') is processed few lines later. // The case for isModEnabled('productbatch') is processed few lines later.
$savconst = getDolGlobalString('STOCK_CALCULATE_ON_BILL'); $savconst = getDolGlobalString('STOCK_CALCULATE_ON_BILL');

View File

@@ -162,7 +162,7 @@ a.info-box-text-a i.fa.fa-exclamation-triangle, span.badge i.fa.fa-exclamation-t
} }
.info-box-line { .info-box-line {
line-height: 1.35em; line-height: 1.25em;
} }
.info-box-line-text { .info-box-line-text {
overflow: hidden; overflow: hidden;
@@ -350,6 +350,9 @@ a.info-box-text{ text-decoration: none;}
.infobox-haslink .info-box-icon .info-box-createlink span.fas { .infobox-haslink .info-box-icon .info-box-createlink span.fas {
margin:auto; margin:auto;
} }
.infobox-haslink i.fa.fa-exclamation-triangle.hideonsmartphone {
display: none;
}
/* ICONS INFO BOX */ /* ICONS INFO BOX */
@@ -682,7 +685,6 @@ a.vmenu span, span.vmenu, span.vmenu span {
.info-box-module .info-box-content { .info-box-module .info-box-content {
height: 98px; height: 98px;
} }

View File

@@ -750,3 +750,6 @@ if (GETPOSTISSET('THEME_SATURATE_RATIO')) {
.infobox-haslink .info-box-icon .info-box-createlink span.fas { .infobox-haslink .info-box-icon .info-box-createlink span.fas {
margin:auto; margin:auto;
} }
.infobox-haslink i.fa.fa-exclamation-triangle.hideonsmartphone {
display: none;
}

View File

@@ -86,6 +86,7 @@ $cancel = GETPOST('cancel', 'alpha');
$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'usercard'; // To manage different context of search $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'usercard'; // To manage different context of search
$backtopage = GETPOST('backtopage'); $backtopage = GETPOST('backtopage');
$backtopageforcancel = GETPOST('backtopageforcancel'); $backtopageforcancel = GETPOST('backtopageforcancel');
$forcepasswordchange = GETPOSTINT('forcepasswordchange');
if (empty($id) && $action != 'add' && $action != 'create') { if (empty($id) && $action != 'add' && $action != 'create') {
$id = $user->id; $id = $user->id;
@@ -345,6 +346,7 @@ if (empty($reshook)) {
$object->datestartvalidity = $datestartvalidity; $object->datestartvalidity = $datestartvalidity;
$object->dateendvalidity = $dateendvalidity; $object->dateendvalidity = $dateendvalidity;
$object->birth = $dateofbirth; $object->birth = $dateofbirth;
$object->force_pass_change = $forcepasswordchange;
$object->fk_warehouse = GETPOSTINT('fk_warehouse'); $object->fk_warehouse = GETPOSTINT('fk_warehouse');
@@ -527,6 +529,7 @@ if (empty($reshook)) {
$object->datestartvalidity = $datestartvalidity; $object->datestartvalidity = $datestartvalidity;
$object->dateendvalidity = $dateendvalidity; $object->dateendvalidity = $dateendvalidity;
$object->birth = $dateofbirth; $object->birth = $dateofbirth;
$object->force_pass_change = $forcepasswordchange;
if (isModEnabled('stock')) { if (isModEnabled('stock')) {
$object->fk_warehouse = GETPOSTINT('fk_warehouse'); $object->fk_warehouse = GETPOSTINT('fk_warehouse');
@@ -1215,6 +1218,15 @@ if ($action == 'create' || $action == 'adduserldap') {
print '</td>'; print '</td>';
print "</tr>\n"; print "</tr>\n";
// Force update on next login -- only on dolibarr auth context
if ($_SESSION["dol_authmode"] == 'dolibarr') {
print '<tr><td class="titlefieldcreate">'.$langs->trans("ForcePasswordChange").'</td>';
print '<td>';
print '<input type="checkbox" name="forcepasswordchange" value="1"'.(GETPOST('forcepasswordchange') == '1' ? ' checked="checked"' : '').'>';
print '</td>';
print "</tr>\n";
}
// Password // Password
print '<tr><td class="fieldrequired">'.$langs->trans("Password").'</td>'; print '<tr><td class="fieldrequired">'.$langs->trans("Password").'</td>';
print '<td>'; print '<td>';
@@ -2009,6 +2021,20 @@ if ($action == 'create' || $action == 'adduserldap') {
print '</td>'; print '</td>';
print "</tr>\n"; print "</tr>\n";
// Force update on next login only on dolibarr auth mode
if ($_SESSION["dol_authmode"] == 'dolibarr') {
print '<tr><td class="titlefieldcreate">'.$langs->trans("ForcePasswordChange").'</td>';
print '<td>';
if (getDolGlobalInt('MAIN_OPTIMIZEFORTEXTBROWSER') < 2) {
print '<input type="checkbox" disabled name="forcepasswordchange" value="1"'.($object->force_pass_change ? ' checked="checked"' : '').'>';
} else {
print yn($object->force_pass_change);
}
print '</td>';
print "</tr>\n";
}
// Password for LDAP or HTTP Basic // Password for LDAP or HTTP Basic
$valuetoshow = ''; $valuetoshow = '';
if (preg_match('/ldap/', $dolibarr_main_authentication)) { if (preg_match('/ldap/', $dolibarr_main_authentication)) {
@@ -2683,6 +2709,19 @@ if ($action == 'create' || $action == 'adduserldap') {
print '</td>'; print '</td>';
print "</tr>\n"; print "</tr>\n";
// Force update on next login only on dolibarr auth mode
if ($_SESSION["dol_authmode"] == 'dolibarr') {
print '<tr>';
print '<td>'.$form->editfieldkey('ForcePasswordChange', 'forcepasswordchange', '', $object, 0).'</td><td>';
if ($permissiontoedit) {
print '<input type="checkbox" name="forcepasswordchange" value="1"'.($object->force_pass_change ? ' checked="checked"' : '').'>';
} else {
print '<input type="checkbox" name="forcepasswordchange" disabled value="1"'.($object->force_pass_change ? ' checked="checked"' : '').'>';
}
print '</td></tr>';
}
// Pass // Pass
print '<tr><td class="titlefieldcreate">'.$langs->trans("Password").'</td>'; print '<tr><td class="titlefieldcreate">'.$langs->trans("Password").'</td>';
print '<td>'; print '<td>';

View File

@@ -2351,6 +2351,7 @@ class User extends CommonObject
$sql .= ", fk_warehouse = ".($this->fk_warehouse > 0 ? $this->fk_warehouse : "null"); $sql .= ", fk_warehouse = ".($this->fk_warehouse > 0 ? $this->fk_warehouse : "null");
$sql .= ", fk_establishment = ".($this->fk_establishment > 0 ? $this->fk_establishment : "null"); $sql .= ", fk_establishment = ".($this->fk_establishment > 0 ? $this->fk_establishment : "null");
$sql .= ", lang = ".($this->lang ? "'".$this->db->escape($this->lang)."'" : "null"); $sql .= ", lang = ".($this->lang ? "'".$this->db->escape($this->lang)."'" : "null");
$sql .= ", force_pass_change = ".($this->force_pass_change ? ((int) $this->force_pass_change) : "0");
$sql .= " WHERE rowid = ".((int) $this->id); $sql .= " WHERE rowid = ".((int) $this->id);
dol_syslog(get_class($this)."::update", LOG_DEBUG); dol_syslog(get_class($this)."::update", LOG_DEBUG);

View File

@@ -2,7 +2,7 @@
/* Copyright (C) 2006-2016 Laurent Destailleur <eldy@users.sourceforge.net> /* Copyright (C) 2006-2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2012 JF FERRY <jfefe@aternatik.fr> * Copyright (C) 2012 JF FERRY <jfefe@aternatik.fr>
* Copyright (C) 2020-2024 Frédéric France <frederic.france@free.fr> * Copyright (C) 2020-2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -358,7 +358,7 @@ $server->register(
/** /**
* Get produt or service * Get product or service
* *
* @param array{login:string,password:string,entity:?int,dolibarrkey:string} $authentication Array of authentication information * @param array{login:string,password:string,entity:?int,dolibarrkey:string} $authentication Array of authentication information
* @param int $id Id of object * @param int $id Id of object

View File

@@ -1,6 +1,6 @@
<?php <?php
/* Copyright (C) 2006-2016 Laurent Destailleur <eldy@users.sourceforge.net> /* Copyright (C) 2006-2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024-2025 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 * This program is free software; you can redistribute it and/or modify
@@ -327,7 +327,7 @@ $server->register(
/** /**
* Get produt or service * Get product or service
* *
* @param array{login:string,password:string,entity:?int,dolibarrkey:string} $authentication Array of authentication information * @param array{login:string,password:string,entity:?int,dolibarrkey:string} $authentication Array of authentication information
* @param int $id Id of object * @param int $id Id of object

View File

@@ -5,7 +5,7 @@
* Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr> * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
* Copyright (C) 2020 Nicolas ZABOURI <info@inovea-conseil.com> * Copyright (C) 2020 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr> * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -279,6 +279,18 @@ class WebsitePage extends CommonObject
// Remove spaces and be sure we have main language only // Remove spaces and be sure we have main language only
$this->lang = preg_replace('/[_-].*$/', '', trim($this->lang)); // en_US or en-US -> en $this->lang = preg_replace('/[_-].*$/', '', trim($this->lang)); // en_US or en-US -> en
// Test if page contains dynamic PHP content
if (!$user->hasRight('website', 'writephp')) {
// Check there is no PHP content into the imported file (must be only HTML + JS)
$phpcontent = dolKeepOnlyPhpCode($this->content);
if ($phpcontent) {
$this->error = 'Error: you try to create a page with PHP content without having permissions for that.';
$this->errors[] = $this->error;
return -1;
}
}
return $this->createCommon($user, $notrigger); return $this->createCommon($user, $notrigger);
} }

View File

@@ -1,7 +1,7 @@
<?php <?php
/* Copyright (C) 2016-2023 Laurent Destailleur <eldy@users.sourceforge.net> /* Copyright (C) 2016-2023 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2020 Nicolas ZABOURI <info@inovea-conseil.com> * Copyright (C) 2020 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024-2025 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 * This program is free software; you can redistribute it and/or modify
@@ -880,6 +880,7 @@ if ($action == 'addcontainer' && $usercanedit) {
// Remove comments // Remove comments
$tmp['content'] = removeHtmlComment($tmp['content']); $tmp['content'] = removeHtmlComment($tmp['content']);
/* disable this, moved into the create() method
// Check there is no PHP content into the imported file (must be only HTML + JS) // Check there is no PHP content into the imported file (must be only HTML + JS)
$phpcontent = dolKeepOnlyPhpCode($tmp['content']); $phpcontent = dolKeepOnlyPhpCode($tmp['content']);
if ($phpcontent) { if ($phpcontent) {
@@ -887,6 +888,7 @@ if ($action == 'addcontainer' && $usercanedit) {
setEventMessages('Error getting '.$urltograb.': file that include PHP content is not allowed', null, 'errors'); setEventMessages('Error getting '.$urltograb.': file that include PHP content is not allowed', null, 'errors');
$action = 'createcontainer'; $action = 'createcontainer';
} }
*/
} }
if (!$error) { if (!$error) {
@@ -1170,7 +1172,8 @@ if ($action == 'addcontainer' && $usercanedit) {
$objectpage->title = str_replace(array('<', '>'), '', GETPOST('WEBSITE_TITLE', 'alphanohtml')); $objectpage->title = str_replace(array('<', '>'), '', GETPOST('WEBSITE_TITLE', 'alphanohtml'));
$objectpage->type_container = GETPOST('WEBSITE_TYPE_CONTAINER', 'aZ09'); $objectpage->type_container = GETPOST('WEBSITE_TYPE_CONTAINER', 'aZ09');
$objectpage->pageurl = GETPOST('WEBSITE_PAGENAME', 'alpha'); $objectpage->pageurl = dol_sanitizeUrl(GETPOST('WEBSITE_PAGENAME', 'alpha'));
$objectpage->ref = $objectpage->pageurl;
$objectpage->aliasalt = $newaliasnames; $objectpage->aliasalt = $newaliasnames;
$objectpage->description = str_replace(array('<', '>'), '', GETPOST('WEBSITE_DESCRIPTION', 'alphanohtml')); $objectpage->description = str_replace(array('<', '>'), '', GETPOST('WEBSITE_DESCRIPTION', 'alphanohtml'));
$objectpage->lang = GETPOST('WEBSITE_LANG', 'aZ09'); $objectpage->lang = GETPOST('WEBSITE_LANG', 'aZ09');
@@ -1263,6 +1266,7 @@ if ($action == 'addcontainer' && $usercanedit) {
$pageid = 0; $pageid = 0;
if (!$error) { if (!$error) {
// Create page. This also check there is no PHP content if user has no pemrissions for that.
$pageid = $objectpage->create($user); $pageid = $objectpage->create($user);
if ($pageid <= 0) { if ($pageid <= 0) {
$error++; $error++;
@@ -2171,7 +2175,7 @@ if ($action == 'updatemeta' && $usercanedit) {
$objectpage->title = str_replace(array('<', '>'), '', GETPOST('WEBSITE_TITLE', 'alphanohtml')); $objectpage->title = str_replace(array('<', '>'), '', GETPOST('WEBSITE_TITLE', 'alphanohtml'));
$objectpage->type_container = GETPOST('WEBSITE_TYPE_CONTAINER', 'aZ09'); $objectpage->type_container = GETPOST('WEBSITE_TYPE_CONTAINER', 'aZ09');
$objectpage->pageurl = GETPOST('WEBSITE_PAGENAME', 'alpha'); $objectpage->pageurl = dol_sanitizeUrl(GETPOST('WEBSITE_PAGENAME', 'alpha'));
$objectpage->aliasalt = $newaliasnames; $objectpage->aliasalt = $newaliasnames;
$objectpage->lang = GETPOST('WEBSITE_LANG', 'aZ09'); $objectpage->lang = GETPOST('WEBSITE_LANG', 'aZ09');
$objectpage->otherlang = GETPOST('WEBSITE_OTHERLANG', 'aZ09comma'); $objectpage->otherlang = GETPOST('WEBSITE_OTHERLANG', 'aZ09comma');
@@ -3387,6 +3391,7 @@ if (!GETPOST('hide_websitemenu')) {
$examplewithapache = "<VirtualHost *:80>\n"; $examplewithapache = "<VirtualHost *:80>\n";
$examplewithapache .= '#php_admin_value open_basedir /tmp/:'.DOL_DOCUMENT_ROOT.':'.DOL_DATA_ROOT.':/dev/urandom'."\n"; $examplewithapache .= '#php_admin_value open_basedir /tmp/:'.DOL_DOCUMENT_ROOT.':'.DOL_DATA_ROOT.':/dev/urandom'."\n";
//$examplewithapache .= '#php_admin_value disable_functions "exec,passthru,shell_exec,system,popen,proc_open"'."\n"; This is not effective if not in php.ini
$examplewithapache .= "\n"; $examplewithapache .= "\n";
$examplewithapache .= 'DocumentRoot "'.DOL_DOCUMENT_ROOT.'"'."\n"; $examplewithapache .= 'DocumentRoot "'.DOL_DOCUMENT_ROOT.'"'."\n";
$examplewithapache .= "\n"; $examplewithapache .= "\n";

View File

@@ -3,7 +3,7 @@
/* /*
* Copyright (C) 2009-2012 Laurent Destailleur <eldy@users.sourceforge.net> * Copyright (C) 2009-2012 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr> * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
* Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com> * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@@ -168,7 +168,7 @@ foreach ($argv as $key => $value) {
print 'Error: Bad date format or value'."\n"; print 'Error: Bad date format or value'."\n";
exit(1); exit(1);
} }
print 'Rebuild PDF for ivoices with at least one payment between '.dol_print_date($paymentdateafter, 'day', 'gmt')." and ".dol_print_date($paymentdatebefore, 'day', 'gmt').".\n"; print 'Rebuild PDF for invoices with at least one payment between '.dol_print_date($paymentdateafter, 'day', 'gmt')." and ".dol_print_date($paymentdatebefore, 'day', 'gmt').".\n";
} }
if ($value == 'filter=nopayment') { if ($value == 'filter=nopayment') {
@@ -176,7 +176,7 @@ foreach ($argv as $key => $value) {
$option .= (empty($option) ? '' : '_').'nopayment'; $option .= (empty($option) ? '' : '_').'nopayment';
$filter[] = 'nopayment'; $filter[] = 'nopayment';
print 'Rebuild PDF for ivoices with no payment done yet.'."\n"; print 'Rebuild PDF for invoices with no payment done yet.'."\n";
} }
if ($value == 'filter=bank') { if ($value == 'filter=bank') {