From 0914d623495b3a1255c391497773b60f269f8427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 10:07:41 +0100 Subject: [PATCH 001/185] fix phpstan --- build/phpstan/phpstan-baseline.neon | 60 ----------------------- htdocs/adherents/class/adherent.class.php | 16 +++--- htdocs/adherents/list.php | 8 +-- htdocs/adherents/messaging.php | 5 +- htdocs/adherents/subscription.php | 44 ++++++++--------- htdocs/adherents/subscription/list.php | 17 ++++--- 6 files changed, 46 insertions(+), 104 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index 9b055ffc31c..2f99b81a599 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -1014,12 +1014,6 @@ parameters: count: 1 path: ../../htdocs/adherents/class/adherent.class.php - - - message: '#^Property Adherent\:\:\$first_subscription_amount \(int\|string\) in isset\(\) is not nullable\.$#' - identifier: isset.property - count: 1 - path: ../../htdocs/adherents/class/adherent.class.php - - message: '#^Property Adherent\:\:\$last_subscription_amount \(int\|string\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -1170,12 +1164,6 @@ parameters: count: 1 path: ../../htdocs/adherents/messaging.php - - - message: '#^Variable \$socid might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/adherents/messaging.php - - message: '#^Property Partnership\:\:\$entity \(int\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -1188,54 +1176,12 @@ parameters: count: 1 path: ../../htdocs/adherents/partnership.php - - - message: '#^Variable \$label might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/adherents/stats/geo.php - - - - message: '#^Variable \$theme_datacolor might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/adherents/stats/geo.php - - - - message: '#^Negated boolean expression is always true\.$#' - identifier: booleanNot.alwaysTrue - count: 1 - path: ../../htdocs/adherents/subscription.php - - message: '#^Variable \$bankline in empty\(\) always exists and is not falsy\.$#' identifier: empty.variable count: 1 path: ../../htdocs/adherents/subscription/card.php - - - message: '#^Empty array passed to foreach\.$#' - identifier: foreach.emptyArray - count: 1 - path: ../../htdocs/adherents/subscription/list.php - - - - message: '#^If condition is always false\.$#' - identifier: if.alwaysFalse - count: 2 - path: ../../htdocs/adherents/subscription/list.php - - - - message: '#^Result of && is always false\.$#' - identifier: booleanAnd.alwaysFalse - count: 1 - path: ../../htdocs/adherents/subscription/list.php - - - - message: '#^Right side of && is always false\.$#' - identifier: booleanAnd.rightAlwaysFalse - count: 1 - path: ../../htdocs/adherents/subscription/list.php - - message: '#^Variable \$object might not be defined\.$#' identifier: variable.undefined @@ -7626,12 +7572,6 @@ parameters: count: 3 path: ../../htdocs/compta/tva/payments.php - - - message: '#^Call to function is_array\(\) with list\ will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../htdocs/compta/tva/quadri_detail.php - - message: '#^Call to function is_array\(\) with list\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index 7ad5ee54ee7..35558e6f4fe 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -236,12 +236,12 @@ class Adherent extends CommonObject public $need_subscription; /** - * @var int user_id + * @var int|null user_id */ public $user_id; /** - * @var string user_login + * @var string|null user_login */ public $user_login; @@ -254,32 +254,32 @@ class Adherent extends CommonObject // Fields loaded by fetch_subscriptions() from member table /** - * @var int|string date + * @var int|string|null date */ public $first_subscription_date; /** - * @var int|string date + * @var int|string|null date */ public $first_subscription_date_start; /** - * @var int|string date + * @var int|string|null date */ public $first_subscription_date_end; /** - * @var int|string date + * @var int|string|null date */ public $first_subscription_amount; /** - * @var int|string date + * @var int|string|null date */ public $last_subscription_date; /** - * @var int|string date + * @var int|string|null date */ public $last_subscription_date_start; diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 8769e9916cc..acc6ceb4dcd 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -235,10 +235,10 @@ if (!GETPOST('confirmmassaction', 'alpha') && $massaction != 'presend' && $massa $massaction = ''; } -$permissiontoread = ($user->hasRight('adherent', 'lire') == 1); -$permissiontodelete = ($user->hasRight('adherent', 'supprimer') == 1); -$permissiontoadd = ($user->hasRight('adherent', 'creer') == 1); -$uploaddir = $conf->adherent->dir_output; +$permissiontoread = $user->hasRight('adherent', 'lire'); +$permissiontodelete = $user->hasRight('adherent', 'supprimer'); +$permissiontoadd = $user->hasRight('adherent', 'creer'); +$uploaddir = $conf->member->dir_output; $error = 0; $parameters = array('socid' => isset($socid) ? $socid : null, 'arrayfields' => &$arrayfields); diff --git a/htdocs/adherents/messaging.php b/htdocs/adherents/messaging.php index af48d7cf822..de637315753 100644 --- a/htdocs/adherents/messaging.php +++ b/htdocs/adherents/messaging.php @@ -81,7 +81,10 @@ if (!$sortfield) { if (!$sortorder) { $sortorder = 'DESC,DESC'; } - +$socid = GETPOSTINT('socid'); +if ($user->socid > 0) { + $socid = $user->socid; +} // Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context $hookmanager->initHooks(array('agendathirdparty', 'globalcard')); diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 3b7b80d6935..069f89de048 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -179,35 +179,33 @@ if (empty($reshook) && $action == 'setuserid' && ($user->hasRight('user', 'self' if (empty($reshook) && $action == 'setsocid' && $permissiontoaddmember) { $error = 0; - if (!$error) { - if (GETPOSTINT('socid') != $object->socid) { // If link differs from currently in database - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."adherent"; - $sql .= " WHERE fk_soc = ".((int) GETPOSTINT('socid')); - $resql = $db->query($sql); - if ($resql) { - $obj = $db->fetch_object($resql); - if ($obj && $obj->rowid > 0) { - $othermember = new Adherent($db); - $othermember->fetch($obj->rowid); - $thirdparty = new Societe($db); - $thirdparty->fetch(GETPOSTINT('socid')); - $error++; - setEventMessages($langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty", $othermember->getFullName($langs), $othermember->login, $thirdparty->name), null, 'errors'); - } + if (GETPOSTINT('socid') != $object->socid) { // If link differs from currently in database + $sql = "SELECT rowid FROM " . MAIN_DB_PREFIX . "adherent"; + $sql .= " WHERE fk_soc = " . ((int) GETPOSTINT('socid')); + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + if ($obj && $obj->rowid > 0) { + $othermember = new Adherent($db); + $othermember->fetch($obj->rowid); + $thirdparty = new Societe($db); + $thirdparty->fetch(GETPOSTINT('socid')); + $error++; + setEventMessages($langs->trans("ErrorMemberIsAlreadyLinkedToThisThirdParty", $othermember->getFullName($langs), $othermember->login, $thirdparty->name), null, 'errors'); } + } - if (!$error) { - $result = $object->setThirdPartyId(GETPOSTINT('socid')); - if ($result < 0) { - dol_print_error(null, $object->error); - } - $action = ''; + if (!$error) { + $result = $object->setThirdPartyId(GETPOSTINT('socid')); + if ($result < 0) { + dol_print_error(null, $object->error); } + $action = ''; } } } -if ($user->hasRight('adherent', 'cotisation', 'creer') && $action == 'subscription' && !$cancel) { +if (empty($reshook) && $user->hasRight('adherent', 'cotisation', 'creer') && $action == 'subscription' && !$cancel) { $error = 0; $langs->load("banks"); @@ -701,7 +699,7 @@ if ($user->hasRight('adherent', 'cotisation', 'creer')) { if ($action != 'addsubscription' && $action != 'create_thirdparty') { print '
'; - if ($object->statut > 0) { + if ($object->status > 0) { print '"; } else { print ''; diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index aa50ccc6a4f..c34a84824cc 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -63,7 +63,7 @@ $search_login = GETPOST('search_login', 'alpha'); $search_note = GETPOST('search_note', 'alpha'); $search_account = GETPOST('search_account', 'alpha'); $search_amount = GETPOST('search_amount', 'alpha'); -$search_all = ''; +$search_all = trim(GETPOST('search_all', 'alphanohtml')); $date_select = GETPOST("date_select", 'alpha'); @@ -98,6 +98,8 @@ $search_array_options = $extrafields->getOptionalsFromPost($object->table_elemen // List of fields to search into when doing a "search in all" $fieldstosearchall = array( + 'c.rowid' => 'Ref', + 'c.note' => "Label", ); $arrayfields = array( 'd.ref' => array('label' => "Ref", 'checked' => 1), @@ -105,7 +107,7 @@ $arrayfields = array( 'd.lastname' => array('label' => "Lastname", 'checked' => 1), 'd.firstname' => array('label' => "Firstname", 'checked' => 1), 'd.login' => array('label' => "Login", 'checked' => 1), - 't.libelle' => array('label' => "Label", 'checked' => 1), + 'c.note' => array('label' => "Label", 'checked' => 1), 'd.bank' => array('label' => "BankAccount", 'checked' => 1, 'enabled' => (isModEnabled('bank'))), /*'d.note_public'=>array('label'=>"NotePublic", 'checked'=>0), 'd.note_private'=>array('label'=>"NotePrivate", 'checked'=>0),*/ @@ -166,7 +168,7 @@ if (empty($reshook)) { // Mass actions $objectclass = 'Subscription'; $objectlabel = 'Subscription'; - $uploaddir = $conf->adherent->dir_output; + $uploaddir = $conf->member->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } @@ -395,7 +397,6 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; if ($search_all) { $setupstring = ''; - // @phan-suppress-next-line PhanEmptyForeach foreach ($fieldstosearchall as $key => $val) { $fieldstosearchall[$key] = $langs->trans($val); $setupstring .= $key."=".$val.";"; @@ -474,7 +475,7 @@ if (!empty($arrayfields['d.login']['checked'])) { print ''; } -if (!empty($arrayfields['t.libelle']['checked'])) { +if (!empty($arrayfields['c.note']['checked'])) { print ''; print ''; print ''; @@ -557,8 +558,8 @@ if (!empty($arrayfields['d.login']['checked'])) { print_liste_field_titre($arrayfields['d.login']['label'], $_SERVER["PHP_SELF"], "d.login", $param, "", "", $sortfield, $sortorder); $totalarray['nbfield']++; } -if (!empty($arrayfields['t.libelle']['checked'])) { - print_liste_field_titre($arrayfields['t.libelle']['label'], $_SERVER["PHP_SELF"], "c.note", $param, "", '', $sortfield, $sortorder); +if (!empty($arrayfields['c.note']['checked'])) { + print_liste_field_titre($arrayfields['c.note']['label'], $_SERVER["PHP_SELF"], "c.note", $param, "", '', $sortfield, $sortorder); $totalarray['nbfield']++; } if (!empty($arrayfields['d.bank']['checked'])) { @@ -725,7 +726,7 @@ while ($i < $imaxinloop) { } // Label - if (!empty($arrayfields['t.libelle']['checked'])) { + if (!empty($arrayfields['c.note']['checked'])) { print ''; print dol_escape_htmltag(dolGetFirstLineOfText($obj->note_private)); print ''; From f3abc3825f2add4a84acc81bd98a6a77f7d9663f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 10:38:30 +0100 Subject: [PATCH 002/185] fix phpstan doc ui --- build/phpstan/phpstan-baseline.neon | 18 ----------- htdocs/admin/tools/ui/components/badges.php | 28 +++++++++-------- htdocs/admin/tools/ui/components/buttons.php | 24 ++++++++------- .../tools/ui/components/event-message.php | 23 +++++++------- htdocs/admin/tools/ui/components/index.php | 30 +++++++++++-------- .../tools/ui/components/progress-bars.php | 24 ++++++++------- .../admin/tools/ui/components/test_arrays.php | 29 +++++++++++++++--- .../tools/ui/components/test_buttons.php | 29 +++++++++++++++++- .../admin/tools/ui/components/test_forms.php | 12 +++++++- htdocs/admin/tools/ui/content/tables.php | 22 +++++++------- htdocs/admin/tools/ui/index.php | 27 +++++++++-------- phpstan.neon.dist | 1 - 12 files changed, 164 insertions(+), 103 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index 9b055ffc31c..6b70662a01d 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -1188,18 +1188,6 @@ parameters: count: 1 path: ../../htdocs/adherents/partnership.php - - - message: '#^Variable \$label might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/adherents/stats/geo.php - - - - message: '#^Variable \$theme_datacolor might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/adherents/stats/geo.php - - message: '#^Negated boolean expression is always true\.$#' identifier: booleanNot.alwaysTrue @@ -7626,12 +7614,6 @@ parameters: count: 3 path: ../../htdocs/compta/tva/payments.php - - - message: '#^Call to function is_array\(\) with list\ will always evaluate to true\.$#' - identifier: function.alreadyNarrowedType - count: 1 - path: ../../htdocs/compta/tva/quadri_detail.php - - message: '#^Call to function is_array\(\) with list\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType diff --git a/htdocs/admin/tools/ui/components/badges.php b/htdocs/admin/tools/ui/components/badges.php index e47b8090ce4..b698113dac5 100644 --- a/htdocs/admin/tools/ui/components/badges.php +++ b/htdocs/admin/tools/ui/components/badges.php @@ -1,6 +1,7 @@ + * Copyright (C) 2024 Frédéric France * * This program and files/directory inner it is free software: you can * redistribute it and/or modify it under the terms of the @@ -17,20 +18,23 @@ * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php'; -endif; -if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php'; -endif; -if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php'; -endif; +// Load Dolibarr environment +require '../../../../main.inc.php'; + +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ // Protection if external user -if ($user->socid > 0) : accessforbidden(); -endif; +if ($user->socid > 0) { + accessforbidden(); +} // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); @@ -49,7 +53,7 @@ $documentation->view = array('Components','Badges'); $documentation->showSidebar(); ?>
- + showBreadCrumb(); ?>
@@ -310,4 +314,4 @@ $documentation->showSidebar(); ?> docFooter(); -?> \ No newline at end of file +?> diff --git a/htdocs/admin/tools/ui/components/buttons.php b/htdocs/admin/tools/ui/components/buttons.php index 1ad142730f0..62de3b23fce 100644 --- a/htdocs/admin/tools/ui/components/buttons.php +++ b/htdocs/admin/tools/ui/components/buttons.php @@ -1,6 +1,7 @@ + * Copyright (C) 2024 Frédéric France * * This program and files/directory inner it is free software: you can * redistribute it and/or modify it under the terms of the @@ -17,20 +18,23 @@ * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php'; -endif; -if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php'; -endif; -if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php'; -endif; +// Load Dolibarr environment +require '../../../../main.inc.php'; + +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ // Protection if external user -if ($user->socid > 0) : accessforbidden(); -endif; +if ($user->socid > 0) { + accessforbidden(); +} // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); diff --git a/htdocs/admin/tools/ui/components/event-message.php b/htdocs/admin/tools/ui/components/event-message.php index 98e3080c7d3..6065237d90b 100644 --- a/htdocs/admin/tools/ui/components/event-message.php +++ b/htdocs/admin/tools/ui/components/event-message.php @@ -1,6 +1,7 @@ + * Copyright (C) 2024 Frédéric France * * This program and files/directory inner it is free software: you can * redistribute it and/or modify it under the terms of the @@ -17,21 +18,23 @@ * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php'; -endif; -if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php'; -endif; -if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php'; -endif; +// Load Dolibarr environment +require '../../../../main.inc.php'; +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ // Protection if external user -if ($user->socid > 0) : accessforbidden(); -endif; +if ($user->socid > 0) { + accessforbidden(); +} // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); diff --git a/htdocs/admin/tools/ui/components/index.php b/htdocs/admin/tools/ui/components/index.php index 32af131fb91..e6023af16c7 100644 --- a/htdocs/admin/tools/ui/components/index.php +++ b/htdocs/admin/tools/ui/components/index.php @@ -1,6 +1,7 @@ + * Copyright (C) 2024 Frédéric France * * This program and files/directory inner it is free software: you can * redistribute it and/or modify it under the terms of the @@ -17,20 +18,23 @@ * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php'; -endif; -if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php'; -endif; -if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php'; -endif; +// Load Dolibarr environment +require '../../../../main.inc.php'; + +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ // Protection if external user -if ($user->socid > 0) : accessforbidden(); -endif; +if ($user->socid > 0) { + accessforbidden(); +} // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); @@ -48,7 +52,7 @@ $documentation->view = array('Components'); $documentation->showSidebar(); ?>
- + showBreadCrumb(); ?>
@@ -56,11 +60,11 @@ $documentation->showSidebar(); ?>

trans('DocComponentsTitle'); ?>

trans('DocComponentsMainDescription'); ?>

- showSummary(); ?> + showSummary(); ?>
docFooter(); -?> \ No newline at end of file +?> diff --git a/htdocs/admin/tools/ui/components/progress-bars.php b/htdocs/admin/tools/ui/components/progress-bars.php index f860fabb579..b53bb335d6e 100644 --- a/htdocs/admin/tools/ui/components/progress-bars.php +++ b/htdocs/admin/tools/ui/components/progress-bars.php @@ -1,6 +1,7 @@ + * Copyright (C) 2024 Frédéric France * * This program and files/directory inner it is free software: you can * redistribute it and/or modify it under the terms of the @@ -17,20 +18,23 @@ * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php'; -endif; -if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php'; -endif; -if (! $res && file_exists("../../../../main.inc.php")) : $res=@include '../../../../main.inc.php'; -endif; +// Load Dolibarr environment +require '../../../../main.inc.php'; + +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ // Protection if external user -if ($user->socid > 0) : accessforbidden(); -endif; +if ($user->socid > 0) { + accessforbidden(); +} // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); diff --git a/htdocs/admin/tools/ui/components/test_arrays.php b/htdocs/admin/tools/ui/components/test_arrays.php index 8954e0cd7a3..14792a0353a 100644 --- a/htdocs/admin/tools/ui/components/test_arrays.php +++ b/htdocs/admin/tools/ui/components/test_arrays.php @@ -1,14 +1,35 @@ + * + * This program and files/directory inner it is free software: you can + * redistribute it and/or modify it under the terms of the + * GNU Affero General Public License (AGPL) as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AGPL for more details. + * + * You should have received a copy of the GNU AGPL + * along with this program. If not, see . */ // Load Dolibarr environment -@include '../../main.inc.php'; +require '../../../../main.inc.php'; -// Security -if ($dolibarr_main_prod) { - accessforbidden('Access forbidden when $dolibarr_main_prod is set to 1'); +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ + +// Protection if external user +if ($user->socid > 0) { + accessforbidden(); } diff --git a/htdocs/admin/tools/ui/components/test_buttons.php b/htdocs/admin/tools/ui/components/test_buttons.php index 8eef7aa0b6c..619e91b3922 100644 --- a/htdocs/admin/tools/ui/components/test_buttons.php +++ b/htdocs/admin/tools/ui/components/test_buttons.php @@ -1,4 +1,22 @@ + */ +/* + * This program and files/directory inner it is free software: you can + * redistribute it and/or modify it under the terms of the + * GNU Affero General Public License (AGPL) as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AGPL for more details. + * + * You should have received a copy of the GNU AGPL + * along with this program. If not, see . + */ + if (!defined('NOREQUIRESOC')) { define('NOREQUIRESOC', '1'); } @@ -25,9 +43,18 @@ if (!defined('NOREQUIREMENU')) { } session_cache_limiter('public'); -require_once '../../main.inc.php'; +require '../../../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + * + * @var int $dolibarr_main_prod + */ + // Security if ($dolibarr_main_prod) { accessforbidden(); diff --git a/htdocs/admin/tools/ui/components/test_forms.php b/htdocs/admin/tools/ui/components/test_forms.php index 60f351eb994..60c32389b0d 100644 --- a/htdocs/admin/tools/ui/components/test_forms.php +++ b/htdocs/admin/tools/ui/components/test_forms.php @@ -14,6 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + define("NOCSRFCHECK", 1); // We accept to go on this page from external web site. //define("NOLOGIN",1); // This means this output page does not require to be logged. /*if (!defined('NOSESSION')) { @@ -21,9 +22,18 @@ define("NOCSRFCHECK", 1); // We accept to go on this page from external web site }*/ // Load Dolibarr environment -require '../../main.inc.php'; +require '../../../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + * + * @var int $dolibarr_main_prod + */ + // Security if ($dolibarr_main_prod) { accessforbidden('Access forbidden when $dolibarr_main_prod is set to 1'); diff --git a/htdocs/admin/tools/ui/content/tables.php b/htdocs/admin/tools/ui/content/tables.php index 00fd9bbf666..2423fb690a6 100644 --- a/htdocs/admin/tools/ui/content/tables.php +++ b/htdocs/admin/tools/ui/content/tables.php @@ -1,6 +1,7 @@ + * Copyright (C) 2024 Frédéric France * * This program and files/directory inner it is free software: you can * redistribute it and/or modify it under the terms of the @@ -17,16 +18,15 @@ * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../../main.inc.php")) { - $res=@include '../../main.inc.php'; -} -if (! $res && file_exists("../../../main.inc.php")) { - $res=@include '../../../main.inc.php'; -} -if (! $res && file_exists("../../../../main.inc.php")) { - $res=@include '../../../../main.inc.php'; -} +// Load Dolibarr environment +require '../../../../main.inc.php'; + +/** + * @var DoliDB $db + * @var HookManager $hookmanager + * @var Translate $langs + * @var User $user + */ // Protection if external user if ($user->socid > 0) { @@ -34,7 +34,7 @@ if ($user->socid > 0) { } // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); diff --git a/htdocs/admin/tools/ui/index.php b/htdocs/admin/tools/ui/index.php index 2e64da27e4e..548b6020e91 100644 --- a/htdocs/admin/tools/ui/index.php +++ b/htdocs/admin/tools/ui/index.php @@ -1,6 +1,7 @@ + * Copyright (C) 2024 Frédéric France * * This program and files/directory inner it is free software: you can * redistribute it and/or modify it under the terms of the @@ -17,20 +18,22 @@ * along with this program. If not, see . */ -$res=0; -if (! $res && file_exists("../main.inc.php")) : $res=@include '../main.inc.php'; -endif; -if (! $res && file_exists("../../main.inc.php")) : $res=@include '../../main.inc.php'; -endif; -if (! $res && file_exists("../../../main.inc.php")) : $res=@include '../../../main.inc.php'; -endif; +// Load Dolibarr environment +require '../../../main.inc.php'; + +/** + * @var DoliDB $db + * @var Translate $langs + * @var User $user + */ // Protection if external user -if ($user->socid > 0) : accessforbidden(); -endif; +if ($user->socid > 0) { + accessforbidden(); +} // Includes -dol_include_once('admin/tools/ui/class/documentation.class.php'); +require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php'; // Load documentation translations $langs->load('uxdocumentation'); @@ -48,7 +51,7 @@ $documentation->view = array('DocumentationHome'); $documentation->showSidebar(); ?>
- + showBreadCrumb(); ?>
@@ -61,4 +64,4 @@ $documentation->showSidebar(); ?> docFooter(); -?> \ No newline at end of file +?> diff --git a/phpstan.neon.dist b/phpstan.neon.dist index de1271a36e1..a21273cea08 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -19,7 +19,6 @@ parameters: - scripts excludePaths: analyseAndScan: - - htdocs/admin/tools/ui/* - htdocs/custom/* - htdocs/documents/* - htdocs/install/doctemplates/* From a5dde7fe83b0ca17a32715184f14a2fb04e21948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 10:53:07 +0100 Subject: [PATCH 003/185] fix phpstan doc ui --- htdocs/admin/tools/ui/class/documentation.class.php | 6 +++++- htdocs/admin/tools/ui/components/test_arrays.php | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/tools/ui/class/documentation.class.php b/htdocs/admin/tools/ui/class/documentation.class.php index 584f6c36a7f..3d5128cc16b 100644 --- a/htdocs/admin/tools/ui/class/documentation.class.php +++ b/htdocs/admin/tools/ui/class/documentation.class.php @@ -1,5 +1,6 @@ + * Copyright (C) 2024 Frédéric France * * 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 @@ -57,6 +58,7 @@ class Documentation * Constructor * * @param DoliDB $db Database handler + * @return void */ public function __construct(DoliDB $db) { @@ -223,7 +225,8 @@ class Documentation } /** - * Output sidebar + * Output sidebar + * * @return void */ public function showSidebar() @@ -320,6 +323,7 @@ class Documentation public function showSummary($showsubmenu = 1, $showsubmenu_summary = 1) { $i = 0; + $menu_entry = []; if (!empty($this->view)) : // On se place au bon niveau foreach ($this->view as $view) { diff --git a/htdocs/admin/tools/ui/components/test_arrays.php b/htdocs/admin/tools/ui/components/test_arrays.php index 14792a0353a..0cfaf869942 100644 --- a/htdocs/admin/tools/ui/components/test_arrays.php +++ b/htdocs/admin/tools/ui/components/test_arrays.php @@ -40,7 +40,9 @@ if ($user->socid > 0) { $form = new Form($db); -$usedolheader = 1; // 1 = Test inside a dolibarr page, 0 = Use hard coded header +// 1 = Test inside a dolibarr page, 0 = Use hard coded header +// Using a dolibarr constant avoid phpstan hardcoded value always true or false +$usedolheader = getDolGlobalInt('MAIN_TEST_UI_IN_DOLIBARR_PAGE', 1); // HEADER //-------- From 7c4ddc4c3cbe205e403f21360e4eb3cd04709d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 11:07:41 +0100 Subject: [PATCH 004/185] fix phpstan doc ui --- .../tools/ui/class/documentation.class.php | 4 +-- .../admin/tools/ui/components/test_arrays.php | 35 +++++++++---------- .../tools/ui/components/test_buttons.php | 3 +- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/htdocs/admin/tools/ui/class/documentation.class.php b/htdocs/admin/tools/ui/class/documentation.class.php index 3d5128cc16b..06a919d274f 100644 --- a/htdocs/admin/tools/ui/class/documentation.class.php +++ b/htdocs/admin/tools/ui/class/documentation.class.php @@ -77,7 +77,6 @@ class Documentation */ private function setMenu() { - global $hookmanager; @@ -315,7 +314,8 @@ class Documentation } /** - * Output summary + * Output summary + * * @param int $showsubmenu Show Sub menus: 0 = No, 1 = Yes * @param int $showsubmenu_summary Show summary of sub menus: 0 = No, 1 = Yes * @return void diff --git a/htdocs/admin/tools/ui/components/test_arrays.php b/htdocs/admin/tools/ui/components/test_arrays.php index 0cfaf869942..553816c58d5 100644 --- a/htdocs/admin/tools/ui/components/test_arrays.php +++ b/htdocs/admin/tools/ui/components/test_arrays.php @@ -32,7 +32,7 @@ if ($user->socid > 0) { accessforbidden(); } - +$optioncss = GETPOST('optioncsss', 'alpha'); /* * View @@ -186,15 +186,14 @@ $productspecimen = new Product($db); $productspecimen->initAsSpecimen(); $object = $productspecimen; $param = ''; -$actioncode = ''; -$status = ''; -$filter = ''; -$filtert = ''; -$socid = 0; -$type = 0; -$usergroup = 0; - -$sortfield = 'aaa'; +$actioncode = getDolGlobalString('MAIN_TEST_UI_ACTION_CODE'); // '' by default +$status = getDolGlobalString('MAIN_TEST_UI_STATUS'); // '' by default; +$filter = getDolGlobalString('MAIN_TEST_UI_FILTER'); // '' by default; +$filtert = getDolGlobalString('MAIN_TEST_UI_FILTERT'); // '' by default; +$socid = getDolGlobalInt('MAIN_TEST_UI_SOCID', 0); // 0 by default; +$type = getDolGlobalInt('MAIN_TEST_UI_TYPE', 0); // 0 by default; +$usergroup = getDolGlobalInt('MAIN_TEST_UI_USERGROUP', 0); // 0 by default; +$sortfield = getDolGlobalString('MAIN_TEST_UI_SORTFIELD', 'aaa'); // 'aaa' by default; $sortorder = 'ASC'; $tasksarray = array(1, 2, 3); // To force having several lines $tagidfortablednd = 'tablelines3'; @@ -265,18 +264,16 @@ $cate_arbo = array('field1' => 'value1d into the select list D', 'field2' => 'va $moreforfilter .= $form->selectarray('search_ddd', $cate_arbo, '', 1, 0, 0, '', 0, 0, 0, '', 'maxwidth300', 1); // List with js combo forced $moreforfilter .= '
'; -if (!empty($moreforfilter)) { - print '
'; - print $moreforfilter; - $parameters = array(); - $reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - print '
'; -} +print '
'; +print $moreforfilter; +$parameters = array(); +$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook +print $hookmanager->resPrint; +print '
'; ?> -" id="tablelines3"> +
" id="tablelines3"> trans('title1'), 0, $_SERVER["PHP_SELF"], 'aaa', '', '', 'align="left"', $sortfield, $sortorder); ?> diff --git a/htdocs/admin/tools/ui/components/test_buttons.php b/htdocs/admin/tools/ui/components/test_buttons.php index 619e91b3922..dbeba208def 100644 --- a/htdocs/admin/tools/ui/components/test_buttons.php +++ b/htdocs/admin/tools/ui/components/test_buttons.php @@ -1,7 +1,6 @@ - */ -/* + * * This program and files/directory inner it is free software: you can * redistribute it and/or modify it under the terms of the * GNU Affero General Public License (AGPL) as published by From ecd90383054e6e325085713e6f35e1dd4e40507d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 11:14:13 +0100 Subject: [PATCH 005/185] fix phpstan doc ui --- htdocs/admin/tools/ui/components/badges.php | 13 ++++++------- htdocs/admin/tools/ui/components/buttons.php | 13 ++++++------- htdocs/admin/tools/ui/components/event-message.php | 13 ++++++------- htdocs/admin/tools/ui/components/index.php | 13 ++++++------- htdocs/admin/tools/ui/components/progress-bars.php | 13 ++++++------- htdocs/admin/tools/ui/components/test_arrays.php | 13 ++++++------- htdocs/admin/tools/ui/components/test_buttons.php | 13 ++++++------- htdocs/admin/tools/ui/content/tables.php | 13 ++++++------- htdocs/admin/tools/ui/index.php | 13 ++++++------- 9 files changed, 54 insertions(+), 63 deletions(-) diff --git a/htdocs/admin/tools/ui/components/badges.php b/htdocs/admin/tools/ui/components/badges.php index b698113dac5..1fbe2947b25 100644 --- a/htdocs/admin/tools/ui/components/badges.php +++ b/htdocs/admin/tools/ui/components/badges.php @@ -3,19 +3,18 @@ * Copyright (C) 2024 Anthony Damhet * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ // Load Dolibarr environment diff --git a/htdocs/admin/tools/ui/components/buttons.php b/htdocs/admin/tools/ui/components/buttons.php index 62de3b23fce..777bef5d7d5 100644 --- a/htdocs/admin/tools/ui/components/buttons.php +++ b/htdocs/admin/tools/ui/components/buttons.php @@ -3,19 +3,18 @@ * Copyright (C) 2024 Anthony Damhet * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ // Load Dolibarr environment diff --git a/htdocs/admin/tools/ui/components/event-message.php b/htdocs/admin/tools/ui/components/event-message.php index 6065237d90b..78a038e0141 100644 --- a/htdocs/admin/tools/ui/components/event-message.php +++ b/htdocs/admin/tools/ui/components/event-message.php @@ -3,19 +3,18 @@ * Copyright (C) 2024 Anthony Damhet * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ // Load Dolibarr environment diff --git a/htdocs/admin/tools/ui/components/index.php b/htdocs/admin/tools/ui/components/index.php index e6023af16c7..409d96d22a7 100644 --- a/htdocs/admin/tools/ui/components/index.php +++ b/htdocs/admin/tools/ui/components/index.php @@ -3,19 +3,18 @@ * Copyright (C) 2024 Anthony Damhet * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ // Load Dolibarr environment diff --git a/htdocs/admin/tools/ui/components/progress-bars.php b/htdocs/admin/tools/ui/components/progress-bars.php index b53bb335d6e..1e290584423 100644 --- a/htdocs/admin/tools/ui/components/progress-bars.php +++ b/htdocs/admin/tools/ui/components/progress-bars.php @@ -3,19 +3,18 @@ * Copyright (C) 2024 Anthony Damhet * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ // Load Dolibarr environment diff --git a/htdocs/admin/tools/ui/components/test_arrays.php b/htdocs/admin/tools/ui/components/test_arrays.php index 553816c58d5..4a4fdf6baca 100644 --- a/htdocs/admin/tools/ui/components/test_arrays.php +++ b/htdocs/admin/tools/ui/components/test_arrays.php @@ -1,19 +1,18 @@ * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ diff --git a/htdocs/admin/tools/ui/components/test_buttons.php b/htdocs/admin/tools/ui/components/test_buttons.php index dbeba208def..0c7412ed719 100644 --- a/htdocs/admin/tools/ui/components/test_buttons.php +++ b/htdocs/admin/tools/ui/components/test_buttons.php @@ -1,19 +1,18 @@ * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ if (!defined('NOREQUIRESOC')) { diff --git a/htdocs/admin/tools/ui/content/tables.php b/htdocs/admin/tools/ui/content/tables.php index 2423fb690a6..9ab70ba6f38 100644 --- a/htdocs/admin/tools/ui/content/tables.php +++ b/htdocs/admin/tools/ui/content/tables.php @@ -3,19 +3,18 @@ * Copyright (C) 2024 Anthony Damhet * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ // Load Dolibarr environment diff --git a/htdocs/admin/tools/ui/index.php b/htdocs/admin/tools/ui/index.php index 548b6020e91..76baca72436 100644 --- a/htdocs/admin/tools/ui/index.php +++ b/htdocs/admin/tools/ui/index.php @@ -3,19 +3,18 @@ * Copyright (C) 2024 Anthony Damhet * Copyright (C) 2024 Frédéric France * - * This program and files/directory inner it is free software: you can - * redistribute it and/or modify it under the terms of the - * GNU Affero General Public License (AGPL) as published by - * the Free Software Foundation, either version 3 of the License, or + * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU AGPL for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU AGPL - * along with this program. If not, see . + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ // Load Dolibarr environment From 649051be6fc272181030f2e5cdb21cd809b69225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 11:24:51 +0100 Subject: [PATCH 006/185] clean baseline --- build/phpstan/phpstan-baseline.neon | 54 +++++++++++++++++++ htdocs/admin/tools/ui/components/buttons.php | 6 ++- .../tools/ui/components/test_buttons.php | 14 ++--- 3 files changed, 65 insertions(+), 9 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index 6b70662a01d..c5a090e5a2a 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -1962,6 +1962,60 @@ parameters: count: 2 path: ../../htdocs/admin/tools/purge.php + - + message: '#^Method Documentation\:\:displayMenu\(\) has parameter \$menu with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + + - + message: '#^Method Documentation\:\:displaySummary\(\) has parameter \$menu with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + + - + message: '#^Method Documentation\:\:setMenu\(\) should return mixed but return statement is missing\.$#' + identifier: return.missing + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + + - + message: '#^Method Documentation\:\:showCode\(\) has parameter \$lines with no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + + - + message: '#^Property Documentation\:\:\$menu type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + + - + message: '#^Property Documentation\:\:\$summary type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + + - + message: '#^Property Documentation\:\:\$view type has no value type specified in iterable type array\.$#' + identifier: missingType.iterableValue + count: 1 + path: ../../htdocs/admin/tools/ui/class/documentation.class.php + + - + message: '#^Parameter \#7 \$params of function dolGetButtonAction expects array\{confirm\?\: array\{url\?\: string, title\?\: string, content\?\: string, action\-btn\-label\?\: string, cancel\-btn\-label\?\: string, modal\?\: bool\}, attr\?\: array\, areDropdownButtons\?\: bool, backtopage\?\: string, lang\?\: string, enabled\?\: bool, perm\?\: int\<0, 1\>, label\?\: string, \.\.\.\}, array\{confirm\: true\} given\.$#' + identifier: argument.type + count: 2 + path: ../../htdocs/admin/tools/ui/components/buttons.php + + - + message: '#^Parameter \#7 \$params of function dolGetButtonAction expects array\{confirm\?\: array\{url\?\: string, title\?\: string, content\?\: string, action\-btn\-label\?\: string, cancel\-btn\-label\?\: string, modal\?\: bool\}, attr\?\: array\, areDropdownButtons\?\: bool, backtopage\?\: string, lang\?\: string, enabled\?\: bool, perm\?\: int\<0, 1\>, label\?\: string, \.\.\.\}, array\{confirm\: true\} given\.$#' + identifier: argument.type + count: 2 + path: ../../htdocs/admin/tools/ui/components/test_buttons.php + - message: '#^Variable \$massactionbutton in empty\(\) always exists and is always falsy\.$#' identifier: empty.variable diff --git a/htdocs/admin/tools/ui/components/buttons.php b/htdocs/admin/tools/ui/components/buttons.php index 777bef5d7d5..fcea0cf0358 100644 --- a/htdocs/admin/tools/ui/components/buttons.php +++ b/htdocs/admin/tools/ui/components/buttons.php @@ -217,13 +217,15 @@ $documentation->showSidebar(); ?> 'lang'=>'documentation@documentation', 'url'=> $submenu_url.'#'.$id, 'label' => 'My SubAction 1', - 'perm' => 1 + 'perm' => true, + 'enabled' => true, ), array( 'lang'=>'documentation@documentation', 'url'=> $submenu_url.'#'.$id, 'label' => 'My SubAction 2', - 'perm' => 0 + 'perm' => false, + 'enabled' => true, ), ); $params = array(); diff --git a/htdocs/admin/tools/ui/components/test_buttons.php b/htdocs/admin/tools/ui/components/test_buttons.php index 0c7412ed719..5fbe11b0676 100644 --- a/htdocs/admin/tools/ui/components/test_buttons.php +++ b/htdocs/admin/tools/ui/components/test_buttons.php @@ -154,7 +154,7 @@ llxHeader('', 'Documentation and examples for theme'); $url = '#'.$id; $userRight = 1; $params = array( - 'confirm' => true + 'confirm' => true ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); @@ -167,13 +167,13 @@ llxHeader('', 'Documentation and examples for theme'); $url = $_SERVER['PHP_SELF'] . '?token='.newToken().'#'.$id; $params = array( - 'confirm' => array( + 'confirm' => array( 'url' => 'your confirm action url', 'title' => 'Your title to display', 'action-btn-label' => 'Your confirm label', 'cancel-btn-label' => 'Your cancel label', 'content' => 'Content to display with HTML compatible
  • test 01
  • test 02
  • test 03
' - ) + ) ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); @@ -193,7 +193,7 @@ llxHeader('', 'Documentation and examples for theme'); $url = '#'.$id; $userRight = 0; $params = array( - 'confirm' => true + 'confirm' => true, ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); @@ -206,13 +206,13 @@ llxHeader('', 'Documentation and examples for theme'); $url = $_SERVER['PHP_SELF'] . '?token='.newToken().'#'.$id; $params = array( - 'confirm' => array( + 'confirm' => array( 'url' => 'your confirm action url', 'title' => 'Your title to display', 'action-btn-label' => 'Your confirm label', 'cancel-btn-label' => 'Your cancel label', - 'content' => 'Content to display with HTML compatible
  • test 01
  • test 02
  • test 03
' - ) + 'content' => 'Content to display with HTML compatible
  • test 01
  • test 02
  • test 03
', + ) ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); From 4a300cfdf0d1856eeeffdb7cf13887ce9a1ee827 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 12:50:49 +0100 Subject: [PATCH 007/185] clean baseline --- build/phpstan/phpstan-baseline.neon | 6 ------ htdocs/admin/tools/ui/components/test_buttons.php | 6 +++--- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index c5a090e5a2a..53d18a78fc1 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -2010,12 +2010,6 @@ parameters: count: 2 path: ../../htdocs/admin/tools/ui/components/buttons.php - - - message: '#^Parameter \#7 \$params of function dolGetButtonAction expects array\{confirm\?\: array\{url\?\: string, title\?\: string, content\?\: string, action\-btn\-label\?\: string, cancel\-btn\-label\?\: string, modal\?\: bool\}, attr\?\: array\, areDropdownButtons\?\: bool, backtopage\?\: string, lang\?\: string, enabled\?\: bool, perm\?\: int\<0, 1\>, label\?\: string, \.\.\.\}, array\{confirm\: true\} given\.$#' - identifier: argument.type - count: 2 - path: ../../htdocs/admin/tools/ui/components/test_buttons.php - - message: '#^Variable \$massactionbutton in empty\(\) always exists and is always falsy\.$#' identifier: empty.variable diff --git a/htdocs/admin/tools/ui/components/test_buttons.php b/htdocs/admin/tools/ui/components/test_buttons.php index 5fbe11b0676..449196c25a2 100644 --- a/htdocs/admin/tools/ui/components/test_buttons.php +++ b/htdocs/admin/tools/ui/components/test_buttons.php @@ -154,7 +154,7 @@ llxHeader('', 'Documentation and examples for theme'); $url = '#'.$id; $userRight = 1; $params = array( - 'confirm' => true + 'confirm' => [], ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); @@ -172,7 +172,7 @@ llxHeader('', 'Documentation and examples for theme'); 'title' => 'Your title to display', 'action-btn-label' => 'Your confirm label', 'cancel-btn-label' => 'Your cancel label', - 'content' => 'Content to display with HTML compatible
  • test 01
  • test 02
  • test 03
' + 'content' => 'Content to display with HTML compatible
  • test 01
  • test 02
  • test 03
', ) ); @@ -193,7 +193,7 @@ llxHeader('', 'Documentation and examples for theme'); $url = '#'.$id; $userRight = 0; $params = array( - 'confirm' => true, + 'confirm' => [], ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); From e285982eaee6bd0d99ab670545f08295edaa87e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 12:52:07 +0100 Subject: [PATCH 008/185] clean baseline --- htdocs/admin/tools/ui/components/buttons.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/tools/ui/components/buttons.php b/htdocs/admin/tools/ui/components/buttons.php index fcea0cf0358..b33eecfa6fc 100644 --- a/htdocs/admin/tools/ui/components/buttons.php +++ b/htdocs/admin/tools/ui/components/buttons.php @@ -147,7 +147,7 @@ $documentation->showSidebar(); ?> $id = 'button-id-7'; $url = '#'.$id; $params = array( - 'confirm' => true + 'confirm' => [], ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); @@ -173,7 +173,7 @@ $documentation->showSidebar(); ?> $id = 'button-id-9'; $url = '#'.$id; $params = array( - 'confirm' => true + 'confirm' => [], ); print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params); ?> From 71d532062aae5bd04a4d7a1452ef7af60bf8ac1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 12:52:34 +0100 Subject: [PATCH 009/185] clean baseline --- build/phpstan/phpstan-baseline.neon | 6 ------ 1 file changed, 6 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index 53d18a78fc1..b79a2dd2419 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -2004,12 +2004,6 @@ parameters: count: 1 path: ../../htdocs/admin/tools/ui/class/documentation.class.php - - - message: '#^Parameter \#7 \$params of function dolGetButtonAction expects array\{confirm\?\: array\{url\?\: string, title\?\: string, content\?\: string, action\-btn\-label\?\: string, cancel\-btn\-label\?\: string, modal\?\: bool\}, attr\?\: array\, areDropdownButtons\?\: bool, backtopage\?\: string, lang\?\: string, enabled\?\: bool, perm\?\: int\<0, 1\>, label\?\: string, \.\.\.\}, array\{confirm\: true\} given\.$#' - identifier: argument.type - count: 2 - path: ../../htdocs/admin/tools/ui/components/buttons.php - - message: '#^Variable \$massactionbutton in empty\(\) always exists and is always falsy\.$#' identifier: empty.variable From 793ca018670ebe9f752d4c016b091266b5f8c806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 12:57:30 +0100 Subject: [PATCH 010/185] clean baseline --- htdocs/admin/tools/ui/components/buttons.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/tools/ui/components/buttons.php b/htdocs/admin/tools/ui/components/buttons.php index b33eecfa6fc..b2a947ebe17 100644 --- a/htdocs/admin/tools/ui/components/buttons.php +++ b/htdocs/admin/tools/ui/components/buttons.php @@ -182,7 +182,7 @@ $documentation->showSidebar(); ?> ' true', + ' \'confirm\' => [],', ');', '', '// Custom parameters', @@ -192,7 +192,7 @@ $documentation->showSidebar(); ?> ' \'title\' => \'Your title to display\',', ' \'action-btn-label\' => \'Your confirm label\',', ' \'cancel-btn-label\' => \'Your cancel label\',', - ' \'content\' => \'Content to display with HTML compatible
  • test 01
  • test 02
  • test 03
\'', + ' \'content\' => \'Content to display with HTML compatible
  • test 01
  • test 02
  • test 03
\',', ' )', ');', '', From 49846ca14912282ebd1978f91e73e6a3a1c4396f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 13:34:37 +0100 Subject: [PATCH 011/185] use ace editor to display source code --- .../tools/ui/class/documentation.class.php | 16 ++++++------ htdocs/admin/tools/ui/components/badges.php | 7 ++++- htdocs/admin/tools/ui/components/buttons.php | 26 +++++++++---------- .../tools/ui/components/event-message.php | 13 +++++++--- .../tools/ui/components/progress-bars.php | 8 +++++- 5 files changed, 42 insertions(+), 28 deletions(-) diff --git a/htdocs/admin/tools/ui/class/documentation.class.php b/htdocs/admin/tools/ui/class/documentation.class.php index 06a919d274f..437c762c0c6 100644 --- a/htdocs/admin/tools/ui/class/documentation.class.php +++ b/htdocs/admin/tools/ui/class/documentation.class.php @@ -388,16 +388,16 @@ class Documentation * Output a View Code area * * @param array $lines Lines of code to show + * @param string $option Source code language ('html', 'php' etc) * @return void */ - public function showCode($lines = array()) + public function showCode($lines = array(), $option = 'html') { - print '
';
-		if (!empty($lines)) {
-			foreach ($lines as $lineofcode) {
-				print dol_htmlentities($lineofcode).'
'; - } - } - print '
'; + require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; + print '
'; + $content = implode("\n", $lines); + $doleditor = new DolEditor(md5($content), $content, '', 0, 'Basic', 'In', true, false, 'ace', 0, '99%', 1); + print $doleditor->Create(1, '', false, '', $option); + print '
'; } } diff --git a/htdocs/admin/tools/ui/components/badges.php b/htdocs/admin/tools/ui/components/badges.php index 1fbe2947b25..0d147b603be 100644 --- a/htdocs/admin/tools/ui/components/badges.php +++ b/htdocs/admin/tools/ui/components/badges.php @@ -41,8 +41,13 @@ $langs->load('uxdocumentation'); // $documentation = new Documentation($db); +$morejs = [ + '/includes/ace/src/ace.js', + '/includes/ace/src/ext-statusbar.js', + '/includes/ace/src/ext-language_tools.js', +]; // Output html head + body - Param is Title -$documentation->docHeader('Badges'); +$documentation->docHeader('Badges', $morejs); // Set view for menu and breadcrumb // Menu must be set in constructor of documentation class diff --git a/htdocs/admin/tools/ui/components/buttons.php b/htdocs/admin/tools/ui/components/buttons.php index b2a947ebe17..63aabb3c586 100644 --- a/htdocs/admin/tools/ui/components/buttons.php +++ b/htdocs/admin/tools/ui/components/buttons.php @@ -40,9 +40,13 @@ $langs->load('uxdocumentation'); // $documentation = new Documentation($db); - +$morejs = [ + '/includes/ace/src/ace.js', + '/includes/ace/src/ext-statusbar.js', + '/includes/ace/src/ext-language_tools.js', +]; // Output html head + body - Param is Title -$documentation->docHeader('Buttons'); +$documentation->docHeader('Buttons', $morejs); // Set view for menu and breadcrumb // Menu must be set in constructor of documentation class @@ -131,7 +135,7 @@ $documentation->showSidebar(); ?> ' */', 'print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);', ); - echo $documentation->showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?> @@ -198,7 +202,7 @@ $documentation->showSidebar(); ?> '', 'print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);', ); - echo $documentation->showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?> @@ -255,7 +259,7 @@ $documentation->showSidebar(); ?> ');', 'print dolGetButtonAction($label, $html, $actionType, $url, $id, $userRight, $params);' ); - echo $documentation->showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?> @@ -282,7 +286,7 @@ $documentation->showSidebar(); ?> 'print \' \';', ); - echo $documentation->showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?> @@ -322,7 +326,7 @@ $documentation->showSidebar(); ?> trans('Label'); + $btnLabel = $langs->trans('Label', 'php'); print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', 0, ['forcenohideoftext'=>1]); // Not Enough Permissions print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', 1, ['forcenohideoftext'=>1]); // Active print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', 2, ['forcenohideoftext'=>1]); // Active and selected @@ -348,15 +352,9 @@ $documentation->showSidebar(); ?> '$status = -2; // Disabled without info', 'print dolGetButtonTitle($btnLabel, \'\', \'fa fa-download\', \'#\', \'\', $status, [\'forcenohideoftext\'=>1]);', ); - echo $documentation->showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?> - - - - - - diff --git a/htdocs/admin/tools/ui/components/event-message.php b/htdocs/admin/tools/ui/components/event-message.php index 78a038e0141..f612f05a0c2 100644 --- a/htdocs/admin/tools/ui/components/event-message.php +++ b/htdocs/admin/tools/ui/components/event-message.php @@ -57,9 +57,13 @@ if ($action == 'displayeventmessage') { // $documentation = new Documentation($db); - +$morejs = [ + '/includes/ace/src/ace.js', + '/includes/ace/src/ext-statusbar.js', + '/includes/ace/src/ext-language_tools.js', +]; // Output html head + body - Param is Title -$documentation->docHeader('SetEventMessages'); +$documentation->docHeader('SetEventMessages', $morejs); // Set view for menu and breadcrumb // Menu must be set in constructor of documentation class @@ -123,7 +127,7 @@ $documentation->showSidebar(); ?> 'setEventMessages("message", null);', 'setEventMessages(null, messages[]);', ); - echo $documentation->showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?> @@ -158,11 +162,12 @@ $documentation->showSidebar(); ?> showCode($lines); ?> + echo $documentation->showCode($lines, 'php'); ?> diff --git a/htdocs/admin/tools/ui/components/progress-bars.php b/htdocs/admin/tools/ui/components/progress-bars.php index 1e290584423..fda0b0527fc 100644 --- a/htdocs/admin/tools/ui/components/progress-bars.php +++ b/htdocs/admin/tools/ui/components/progress-bars.php @@ -41,8 +41,13 @@ $langs->load('uxdocumentation'); // $documentation = new Documentation($db); +$morejs = [ + '/includes/ace/src/ace.js', + '/includes/ace/src/ext-statusbar.js', + '/includes/ace/src/ext-language_tools.js', +]; // Output html head + body - Param is Title -$documentation->docHeader('Progress-bars'); +$documentation->docHeader('Progress-bars', $morejs); // Set view for menu and breadcrumb // Menu must be set in constructor of documentation class @@ -250,6 +255,7 @@ $documentation->showSidebar(); ?> '
', '', '', + '', ); echo $documentation->showCode($lines); ?> From f1adc0fe828a2985cd1fadade82d3b178360504b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 13:55:12 +0100 Subject: [PATCH 012/185] can set ace editor to readonly --- htdocs/core/class/doleditor.class.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index 8d287b33a81..94edfbce43c 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -394,9 +394,10 @@ class DolEditor $out .= ''."\n"; } From c272a1242cf4cabb956b977e13c6013847c28bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sat, 23 Nov 2024 14:19:29 +0100 Subject: [PATCH 013/185] can set ace editor to readonly --- htdocs/admin/tools/ui/class/documentation.class.php | 2 +- htdocs/admin/tools/ui/components/buttons.php | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/tools/ui/class/documentation.class.php b/htdocs/admin/tools/ui/class/documentation.class.php index 437c762c0c6..4de7133c9e6 100644 --- a/htdocs/admin/tools/ui/class/documentation.class.php +++ b/htdocs/admin/tools/ui/class/documentation.class.php @@ -395,7 +395,7 @@ class Documentation { require_once DOL_DOCUMENT_ROOT . '/core/class/doleditor.class.php'; print '
'; - $content = implode("\n", $lines); + $content = implode("\n", $lines) . "\n"; $doleditor = new DolEditor(md5($content), $content, '', 0, 'Basic', 'In', true, false, 'ace', 0, '99%', 1); print $doleditor->Create(1, '', false, '', $option); print '
'; diff --git a/htdocs/admin/tools/ui/components/buttons.php b/htdocs/admin/tools/ui/components/buttons.php index 63aabb3c586..0fe09e06d02 100644 --- a/htdocs/admin/tools/ui/components/buttons.php +++ b/htdocs/admin/tools/ui/components/buttons.php @@ -322,10 +322,9 @@ $documentation->showSidebar(); ?> 'print dolGetButtonTitle($btnLabel, \'\', \'fa fa-file\', \'#\', \'\', $status);', ); - echo $documentation->showCode($lines); ?>
+ echo $documentation->showCode($lines, 'php'); ?>
trans('Label', 'php'); print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', 0, ['forcenohideoftext'=>1]); // Not Enough Permissions print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', 1, ['forcenohideoftext'=>1]); // Active @@ -333,7 +332,6 @@ $documentation->showSidebar(); ?> print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', -1, ['forcenohideoftext'=>1]); // Functionality is disabled print dolGetButtonTitle($btnLabel, '', 'fa fa-download', '#', '', -2, ['forcenohideoftext'=>1]); // Disabled without info - ?>
From 8a50ddaf9207cb8865e4e8b810949ed0f58eb86c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 26 Nov 2024 08:12:27 +0100 Subject: [PATCH 014/185] restore code --- htdocs/admin/tools/ui/components/test_arrays.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/admin/tools/ui/components/test_arrays.php b/htdocs/admin/tools/ui/components/test_arrays.php index 4a4fdf6baca..0e02e1b8885 100644 --- a/htdocs/admin/tools/ui/components/test_arrays.php +++ b/htdocs/admin/tools/ui/components/test_arrays.php @@ -24,8 +24,14 @@ require '../../../../main.inc.php'; * @var HookManager $hookmanager * @var Translate $langs * @var User $user + * + * @var int $dolibarr_main_prod */ +// Security +if ($dolibarr_main_prod) { + accessforbidden('Access forbidden when $dolibarr_main_prod is set to 1'); +} // Protection if external user if ($user->socid > 0) { accessforbidden(); From 46581d588625fe67e61ae25d073ea712df325566 Mon Sep 17 00:00:00 2001 From: Irvine Fleith Date: Tue, 26 Nov 2024 09:42:32 +0100 Subject: [PATCH 015/185] FIX : Hidden dropdown download link in project --- htdocs/projet/element.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index f91fefb9f27..59b35e98599 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -1288,7 +1288,7 @@ foreach ($listofreferent as $key => $value) { print "\n"; // Ref - print '
\n"; // Product and qty on stock movement From 89fc9ac8eafa2e34c6aa52e747ceed8e0c08c5c9 Mon Sep 17 00:00:00 2001 From: Pichi1966 <57623859+josett225@users.noreply.github.com> Date: Sun, 1 Dec 2024 18:55:31 +0100 Subject: [PATCH 017/185] FIX Accounting Closure Duplicates and more Update bookkeeping.class.php FIX I did further testing and investigation and I fixed the following issues that stop doing a full closure without duplicate lines generated by an unclean database : - different label_compte with same account number - removing label_compte is raising an issue and the code in the line around 2770 $bookkeeping->label_compte = $obj->label_compte; - different subledger_label with same subledger_account - empty versus null values for subledger_label and subledger_account - opening_balance is 0 as it creates a bookkeeping entry for now. FIX - Update Accounting closure with missing too many A-Nouveau #30039) --- .../accountancy/class/bookkeeping.class.php | 56 ++++++++++++++----- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index be140363e3c..834df5b690c 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -2692,10 +2692,8 @@ class BookKeeping extends CommonObject $sql = 'SELECT'; $sql .= " t.numero_compte,"; - $sql .= " t.label_compte,"; if ($separate_auxiliary_account) { - $sql .= " t.subledger_account,"; - $sql .= " t.subledger_label,"; + $sql .= " NULLIF(t.subledger_account, '') as subledger_account,"; // fix db issues with Null or "" values } $sql .= " aa.pcg_type,"; $sql .= " (SUM(t.credit) - SUM(t.debit)) as opening_balance"; @@ -2707,10 +2705,11 @@ class BookKeeping extends CommonObject $sql .= ' AND aa.pcg_type IN (' . $this->db->sanitize(implode(',', $pcg_type_filter), 1) . ')'; $sql .= " AND DATE(t.doc_date) >= '" . $this->db->idate($fiscal_period->date_start) . "'"; $sql .= " AND DATE(t.doc_date) <= '" . $this->db->idate($fiscal_period->date_end) . "'"; - $sql .= ' GROUP BY t.numero_compte, t.label_compte, aa.pcg_type'; + $sql .= ' GROUP BY t.numero_compte, aa.pcg_type'; if ($separate_auxiliary_account) { - $sql .= ' ,t.subledger_account, t.subledger_label'; + $sql .= " , NULLIF(t.subledger_account, '')"; } + $sql .= ' HAVING (SUM(t.credit) - SUM(t.debit)) != 0 '; // Exclude rows with opening_balance = 0 $sql .= $this->db->order("t.numero_compte", "ASC"); $resql = $this->db->query($sql); @@ -2732,23 +2731,38 @@ class BookKeeping extends CommonObject $bookkeeping = new BookKeeping($this->db); $bookkeeping->doc_date = $new_fiscal_period->date_start; $bookkeeping->date_lim_reglement = ''; - $bookkeeping->doc_ref = $new_fiscal_period->label; + $bookkeeping->doc_ref = $fiscal_period->label; $bookkeeping->date_creation = $now; $bookkeeping->doc_type = 'closure'; - $bookkeeping->fk_doc = $new_fiscal_period->id; + $bookkeeping->fk_doc = $fiscal_period->id; $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add $bookkeeping->thirdparty_code = ''; if ($separate_auxiliary_account) { $bookkeeping->subledger_account = $obj->subledger_account; - $bookkeeping->subledger_label = $obj->subledger_label; + $sql = 'SELECT'; + $sql .= " subledger_label"; + $sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element; + $sql .= " WHERE subledger_account = '" . $this->db->escape($obj->subledger_account) . "'"; + $sql .= " ORDER BY doc_date DESC"; + $sql .= " LIMIT 1"; + $result = $this->db->query($sql); + if (!$result) { + $this->errors[] = 'Error: ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + $error++; + } + $objtmp = $this->db->fetch_object($result); + $bookkeeping->subledger_label = $objtmp->subledger_label; // latest subledger label used } else { - $bookkeeping->subledger_account = ''; - $bookkeeping->subledger_label = ''; + $bookkeeping->subledger_account = null; + $bookkeeping->subledger_label = null; } $bookkeeping->numero_compte = $obj->numero_compte; - $bookkeeping->label_compte = $obj->label_compte; + $accountingaccount = new AccountingAccount($this->db); + $accountingaccount->fetch('', $obj->numero_compte); + $bookkeeping->label_compte = $accountingaccount->label; // latest account label used $bookkeeping->label_operation = $new_fiscal_period->label; $bookkeeping->montant = $mt; @@ -2787,12 +2801,24 @@ class BookKeeping extends CommonObject $bookkeeping->thirdparty_code = ''; if ($separate_auxiliary_account) { - $bookkeeping->subledger_label = ''; $bookkeeping->subledger_account = $obj->subledger_account; - $bookkeeping->subledger_label = $obj->subledger_label; + $sql = 'SELECT'; + $sql .= " subledger_label"; + $sql .= " FROM " . MAIN_DB_PREFIX . $this->table_element; + $sql .= " WHERE subledger_account = '" . $this->db->escape($obj->subledger_account) . "'"; + $sql .= " ORDER BY doc_date DESC"; + $sql .= " LIMIT 1"; + $result = $this->db->query($sql); + if (!$result) { + $this->errors[] = 'Error: ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + $error++; + } + $objtmp = $this->db->fetch_object($result); + $bookkeeping->subledger_label = $objtmp->subledger_label; // latest subledger label used } else { - $bookkeeping->subledger_account = ''; - $bookkeeping->subledger_label = ''; + $bookkeeping->subledger_account = null; + $bookkeeping->subledger_label = null; } $bookkeeping->numero_compte = $accountingaccount->account_number; From 7e3624ee27f4b3db157d8a1391cc98125b2f1fd0 Mon Sep 17 00:00:00 2001 From: Pichi1966 <57623859+josett225@users.noreply.github.com> Date: Sun, 1 Dec 2024 19:08:53 +0100 Subject: [PATCH 018/185] Clean Spaces versu tab --- htdocs/accountancy/class/bookkeeping.class.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 834df5b690c..527049ea06b 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -3,6 +3,7 @@ * Copyright (C) 2015-2022 Alexandre Spangaro * Copyright (C) 2015-2020 Florian Henry * Copyright (C) 2018-2020 Frédéric France + * Copyright (C) 2024 Jose MARTINEZ * * 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 @@ -2748,9 +2749,9 @@ class BookKeeping extends CommonObject $sql .= " LIMIT 1"; $result = $this->db->query($sql); if (!$result) { - $this->errors[] = 'Error: ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); - $error++; + $this->errors[] = 'Error: ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + $error++; } $objtmp = $this->db->fetch_object($result); $bookkeeping->subledger_label = $objtmp->subledger_label; // latest subledger label used @@ -2810,9 +2811,9 @@ class BookKeeping extends CommonObject $sql .= " LIMIT 1"; $result = $this->db->query($sql); if (!$result) { - $this->errors[] = 'Error: ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); - $error++; + $this->errors[] = 'Error: ' . $this->db->lasterror(); + dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + $error++; } $objtmp = $this->db->fetch_object($result); $bookkeeping->subledger_label = $objtmp->subledger_label; // latest subledger label used From cae32863ae4eb9d9f7869674ba0ec5c2ba77f0e6 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 5 Dec 2024 10:35:34 +0100 Subject: [PATCH 019/185] fix: fatal error php 8, invoice situation --- htdocs/compta/facture/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 1fbe7c56502..29e5c0f369e 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2742,7 +2742,7 @@ if (empty($reshook)) { // Invoice situation if (getDolGlobalInt('INVOICE_USE_SITUATION') == 2) { $previousprogress = $line->get_allprev_progress($line->fk_facture); - $fullprogress = price2num(GETPOST('progress', 'alpha')); + $fullprogress = price2num(GETPOST('progress', 'alpha'), 'MU'); if ($fullprogress < $previousprogress) { $error++; From 4ebb0a121a4bccaddb2f6b2e6edf6bc8b61cedd1 Mon Sep 17 00:00:00 2001 From: Maximilien Valenzano Date: Fri, 6 Dec 2024 19:16:00 +0100 Subject: [PATCH 020/185] fix(invoice): mutlicurrency_tx correct value --- htdocs/compta/facture/card.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 1fbe7c56502..e6296d0860f 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1093,7 +1093,7 @@ if (empty($reshook)) { $object->fk_incoterms = GETPOSTINT('incoterm_id'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); - $object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx'); + $object->multicurrency_tx = GETPOST('originmulticurrency_tx'); // Special properties of replacement invoice $object->fk_facture_source = GETPOSTINT('fac_replacement'); @@ -1154,7 +1154,7 @@ if (empty($reshook)) { $object->fk_incoterms = GETPOSTINT('incoterm_id'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); - $object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx'); + $object->multicurrency_tx = GETPOST('originmulticurrency_tx'); // Special properties of replacement invoice $object->fk_facture_source = $sourceinvoice > 0 ? $sourceinvoice : ''; @@ -1393,7 +1393,7 @@ if (empty($reshook)) { $object->fk_incoterms = GETPOSTINT('incoterm_id'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); - $object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx'); + $object->multicurrency_tx = GETPOST('originmulticurrency_tx'); // Source facture $object->fac_rec = GETPOSTINT('fac_rec'); @@ -1480,7 +1480,7 @@ if (empty($reshook)) { $object->fk_incoterms = GETPOSTINT('incoterm_id'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); - $object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx'); + $object->multicurrency_tx = GETPOST('originmulticurrency_tx'); if (GETPOST('type') == Facture::TYPE_SITUATION) { $object->situation_counter = 1; From 25e32241218341fc8f34763342a4fa8fb7774b9b Mon Sep 17 00:00:00 2001 From: Pichi1966 <57623859+josett225@users.noreply.github.com> Date: Sun, 8 Dec 2024 11:36:26 +0100 Subject: [PATCH 021/185] Close #30039 and port code on this one This will help to better and understand and follow this fix --- htdocs/accountancy/class/bookkeeping.class.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 527049ea06b..bb6d102843d 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -27,6 +27,7 @@ // Class require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/commonobjectline.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/fiscalyear.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php'; require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php'; @@ -328,7 +329,7 @@ class BookKeeping extends CommonObject $this->piece_num = 0; // First check if line not yet already in bookkeeping. - // Note that we must include 'doc_type - fk_doc - numero_compte - label' to be sure to have unicity of line (because we may have several lines + // Note that we must include 'doc_type - fk_doc - numero_compte - label - subledger_account (if not empty)' to be sure to have unicity of line (because we may have several lines // with same doc_type, fk_doc, numero_compte for 1 invoice line when using localtaxes with same account) // WARNING: This is not reliable, label may have been modified. This is just a small protection. // The page that make transfer make the test on couple (doc_type - fk_doc) only. @@ -342,6 +343,9 @@ class BookKeeping extends CommonObject } $sql .= " AND numero_compte = '".$this->db->escape($this->numero_compte)."'"; $sql .= " AND label_operation = '".$this->db->escape($this->label_operation)."'"; + if (!empty($this->subledger_account)) { + $sql .= " AND subledger_account = '".$this->db->escape($this->subledger_account)."'"; + } $sql .= " AND entity = ".$conf->entity; // Do not use getEntity for accounting features $resql = $this->db->query($sql); From c7329a723eb8f55c96e9b61a53625f6bb9267559 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Sun, 8 Dec 2024 12:23:06 +0100 Subject: [PATCH 022/185] fix: fatal error php 8, invoice situation --- htdocs/compta/facture/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 29e5c0f369e..52ca49863c3 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2742,7 +2742,7 @@ if (empty($reshook)) { // Invoice situation if (getDolGlobalInt('INVOICE_USE_SITUATION') == 2) { $previousprogress = $line->get_allprev_progress($line->fk_facture); - $fullprogress = price2num(GETPOST('progress', 'alpha'), 'MU'); + $fullprogress = price2num(GETPOST('progress', 'alpha'), 2); if ($fullprogress < $previousprogress) { $error++; From 25d0d4e851b881bafbf28880e7afe6c4cc5235fe Mon Sep 17 00:00:00 2001 From: Maximilien Valenzano Date: Mon, 9 Dec 2024 09:47:37 +0100 Subject: [PATCH 023/185] fix(invoice): mutlicurrency_tx correct value by float on compta & fourn --- htdocs/compta/facture/card.php | 2 +- htdocs/fourn/facture/card.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index e6296d0860f..b4e8128ffaa 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1093,7 +1093,7 @@ if (empty($reshook)) { $object->fk_incoterms = GETPOSTINT('incoterm_id'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); - $object->multicurrency_tx = GETPOST('originmulticurrency_tx'); + $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx'); // Special properties of replacement invoice $object->fk_facture_source = GETPOSTINT('fac_replacement'); diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index ed924373e5e..16bc4adf788 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -836,7 +836,7 @@ if (empty($reshook)) { $object->fk_incoterms = GETPOSTINT('incoterm_id'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); - $object->multicurrency_tx = GETPOSTINT('originmulticurrency_tx'); + $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx'); $object->transport_mode_id = GETPOSTINT('transport_mode_id'); // Proprietes particulieres a facture de replacement From 82e092fda38a7dce0f9946f287aa9f04bee473f7 Mon Sep 17 00:00:00 2001 From: Jyhere Date: Mon, 9 Dec 2024 11:44:09 +0100 Subject: [PATCH 024/185] FIX: deleting a reception do not create reverse stock movements --- htdocs/reception/class/reception.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 86e8d046ff9..7154ad16eac 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -1116,7 +1116,7 @@ class Reception extends CommonObject $this->db->begin(); // Stock control - if (isModEnabled('stock') && !getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION') && $this->statut > 0) { + if (isModEnabled('stock') && getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION') && $this->statut > 0) { require_once DOL_DOCUMENT_ROOT."/product/stock/class/mouvementstock.class.php"; $langs->load("agenda"); @@ -1140,7 +1140,7 @@ class Reception extends CommonObject // we do not log origin because it will be deleted $mouvS->origin = null; - $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, 0, $langs->trans("ReceptionDeletedInDolibarr", $this->ref), '', $obj->eatby, $obj->sellby, $obj->batch); // Price is set to 0, because we don't want to see WAP changed + $result = $mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, 0, $langs->trans("ReceptionDeletedInDolibarr", $this->ref), '', $obj->eatby ? $this->db->jdate($obj->eatby) : null, $obj->sellby ? $this->db->jdate($obj->sellby) : null, $obj->batch); // Price is set to 0, because we don't want to see WAP changed if ($result < 0) { $error++; $this->error = $mouvS->error; From b86c1b22f4d4a120619f5a33d02f9a6b3a498afe Mon Sep 17 00:00:00 2001 From: Pichi1966 <57623859+josett225@users.noreply.github.com> Date: Mon, 9 Dec 2024 12:46:47 +0100 Subject: [PATCH 025/185] Update Closure Income Labels --- htdocs/accountancy/class/bookkeeping.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index bb6d102843d..c93a8e47b57 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -2798,10 +2798,10 @@ class BookKeeping extends CommonObject $bookkeeping = new BookKeeping($this->db); $bookkeeping->doc_date = $new_fiscal_period->date_start; $bookkeeping->date_lim_reglement = ''; - $bookkeeping->doc_ref = $new_fiscal_period->label; + $bookkeeping->doc_ref = $fiscal_period->label; $bookkeeping->date_creation = $now; $bookkeeping->doc_type = 'closure'; - $bookkeeping->fk_doc = $new_fiscal_period->id; + $bookkeeping->fk_doc = $fiscal_period->id; $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add $bookkeeping->thirdparty_code = ''; From 505449451b21d23300c6824d9b6f3e6e22a3203f Mon Sep 17 00:00:00 2001 From: John BOTELLA <68917336+thersane-john@users.noreply.github.com> Date: Mon, 9 Dec 2024 14:41:57 +0100 Subject: [PATCH 026/185] fix hook result --- htdocs/core/lib/pdf.lib.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 92b538c5824..5358fa5af52 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -2618,8 +2618,9 @@ function pdf_getLinkedObjects(&$object, $outputlangs) if (is_object($hookmanager)) { $parameters = array('linkedobjects' => $linkedobjects, 'outputlangs' => $outputlangs); $action = ''; - $hookmanager->executeHooks('pdf_getLinkedObjects', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks - if (!empty($hookmanager->resArray)) { + $reshook = $hookmanager->executeHooks('pdf_getLinkedObjects', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + if ($reshook>0) { + // The array must be reinserted even if it is empty because clearing the array could be one of the actions performed by the hook. $linkedobjects = $hookmanager->resArray; } } From 15d953643b3498ccc2746757a56debbc5fdcd4b0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 9 Dec 2024 15:00:49 +0100 Subject: [PATCH 027/185] Update card.php --- htdocs/compta/facture/card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index b4e8128ffaa..58879c7a831 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1154,7 +1154,7 @@ if (empty($reshook)) { $object->fk_incoterms = GETPOSTINT('incoterm_id'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); - $object->multicurrency_tx = GETPOST('originmulticurrency_tx'); + $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx'); // Special properties of replacement invoice $object->fk_facture_source = $sourceinvoice > 0 ? $sourceinvoice : ''; @@ -1393,7 +1393,7 @@ if (empty($reshook)) { $object->fk_incoterms = GETPOSTINT('incoterm_id'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); - $object->multicurrency_tx = GETPOST('originmulticurrency_tx'); + $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx'); // Source facture $object->fac_rec = GETPOSTINT('fac_rec'); @@ -1480,7 +1480,7 @@ if (empty($reshook)) { $object->fk_incoterms = GETPOSTINT('incoterm_id'); $object->location_incoterms = GETPOST('location_incoterms', 'alpha'); $object->multicurrency_code = GETPOST('multicurrency_code', 'alpha'); - $object->multicurrency_tx = GETPOST('originmulticurrency_tx'); + $object->multicurrency_tx = GETPOSTFLOAT('originmulticurrency_tx'); if (GETPOST('type') == Facture::TYPE_SITUATION) { $object->situation_counter = 1; From 6cbbcbe97d206c37e32322577a091b6d4a91e048 Mon Sep 17 00:00:00 2001 From: Jyhere Date: Mon, 9 Dec 2024 16:08:25 +0100 Subject: [PATCH 028/185] FIX: reverse stock movement condition on reception deletion is incomplete --- htdocs/reception/class/reception.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 7154ad16eac..a4326db632f 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -1116,7 +1116,9 @@ class Reception extends CommonObject $this->db->begin(); // Stock control - if (isModEnabled('stock') && getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION') && $this->statut > 0) { + if (isModEnabled('stock') && ((getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION') && $this->status > Reception::STATUS_DRAFT) + || (getDolGlobalInt('STOCK_CALCULATE_ON_RECEPTION_CLOSE') && $this->status == Reception::STATUS_CLOSED)) + ) { require_once DOL_DOCUMENT_ROOT."/product/stock/class/mouvementstock.class.php"; $langs->load("agenda"); From 956cea11674f36c8079d03b6277734f0221bb032 Mon Sep 17 00:00:00 2001 From: John BOTELLA <68917336+thersane-john@users.noreply.github.com> Date: Mon, 9 Dec 2024 16:24:57 +0100 Subject: [PATCH 029/185] fix missing concat --- htdocs/core/lib/pdf.lib.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 5358fa5af52..92f2c55aa73 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -2619,7 +2619,9 @@ function pdf_getLinkedObjects(&$object, $outputlangs) $parameters = array('linkedobjects' => $linkedobjects, 'outputlangs' => $outputlangs); $action = ''; $reshook = $hookmanager->executeHooks('pdf_getLinkedObjects', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks - if ($reshook>0) { + if (empty($reshook)) { + $linkedobjects = array_replace($linkedobjects, $hookmanager->resArray); // array_replace is used to preserve keys + } elseif ($reshook>0) { // The array must be reinserted even if it is empty because clearing the array could be one of the actions performed by the hook. $linkedobjects = $hookmanager->resArray; } From f8bd644b58b6a6d25b6bc0c1aed83e7acbdbf267 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Mon, 9 Dec 2024 17:41:56 +0100 Subject: [PATCH 030/185] fix: Variant with multiprice, on creation of variant, percent variation is not save --- htdocs/product/class/product.class.php | 4 ++-- htdocs/variants/class/ProductCombination.class.php | 12 ++++++------ htdocs/variants/combinations.php | 11 ++++++----- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 271f08be9d0..faa655b9bdc 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2668,7 +2668,7 @@ class Product extends CommonObject // Load multiprices array if (getDolGlobalString('PRODUIT_MULTIPRICES') && empty($ignore_price_load)) { // prices per segment - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + for ($i = 1; $i <= getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); $i++) { $sql = "SELECT price, price_ttc, price_min, price_min_ttc,"; $sql .= " price_base_type, tva_tx, default_vat_code, tosell, price_by_qty, rowid, recuperableonly"; $sql .= " FROM ".$this->db->prefix()."product_price"; @@ -2778,7 +2778,7 @@ class Product extends CommonObject return -1; } } elseif (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES') && empty($ignore_price_load)) { // prices per customer and quantity - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + for ($i = 1; $i <= getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); $i++) { $sql = "SELECT price, price_ttc, price_min, price_min_ttc,"; $sql .= " price_base_type, tva_tx, default_vat_code, tosell, price_by_qty, rowid, recuperableonly"; $sql .= " FROM ".$this->db->prefix()."product_price"; diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 7a2212ca55b..cc2c56c8f1b 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -526,12 +526,12 @@ class ProductCombination // MultiPrix if (getDolGlobalString('PRODUIT_MULTIPRICES')) { - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + for ($i = 1; $i <= getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); $i++) { if ($parent->multiprices[$i] != '' || isset($this->combination_price_levels[$i]->variation_price)) { $new_type = empty($parent->multiprices_base_type[$i]) ? 'HT' : $parent->multiprices_base_type[$i]; $new_min_price = $parent->multiprices_min[$i]; $variation_price = (float) (!isset($this->combination_price_levels[$i]->variation_price) ? $this->variation_price : $this->combination_price_levels[$i]->variation_price); - $variation_price_percentage = (float) (!isset($this->combination_price_levels[$i]->variation_price_percentage) ? $this->variation_price_percentage : $this->combination_price_levels[$i]->variation_price_percentage); + $variation_price_percentage = (bool) (!isset($this->combination_price_levels[$i]->variation_price_percentage) ? $this->variation_price_percentage : $this->combination_price_levels[$i]->variation_price_percentage); if ($parent->prices_by_qty_list[$i]) { $new_psq = 1; @@ -828,21 +828,21 @@ class ProductCombination $newproduct->description .= ''.$prodattr->label.': '.$prodattrval->value; } - $newcomb->variation_price_percentage = $price_var_percent[1]; + $newcomb->variation_price_percentage = (bool) $price_var_percent[1]; $newcomb->variation_price = $price_impact[1]; $newcomb->variation_weight = $weight_impact; $newcomb->variation_ref_ext = $this->db->escape($ref_ext); // Init price level - if ($conf->global->PRODUIT_MULTIPRICES) { - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + if (getDolGlobalString('PRODUIT_MULTIPRICES')) { + for ($i = 1; $i <= getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); $i++) { $productCombinationLevel = new ProductCombinationLevel($this->db); $productCombinationLevel->fk_product_attribute_combination = $newcomb->id; $productCombinationLevel->fk_price_level = $i; $productCombinationLevel->variation_price = $price_impact[$i]; if (is_array($price_var_percent)) { - $productCombinationLevel->variation_price_percentage = (empty($price_var_percent[$i]) ? false : $price_var_percent[$i]); + $productCombinationLevel->variation_price_percentage = (bool) $price_var_percent[$i] ; } else { $productCombinationLevel->variation_price_percentage = $price_var_percent; } diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index cad40bcf1e5..663a567c31a 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -295,7 +295,7 @@ if (($action == 'add' || $action == 'create') && empty($massaction) && !GETPOST( if (getDolGlobalString('PRODUIT_MULTIPRICES')) { $prodcomb->combination_price_levels = array(); - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + for ($i = 1; $i <= getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); $i++) { $productCombinationLevel = new ProductCombinationLevel($db); $productCombinationLevel->fk_product_attribute_combination = $prodcomb->id; $productCombinationLevel->fk_price_level = $i; @@ -717,14 +717,15 @@ if (!empty($id) || !empty($ref)) { fetchCombinationPriceLevels(); - for ($i = 1; $i <= $conf->global->PRODUIT_MULTIPRICES_LIMIT; $i++) { + for ($i = 1; $i <= getDolGlobalInt('PRODUIT_MULTIPRICES_LIMIT'); $i++) { $keyforlabel = 'PRODUIT_MULTIPRICES_LABEL'.$i; $text = $langs->trans('ImpactOnPriceLevel', $i).' - '.getDolGlobalString($keyforlabel); print ''; @@ -734,7 +735,7 @@ if (!empty($id) || !empty($ref)) { } print ''; print ''; print ''; @@ -761,7 +762,7 @@ if (!empty($id) || !empty($ref)) { let priceImpact = $( "#level_price_impact_1" ).val(); let priceImpactPrecent = $( "#level_price_impact_percent_1" ).prop("checked"); - var multipricelimit = global->PRODUIT_MULTIPRICES_LIMIT); ?> + let multipricelimit = for (let i = 2; i <= multipricelimit; i++) { $( "#level_price_impact_" + i ).val(priceImpact); From 0c2086936ddcf405d56d40e1f3292882969ca627 Mon Sep 17 00:00:00 2001 From: Quentin-Seekness <72733832+Quentin-Seekness@users.noreply.github.com> Date: Wed, 11 Dec 2024 12:06:24 +0100 Subject: [PATCH 031/185] Best buy price on a product should be including discounts --- htdocs/fourn/class/fournisseur.product.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 5edfa06eae1..7c5854ecdfb 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -976,7 +976,7 @@ class ProductFournisseur extends Product } } - if ($fourn_unitprice < $min || $min == -1) { + if ($fourn_unitprice_with_discount < $min || $min == -1) { $this->id = $prodid; $this->product_fourn_price_id = $record["product_fourn_price_id"]; $this->ref_supplier = $record["ref_fourn"]; @@ -1000,7 +1000,7 @@ class ProductFournisseur extends Product $this->fourn_multicurrency_id = $record["fk_multicurrency"]; $this->fourn_multicurrency_code = $record["multicurrency_code"]; - $min = $fourn_unitprice; + $min = $fourn_unitprice_with_discount; } } } From eea5f2342b1ea543dff2611546f6d9f66c37cd79 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 11 Dec 2024 18:04:28 +0100 Subject: [PATCH 032/185] FIX default user in stat page --- htdocs/compta/facture/stats/index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/facture/stats/index.php b/htdocs/compta/facture/stats/index.php index b4386092f5f..da137d063a1 100644 --- a/htdocs/compta/facture/stats/index.php +++ b/htdocs/compta/facture/stats/index.php @@ -299,7 +299,7 @@ print ''; // ThirdParty Type print ''; // Status print ''; - print ''; + print ''; $x_coll_sum = 0; foreach (array_keys($x_coll) as $rate) { From 8f7122c7075db11bbc9a818081d85578623aff02 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Sun, 15 Dec 2024 02:02:14 +0100 Subject: [PATCH 038/185] Clean sql --- htdocs/public/donations/donateurs_code.php | 4 ++-- htdocs/public/members/public_list.php | 4 ---- htdocs/public/onlinesign/newonlinesign.php | 2 +- htdocs/public/opensurvey/studs.php | 2 +- htdocs/public/payment/paymentok.php | 2 +- htdocs/public/project/viewandvote.php | 4 ++-- htdocs/public/stripe/ipn.php | 2 +- htdocs/public/ticket/list.php | 21 ++++++++++----------- 8 files changed, 18 insertions(+), 23 deletions(-) diff --git a/htdocs/public/donations/donateurs_code.php b/htdocs/public/donations/donateurs_code.php index 509eb553288..b1b481a3965 100644 --- a/htdocs/public/donations/donateurs_code.php +++ b/htdocs/public/donations/donateurs_code.php @@ -79,7 +79,7 @@ $resql = $db->query($sql); if ($resql) { $num = $db->num_rows($resql); if ($num) { - print "
'; + print ''; if ($tablename == 'expensereport_det') { print $expensereport->getNomUrl(1); } else { From caabaabb54691d56273733999cbd1d8425b9d510 Mon Sep 17 00:00:00 2001 From: Irvine Fleith Date: Thu, 28 Nov 2024 13:59:07 +0100 Subject: [PATCH 016/185] Added table for handling tdoverflowmax --- htdocs/projet/element.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 59b35e98599..1013d1f7398 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -1292,6 +1292,7 @@ foreach ($listofreferent as $key => $value) { if ($tablename == 'expensereport_det') { print $expensereport->getNomUrl(1); } else { + print ''; + + print '
'; // Show ref with link if ($element instanceof Task) { print $element->getNomUrl(1, 'withproject', 'time'); @@ -1327,6 +1328,10 @@ foreach ($listofreferent as $key => $value) { } print ''; + print ''; + // Show supplier ref if (!empty($element->ref_supplier)) { print ' - '.$element->ref_supplier; @@ -1339,6 +1344,8 @@ foreach ($listofreferent as $key => $value) { if (empty($element->ref_customer) && !empty($element->ref_client)) { print ' - '.$element->ref_client; } + + print '
'; } print "
- > + + >
'; - print 'combination_price_levels[$i]->variation_price_percentage) ? ' checked' : '').'> '; + print 'combination_price_levels[$i]->variation_price_percentage ? ' checked' : '').'> '; print '
'.$langs->trans("ThirdPartyType").''; -$sortparam_typent = (!getDolGlobalString('SOCIETE_SORT_ON_TYPEENT') ? 'ASC' : $conf->global->SOCIETE_SORT_ON_TYPEENT); // NONE means we keep sort of original array, so we sort on position. ASC, means next function will sort on label. +$sortparam_typent = getDolGlobalString('SOCIETE_SORT_ON_TYPEENT', 'ASC'); // NONE means we keep sort of original array, so we sort on position. ASC, means next function will sort on label. print $form->selectarray("typent_id", $formcompany->typent_array(0), $typent_id, 1, 0, 0, '', 0, 0, 0, $sortparam_typent, '', 1); if ($user->admin) { print ' '.info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); @@ -327,7 +327,7 @@ if (isModEnabled('category')) { // User print '
'.$langs->trans("CreatedBy").''; print img_picto('', 'user', 'class="pictofixedwidth"'); -print $form->select_dolusers($userid, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300'); +print $form->select_dolusers($userid ? $userid : -1, 'userid', 1, '', 0, '', '', 0, 0, 0, '', 0, '', 'widthcentpercentminusx maxwidth300'); print '
'.$langs->trans("Status").''; From 2ccc6f71ae249808f1a28514eef1de882fd60b19 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 12 Dec 2024 11:58:52 +0100 Subject: [PATCH 033/185] FIX wrong trigger name (MODIFY instead UPDATE) --- ...face_95_modZapier_ZapierTriggers.class.php | 20 +++++++++---------- ..._99_modMyModule_MyModuleTriggers.class.php | 20 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/htdocs/core/triggers/interface_95_modZapier_ZapierTriggers.class.php b/htdocs/core/triggers/interface_95_modZapier_ZapierTriggers.class.php index ea846616096..6665242aba2 100644 --- a/htdocs/core/triggers/interface_95_modZapier_ZapierTriggers.class.php +++ b/htdocs/core/triggers/interface_95_modZapier_ZapierTriggers.class.php @@ -224,7 +224,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers case 'ORDER_CLASSIFY_BILLED': case 'ORDER_SETDRAFT': case 'LINEORDER_INSERT': - case 'LINEORDER_UPDATE': + case 'LINEORDER_MODIFY': case 'LINEORDER_DELETE': break; // Supplier orders @@ -239,7 +239,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'ORDER_SUPPLIER_RECEIVE': // case 'LINEORDER_SUPPLIER_DISPATCH': // case 'LINEORDER_SUPPLIER_CREATE': - // case 'LINEORDER_SUPPLIER_UPDATE': + // case 'LINEORDER_SUPPLIER_MODIFY': // Proposals // case 'PROPAL_CREATE': @@ -251,7 +251,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'PROPAL_CLOSE_REFUSED': // case 'PROPAL_DELETE': // case 'LINEPROPAL_INSERT': - // case 'LINEPROPAL_UPDATE': + // case 'LINEPROPAL_MODIFY': // case 'LINEPROPAL_DELETE': // SupplierProposal @@ -264,7 +264,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'SUPPLIER_PROPOSAL_CLOSE_REFUSED': // case 'SUPPLIER_PROPOSAL_DELETE': // case 'LINESUPPLIER_PROPOSAL_INSERT': - // case 'LINESUPPLIER_PROPOSAL_UPDATE': + // case 'LINESUPPLIER_PROPOSAL_MODIFY': // case 'LINESUPPLIER_PROPOSAL_DELETE': // Contracts @@ -274,7 +274,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'CONTRACT_CLOSE': // case 'CONTRACT_DELETE': // case 'LINECONTRACT_INSERT': - // case 'LINECONTRACT_UPDATE': + // case 'LINECONTRACT_MODIFY': // case 'LINECONTRACT_DELETE': // Bills @@ -288,19 +288,19 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'BILL_DELETE': // case 'BILL_PAYED': // case 'LINEBILL_INSERT': - // case 'LINEBILL_UPDATE': + // case 'LINEBILL_MODIFY': // case 'LINEBILL_DELETE': //Supplier Bill // case 'BILL_SUPPLIER_CREATE': - // case 'BILL_SUPPLIER_UPDATE': + // case 'BILL_SUPPLIER_MODIFY': // case 'BILL_SUPPLIER_DELETE': // case 'BILL_SUPPLIER_PAYED': // case 'BILL_SUPPLIER_UNPAYED': // case 'BILL_SUPPLIER_VALIDATE': // case 'BILL_SUPPLIER_UNVALIDATE': // case 'LINEBILL_SUPPLIER_CREATE': - // case 'LINEBILL_SUPPLIER_UPDATE': + // case 'LINEBILL_SUPPLIER_MODIFY': // case 'LINEBILL_SUPPLIER_DELETE': // Payments @@ -316,7 +316,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // Donation // case 'DON_CREATE': - // case 'DON_UPDATE': + // case 'DON_MODIFY': // case 'DON_DELETE': // Interventions @@ -325,7 +325,7 @@ class InterfaceZapierTriggers extends DolibarrTriggers // case 'FICHINTER_VALIDATE': // case 'FICHINTER_DELETE': // case 'LINEFICHINTER_CREATE': - // case 'LINEFICHINTER_UPDATE': + // case 'LINEFICHINTER_MODIFY': // case 'LINEFICHINTER_DELETE': // Members diff --git a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php index 392addd84d0..ff435dbf4be 100644 --- a/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php +++ b/htdocs/modulebuilder/template/core/triggers/interface_99_modMyModule_MyModuleTriggers.class.php @@ -165,7 +165,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'ORDER_CLASSIFY_BILLED': //case 'ORDER_SETDRAFT': //case 'LINEORDER_INSERT': - //case 'LINEORDER_UPDATE': + //case 'LINEORDER_MODIFY': //case 'LINEORDER_DELETE': // Supplier orders @@ -180,7 +180,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'ORDER_SUPPLIER_RECEIVE': //case 'LINEORDER_SUPPLIER_DISPATCH': //case 'LINEORDER_SUPPLIER_CREATE': - //case 'LINEORDER_SUPPLIER_UPDATE': + //case 'LINEORDER_SUPPLIER_MODIFY': //case 'LINEORDER_SUPPLIER_DELETE': // Proposals @@ -192,7 +192,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'PROPAL_CLOSE_REFUSED': //case 'PROPAL_DELETE': //case 'LINEPROPAL_INSERT': - //case 'LINEPROPAL_UPDATE': + //case 'LINEPROPAL_MODIFY': //case 'LINEPROPAL_DELETE': // SupplierProposal @@ -204,7 +204,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'SUPPLIER_PROPOSAL_CLOSE_REFUSED': //case 'SUPPLIER_PROPOSAL_DELETE': //case 'LINESUPPLIER_PROPOSAL_INSERT': - //case 'LINESUPPLIER_PROPOSAL_UPDATE': + //case 'LINESUPPLIER_PROPOSAL_MODIFY': //case 'LINESUPPLIER_PROPOSAL_DELETE': // Contracts @@ -215,7 +215,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'CONTRACT_CLOSE': //case 'CONTRACT_DELETE': //case 'LINECONTRACT_INSERT': - //case 'LINECONTRACT_UPDATE': + //case 'LINECONTRACT_MODIFY': //case 'LINECONTRACT_DELETE': // Bills @@ -228,19 +228,19 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'BILL_DELETE': //case 'BILL_PAYED': //case 'LINEBILL_INSERT': - //case 'LINEBILL_UPDATE': + //case 'LINEBILL_MODIFY': //case 'LINEBILL_DELETE': //Supplier Bill //case 'BILL_SUPPLIER_CREATE': - //case 'BILL_SUPPLIER_UPDATE': + //case 'BILL_SUPPLIER_MODIFY': //case 'BILL_SUPPLIER_DELETE': //case 'BILL_SUPPLIER_PAYED': //case 'BILL_SUPPLIER_UNPAYED': //case 'BILL_SUPPLIER_VALIDATE': //case 'BILL_SUPPLIER_UNVALIDATE': //case 'LINEBILL_SUPPLIER_CREATE': - //case 'LINEBILL_SUPPLIER_UPDATE': + //case 'LINEBILL_SUPPLIER_MODIFY': //case 'LINEBILL_SUPPLIER_DELETE': // Payments @@ -256,7 +256,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers // Donation //case 'DON_CREATE': - //case 'DON_UPDATE': + //case 'DON_MODIFY': //case 'DON_DELETE': // Interventions @@ -265,7 +265,7 @@ class InterfaceMyModuleTriggers extends DolibarrTriggers //case 'FICHINTER_VALIDATE': //case 'FICHINTER_DELETE': //case 'LINEFICHINTER_CREATE': - //case 'LINEFICHINTER_UPDATE': + //case 'LINEFICHINTER_MODIFY': //case 'LINEFICHINTER_DELETE': // Members From 2b3bd3d6dc2e48751de92cb7adcdeda03e72133c Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 13 Dec 2024 09:19:10 +0100 Subject: [PATCH 034/185] FIX can not convert to reduc if draft status --- htdocs/fourn/facture/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 4270d723959..3a9f7d1c310 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -4064,7 +4064,7 @@ if ($action == 'create') { } // Reverse back money or convert to reduction - if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD) { + if ($object->status == FactureFournisseur::STATUS_VALIDATED && ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD)) { // For credit note only if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0) { if ($resteapayer == 0) { From 62c1d500e8db181ba99312c4eaa349be9c317f85 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 13 Dec 2024 14:05:04 +0100 Subject: [PATCH 035/185] Avoid errors --- .github/workflows/pr-18-autolabel.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr-18-autolabel.yaml b/.github/workflows/pr-18-autolabel.yaml index 4524d02815b..4f7b08ea725 100644 --- a/.github/workflows/pr-18-autolabel.yaml +++ b/.github/workflows/pr-18-autolabel.yaml @@ -18,3 +18,4 @@ jobs: with: repo-token: ${{ secrets.GITHUB_TOKEN }} configuration-path: .github/changed-lines-count-labeler.yml + continue-on-error: true \ No newline at end of file From 03b560d6886afee3baa0bb05f4ceb5cf4424708a Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 13 Dec 2024 14:51:46 +0100 Subject: [PATCH 036/185] FIX wrong check --- htdocs/fourn/facture/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 3a9f7d1c310..01f43d6dc45 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -4064,7 +4064,7 @@ if ($action == 'create') { } // Reverse back money or convert to reduction - if ($object->status == FactureFournisseur::STATUS_VALIDATED && ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD)) { + if ($object->status != FactureFournisseur::STATUS_DRAFT && ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_STANDARD)) { // For credit note only if ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->statut == 1 && $object->paye == 0) { if ($resteapayer == 0) { From 323093eaeaad74d030e9e180b0ac43361e309126 Mon Sep 17 00:00:00 2001 From: sonikf <93765174+sonikf@users.noreply.github.com> Date: Sat, 14 Dec 2024 19:23:36 +0200 Subject: [PATCH 037/185] FIX #32317 Error with report by month sales tax --- htdocs/compta/localtax/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/localtax/index.php b/htdocs/compta/localtax/index.php index caa5173a13c..ec785aec784 100644 --- a/htdocs/compta/localtax/index.php +++ b/htdocs/compta/localtax/index.php @@ -446,7 +446,7 @@ while ((($y < $yend) || ($y == $yend && $m <= $mend)) && $mcursor < 1000) { // $ print '
'.dol_print_date(dol_mktime(0, 0, 0, $m, 1, $y), "%b %Y").''.dol_print_date(dol_mktime(0, 0, 0, (int) $m, 1, (int) $y), "%b %Y").'
"; + print '
'; print ''; print ""; @@ -97,7 +97,7 @@ if ($resql) { print "\n"; } print "\n"; - print ''; + print ''; print ""; $i++; } diff --git a/htdocs/public/members/public_list.php b/htdocs/public/members/public_list.php index 74bfe4e6d74..4cd5e5e291b 100644 --- a/htdocs/public/members/public_list.php +++ b/htdocs/public/members/public_list.php @@ -158,10 +158,6 @@ if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) { $sql .= $db->order($sortfield, $sortorder); $sql .= $db->plimit($conf->liste_limit + 1, $offset); -//$sql = "SELECT d.rowid, d.firstname, d.lastname, d.societe, zip, town, d.email, t.libelle as type, d.morphy, d.statut, t.subscription"; -//$sql .= " FROM ".MAIN_DB_PREFIX."adherent as d, ".MAIN_DB_PREFIX."adherent_type as t"; -//$sql .= " WHERE d.fk_adherent_type = t.rowid AND d.statut = $statut"; -//$sql .= " ORDER BY $sortfield $sortorder " . $db->plimit($conf->liste_limit, $offset); $result = $db->query($sql); diff --git a/htdocs/public/onlinesign/newonlinesign.php b/htdocs/public/onlinesign/newonlinesign.php index 873a0a02b56..f51498f2bda 100644 --- a/htdocs/public/onlinesign/newonlinesign.php +++ b/htdocs/public/onlinesign/newonlinesign.php @@ -184,7 +184,7 @@ if ($action == 'confirm_refusepropal' && $confirm == 'yes') { $db->begin(); $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; - $sql .= " SET fk_statut = ".((int) $object::STATUS_NOTSIGNED).", note_private = '".$db->escape($object->note_private)."', date_signature='".$db->idate(dol_now())."'"; + $sql .= " SET fk_statut = ".((int) $object::STATUS_NOTSIGNED).", note_private = '".$db->escape($object->note_private)."', date_signature = '".$db->idate(dol_now())."'"; $sql .= " WHERE rowid = ".((int) $object->id); dol_syslog(__FILE__, LOG_DEBUG); diff --git a/htdocs/public/opensurvey/studs.php b/htdocs/public/opensurvey/studs.php index 2c8c227984b..dd2e05bc3fb 100644 --- a/htdocs/public/opensurvey/studs.php +++ b/htdocs/public/opensurvey/studs.php @@ -183,7 +183,7 @@ if (GETPOST("boutonp") || GETPOST("boutonp.x") || GETPOST("boutonp_x")) { // bo // Check if vote already exists $sql = 'SELECT id_users, nom as name'; $sql .= ' FROM '.MAIN_DB_PREFIX.'opensurvey_user_studs'; - $sql .= " WHERE id_sondage='".$db->escape($numsondage)."' AND nom = '".$db->escape($nom)."' ORDER BY id_users"; + $sql .= " WHERE id_sondage = '".$db->escape($numsondage)."' AND nom = '".$db->escape($nom)."' ORDER BY id_users"; $resql = $db->query($sql); if (!$resql) { dol_print_error($db); diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index b066c2e08b7..58ec412a7a4 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -729,7 +729,7 @@ if ($ispaymentok) { } } else { $sql = "INSERT INTO ".MAIN_DB_PREFIX."societe_account (fk_soc, login, key_account, site, site_account, status, entity, date_creation, fk_user_creat)"; - $sql .= " VALUES (".$thirdparty_id.", '', '".$db->escape($stripecu)."', 'stripe', '".$db->escape($stripearrayofkeysbyenv[$servicestatus]['publishable_key'])."', ".((int) $servicestatus).", ".((int) $conf->entity).", '".$db->idate(dol_now())."', 0)"; + $sql .= " VALUES (".((int) $thirdparty_id).", '', '".$db->escape($stripecu)."', 'stripe', '".$db->escape($stripearrayofkeysbyenv[$servicestatus]['publishable_key'])."', ".((int) $servicestatus).", ".((int) $conf->entity).", '".$db->idate(dol_now())."', 0)"; $resql = $db->query($sql); if (!$resql) { // should not happen $error++; diff --git a/htdocs/public/project/viewandvote.php b/htdocs/public/project/viewandvote.php index 50dec036e9a..11be6efcada 100644 --- a/htdocs/public/project/viewandvote.php +++ b/htdocs/public/project/viewandvote.php @@ -112,8 +112,8 @@ $listOfConferences .= ''; $sql = "SELECT a.id, a.fk_action, a.datep, a.datep2, a.label, a.fk_soc, a.note, ca.libelle as label FROM ".MAIN_DB_PREFIX."actioncomm as a - INNER JOIN ".MAIN_DB_PREFIX."c_actioncomm as ca ON (a.fk_action=ca.id) - WHERE a.status<2"; + INNER JOIN ".MAIN_DB_PREFIX."c_actioncomm as ca ON (a.fk_action = ca.id) + WHERE a.status < 2"; $sqlforconf = $sql." AND ca.module='conference@eventorganization'"; //$sqlforbooth = $sql." AND ca.module='booth@eventorganization'"; diff --git a/htdocs/public/stripe/ipn.php b/htdocs/public/stripe/ipn.php index 1a70c445f81..604c54aec40 100644 --- a/htdocs/public/stripe/ipn.php +++ b/htdocs/public/stripe/ipn.php @@ -314,7 +314,7 @@ if ($event->type == 'payout.created') { //TODO: delete customer's source } elseif ($event->type == 'customer.deleted') { $db->begin(); - $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_account WHERE key_account = '".$db->escape($event->data->object->id)."' and site='stripe'"; + $sql = "DELETE FROM ".MAIN_DB_PREFIX."societe_account WHERE key_account = '".$db->escape($event->data->object->id)."' AND site = 'stripe'"; $db->query($sql); $db->commit(); } elseif ($event->type == 'payment_intent.succeeded') { // Called when making payment with PaymentIntent method ($conf->global->STRIPE_USE_NEW_CHECKOUT is on). diff --git a/htdocs/public/ticket/list.php b/htdocs/public/ticket/list.php index 4a7bbf39a6f..28c5a57de63 100644 --- a/htdocs/public/ticket/list.php +++ b/htdocs/public/ticket/list.php @@ -87,7 +87,6 @@ if (!isModEnabled('ticket')) { } - /* * Actions */ @@ -383,26 +382,26 @@ if ($action == "view_ticketlist") { } $sql .= " WHERE t.entity IN (".getEntity('ticket').")"; $sql .= " AND ((tc.source = 'external'"; - $sql .= " AND tc.element='".$db->escape($object->element)."'"; - $sql .= " AND tc.active=1"; - $sql .= " AND sp.email='".$db->escape($_SESSION['email_customer'])."')"; // email found into an external contact - $sql .= " OR s.email='".$db->escape($_SESSION['email_customer'])."'"; // or email of the linked company - $sql .= " OR t.origin_email='".$db->escape($_SESSION['email_customer'])."')"; // or email of the requester + $sql .= " AND tc.element = '".$db->escape($object->element)."'"; + $sql .= " AND tc.active = 1"; + $sql .= " AND sp.email = '".$db->escape($_SESSION['email_customer'])."')"; // email found into an external contact + $sql .= " OR s.email = '".$db->escape($_SESSION['email_customer'])."'"; // or email of the linked company + $sql .= " OR t.origin_email = '".$db->escape($_SESSION['email_customer'])."')"; // or email of the requester // Manage filter if (!empty($filter)) { foreach ($filter as $key => $value) { if (strpos($key, 'date')) { // To allow $filter['YEAR(s.dated)']=>$year - $sql .= " AND ".$key." = '".$db->escape($value)."'"; + $sql .= " AND ".$db->sanitize($key)." = '".$db->escape($value)."'"; } elseif (($key == 't.fk_user_assign') || ($key == 't.type_code') || ($key == 't.category_code') || ($key == 't.severity_code')) { - $sql .= " AND ".$key." = '".$db->escape($value)."'"; + $sql .= " AND ".$db->sanitize($key)." = '".$db->escape($value)."'"; } elseif ($key == 't.fk_statut') { if (is_array($value) && count($value) > 0) { - $sql .= " AND ".$key." IN (".$db->sanitize(implode(',', $value)).")"; + $sql .= " AND ".$db->sanitize($key)." IN (".$db->sanitize(implode(',', $value)).")"; } else { - $sql .= " AND ".$key." = ".((int) $value); + $sql .= " AND ".$db->sanitize($key)." = ".((int) $value); } } else { - $sql .= " AND ".$key." LIKE '%".$db->escape($value)."%'"; + $sql .= " AND ".$db->sanitize($key)." LIKE '%".$db->escape($value)."%'"; } } } From 27a1edb6fc1d0f1b154c714647e80d22a44af2a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sun, 15 Dec 2024 08:58:20 +0100 Subject: [PATCH 039/185] fix phpstan --- build/phpstan/phpstan-baseline.neon | 8 +------- .../class/recruitmentjobposition.class.php | 12 +++++------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index e4b3a0c31c9..9f5c8d9d8a7 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -29841,7 +29841,7 @@ parameters: - message: '#^Negated boolean expression is always true\.$#' identifier: booleanNot.alwaysTrue - count: 2 + count: 1 path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php - @@ -29856,12 +29856,6 @@ parameters: count: 1 path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php - - - message: '#^Variable \$error in empty\(\) always exists and is always falsy\.$#' - identifier: empty.variable - count: 1 - path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php - - message: '#^Parameter \#1 \$object of method CommonDocGenerator\:\:get_substitutionarray_each_var_object\(\) expects array\, RecruitmentJobPosition given\.$#' identifier: argument.type diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index 0e5a14e12ea..49aefd7f41b 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -765,14 +765,12 @@ class RecruitmentJobPosition extends CommonObject $this->generateDocument($modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); } - if (!$error) { - $this->oldcopy = clone $this; - $this->status = $status; - $this->date_cloture = $now; - $this->note_private = $newprivatenote; - } + $this->oldcopy = clone $this; + $this->status = $status; + $this->date_cloture = $now; + $this->note_private = $newprivatenote; - if (!$notrigger && empty($error)) { + if (!$notrigger /* && empty($error) */) { // Call trigger $result = $this->call_trigger($triggerName, $user); if ($result < 0) { From 22be2de2596f090b769b6386e651accb5dcc51ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sun, 15 Dec 2024 09:01:36 +0100 Subject: [PATCH 040/185] fix phpstan --- build/phpstan/phpstan-baseline.neon | 6 ------ .../recruitment/class/recruitmentjobposition.class.php | 10 +--------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index 9f5c8d9d8a7..ad84c0bed0a 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -29838,12 +29838,6 @@ parameters: count: 1 path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php - - - message: '#^Negated boolean expression is always true\.$#' - identifier: booleanNot.alwaysTrue - count: 1 - path: ../../htdocs/recruitment/class/recruitmentjobposition.class.php - - message: '#^Property CommonObject\:\:\$ismultientitymanaged \(int\<0, 1\>\|string\) in isset\(\) is not nullable\.$#' identifier: isset.property diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index 49aefd7f41b..bb64a3ccb34 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -552,20 +552,12 @@ class RecruitmentJobPosition extends CommonObject return 0; } - /*if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitmentjobposition->create)) - || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && !empty($user->rights->recruitmentjobposition->recruitmentjobposition_advance->validate)))) - { - $this->error='NotEnoughPermissions'; - dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); - return -1; - }*/ - $now = dol_now(); $this->db->begin(); // Define new ref - if (!$error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life + if (/* !$error && */ (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) { // empty should not happened, but when it occurs, the test save life $num = $this->getNextNumRef(); } else { $num = $this->ref; From 2bb990344ef03b452ac88623b01e3b0342d49e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sun, 15 Dec 2024 09:08:27 +0100 Subject: [PATCH 041/185] fix phpstan --- build/phpstan/phpstan-baseline.neon | 12 ------- htdocs/core/class/commonobject.class.php | 34 +++++++++---------- .../asset/doc/pdf_standard_asset.modules.php | 3 +- ...tandard_recruitmentjobposition.modules.php | 3 +- 4 files changed, 21 insertions(+), 31 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index ad84c0bed0a..3d079bdac6e 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -12426,12 +12426,6 @@ parameters: count: 1 path: ../../htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php - - - message: '#^Variable \$outputlangsbis might not be defined\.$#' - identifier: variable.undefined - count: 7 - path: ../../htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php - - message: '#^Property mod_asset_standard\:\:\$prefix has no type specified\.$#' identifier: missingType.property @@ -29898,12 +29892,6 @@ parameters: count: 1 path: ../../htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php - - - message: '#^Variable \$outputlangsbis might not be defined\.$#' - identifier: variable.undefined - count: 7 - path: ../../htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php - - message: '#^Variable \$badgeStatus0 might not be defined\.$#' identifier: variable.undefined diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index caa1db00df2..28422a2d77f 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -1,22 +1,22 @@ - * Copyright (C) 2005-2013 Regis Houssin - * Copyright (C) 2010-2020 Juanjo Menent - * Copyright (C) 2012-2013 Christophe Battarel - * Copyright (C) 2011-2022 Philippe Grand - * Copyright (C) 2012-2015 Marcos García - * Copyright (C) 2012-2015 Raphaël Doursenaud - * Copyright (C) 2012 Cedric Salvador - * Copyright (C) 2015-2022 Alexandre Spangaro - * Copyright (C) 2016 Bahfir abbes - * Copyright (C) 2017 ATM Consulting - * Copyright (C) 2017-2019 Nicolas ZABOURI - * Copyright (C) 2017 Rui Strecht +/* Copyright (C) 2006-2015 Laurent Destailleur + * Copyright (C) 2005-2013 Regis Houssin + * Copyright (C) 2010-2020 Juanjo Menent + * Copyright (C) 2012-2013 Christophe Battarel + * Copyright (C) 2011-2022 Philippe Grand + * Copyright (C) 2012-2015 Marcos García + * Copyright (C) 2012-2015 Raphaël Doursenaud + * Copyright (C) 2012 Cedric Salvador + * Copyright (C) 2015-2022 Alexandre Spangaro + * Copyright (C) 2016 Bahfir abbes + * Copyright (C) 2017 ATM Consulting + * Copyright (C) 2017-2019 Nicolas ZABOURI + * Copyright (C) 2017 Rui Strecht * Copyright (C) 2018-2024 Frédéric France - * Copyright (C) 2018 Josep Lluís Amador - * Copyright (C) 2023 Gauthier VERDOL - * Copyright (C) 2021 Grégory Blémand - * Copyright (C) 2023 Lenin Rivas + * Copyright (C) 2018 Josep Lluís Amador + * Copyright (C) 2023 Gauthier VERDOL + * Copyright (C) 2021 Grégory Blémand + * Copyright (C) 2023 Lenin Rivas * Copyright (C) 2024 MDW * Copyright (C) 2024 William Mead * diff --git a/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php b/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php index 0992224c367..96140ac1780 100644 --- a/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php +++ b/htdocs/core/modules/asset/doc/pdf_standard_asset.modules.php @@ -173,8 +173,9 @@ class pdf_standard_asset extends ModelePDFAsset // Load translation files required by the page $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies")); + global $outputlangsbis; + $outputlangsbis = null; if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && $outputlangs->defaultlang != getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')) { - global $outputlangsbis; $outputlangsbis = new Translate('', $conf); $outputlangsbis->setDefaultLang(getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')); $outputlangsbis->loadLangs(array("main", "bills", "products", "dict", "companies")); diff --git a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php index 475cb21f216..7402190de2b 100644 --- a/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php +++ b/htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php @@ -210,8 +210,9 @@ class pdf_standard_recruitmentjobposition extends ModelePDFRecruitmentJobPositio // Load translation files required by the page $outputlangs->loadLangs(array("main", "bills", "products", "dict", "companies")); + global $outputlangsbis; + $outputlangsbis = null; if (getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE') && $outputlangs->defaultlang != getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')) { - global $outputlangsbis; $outputlangsbis = new Translate('', $conf); $outputlangsbis->setDefaultLang(getDolGlobalString('PDF_USE_ALSO_LANGUAGE_CODE')); $outputlangsbis->loadLangs(array("main", "bills", "products", "dict", "companies")); From 1afe0047fb7fe9c5650a9c55d71d924f4c313871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Sun, 15 Dec 2024 09:39:02 +0100 Subject: [PATCH 042/185] fix phpstan --- htdocs/document.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/document.php b/htdocs/document.php index 9b440a30e06..895256a1def 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -102,9 +102,12 @@ function llxHeader($head = '', $title = '', $help_url = '', $target = '', $disab * Footer empty * * @ignore + * @param string $comment A text to add as HTML comment into HTML generated page + * @param string $zone 'private' (for private pages) or 'public' (for public pages) + * @param int $disabledoutputofmessages Clear all messages stored into session without displaying them * @return void */ -function llxFooter() +function llxFooter($comment = '', $zone = 'private', $disabledoutputofmessages = 0) { } From 0a250142cc726d5b43cc6b458e06a6bffe5d50fe Mon Sep 17 00:00:00 2001 From: matthieu-michou-wattandsea <70541072+matthieu-michou-wattandsea@users.noreply.github.com> Date: Sun, 15 Dec 2024 10:49:55 +0100 Subject: [PATCH 043/185] API REST : specify creation date for new contact, as for companies and products --- htdocs/contact/class/contact.class.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index 0a97ee8f407..082639332be 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -484,6 +484,10 @@ class Contact extends CommonObject $error = 0; $now = dol_now(); + if (empty($this->date_creation)) { + $this->date_creation = $now; + } + $this->db->begin(); // Clean parameters From 03bf9c9a4f8b5cbce29afd9fc440d84d1c2feb42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charl=C3=A8ne=20Benke?= <1179011+defrance@users.noreply.github.com> Date: Sun, 15 Dec 2024 13:57:45 +0100 Subject: [PATCH 044/185] fix login error on update with captcha --- htdocs/core/tpl/login.tpl.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index 077f7d4aeb1..e2ba274dfb2 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -3,6 +3,7 @@ * Copyright (C) 2011-2022 Laurent Destailleur * Copyright (C) 2024 MDW * Copyright (C) 2024 Frédéric France + * Copyright (C) 2024 Charlene Benke * * 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 @@ -317,7 +318,7 @@ if (!empty($captcha)) { } // List of directories where we can find captcha handlers - $dirModCaptcha = array_merge(array('main' => '/core/modules/security/captcha/'), is_array($conf->modules_parts['captcha']) ? $conf->modules_parts['captcha'] : array()); + $dirModCaptcha = array_merge(array('main' => '/core/modules/security/captcha/'), isset($conf->modules_parts['captcha']) ? $conf->modules_parts['captcha'] : array()); $fullpathclassfile = ''; foreach ($dirModCaptcha as $dir) { $fullpathclassfile = dol_buildpath($dir."modCaptcha".ucfirst($captcha).'.class.php', 0, 2); @@ -334,7 +335,7 @@ if (!empty($captcha)) { $classname = "modCaptcha".ucfirst($captcha); if (class_exists($classname)) { /** @var ModeleCaptcha $captchaobj */ - $captchaobj = new $classname($db, $conf, $langs, $user); + $captchaobj = new $classname($db, $conf, $langs, null); '@phan-var-force ModeleCaptcha $captchaobj'; if (is_object($captchaobj) && method_exists($captchaobj, 'getCaptchaCodeForForm')) { From 7c94a01cc5c7b121752938cd4a07876d73d0351a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Charl=C3=A8ne=20Benke?= <1179011+defrance@users.noreply.github.com> Date: Sun, 15 Dec 2024 14:01:33 +0100 Subject: [PATCH 045/185] Update login.tpl.php --- htdocs/core/tpl/login.tpl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index e2ba274dfb2..54c2238adfa 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -318,7 +318,7 @@ if (!empty($captcha)) { } // List of directories where we can find captcha handlers - $dirModCaptcha = array_merge(array('main' => '/core/modules/security/captcha/'), isset($conf->modules_parts['captcha']) ? $conf->modules_parts['captcha'] : array()); + $dirModCaptcha = array_merge(array('main' => '/core/modules/security/captcha/'), (isset($conf->modules_parts['captcha']) && is_array($conf->modules_parts['captcha'])) ? $conf->modules_parts['captcha'] : array()); $fullpathclassfile = ''; foreach ($dirModCaptcha as $dir) { $fullpathclassfile = dol_buildpath($dir."modCaptcha".ucfirst($captcha).'.class.php', 0, 2); From 1c7deda18de7091e9201e39643f53da43d9aa41b Mon Sep 17 00:00:00 2001 From: Alexandre Janniaux Date: Sun, 15 Dec 2024 17:54:48 +0100 Subject: [PATCH 046/185] sellsjournal: remove tab character in SQL It shows as the following in the logs: GROUP BY fk_facture \x09AND fk_facture IN (8) AND fd.total_ttc <> 0 AND fd.fk_code_ventilation <= 0 fd.product_type <= 2 WHERE \x09llx_facturedet as fd FROM --- htdocs/accountancy/journal/sellsjournal.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index ecf9ce56121..2b166dff8d9 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -461,12 +461,12 @@ SELECT fk_facture, COUNT(fd.rowid) as nb FROM - ".MAIN_DB_PREFIX."facturedet as fd + ".MAIN_DB_PREFIX."facturedet as fd WHERE fd.product_type <= 2 AND fd.fk_code_ventilation <= 0 AND fd.total_ttc <> 0 - AND fk_facture IN (".$db->sanitize(implode(",", array_keys($tabfac))).") + AND fk_facture IN (".$db->sanitize(implode(",", array_keys($tabfac))).") GROUP BY fk_facture "; $resql = $db->query($sql); From 43f50ee7b878162fca65493ea22bee414ffff6eb Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 16 Dec 2024 10:26:32 +0100 Subject: [PATCH 047/185] FIX broken feature, entity can not be empty ! --- htdocs/core/lib/files.lib.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index e8e347e7647..ca4268f76c1 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -2747,12 +2747,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, if (empty($modulepart)) { return 'ErrorBadParameter'; } + // entity can't be empty if (empty($entity)) { - if (!isModEnabled('multicompany')) { - $entity = 1; - } else { - $entity = 0; - } + $entity = $conf->entity; } // Fix modulepart for backward compatibility if ($modulepart == 'facture') { @@ -2803,9 +2800,6 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, if (isModEnabled('multicompany') && (empty($entity) || empty($conf->medias->multidir_output[$entity]))) { return array('accessallowed' => 0, 'error' => 'Value entity must be provided'); } */ - if (empty($entity)) { - $entity = 1; - } $accessallowed = 1; $original_file = (empty($conf->medias->multidir_output[$entity]) ? $conf->medias->dir_output : $conf->medias->multidir_output[$entity]).'/'.$original_file; } elseif ($modulepart == 'logs' && !empty($dolibarr_main_data_root)) { From a6da3b189aed15e86e642eadbbff9cd1ae079e0e Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 16 Dec 2024 12:59:16 +0100 Subject: [PATCH 048/185] Not required, but for better code consistency --- htdocs/core/get_menudiv.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/get_menudiv.php b/htdocs/core/get_menudiv.php index 4dfe4cc5c75..7d8879e3b32 100644 --- a/htdocs/core/get_menudiv.php +++ b/htdocs/core/get_menudiv.php @@ -252,7 +252,7 @@ if (!class_exists('MenuManager')) { $menufound = 0; $dirmenus = array_merge(array("/core/menus/"), (array) $conf->modules_parts['menus']); foreach ($dirmenus as $dirmenu) { - $menufound = dol_include_once($dirmenu."standard/".$file_menu); + $menufound = dol_include_once($dirmenu."standard/".dol_sanitizeFileName($file_menu)); if ($menufound) { break; } @@ -260,7 +260,7 @@ if (!class_exists('MenuManager')) { if (!$menufound) { // If failed to include, we try with standard dol_syslog("You define a menu manager '".$file_menu."' that can not be loaded.", LOG_WARNING); $file_menu = 'eldy_menu.php'; - include_once DOL_DOCUMENT_ROOT."/core/menus/standard/".$file_menu; + include_once DOL_DOCUMENT_ROOT."/core/menus/standard/".dol_sanitizeFileName($file_menu); } } $menumanager = new MenuManager($db, empty($user->socid) ? 0 : 1); From bf7b77665373ad64bc8b4ca9461608a70da2521a Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 16 Dec 2024 14:00:04 +0100 Subject: [PATCH 049/185] FIX add a line in expensereport refused --- htdocs/expensereport/card.php | 12 ++++++------ htdocs/expensereport/class/expensereport.class.php | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index a66d2fef421..9cfe25d872c 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1566,7 +1566,7 @@ if ($action == 'create') { $head = expensereport_prepare_head($object); - if ($action == 'edit' && ($object->status < 3 || $object->status == 99)) { + if ($action == 'edit' && ($object->status < 3 || $object->status == ExpenseReport::STATUS_REFUSED)) { print "
\n"; print ''; print ''; @@ -1574,7 +1574,7 @@ if ($action == 'create') { print dol_get_fiche_head($head, 'card', $langs->trans("ExpenseReport"), 0, 'trip'); - if ($object->status == 99) { + if ($object->status == ExpenseReport::STATUS_REFUSED) { print ''; } else { print ''; @@ -1640,7 +1640,7 @@ if ($action == 'create') { print ''; } - if ($object->status == 6) { + if ($object->status == ExpenseReport::STATUS_CLOSED) { print '
'; print ''; print ''; } - if ($object->status == $object::STATUS_CLOSED) { + if ($object->status == ExpenseReport::STATUS_CLOSED) { /* TODO this fields are not yet filled print ''; print ''; @@ -2600,12 +2600,12 @@ if ($action == 'create') { // Unit price net print ''; // Unit price with tax print ''; // Quantity diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index f6a327d5a03..7bb2851d136 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -1927,7 +1927,7 @@ class ExpenseReport extends CommonObject dol_syslog(get_class($this)."::addline qty=$qty, up=$up, fk_c_type_fees=$fk_c_type_fees, vatrate=$vatrate, date=$date, fk_project=$fk_project, type=$type, comments=$comments", LOG_DEBUG); - if ($this->status == self::STATUS_DRAFT) { + if ($this->status == self::STATUS_DRAFT || $this->status == self::STATUS_REFUSED) { if (empty($qty)) { $qty = 0; } @@ -2021,7 +2021,7 @@ class ExpenseReport extends CommonObject } } else { dol_syslog(get_class($this)."::addline status of expense report must be Draft to allow use of ->addline()", LOG_ERR); - $this->error = 'ErrorExpenseNotDraft'; + $this->error = 'ErrorExpenseNotDraftAndNotRefused'; return -3; } } From c40567a98cac8cb745ca2add91aa124f57d194ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 16 Dec 2024 14:21:32 +0100 Subject: [PATCH 050/185] fix phpstan --- build/phpstan/bootstrap_action.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build/phpstan/bootstrap_action.php b/build/phpstan/bootstrap_action.php index 2bcc70dd965..f1a6a638f91 100644 --- a/build/phpstan/bootstrap_action.php +++ b/build/phpstan/bootstrap_action.php @@ -27,6 +27,7 @@ if (!defined("NOHTTPSREDIRECT")) { } // Defined some constants and load Dolibarr env to reduce PHPStan bootstrap that fails to load a lot of things. +$dolibarr_main_document_root = __DIR__ . '/../../htdocs'; define('DOL_DOCUMENT_ROOT', __DIR__ . '/../../htdocs'); define('DOL_DATA_ROOT', __DIR__ . '/../../documents'); define('DOL_URL_ROOT', '/'); @@ -42,6 +43,7 @@ define('MAIN_DB_PREFIX', 'llx_'); * @var User $user */ - global $conf, $db, $hookmanager, $langs, $mysoc, $user; +global $conf, $db, $hookmanager, $langs, $mysoc, $user; +global $dolibarr_main_document_root; // include_once DOL_DOCUMENT_ROOT . '/../../htdocs/main.inc.php'; From 5573ca35c32e1ffc6af8a45d908ccb3ffab0aa0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9=20Cendrier?= Date: Mon, 16 Dec 2024 15:32:54 +0100 Subject: [PATCH 051/185] FIX: comparing strings with numbers can be touchy --- htdocs/product/class/product.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 96a8d9fc59d..24ed27c5bf7 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1273,7 +1273,7 @@ class Product extends CommonObject $sql .= ", sell_or_eat_by_mandatory = ".((empty($this->sell_or_eat_by_mandatory) || $this->sell_or_eat_by_mandatory < 0) ? 0 : (int) $this->sell_or_eat_by_mandatory); $sql .= ", batch_mask = '".$this->db->escape($this->batch_mask)."'"; - $sql .= ", finished = ".((!isset($this->finished) || $this->finished < 0 || $this->finished == '') ? "null" : (int) $this->finished); + $sql .= ", finished = ".((!isset($this->finished) || $this->finished < 0 || $this->finished === '') ? "null" : (int) $this->finished); $sql .= ", fk_default_bom = ".((!isset($this->fk_default_bom) || $this->fk_default_bom < 0 || $this->fk_default_bom == '') ? "null" : (int) $this->fk_default_bom); $sql .= ", net_measure = ".($this->net_measure != '' ? "'".$this->db->escape($this->net_measure)."'" : 'null'); $sql .= ", net_measure_units = ".($this->net_measure_units != '' ? "'".$this->db->escape($this->net_measure_units)."'" : 'null'); From 817ddc1b8278888010734d783cc456b3dd89a78a Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Tue, 17 Dec 2024 08:01:15 +0100 Subject: [PATCH 052/185] Revert "FIX broken feature, entity can not be empty !" This reverts commit 43f50ee7b878162fca65493ea22bee414ffff6eb. --- htdocs/core/lib/files.lib.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index ca4268f76c1..e8e347e7647 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -2747,9 +2747,12 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, if (empty($modulepart)) { return 'ErrorBadParameter'; } - // entity can't be empty if (empty($entity)) { - $entity = $conf->entity; + if (!isModEnabled('multicompany')) { + $entity = 1; + } else { + $entity = 0; + } } // Fix modulepart for backward compatibility if ($modulepart == 'facture') { @@ -2800,6 +2803,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, if (isModEnabled('multicompany') && (empty($entity) || empty($conf->medias->multidir_output[$entity]))) { return array('accessallowed' => 0, 'error' => 'Value entity must be provided'); } */ + if (empty($entity)) { + $entity = 1; + } $accessallowed = 1; $original_file = (empty($conf->medias->multidir_output[$entity]) ? $conf->medias->dir_output : $conf->medias->multidir_output[$entity]).'/'.$original_file; } elseif ($modulepart == 'logs' && !empty($dolibarr_main_data_root)) { From 253d3eceeb61127f128f78e1c11b9f715c11bb40 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Tue, 17 Dec 2024 08:01:55 +0100 Subject: [PATCH 053/185] FIX broken feature, wrong GETPOSTINT parameter --- htdocs/document.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/document.php b/htdocs/document.php index ede788ab2fa..f0e60549d1c 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -103,7 +103,7 @@ $original_file = GETPOST('file', 'alphanohtml'); $hashp = GETPOST('hashp', 'aZ09'); $modulepart = GETPOST('modulepart', 'alpha'); $urlsource = GETPOST('urlsource', 'alpha'); -$entity = GETPOSTINT('entity', $conf->entity); +$entity = GETPOSTINT('entity'); // Security check if (empty($modulepart) && empty($hashp)) { From 83fb45a6ba59d2ecedfb67c625eb848c8532f856 Mon Sep 17 00:00:00 2001 From: alsoft10 Date: Tue, 17 Dec 2024 14:04:02 +0530 Subject: [PATCH 054/185] FIX#32391 --- htdocs/societe/class/api_contacts.class.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index 3499bf09b92..a103c6e991b 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -192,9 +192,11 @@ class Contacts extends DolibarrApi } $sql = "SELECT t.rowid"; - $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as t"; if ($category > 0) { - $sql .= ", ".MAIN_DB_PREFIX."categorie_contact as c"; + $sql .= " FROM (".MAIN_DB_PREFIX."socpeople as t"; + $sql .= ", ".MAIN_DB_PREFIX."categorie_contact as c)"; + } else { + $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as t"; } $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople_extrafields as te ON te.fk_object = t.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON t.fk_soc = s.rowid"; From 55c6feef8cf4baffdf0adc11eab494f0f74b11b3 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 17 Dec 2024 10:15:32 +0100 Subject: [PATCH 055/185] Fix css --- htdocs/comm/propal/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index 9ad46ac19d6..59bea619be2 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -1938,8 +1938,8 @@ while ($i < $imaxinloop) { } // Country if (!empty($arrayfields['country.code_iso']['checked'])) { - print ''; if (!$i) { From f8a36a0283a181a5e9b20a120efe94250bf7ec69 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 17 Dec 2024 11:07:57 +0100 Subject: [PATCH 056/185] Add link to CVE.org --- dev/tools/apstats.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev/tools/apstats.php b/dev/tools/apstats.php index fa27133329a..825257dadbe 100755 --- a/dev/tools/apstats.php +++ b/dev/tools/apstats.php @@ -883,7 +883,7 @@ $html .= '

'.$title_security $html .= '
'."\n"; $html .= '
'."\n"; $html .= '

".$langs->trans("Name")." / ".$langs->trans("Company")."".$langs->trans("Anonymous")."".dol_print_date($db->jdate($objp->datedon))."'.number_format($objp->amount, 2, '.', ' ').' '.$langs->trans("Currency".$conf->currency).''.price($objp->amount).' '.$langs->trans("Currency".$conf->currency).'
'.$langs->trans('Note').'
'.$langs->trans("AUTHORPAIEMENT").''; @@ -1858,7 +1858,7 @@ if ($action == 'create') { print '
'.$langs->trans("AUTHORPAIEMENT").''; - print ''; + print ''; print ''; - print ''; + print ''; print ''; $tmparray = getCountry($obj->fk_pays, 'all'); + print ''; print $tmparray['label']; print '
'."\n"; -$html .= ''."\n"; +$html .= ''."\n"; foreach ($arrayofalerts as $key => $alert) { $cve = ''; $yogosha = empty($alert['issueidyogosha']) ? '' : $alert['issueidyogosha']; From 3fa0b65c0cb740f23dd6f59b9ef9015252872d8b Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 17 Dec 2024 13:33:29 +0100 Subject: [PATCH 057/185] Fix filter on contact --- htdocs/societe/class/api_contacts.class.php | 36 ++++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index 0af1d485070..b14a87d5a14 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -194,9 +194,6 @@ class Contacts extends DolibarrApi $sql = "SELECT t.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as t"; - if ($category > 0) { - $sql .= ", ".MAIN_DB_PREFIX."categorie_contact as c"; - } $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople_extrafields as te ON te.fk_object = t.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON t.fk_soc = s.rowid"; $sql .= ' WHERE t.entity IN ('.getEntity('contact').')'; @@ -213,8 +210,37 @@ class Contacts extends DolibarrApi } // Select contacts of given category if ($category > 0) { - $sql .= " AND c.fk_categorie = ".((int) $category); - $sql .= " AND c.fk_socpeople = t.rowid "; + // Search Contact Categories + $searchCategoryContactList = $category ? array($category) : array(); + $searchCategoryContactOperator = 0; + // Search for tag/category ($searchCategoryContactList is an array of ID) + if (!empty($searchCategoryContactList)) { + $searchCategoryContactSqlList = array(); + $listofcategoryid = ''; + foreach ($searchCategoryContactList as $searchCategoryContact) { + if (intval($searchCategoryContact) == -2) { + $searchCategoryContactSqlList[] = "NOT EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople)"; + } elseif (intval($searchCategoryContact) > 0) { + if ($searchCategoryContactOperator == 0) { + $searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople AND ck.fk_categorie = ".((int) $searchCategoryContact).")"; + } else { + $listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryContact); + } + } + } + if ($listofcategoryid) { + $searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople AND ck.fk_categorie IN (".$db->sanitize($listofcategoryid)."))"; + } + if ($searchCategoryContactOperator == 1) { + if (!empty($searchCategoryContactSqlList)) { + $sql .= " AND (".implode(' OR ', $searchCategoryContactSqlList).")"; + } + } else { + if (!empty($searchCategoryContactSqlList)) { + $sql .= " AND (".implode(' AND ', $searchCategoryContactSqlList).")"; + } + } + } } // Add sql filters From b2479ae74fc2de6926e900a929d19ce474fa9336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 17 Dec 2024 15:06:06 +0100 Subject: [PATCH 058/185] Update api_contacts.class.php --- htdocs/societe/class/api_contacts.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index b14a87d5a14..b2e635f7806 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -229,7 +229,7 @@ class Contacts extends DolibarrApi } } if ($listofcategoryid) { - $searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople AND ck.fk_categorie IN (".$db->sanitize($listofcategoryid)."))"; + $searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople AND ck.fk_categorie IN (".$this->db->sanitize($listofcategoryid)."))"; } if ($searchCategoryContactOperator == 1) { if (!empty($searchCategoryContactSqlList)) { From 2f93bac9bfc38d5eb8815596ecce9174c806fa6a Mon Sep 17 00:00:00 2001 From: Irvine Fleith Date: Tue, 17 Dec 2024 15:52:39 +0100 Subject: [PATCH 059/185] FIX : fk_societe_rib --- htdocs/compta/facture/class/facture-rec.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index ef3d96fed53..056d34018fc 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -398,7 +398,7 @@ class FactureRec extends CommonInvoice $sql .= ", '".$this->db->escape($facsrc->multicurrency_code)."'"; $sql .= ", ".((float) $facsrc->multicurrency_tx); $sql .= ", ".((int) $this->suspended); - $sql .= ", ".((int) $this->fk_societe_rib); + $sql .= ", ".(!empty($this->fk_societe_rib) ? ((int) $this->fk_societe_rib) : 'NULL'); $sql .= ")"; if ($this->db->query($sql)) { @@ -571,7 +571,7 @@ class FactureRec extends CommonInvoice $sql .= " localtax2 = ".((float) $this->total_localtax2).","; $sql .= " total_ht = ".((float) $this->total_ht).","; $sql .= " total_ttc = ".((float) $this->total_ttc).","; - $sql .= " fk_societe_rib = ".((int) $this->fk_societe_rib); + $sql .= " fk_societe_rib = ".(!empty($this->fk_societe_rib) ? ((int) $this->fk_societe_rib) : 'NULL');; // TODO Add missing fields $sql .= " WHERE rowid = ".((int) $this->id); From fc82b4f2a9e20966e4f0dce6a2d81c4f07832810 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 17 Dec 2024 17:07:54 +0100 Subject: [PATCH 060/185] Too many false positive --- phpstan.neon.dist | 3 +++ 1 file changed, 3 insertions(+) diff --git a/phpstan.neon.dist b/phpstan.neon.dist index de1271a36e1..c2d6e89d7f1 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -53,6 +53,9 @@ parameters: ignoreErrors: - '#.*phan-var#' - '#^Expression "''…" on a separate line does not do anything\.$#' + - '#is always true#' + - '#is always false#' + - '#will always evaluate to true#' internalErrorsCountLimit: 50 cache: # nodesByFileCountMax: 512 From 1895fb3394db491b6df303438761b2490ea441db Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Tue, 17 Dec 2024 17:27:27 +0100 Subject: [PATCH 061/185] fix: missing token on delete line on MO --- htdocs/mrp/mo_production.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index bedd7714adf..4a48a1fbaab 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -1644,6 +1644,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $href = $_SERVER["PHP_SELF"]; $href .= '?id='.$object->id; $href .= '&action=deleteline'; + $href .= '&token='.newToken(); $href .= '&lineid='.$line->id; print ''; From 12f044fc294b2de5023e0825498ca829d6cf8532 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 17 Dec 2024 20:56:08 +0100 Subject: [PATCH 072/185] fix phan and phpstan --- htdocs/reception/class/reception.class.php | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 86e8d046ff9..22c1ad326ba 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -647,8 +647,7 @@ class Reception extends CommonObject if (intval($result) < 0) { $error++; - $this->errors[] = $mouvS->error; - $this->errors = array_merge($this->errors, $mouvS->errors); + $this->setErrorsFromObject($mouvS); break; } } else { @@ -661,8 +660,7 @@ class Reception extends CommonObject if (intval($result) < 0) { $error++; - $this->errors[] = $mouvS->error; - $this->errors = array_merge($this->errors, $mouvS->errors); + $this->setErrorsFromObject($mouvS); break; } } @@ -809,8 +807,7 @@ class Reception extends CommonObject $ret = $supplierorderdispatch->fetchAll('', '', 0, 0, $filter); if ($ret < 0) { - $this->error = $supplierorderdispatch->error; - $this->errors = $supplierorderdispatch->errors; + $this->setErrorsFromObject($supplierorderdispatch); return $ret; } else { // build array with quantity received by product in all supplier orders (origin) @@ -895,8 +892,7 @@ class Reception extends CommonObject $supplierorderline = new CommandeFournisseurLigne($this->db); $result = $supplierorderline->fetch($id); if ($result <= 0) { - $this->error = $supplierorderline->error; - $this->errors = $supplierorderline->errors; + $this->setErrorsFromObject($supplierorderline); return -1; } From bcad4452348cb12a73494ef20600501863521403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 17 Dec 2024 21:24:07 +0100 Subject: [PATCH 073/185] fix phan and phpstan --- build/phpstan/phpstan-baseline.neon | 6 ------ htdocs/salaries/list.php | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index e68ba34de51..de78f238855 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -30318,12 +30318,6 @@ parameters: count: 1 path: ../../htdocs/salaries/list.php - - - message: '#^Variable \$resteapayer might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/salaries/list.php - - message: '#^Variable \$selected might not be defined\.$#' identifier: variable.undefined diff --git a/htdocs/salaries/list.php b/htdocs/salaries/list.php index c26a609536b..698fdf9ab4f 100644 --- a/htdocs/salaries/list.php +++ b/htdocs/salaries/list.php @@ -211,7 +211,7 @@ if ($massaction == 'withdrawrequest') { if ($objecttmp->status == Salary::STATUS_PAID || $objecttmp->resteapayer == 0) { $error++; setEventMessages($langs->trans("Salary").' '.$objecttmp->ref.' : '.$langs->trans("AlreadyPaid"), $objecttmp->errors, 'errors'); - } elseif ($resteapayer < 0) { + } elseif ($objecttmp->resteapayer < 0) { $error++; setEventMessages($langs->trans("Salary").' '.$objecttmp->ref.' : '.$langs->trans("AmountMustBePositive"), $objecttmp->errors, 'errors'); } From d2ff7481ddfa2e19ad746176d6f48fb0b4e3dd57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 17 Dec 2024 21:42:26 +0100 Subject: [PATCH 074/185] fix phan and phpstan --- htdocs/salaries/class/salary.class.php | 3 ++- htdocs/salaries/list.php | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/salaries/class/salary.class.php b/htdocs/salaries/class/salary.class.php index a70fce80e07..e0d3abf655c 100644 --- a/htdocs/salaries/class/salary.class.php +++ b/htdocs/salaries/class/salary.class.php @@ -120,6 +120,7 @@ class Salary extends CommonObject /** * @var int + * @deprecated see $accountid * @see $accountid */ public $fk_account; @@ -154,7 +155,7 @@ class Salary extends CommonObject const STATUS_PAID = 1; /** - * @var string + * @var float amount remain to pay */ public $resteapayer; diff --git a/htdocs/salaries/list.php b/htdocs/salaries/list.php index 698fdf9ab4f..f72c3a4512f 100644 --- a/htdocs/salaries/list.php +++ b/htdocs/salaries/list.php @@ -193,8 +193,8 @@ if ($massaction == 'withdrawrequest') { $objecttmp = new Salary($db); $result = $objecttmp->fetch($toselectid); if ($result > 0) { - $totalpaid = $objecttmp->getSommePaiement(); - $objecttmp->resteapayer = price2num((float) $objecttmp->amount - $totalpaid, 'MT'); + $totalpaid = (float) $objecttmp->getSommePaiement(); + $objecttmp->resteapayer = (float) price2num((float) $objecttmp->amount - $totalpaid, 'MT'); // hook to finalize the remaining amount, considering e.g. cash discount agreements $parameters = array('remaintopay' => $objecttmp->resteapayer); From 351897e9cee0f4f5d776fd8019170e470b7ff91b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 17 Dec 2024 22:01:11 +0100 Subject: [PATCH 075/185] fix phan and phpstan --- build/phpstan/phpstan-baseline.neon | 12 ------------ .../societe/canvas/company/tpl/card_create.tpl.php | 7 +++++-- htdocs/societe/canvas/company/tpl/card_edit.tpl.php | 2 ++ htdocs/societe/canvas/company/tpl/card_view.tpl.php | 1 + 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index de78f238855..053e33717d6 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -30426,18 +30426,6 @@ parameters: count: 1 path: ../../htdocs/societe/ajax/company.php - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/societe/canvas/company/tpl/card_create.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/societe/canvas/company/tpl/card_edit.tpl.php - - message: '#^Variable \$canvas might not be defined\.$#' identifier: variable.undefined diff --git a/htdocs/societe/canvas/company/tpl/card_create.tpl.php b/htdocs/societe/canvas/company/tpl/card_create.tpl.php index 379abf2e8cc..dc2ef93fc6f 100644 --- a/htdocs/societe/canvas/company/tpl/card_create.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_create.tpl.php @@ -1,6 +1,6 @@ - * Copyright (C) 2010-2012 Laurent Destailleur +/* Copyright (C) 2010 Regis Houssin + * Copyright (C) 2010-2012 Laurent Destailleur * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -18,10 +18,13 @@ */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/societe/canvas/company/tpl/card_edit.tpl.php b/htdocs/societe/canvas/company/tpl/card_edit.tpl.php index 5143b84ea73..03a353f7eb8 100644 --- a/htdocs/societe/canvas/company/tpl/card_edit.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_edit.tpl.php @@ -18,10 +18,12 @@ */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var Translate $langs * @var User $user + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/societe/canvas/company/tpl/card_view.tpl.php b/htdocs/societe/canvas/company/tpl/card_view.tpl.php index 82191b9faa0..efca04178e9 100644 --- a/htdocs/societe/canvas/company/tpl/card_view.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_view.tpl.php @@ -16,6 +16,7 @@ * along with this program. If not, see . */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var Translate $langs From f104e216580a7502e8dbfad3440412e315346766 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 17 Dec 2024 22:11:50 +0100 Subject: [PATCH 076/185] fix phan and phpstan --- build/phpstan/phpstan-baseline.neon | 6 ------ .../canvas/company/tpl/card_view.tpl.php | 17 +++++++++-------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index 053e33717d6..1c7672653e5 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -30426,12 +30426,6 @@ parameters: count: 1 path: ../../htdocs/societe/ajax/company.php - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/societe/canvas/company/tpl/card_view.tpl.php - - message: '#^Variable \$db might not be defined\.$#' identifier: variable.undefined diff --git a/htdocs/societe/canvas/company/tpl/card_view.tpl.php b/htdocs/societe/canvas/company/tpl/card_view.tpl.php index efca04178e9..f1246e4bb66 100644 --- a/htdocs/societe/canvas/company/tpl/card_view.tpl.php +++ b/htdocs/societe/canvas/company/tpl/card_view.tpl.php @@ -21,6 +21,8 @@ * @var CommonObject $this * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { @@ -38,17 +40,16 @@ $head = societe_prepare_head($soc); print dol_get_fiche_head($head, 'card', $langs->trans("ThirdParty"), 0, 'company'); -?> - -control->tpl['error']) { +if ($this->control->tpl['error']) { echo $this->control->tpl['error']; -} ?> -control->tpl['action_delete']) { +} +if ($this->control->tpl['action_delete']) { echo $this->control->tpl['action_delete']; -} ?> -control->tpl['js_checkVatPopup']) { +} +if ($this->control->tpl['js_checkVatPopup']) { echo $this->control->tpl['js_checkVatPopup']; -} ?> +} +?>
Commit IDDateReported on
Yogosha
Reported on
GIT
Reported on
CVE
TitleBranch of fix
Commit IDDateReported on
Yogosha
Reported on
GIT
Reported on
CVE
TitleBranch of fix
'; print ''; From 0278082f27ccc09adbeb14eed9689b732a8e912f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 17 Dec 2024 17:48:04 +0100 Subject: [PATCH 062/185] fix --- .github/workflows/pr-18-autolabel.yaml | 2 +- phpstan.neon.dist | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/pr-18-autolabel.yaml b/.github/workflows/pr-18-autolabel.yaml index 4f7b08ea725..feb9ee17c97 100644 --- a/.github/workflows/pr-18-autolabel.yaml +++ b/.github/workflows/pr-18-autolabel.yaml @@ -18,4 +18,4 @@ jobs: with: repo-token: ${{ secrets.GITHUB_TOKEN }} configuration-path: .github/changed-lines-count-labeler.yml - continue-on-error: true \ No newline at end of file + continue-on-error: true diff --git a/phpstan.neon.dist b/phpstan.neon.dist index c2d6e89d7f1..de1271a36e1 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -53,9 +53,6 @@ parameters: ignoreErrors: - '#.*phan-var#' - '#^Expression "''…" on a separate line does not do anything\.$#' - - '#is always true#' - - '#is always false#' - - '#will always evaluate to true#' internalErrorsCountLimit: 50 cache: # nodesByFileCountMax: 512 From 6623a3c23d4d0a06e5b8be4783db0cb1f728ca9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 17 Dec 2024 17:59:21 +0100 Subject: [PATCH 063/185] remove no more used code --- .../accountancy/class/bookkeeping.class.php | 2 +- htdocs/societe/class/api_contacts.class.php | 36 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 36130e46714..5a8ca7b2eeb 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -69,7 +69,7 @@ class BookKeeping extends CommonObject public $doc_date; /** - * @var int Deadline for payment + * @var int|'' Deadline for payment */ public $date_lim_reglement; diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index b2e635f7806..365d2968f0b 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2019 Frédéric France + * Copyright (C) 2019-2024 Frédéric France * Copyright (C) 2024 MDW * * This program is free software; you can redistribute it and/or modify @@ -212,34 +212,34 @@ class Contacts extends DolibarrApi if ($category > 0) { // Search Contact Categories $searchCategoryContactList = $category ? array($category) : array(); - $searchCategoryContactOperator = 0; + // $searchCategoryContactOperator = 0; // Search for tag/category ($searchCategoryContactList is an array of ID) if (!empty($searchCategoryContactList)) { $searchCategoryContactSqlList = array(); - $listofcategoryid = ''; + // $listofcategoryid = ''; foreach ($searchCategoryContactList as $searchCategoryContact) { if (intval($searchCategoryContact) == -2) { $searchCategoryContactSqlList[] = "NOT EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople)"; } elseif (intval($searchCategoryContact) > 0) { - if ($searchCategoryContactOperator == 0) { + // if ($searchCategoryContactOperator == 0) { $searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople AND ck.fk_categorie = ".((int) $searchCategoryContact).")"; - } else { - $listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryContact); - } + // } else { + // $listofcategoryid .= ($listofcategoryid ? ', ' : '') .((int) $searchCategoryContact); + // } } } - if ($listofcategoryid) { - $searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople AND ck.fk_categorie IN (".$this->db->sanitize($listofcategoryid)."))"; - } - if ($searchCategoryContactOperator == 1) { - if (!empty($searchCategoryContactSqlList)) { - $sql .= " AND (".implode(' OR ', $searchCategoryContactSqlList).")"; - } - } else { - if (!empty($searchCategoryContactSqlList)) { - $sql .= " AND (".implode(' AND ', $searchCategoryContactSqlList).")"; - } + // if ($listofcategoryid) { + // $searchCategoryContactSqlList[] = " EXISTS (SELECT ck.fk_socpeople FROM ".MAIN_DB_PREFIX."categorie_contact as ck WHERE t.rowid = ck.fk_socpeople AND ck.fk_categorie IN (".$this->db->sanitize($listofcategoryid)."))"; + // } + // if ($searchCategoryContactOperator == 1) { + // if (!empty($searchCategoryContactSqlList)) { + // $sql .= " AND (".implode(' OR ', $searchCategoryContactSqlList).")"; + // } + // } else { + if (!empty($searchCategoryContactSqlList)) { + $sql .= " AND (".implode(' AND ', $searchCategoryContactSqlList).")"; } + // } } } From 7959f4b6adb11333714dff5b12f3a276c7379d74 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 17 Dec 2024 18:11:22 +0100 Subject: [PATCH 064/185] Debug use bad amount for the subscription --- htdocs/public/payment/newpayment.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/htdocs/public/payment/newpayment.php b/htdocs/public/payment/newpayment.php index 59f4039c6c8..cbf12d63bcf 100644 --- a/htdocs/public/payment/newpayment.php +++ b/htdocs/public/payment/newpayment.php @@ -1522,9 +1522,8 @@ if ($source == 'member' || $source == 'membersubscription') { $member = new Adherent($db); $adht = new AdherentType($db); - $subscription = new Subscription($db); - $result = $member->fetch('', $ref); + $result = $member->fetch('', $ref, 0, '', true, true); // This fetch also ->last_subscription_amount if ($result <= 0) { $mesg = $member->error; $error++; @@ -1536,7 +1535,7 @@ if ($source == 'member' || $source == 'membersubscription') { $object = $member; if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment - $amount = $subscription->total_ttc; + $amount = $member->last_subscription_amount; if (GETPOST("amount", 'alpha')) { $amount = price2num(GETPOST("amount", 'alpha'), 'MT', 2); } @@ -1673,6 +1672,10 @@ if ($source == 'member' || $source == 'membersubscription') { if (empty($amount) && getDolGlobalString('MEMBER_NEWFORM_AMOUNT')) { $amount = getDolGlobalString('MEMBER_NEWFORM_AMOUNT'); } + // - If an amount was posted from the form (for example from page with types of membership) + if ($caneditamount && GETPOSTISSET('amount') && GETPOSTFLOAT('amount', 'MT') > 0) { + $amount = GETPOSTFLOAT('amount', 'MT'); + } // - If a new amount was posted from the form if ($caneditamount && GETPOSTISSET('newamount') && GETPOSTFLOAT('newamount', 'MT') > 0) { $amount = GETPOSTFLOAT('newamount', 'MT'); From 15d4323b5a33b2339bad7b6d0ab0e742b751851c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 17 Dec 2024 18:13:53 +0100 Subject: [PATCH 065/185] Update bookkeeping.class.php --- htdocs/accountancy/class/bookkeeping.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 1dd9f9c70ac..00f13ec3dfd 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -2941,7 +2941,7 @@ class BookKeeping extends CommonObject $result = $this->db->query($sql); if (!$result) { $this->errors[] = 'Error: ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); $error++; } $objtmp = $this->db->fetch_object($result); From ddabb06037da04bd35efcba17ef22329033971f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 17 Dec 2024 18:20:43 +0100 Subject: [PATCH 066/185] Update bookkeeping.class.php --- htdocs/accountancy/class/bookkeeping.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 00f13ec3dfd..35a710e8b8a 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -2877,7 +2877,7 @@ class BookKeeping extends CommonObject $result = $this->db->query($sql); if (!$result) { $this->errors[] = 'Error: ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); $error++; } $objtmp = $this->db->fetch_object($result); From 07284c4d966a9048c34d8cb913a1be25b50edc92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 17 Dec 2024 18:28:24 +0100 Subject: [PATCH 067/185] Update bookkeeping.class.php --- htdocs/accountancy/class/bookkeeping.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 35a710e8b8a..3529a2a9179 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -69,7 +69,7 @@ class BookKeeping extends CommonObject public $doc_date; /** - * @var int Deadline for payment + * @var int|null|'' Deadline for payment */ public $date_lim_reglement; From 4f780dab1a3c433e690fa0c15238af21d84ca78f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Tue, 17 Dec 2024 18:35:21 +0100 Subject: [PATCH 068/185] Update bookkeeping.class.php --- htdocs/accountancy/class/bookkeeping.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 3529a2a9179..03fffa54ed4 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -99,12 +99,12 @@ class BookKeeping extends CommonObject public $thirdparty_code; /** - * @var string subledger account + * @var string|null subledger account */ public $subledger_account; /** - * @var string subledger label + * @var string|null subledger label */ public $subledger_label; From 6f2611cf740304542e5d1c553bad1e5a860c1aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 17 Dec 2024 18:36:52 +0100 Subject: [PATCH 069/185] fix phan --- dev/tools/phan/baseline.txt | 4 ++-- htdocs/accountancy/class/bookkeeping.class.php | 14 ++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index d69db0e405e..08216e8939a 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -17,7 +17,7 @@ return [ // PhanTypeMismatchProperty : 130+ occurrences // PhanPluginUnknownArrayMethodParamType : 120+ occurrences // PhanPluginUnknownPropertyType : 110+ occurrences - // PhanPossiblyUndeclaredVariable : 80+ occurrences + // PhanPossiblyUndeclaredVariable : 65+ occurrences // PhanRedefineFunction : 45+ occurrences // PhanTypeExpectedObjectPropAccess : 45+ occurrences // PhanTypeMismatchArgumentNullableInternal : 40+ occurrences @@ -507,7 +507,7 @@ return [ 'htdocs/recruitment/admin/setup_candidatures.php' => ['PhanEmptyForeach'], 'htdocs/recruitment/class/recruitmentcandidature.class.php' => ['PhanUndeclaredProperty'], 'htdocs/recruitment/class/recruitmentjobposition.class.php' => ['PhanUndeclaredProperty'], - 'htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php' => ['PhanPossiblyUndeclaredVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], + 'htdocs/recruitment/core/modules/recruitment/doc/pdf_standard_recruitmentjobposition.modules.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/recruitment/core/modules/recruitment/mod_recruitmentcandidature_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'], 'htdocs/recruitment/core/modules/recruitment/mod_recruitmentjobposition_advanced.php' => ['PhanPluginSuspiciousParamOrder', 'PhanUndeclaredProperty'], 'htdocs/recruitment/index.php' => ['PhanUndeclaredGlobalVariable'], diff --git a/htdocs/accountancy/class/bookkeeping.class.php b/htdocs/accountancy/class/bookkeeping.class.php index 5a8ca7b2eeb..f8573c3f75e 100644 --- a/htdocs/accountancy/class/bookkeeping.class.php +++ b/htdocs/accountancy/class/bookkeeping.class.php @@ -69,7 +69,7 @@ class BookKeeping extends CommonObject public $doc_date; /** - * @var int|'' Deadline for payment + * @var int|null|'' Deadline for payment */ public $date_lim_reglement; @@ -2926,7 +2926,7 @@ class BookKeeping extends CommonObject $result = $this->db->query($sql); if (!$result) { $this->errors[] = 'Error: ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); $error++; } $objtmp = $this->db->fetch_object($result); @@ -2938,7 +2938,7 @@ class BookKeeping extends CommonObject $bookkeeping->numero_compte = $obj->numero_compte; $accountingaccount = new AccountingAccount($this->db); - $accountingaccount->fetch('', $obj->numero_compte); + $accountingaccount->fetch(0, $obj->numero_compte); $bookkeeping->label_compte = $accountingaccount->label; // latest account label used $bookkeeping->label_operation = $new_fiscal_period->label; @@ -2953,8 +2953,7 @@ class BookKeeping extends CommonObject $result = $bookkeeping->create($user); if ($result < 0) { - $this->error = $bookkeeping->error; - $this->errors = $bookkeeping->errors; + $this->setErrorsFromObject($bookkeeping); $error++; break; } @@ -2990,7 +2989,7 @@ class BookKeeping extends CommonObject $result = $this->db->query($sql); if (!$result) { $this->errors[] = 'Error: ' . $this->db->lasterror(); - dol_syslog(__METHOD__ . ' ' . join(',', $this->errors), LOG_ERR); + dol_syslog(__METHOD__ . ' ' . implode(',', $this->errors), LOG_ERR); $error++; } $objtmp = $this->db->fetch_object($result); @@ -3015,8 +3014,7 @@ class BookKeeping extends CommonObject $result = $bookkeeping->create($user); if ($result < 0) { - $this->error = $bookkeeping->error; - $this->errors = $bookkeeping->errors; + $this->setErrorsFromObject($bookkeeping); $error++; } } From d89897512376d3109fa098dd077614885b679872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 17 Dec 2024 19:43:31 +0100 Subject: [PATCH 070/185] generate phpstan baseline for new phpstan version 2.0.4 --- build/phpstan/phpstan-baseline.neon | 30 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index d88e33d2e26..0e5c79af5ef 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -463,7 +463,7 @@ parameters: path: ../../htdocs/accountancy/class/accountingaccount.class.php - - message: '#^Call to function array_key_exists\(\) with ''error'' and array\{ref\: mixed, label\: mixed, acquisition_value_ht\: mixed, depreciation\: non\-empty\-array\\}\>, disposal\?\: array\{date\: mixed, amount\: mixed, subject_to_vat\: bool\}\} will always evaluate to false\.$#' + message: '#^Call to function array_key_exists\(\) with ''error'' and array\{ref\: mixed, label\: mixed, acquisition_value_ht\: mixed, depreciation\: non\-empty\-array\\}\>, disposal\?\: array\{date\: mixed, amount\: mixed, subject_to_vat\: bool\}\} will always evaluate to false\.$#' identifier: function.impossibleType count: 1 path: ../../htdocs/accountancy/class/accountingjournal.class.php @@ -625,7 +625,7 @@ parameters: path: ../../htdocs/accountancy/class/lettering.class.php - - message: '#^Parameter \#1 \$link_by_element of method Lettering\:\:getGroupElements\(\) expects array\\>, array\\> given\.$#' + message: '#^Parameter \#1 \$link_by_element of method Lettering\:\:getGroupElements\(\) expects array\\>, array\\> given\.$#' identifier: argument.type count: 1 path: ../../htdocs/accountancy/class/lettering.class.php @@ -894,10 +894,16 @@ parameters: count: 1 path: ../../htdocs/adherents/card.php + - + message: '#^Call to function is_array\(\) with array will always evaluate to true\.$#' + identifier: function.alreadyNarrowedType + count: 1 + path: ../../htdocs/adherents/class/adherent.class.php + - message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType - count: 2 + count: 1 path: ../../htdocs/adherents/class/adherent.class.php - @@ -3343,7 +3349,7 @@ parameters: path: ../../htdocs/categories/class/categorie.class.php - - message: '#^Method Categorie\:\:get_full_arbo\(\) should return \-1\|array\ but returns array\\.$#' + message: '#^Method Categorie\:\:get_full_arbo\(\) should return \-1\|array\ but returns array\\.$#' identifier: return.type count: 1 path: ../../htdocs/categories/class/categorie.class.php @@ -3361,7 +3367,7 @@ parameters: path: ../../htdocs/categories/class/categorie.class.php - - message: '#^Property Categorie\:\:\$cats \(array\\) does not accept array\\.$#' + message: '#^Property Categorie\:\:\$cats \(array\\) does not accept array\\.$#' identifier: assign.propertyType count: 2 path: ../../htdocs/categories/class/categorie.class.php @@ -5311,7 +5317,7 @@ parameters: path: ../../htdocs/compta/cashcontrol/class/cashcontrol.class.php - - message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-array\<\(float\|int\)\> will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/compta/cashcontrol/report.php @@ -6601,7 +6607,7 @@ parameters: path: ../../htdocs/compta/resultat/index.php - - message: '#^Call to function is_array\(\) with non\-empty\-array\\}\> will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-array\\}\> will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/compta/resultat/result.php @@ -7969,7 +7975,7 @@ parameters: path: ../../htdocs/core/actions_linkedfiles.inc.php - - message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/core/actions_massactions.inc.php @@ -10537,7 +10543,7 @@ parameters: path: ../../htdocs/core/class/notify.class.php - - message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/core/class/openid.class.php @@ -13597,7 +13603,7 @@ parameters: path: ../../htdocs/core/modules/hrm/mod_evaluation_standard.php - - message: '#^Call to function is_array\(\) with non\-empty\-array will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with non\-empty\-list\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/core/modules/import/import_csv.modules.php @@ -23299,7 +23305,7 @@ parameters: path: ../../htdocs/master.inc.php - - message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/modulebuilder/index.php @@ -30937,7 +30943,7 @@ parameters: path: ../../htdocs/societe/notify/card.php - - message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' + message: '#^Call to function is_array\(\) with array\ will always evaluate to true\.$#' identifier: function.alreadyNarrowedType count: 1 path: ../../htdocs/societe/paymentmodes.php From 1ab4e57ab963e0a0927485aeda77eb351c8497d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Tue, 17 Dec 2024 20:32:52 +0100 Subject: [PATCH 071/185] fix phan and phpstan --- build/phpstan/phpstan-baseline.neon | 6 ------ dev/tools/phan/baseline.txt | 2 +- htdocs/salaries/paiement_salary.php | 3 ++- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index 0e5c79af5ef..e68ba34de51 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -30342,12 +30342,6 @@ parameters: count: 2 path: ../../htdocs/salaries/paiement_salary.php - - - message: '#^Variable \$sumpaid might not be defined\.$#' - identifier: variable.undefined - count: 3 - path: ../../htdocs/salaries/paiement_salary.php - - message: '#^Negated boolean expression is always false\.$#' identifier: booleanNot.alwaysFalse diff --git a/dev/tools/phan/baseline.txt b/dev/tools/phan/baseline.txt index 08216e8939a..6d3df7446b4 100644 --- a/dev/tools/phan/baseline.txt +++ b/dev/tools/phan/baseline.txt @@ -523,7 +523,7 @@ return [ 'htdocs/salaries/card.php' => ['PhanPossiblyUndeclaredGlobalVariable'], 'htdocs/salaries/class/api_salaries.class.php' => ['PhanPluginUnknownArrayMethodParamType', 'PhanPluginUnknownArrayMethodReturnType'], 'htdocs/salaries/list.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredGlobalVariable'], - 'htdocs/salaries/paiement_salary.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], + 'htdocs/salaries/paiement_salary.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], 'htdocs/salaries/virement_request.php' => ['PhanPossiblyUndeclaredGlobalVariable', 'PhanUndeclaredProperty'], 'htdocs/societe/admin/societe.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredMethod'], 'htdocs/societe/ajax/company.php' => ['PhanTypeMismatchArgumentProbablyReal', 'PhanUndeclaredProperty'], diff --git a/htdocs/salaries/paiement_salary.php b/htdocs/salaries/paiement_salary.php index fcb4cb9ad53..f084e5e1a07 100644 --- a/htdocs/salaries/paiement_salary.php +++ b/htdocs/salaries/paiement_salary.php @@ -167,6 +167,7 @@ $help_url = ''; llxHeader('', '', $help_url); $salary = $object; +$sumpaid = 0.0; // Formulaire de creation d'un paiement de charge if ($action == 'create') { @@ -214,7 +215,7 @@ if ($action == 'create') { $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); - $sumpaid = $obj->total; + $sumpaid = (float) $obj->total; $db->free($resql); } /*print '
'.$langs->trans("AlreadyPaid").''.price($sumpaid,0,$outputlangs,1,-1,-1,$conf->currency).'
From b73bcd68a94b75300cb78a7f4610a60acbc0f43e Mon Sep 17 00:00:00 2001 From: tnegre Date: Wed, 18 Dec 2024 10:36:39 +0100 Subject: [PATCH 077/185] pre-commit : change regex for hook no-commit-to-branch in order to allow branches BEGINNING by 18.0, such as `18.0_fix_foo` --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 47ffeb5e28f..3296110422c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ repos: rev: v4.5.0 hooks: - id: no-commit-to-branch - args: [--branch, develop, --pattern, \d+.0] + args: [--branch, develop, --pattern, \d+.0$] - id: check-yaml args: [--unsafe] - id: check-json From 60624b0b53d7665570d1c8a0023eef38d24f162c Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 18 Dec 2024 12:21:54 +0100 Subject: [PATCH 078/185] Debug v21 --- htdocs/exports/export.php | 15 ++++++++------- htdocs/imports/import.php | 13 ++++++++----- htdocs/langs/en_US/companies.lang | 4 ++-- htdocs/theme/eldy/global.inc.php | 9 ++++++--- htdocs/theme/md/main_menu_fa_icons.inc.php | 7 ++++--- htdocs/theme/md/style.css.php | 7 +++++-- 6 files changed, 33 insertions(+), 22 deletions(-) diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index 61042abf3de..72d260e1525 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -474,7 +474,7 @@ if ($step == 1 || !$datatoexport) { // Affiche les modules d'exports print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table - print '
'; + print '
'; print ''; print ''; print ''; @@ -486,16 +486,17 @@ if ($step == 1 || !$datatoexport) { //var_dump($objexport->array_export_code_for_sort); //$sortedarrayofmodules = dol_sort_array($objexport->array_export_module, 'module_position', 'asc', 0, 0, 1); foreach ($objexport->array_export_code_for_sort as $key => $value) { - print ''."\n"; @@ -468,15 +483,7 @@ print ''."\n"; -// Country -print ''."\n"; - +// State print ''."\n"; -// Currency -print ''."\n"; - // Phone print ''; +// Object of the company +print ''; +print ''; + +// Tax ID Intra-community VAT number +print ''; + // ProfId1 if ($langs->transcountry("ProfId1", $mysoc->country_code) != '-') { print ''; } -// Intra-community VAT number -print ''; - -// Object of the company -print ''; -print ''; - print '
'.$langs->trans("Module").''.$langs->trans("ExportableDatas").'
'; - //print img_object($objexport->array_export_module[$key]->getName(),$export->array_export_module[$key]->picto).' '; - print $objexport->array_export_module[$key]->getName(); + $titleofmodule = $objexport->array_export_module[$key]->getName(); + print '
'; + print dolPrintHTML($titleofmodule); print ''; $entity = preg_replace('/:.*$/', '', $objexport->array_export_icon[$key]); $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); $label = $objexport->array_export_label[$key]; - //print $value.'-'.$icon.'-'.$label."
"; - print img_object($objexport->array_export_module[$key]->getName(), $entityicon).' '; - print $label; + print '
'; + print img_object($objexport->array_export_module[$key]->getName(), $entityicon, 'class="pictofixedwidth"'); + print dolPrintHTML($label); + print '
'; print '
'; if ($objexport->array_export_perms[$key]) { print ''.img_picto($langs->trans("NewExport"), 'next', 'class="fa-15"').''; diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 1e9d77989f4..4d42caf99de 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -351,7 +351,7 @@ if ($step == 1 || !$datatoimport) { // Affiche les modules d'imports print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table - print ''; + print '
'; print ''; print ''; print ''; @@ -362,18 +362,21 @@ if ($step == 1 || !$datatoimport) { $sortedarrayofmodules = dol_sort_array($objimport->array_import_module, 'position_of_profile', 'asc', 0, 0, 1); foreach ($sortedarrayofmodules as $key => $value) { //var_dump($key.' '.$value['position_of_profile'].' '.$value['import_code'].' '.$objimport->array_import_module[$key]['module']->getName().' '.$objimport->array_import_code[$key]); - print ''; } +if (!empty($arrayfields['s.ref_ext']['checked'])) { + print ''; +} // Barcode if (!empty($arrayfields['s.barcode']['checked'])) { print '\n"; + if (!$i) { + $totalarray['nbfield']++; + } + } // Barcode if (!empty($arrayfields['s.barcode']['checked'])) { print ''; From 27ac538e74d88965c1398bc2b8b824eb105a925e Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 18 Dec 2024 15:54:48 +0100 Subject: [PATCH 080/185] Fix security. Make bypass of checkPHPCode more difficult --- htdocs/core/lib/website2.lib.php | 34 ++++++++++++++++++++------------ test/phpunit/WebsiteTest.php | 20 +++++++++++++++---- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index 8ed23b7d88b..ef67cd4ca04 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -694,8 +694,8 @@ function showWebsiteTemplates(Website $website) /** * Check a new string containing only php code (including " * @param string $phpfullcodestring PHP new string. For example "" @@ -742,21 +742,21 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring) $forbiddenphpmethods = array('invoke', 'invokeArgs'); // Method of ReflectionFunction to execute a function foreach ($forbiddenphpstrings as $forbiddenphpstring) { - if (preg_match('/'.preg_quote($forbiddenphpstring, '/').'/ms', $phpfullcodestring)) { + if (preg_match('/'.preg_quote($forbiddenphpstring, '/').'/ims', $phpfullcodestring)) { $error++; setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpstring), null, 'errors'); break; } } - foreach ($forbiddenphpfunctions as $forbiddenphpcommand) { - if (preg_match('/'.$forbiddenphpcommand.'\s*\(/ms', $phpfullcodestring)) { + foreach ($forbiddenphpfunctions as $forbiddenphpfunction) { + if (preg_match('/'.$forbiddenphpfunction.'\s*\(/ims', $phpfullcodestring)) { $error++; - setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpcommand), null, 'errors'); + setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpfunction), null, 'errors'); break; } } foreach ($forbiddenphpmethods as $forbiddenphpmethod) { - if (preg_match('/->'.$forbiddenphpmethod.'/ms', $phpfullcodestring)) { + if (preg_match('/->'.$forbiddenphpmethod.'/ims', $phpfullcodestring)) { $error++; setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpmethod), null, 'errors'); break; @@ -764,14 +764,14 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring) } } - // This char can be used to execute RCE for example using with echo `ls` + // This char can be used to execute RCE for example by using echo `ls` if (!$error) { $forbiddenphpchars = array(); if (!getDolGlobalString('WEBSITE_PHP_ALLOW_DANGEROUS_CHARS')) { // If option is not on, we disallow functions to execute commands $forbiddenphpchars = array("`"); } foreach ($forbiddenphpchars as $forbiddenphpchar) { - if (preg_match('/'.$forbiddenphpchar.'/ms', $phpfullcodestring)) { + if (preg_match('/'.$forbiddenphpchar.'/ims', $phpfullcodestring)) { $error++; setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpchar), null, 'errors'); break; @@ -779,17 +779,25 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring) } } - // Deny dynamic functions '${a}(' or '$a[b](' => So we refuse '}(' and '](' + // Deny code to call a function obfuscated with comment, like "exec/*...*/ ('ls')"; if (!$error) { - if (preg_match('/[}\]]\(/ims', $phpfullcodestring)) { + if (preg_match('/\*\/\s*\(/ims', $phpfullcodestring)) { + $error++; + setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpmethod), null, 'errors'); + } + } + + // Deny dynamic functions '${a}(' or '$a[b](' => So we refuse '}(' and '](' + if (!$error) { + if (preg_match('/[}\]]\s*\(/ims', $phpfullcodestring)) { $error++; setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", ']('), null, 'errors'); } } - // Deny dynamic functions '$xxx(' + // Deny dynamic functions '$xxx(' or '$xxx (' or '$xxx" (' if (!$error) { - if (preg_match('/\$[a-z0-9_\-\/\*]+\(/ims', $phpfullcodestring)) { + if (preg_match('/\$[a-z0-9_\-\/\*\"]+\s*\(/ims', $phpfullcodestring)) { $error++; setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", '$...('), null, 'errors'); } diff --git a/test/phpunit/WebsiteTest.php b/test/phpunit/WebsiteTest.php index 6ccccb17b23..a067202ef85 100644 --- a/test/phpunit/WebsiteTest.php +++ b/test/phpunit/WebsiteTest.php @@ -65,11 +65,11 @@ if (empty($user->id)) { print "Load permissions for admin user nb 1\n"; $user->fetch(1); $user->loadRights(); - - if (empty($user->rights->website)) { - $user->rights->website = new stdClass(); - } } +if (empty($user->rights->website)) { + $user->rights->website = new stdClass(); +} + $conf->global->MAIN_DISABLE_ALL_MAILS = 1; @@ -143,6 +143,18 @@ class WebsiteTest extends CommonClassTest print __METHOD__." result checkPHPCode=".$result."\n"; $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + $t = ''; $s = ';").($_^"/"); ?>'; $result = checkPHPCode($t, $s); From 7ba81d394f974a459cebf2e82dca6b148bd14748 Mon Sep 17 00:00:00 2001 From: Gouttfi Date: Wed, 18 Dec 2024 16:10:32 +0100 Subject: [PATCH 081/185] Removed display of login input field when main_authentication == "googleoauth" --- htdocs/core/tpl/login.tpl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index 54c2238adfa..a9af96af82a 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -282,6 +282,7 @@ if ($disablenofollow) {
"> +file->main_authentication) || $conf->file->main_authentication != 'googleoauth') { ?>
-file->main_authentication) || $conf->file->main_authentication != 'googleoauth') { ?>
Date: Wed, 18 Dec 2024 17:56:41 +0100 Subject: [PATCH 082/185] fix CI --- htdocs/imports/import.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 4d42caf99de..b66cfc1f399 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -375,7 +375,7 @@ if ($step == 1 || !$datatoimport) { $label = $objimport->array_import_label[$key]; print '
'; print img_object($objimport->array_import_module[$key]['module']->getName(), $entityicon, 'class="pictofixedwidth"'); - print dolPrintHtml($label); + print dolPrintHTML($label); print '
'; print '
'; @@ -2164,7 +2164,7 @@ if ($id > 0) { print ''; print ''; print ''; print ''; - print ''; + print ''; // Website print ''; From b8d7825b6f0802db3ff13675136790b7f6b5e7df Mon Sep 17 00:00:00 2001 From: Erik van Berkum Date: Sun, 22 Dec 2024 16:02:36 +0900 Subject: [PATCH 120/185] Update ticket.class.php Solves issue #30890 Blank dashboard after upgrade 19.0.3 to 20.0.2 --- htdocs/ticket/class/ticket.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/ticket/class/ticket.class.php b/htdocs/ticket/class/ticket.class.php index 9121d0ec032..e0da84aa3d9 100644 --- a/htdocs/ticket/class/ticket.class.php +++ b/htdocs/ticket/class/ticket.class.php @@ -3192,7 +3192,7 @@ class Ticket extends CommonObject while ($obj = $this->db->fetch_object($resql)) { $response->nbtodo++; if ($mode == 'opened') { - $datelimit = $this->db->jdate($obj->datec) + $delay_warning; + $datelimit = (int) $this->db->jdate($obj->datec) + (int) $delay_warning; if ($datelimit < $now) { //$response->nbtodolate++; } From fb3067a1a49a7840a83a330576de28f1d19dca3e Mon Sep 17 00:00:00 2001 From: matthieu-michou-wattandsea <70541072+matthieu-michou-wattandsea@users.noreply.github.com> Date: Sun, 22 Dec 2024 12:07:17 +0100 Subject: [PATCH 121/185] Update api_bankaccounts.class.php NEW API REST : bank : add function to get bank account balance --- .../bank/class/api_bankaccounts.class.php | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/htdocs/compta/bank/class/api_bankaccounts.class.php b/htdocs/compta/bank/class/api_bankaccounts.class.php index 1726f6395a7..f36faead44b 100644 --- a/htdocs/compta/bank/class/api_bankaccounts.class.php +++ b/htdocs/compta/bank/class/api_bankaccounts.class.php @@ -691,4 +691,29 @@ class BankAccounts extends DolibarrApi ) ); } + + /** + * Get current account balance by ID + * + * @param int $id ID of account + * @return float $balance balance + * @url GET {id}/balance + * + * @throws RestException + */ + public function getBalance($id) + { + if (!DolibarrApiAccess::$user->hasRight('banque', 'lire')) { + throw new RestException(403); + } + + $account = new Account($this->db); + $result = $account->fetch($id); + + if (!$result) { + throw new RestException(404, 'account not found'); + } + $balance = $account->solde(1); //1=Exclude future operation date (this is to exclude input made in advance and have real account sold) + return $balance; + } } From 0889a357abb2aa98b0c5fe9c62b72abde9399c11 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Sun, 22 Dec 2024 21:44:09 +0100 Subject: [PATCH 122/185] Fix creation of database with pgsql --- .../install/pgsql/functions/functions-bom.sql | 23 +++++++++++++++++++ .../install/pgsql/functions/functions-mo.sql | 23 +++++++++++++++++++ htdocs/install/pgsql/functions/functions.sql | 8 ------- 3 files changed, 46 insertions(+), 8 deletions(-) create mode 100644 htdocs/install/pgsql/functions/functions-bom.sql create mode 100644 htdocs/install/pgsql/functions/functions-mo.sql diff --git a/htdocs/install/pgsql/functions/functions-bom.sql b/htdocs/install/pgsql/functions/functions-bom.sql new file mode 100644 index 00000000000..e31c64e170e --- /dev/null +++ b/htdocs/install/pgsql/functions/functions-bom.sql @@ -0,0 +1,23 @@ +-- ============================================================================ +-- Copyright (C) 2024 Laurent Destailleur +-- +-- 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 +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- ============================================================================ + + +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bom FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bom_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bomline FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bomline_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); diff --git a/htdocs/install/pgsql/functions/functions-mo.sql b/htdocs/install/pgsql/functions/functions-mo.sql new file mode 100644 index 00000000000..37b92ae5269 --- /dev/null +++ b/htdocs/install/pgsql/functions/functions-mo.sql @@ -0,0 +1,23 @@ +-- ============================================================================ +-- Copyright (C) 2024 Laurent Destailleur +-- +-- 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 +-- the Free Software Foundation; either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +-- +-- ============================================================================ + + +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_mo FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_mo_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_production FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); +CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_production_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); diff --git a/htdocs/install/pgsql/functions/functions.sql b/htdocs/install/pgsql/functions/functions.sql index 1d3587c8e7c..5260a44a8c3 100644 --- a/htdocs/install/pgsql/functions/functions.sql +++ b/htdocs/install/pgsql/functions/functions.sql @@ -75,10 +75,6 @@ CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bank_account FOR EAC CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bank_account_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_blockedlog FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_blockedlog_authority FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bom FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bom_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bomline FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bom_bomline_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_bordereau_cheque FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_boxes_def FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_c_email_templates FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); @@ -127,10 +123,6 @@ CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_fichinterdet_extrafi CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_delivery FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_localtax FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_menu FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_mo FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_mo_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_production FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); -CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_mrp_production_extrafields FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_notify FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_notify_def FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON llx_paiement FOR EACH ROW EXECUTE PROCEDURE update_modified_column_tms(); From 40a36e8675fe84777ff40910990e248dbeb7ccd6 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Mon, 23 Dec 2024 06:21:26 +0100 Subject: [PATCH 123/185] FIX "location_incoterms" is a string --- htdocs/delivery/card.php | 2 +- htdocs/expedition/card.php | 2 +- htdocs/expedition/shipment.php | 2 +- htdocs/product/stock/stocktransfer/stocktransfer_card.php | 2 +- htdocs/reception/card.php | 2 +- htdocs/societe/card.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/htdocs/delivery/card.php b/htdocs/delivery/card.php index d8633ef6965..f9578c62e54 100644 --- a/htdocs/delivery/card.php +++ b/htdocs/delivery/card.php @@ -193,7 +193,7 @@ if ($action == 'setdate_delivery' && $permissiontoadd) { } } elseif ($action == 'set_incoterms' && isModEnabled('incoterm')) { // Set incoterm - $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOSTINT('location_incoterms')); + $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms')); } // Update extrafields diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 6f5c3ed4777..0ddbb7c200d 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -183,7 +183,7 @@ if (empty($reshook)) { // Set incoterm if ($action == 'set_incoterms' && isModEnabled('incoterm')) { - $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOSTINT('location_incoterms')); + $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms')); } if ($action == 'setref_customer') { diff --git a/htdocs/expedition/shipment.php b/htdocs/expedition/shipment.php index b7bac99691d..5c1844fab73 100644 --- a/htdocs/expedition/shipment.php +++ b/htdocs/expedition/shipment.php @@ -158,7 +158,7 @@ if (empty($reshook)) { } } elseif ($action == 'set_incoterms' && isModEnabled('incoterm')) { // Set incoterm - $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOSTINT('location_incoterms')); + $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms')); if ($result < 0) { setEventMessages($object->error, $object->errors, 'errors'); } diff --git a/htdocs/product/stock/stocktransfer/stocktransfer_card.php b/htdocs/product/stock/stocktransfer/stocktransfer_card.php index d71bb56640d..9456b6d1597 100644 --- a/htdocs/product/stock/stocktransfer/stocktransfer_card.php +++ b/htdocs/product/stock/stocktransfer/stocktransfer_card.php @@ -387,7 +387,7 @@ if (empty($reshook)) { // Set incoterm if ($action == 'set_incoterms' && isModEnabled('incoterm') && $permissiontoadd) { - $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOSTINT('location_incoterms')); + $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms')); } // Actions to send emails $triggersendname = 'STOCKTRANSFER_SENTBYMAIL'; diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index d62429ea28f..488fef75ffe 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -244,7 +244,7 @@ if (empty($reshook)) { // Set incoterm if ($action == 'set_incoterms' && isModEnabled('incoterm') && $permissiontoadd) { - $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOSTINT('location_incoterms')); + $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms')); } if ($action == 'setref_supplier' && $permissiontoadd) { diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 53842b8b2d8..c73005a8199 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -810,7 +810,7 @@ if (empty($reshook)) { // Set incoterm if ($action == 'set_incoterms' && $user->hasRight('societe', 'creer') && isModEnabled('incoterm')) { $object->fetch($socid); - $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOSTINT('location_incoterms')); + $result = $object->setIncoterms(GETPOSTINT('incoterm_id'), GETPOST('location_incoterms')); } // Set parent company From bf2137089f056b9a1a52c851e338ffbdc8ee6579 Mon Sep 17 00:00:00 2001 From: Brice Werry Date: Mon, 23 Dec 2024 10:31:17 +0100 Subject: [PATCH 124/185] FIX: SUPPLIER_PROPOSAL_FREE_TEXT get HTML tags removed --- htdocs/admin/supplier_proposal.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/supplier_proposal.php b/htdocs/admin/supplier_proposal.php index b296f65a876..02fc5bdaccb 100644 --- a/htdocs/admin/supplier_proposal.php +++ b/htdocs/admin/supplier_proposal.php @@ -195,7 +195,7 @@ if ($action == 'set') { dolibarr_set_const($db, "SUPPLIER_PROPOSAL_ADDON", $value, 'chaine', 0, '', $conf->entity); } elseif (preg_match('/set_(.*)/', $action, $reg)) { $code = $reg[1]; - $value = (GETPOST($code) ? GETPOST($code) : 1); + $value = (GETPOST($code,'restricthtml') ? GETPOST($code,'restricthtml') : 1); $res = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { From 45b6941344ea72d4dd3c34a63a5a0e685d74cdaa Mon Sep 17 00:00:00 2001 From: Brice Werry Date: Mon, 23 Dec 2024 10:42:11 +0100 Subject: [PATCH 125/185] FIX: SUPPLIER_PROPOSAL_FREE_TEXT get HTML tags removed --- htdocs/admin/supplier_proposal.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/admin/supplier_proposal.php b/htdocs/admin/supplier_proposal.php index 02fc5bdaccb..0d49aabbef6 100644 --- a/htdocs/admin/supplier_proposal.php +++ b/htdocs/admin/supplier_proposal.php @@ -195,8 +195,11 @@ if ($action == 'set') { dolibarr_set_const($db, "SUPPLIER_PROPOSAL_ADDON", $value, 'chaine', 0, '', $conf->entity); } elseif (preg_match('/set_(.*)/', $action, $reg)) { $code = $reg[1]; + if ($code == "SUPPLIER_PROPOSAL_FREE_TEXT") { $value = (GETPOST($code,'restricthtml') ? GETPOST($code,'restricthtml') : 1); - + } else { + $value = (GETPOST($code) ? GETPOST($code) : 1); + } $res = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { $error++; From 6ae79f5ec4b4233092bac6223d492ca8eeb3e15d Mon Sep 17 00:00:00 2001 From: Brice Werry Date: Mon, 23 Dec 2024 10:47:07 +0100 Subject: [PATCH 126/185] FIX: SUPPLIER_PROPOSAL_FREE_TEXT get HTML tags removed --- htdocs/admin/supplier_proposal.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/admin/supplier_proposal.php b/htdocs/admin/supplier_proposal.php index 0d49aabbef6..51422388cd4 100644 --- a/htdocs/admin/supplier_proposal.php +++ b/htdocs/admin/supplier_proposal.php @@ -196,9 +196,9 @@ if ($action == 'set') { } elseif (preg_match('/set_(.*)/', $action, $reg)) { $code = $reg[1]; if ($code == "SUPPLIER_PROPOSAL_FREE_TEXT") { - $value = (GETPOST($code,'restricthtml') ? GETPOST($code,'restricthtml') : 1); + $value = (GETPOST($code, 'restricthtml') ? GETPOST($code, 'restricthtml') : 1); } else { - $value = (GETPOST($code) ? GETPOST($code) : 1); + $value = (GETPOST($code) ? GETPOST($code) : 1); } $res = dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity); if (!($res > 0)) { From 2e0eb8ecf119b21dc461f7c34829454e117e7dc0 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 23 Dec 2024 11:57:19 +0100 Subject: [PATCH 127/185] More robust dol_eval function --- htdocs/core/lib/functions.lib.php | 13 +++++--- test/phpunit/SecurityTest.php | 51 ++++++++++++++++++++----------- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index ef0e68c369e..fcf8c8407bf 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -10564,9 +10564,9 @@ function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1' } if (preg_match('/[^a-z0-9\s'.preg_quote($specialcharsallowed, '/').']/i', $s)) { if ($returnvalue) { - return 'Bad string syntax to evaluate (found chars that are not chars for a simple clean eval string): '.$s; + return 'Bad string syntax to evaluate (found chars that are not chars for a simple one line clean eval string): '.$s; } else { - dol_syslog('Bad string syntax to evaluate (found chars that are not chars for a simple clean eval string): '.$s, LOG_WARNING); + dol_syslog('Bad string syntax to evaluate (found chars that are not chars for a simple one line clean eval string): '.$s, LOG_WARNING); return ''; } } @@ -10581,15 +10581,17 @@ function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1' } } - // Now we check if we try dynamic call (by removing white list pattern of using parenthesis then testing if a parenthesis exists) + // Now we check if we try dynamic call + // First we remove white list pattern of using parenthesis then testing if one open parenthesis exists $savescheck = ''; $scheck = $s; while ($scheck && $savescheck != $scheck) { $savescheck = $scheck; $scheck = preg_replace('/->[a-zA-Z0-9_]+\(/', '->__METHOD__', $scheck); // accept parenthesis in '...->method(...' $scheck = preg_replace('/::[a-zA-Z0-9_]+\(/', '->__METHOD__', $scheck); // accept parenthesis in '...::method(...' - $scheck = preg_replace('/^\(/', '__PARENTHESIS__ ', $scheck); // accept parenthesis in '(...'. Must replace with __PARENTHESIS__ with a space after to allow following substitutions - $scheck = preg_replace('/\s\(/', '__PARENTHESIS__ ', $scheck); // accept parenthesis in '... (' like in 'if ($a == 1)'. Must replace with __PARENTHESIS__ with a space after to allow following substitutions + $scheck = preg_replace('/^\(+/', '__PARENTHESIS__ ', $scheck); // accept parenthesis in '(...'. Must replace with "__PARENTHESIS__ with a space after "to allow following substitutions + $scheck = preg_replace('/\&\&\s+\(/', '__ANDPARENTHESIS__ ', $scheck); // accept parenthesis in '... (' like in '&& (...'. Must replace with "__PARENTHESIS__ with a space after" to allow following substitutions + $scheck = preg_replace('/\|\|\s+\(/', '__ORPARENTHESIS__ ', $scheck); // accept parenthesis in '... (' like in '|| (...'. Must replace with "__PARENTHESIS__ with a space after" to allow following substitutions $scheck = preg_replace('/^!?[a-zA-Z0-9_]+\(/', '__FUNCTION__', $scheck); // accept parenthesis in 'function(' and '!function(' $scheck = preg_replace('/\s!?[a-zA-Z0-9_]+\(/', '__FUNCTION__', $scheck); // accept parenthesis in '... function(' and '... !function(' $scheck = preg_replace('/^!\(/', '__NOTANDPARENTHESIS__', $scheck); // accept parenthesis in '!(' @@ -10598,6 +10600,7 @@ function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1' } //print 'scheck='.$scheck." : ".strpos($scheck, '(')."
\n"; + // Now test if it remains 1 one parenthesis. if (strpos($scheck, '(') !== false) { if ($returnvalue) { return 'Bad string syntax to evaluate (mode '.$onlysimplestring.', found call of a function or method without using the direct name of the function): '.$s; diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 9b5db827bc3..45f962a3b47 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -625,52 +625,66 @@ class SecurityTest extends CommonClassTest print "result4 = ".$result."\n"; $this->assertEquals('Parent project not found', $result); + /* not allowed. Not a one line eval string + $result = (string) dol_eval('if ($a == 1) { }', 1, 1); + print "result4b = ".$result."\n"; + $this->assertEquals('aaa', $result); + */ + + // Now string not allowed + $s = 'new abc->invoke(\'whoami\')'; $result = (string) dol_eval($s, 1, 1, '2'); print "result = ".$result."\n"; - $this->assertEquals('Bad string syntax to evaluate: new abc__forbiddenstring__(\'whoami\')', $result); + $this->assertEquals('Bad string syntax to evaluate: new abc__forbiddenstring__(\'whoami\')', $result, 'The string was not detected as evil'); $s = 'new ReflectionFunction(\'abc\')'; $result = (string) dol_eval($s, 1, 1, '2'); print "result = ".$result."\n"; - $this->assertEquals('Bad string syntax to evaluate: new __forbiddenstring__(\'abc\')', $result); + $this->assertEquals('Bad string syntax to evaluate: new __forbiddenstring__(\'abc\')', $result, 'The string was not detected as evil'); $result = dol_eval('$a=function() { }; $a', 1, 1, '0'); // result of dol_eval may be an object Closure print "result5 = ".json_encode($result)."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result)); + $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result), 'The string was not detected as evil'); $result = dol_eval('$a=function() { }; $a();', 1, 1, '1'); print "result6 = ".json_encode($result)."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result)); + $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result), 'The string was not detected as evil'); $result = (string) dol_eval('$a=exec("ls");', 1, 1); print "result7 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $result = (string) dol_eval('$a=exec ("ls")', 1, 1); print "result8 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); + + $result = (string) dol_eval("strrev('metsys') ('whoami')", 1, 1); + print "result8b = ".$result."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $result = (string) dol_eval('$a="test"; $$a;', 1, 0); print "result9 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $result = (string) dol_eval('`ls`', 1, 0); print "result10 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $result = (string) dol_eval("('ex'.'ec')('echo abc')", 1, 0); print "result11 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $result = (string) dol_eval("sprintf(\"%s%s\", \"ex\", \"ec\")('echo abc')", 1, 0); print "result12 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $result = dol_eval("90402.38+267678+0", 1, 1, 1); print "result13 = ".$result."\n"; - $this->assertEquals('358080.38', $result); + $this->assertEquals('358080.38', $result, 'The string was not detected as evil'); + + // Must be allowed global $leftmenu; // Used into strings to eval @@ -706,28 +720,29 @@ class SecurityTest extends CommonClassTest print "result18 = ".$result."\n"; $this->assertFalse($result); + // Not allowed + $a = 'ab'; $result = (string) dol_eval("(\$a.'s')", 1, 0); print "result19 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 19'); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 19 - The string was not detected as evil'); $leftmenu = 'abs'; $result = (string) dol_eval('$leftmenu(-5)', 1, 0); print "result20 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 20'); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 20 - The string was not detected as evil'); $result = (string) dol_eval('str_replace("z","e","zxzc")("whoami");', 1, 0); print "result21 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 21'); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 21 - The string was not detected as evil'); $result = (string) dol_eval('($a = "ex") && ($b = "ec") && ($cmd = "$a$b") && $cmd ("curl localhost:5555")', 1, 0); print "result22 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 22'); - + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 22 - The string was not detected as evil'); $result = (string) dol_eval('\'exec\'("aaa")', 1, 0); - print "result1 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result), 'Cant find the string Bad string syntaxwhen i should'); + print "result23 = ".$result."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result), 'Test 23 - The string was not detected as evil - Can\'t find the string Bad string syntax when i should'); } /** From 4fb736fd0ae8f028e4f24a5fb5fe47da0da644b8 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 23 Dec 2024 14:07:08 +0100 Subject: [PATCH 128/185] Fix security test blocking $_SESSION... --- htdocs/core/lib/functions.lib.php | 18 ++++++++++++++---- htdocs/core/lib/website2.lib.php | 17 +++++++++++++---- test/phpunit/SecurityTest.php | 23 +++++++++++++++++++---- test/phpunit/WebsiteTest.php | 6 ++++++ 4 files changed, 52 insertions(+), 12 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index fcf8c8407bf..0fd073885de 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -10524,7 +10524,7 @@ function verifCond($strToEvaluate, $onlysimplestring = '1') * @param int<0,1> $hideerrors 1=Hide errors * @param string $onlysimplestring '0' (deprecated, do not use it anymore)=Accept all chars, * '1' (most common use)=Accept only simple string with char 'a-z0-9\s^$_+-.*>&|=!?():"\',/@';', - * '2' (used for example for the compute property of extrafields)=Accept also '[]' + * '2' (used for example for the compute property of extrafields)=Accept also '<[]' * @return void|string Nothing or return result of eval (even if type can be int, it is safer to assume string and find all potential typing issues as abs(dol_eval(...)). * @see verifCond(), checkPHPCode() to see sanitizing rules that should be very close. * @phan-suppress PhanPluginUnsafeEval @@ -10552,12 +10552,12 @@ function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1' if ($onlysimplestring == '1' || $onlysimplestring == '2') { // We must accept with 1: '1 && getDolGlobalInt("doesnotexist1") && getDolGlobalString("MAIN_FEATURES_LEVEL")' // We must accept with 1: '$user->hasRight("cabinetmed", "read") && !$object->canvas=="patient@cabinetmed"' - // We must accept with 2: (($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref : "Parent project not found" + // We must accept with 2: (($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($object->id) <= 99) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref : "Parent project not found" - // Check if there is dynamic call (first we check chars are all into use a whitelist chars) + // Check if there is dynamic call (first we check chars are all into a whitelist chars) $specialcharsallowed = '^$_+-.*>&|=!?():"\',/@'; if ($onlysimplestring == '2') { - $specialcharsallowed .= '[]'; + $specialcharsallowed .= '<[]'; } if (getDolGlobalString('MAIN_ALLOW_UNSECURED_SPECIAL_CHARS_IN_DOL_EVAL')) { $specialcharsallowed .= getDolGlobalString('MAIN_ALLOW_UNSECURED_SPECIAL_CHARS_IN_DOL_EVAL'); @@ -10571,6 +10571,16 @@ function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1' } } + // Check if there is a < or <= without spaces before/after + if (preg_match('/<=?[^\s]/', $s)) { + if ($returnvalue) { + return 'Bad string syntax to evaluate (mode '.$onlysimplestring.', found a < or <= without space before and after): '.$s; + } else { + dol_syslog('Bad string syntax to evaluate (mode '.$onlysimplestring.', found a < or <= without space before and after): '.$s, LOG_WARNING); + return ''; + } + } + // Check if there is dynamic call (first we use black list patterns) if (preg_match('/\$[\w]*\s*\(/', $s)) { if ($returnvalue) { diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index 0323e67265a..c82484fc056 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -720,10 +720,19 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring) } } + $phpfullcodestringnew = $phpfullcodestring; + // Then check forbidden commands if (!$error) { - $forbiddenphpstrings = array('$$', '$_', '}['); - //$forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', '_SESSION', '_COOKIE', '_GET', '_POST', '_REQUEST', 'ReflectionFunction')); + if (getDolGlobalString("WEBSITE_DISALLOW_DOLLAR_UNDERSCORE")) { + $phpfullcodestring = preg_replace('/\$_COOKIE\[/', '__DOLLARCOOKIE__', $phpfullcodestring); + $phpfullcodestring = preg_replace('/\$_FILES\[/', '__DOLLARFILES__', $phpfullcodestring); + $phpfullcodestring = preg_replace('/\$_SESSION\[/', '__DOLLARSESSION__', $phpfullcodestring); + $forbiddenphpstrings = array('$$', '$_', '}['); + } else { + $forbiddenphpstrings = array('$$', '}['); + } + //$forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', '_FILES', '_SESSION', '_COOKIE', '_GET', '_POST', '_REQUEST', 'ReflectionFunction')); $forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', 'ReflectionFunction')); $forbiddenphpfunctions = array(); @@ -818,8 +827,8 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring) // No need to block $conf->global->aaa() because PHP try to run the method aaa of $conf->global and not the function into $conf->global->aaa. - // Then check if installmodules does not block dynamic PHP code change. - if ($phpfullcodestringold != $phpfullcodestring) { + // Then check if installmodules.lock does not block dynamic PHP code change. + if ($phpfullcodestringold != $phpfullcodestringnew) { if (!$error) { $dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT); $allowimportsite = true; diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 45f962a3b47..743b6d33c8e 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -623,7 +623,13 @@ class SecurityTest extends CommonClassTest $s = '(($reloadedobj = new Task($db)) && ($reloadedobj->fetchNoCompute($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetchNoCompute($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref : \'Parent project not found\''; $result = (string) dol_eval($s, 1, 1, '2'); print "result4 = ".$result."\n"; - $this->assertEquals('Parent project not found', $result); + $this->assertEquals('Parent project not found', $result, 'Test 4'); + + $s = '4 < 5'; + $result = (string) dol_eval($s, 1, 1, '2'); + print "result5 = ".$result."\n"; + $this->assertEquals('1', $result, 'Test 5'); + /* not allowed. Not a one line eval string $result = (string) dol_eval('if ($a == 1) { }', 1, 1); @@ -633,16 +639,25 @@ class SecurityTest extends CommonClassTest // Now string not allowed + $s = '4 <5'; + $result = (string) dol_eval($s, 1, 1, '2'); // in mode 2, char < is allowed only if followed by a space + print "result = ".$result."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 4 <5 - The string was not detected as evil'); + + $s = '4 < 5'; + $result = (string) dol_eval($s, 1, 1, '1'); // in mode 1, char < is always forbidden + print "result = ".$result."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 4 < 5 - The string was not detected as evil'); + $s = 'new abc->invoke(\'whoami\')'; $result = (string) dol_eval($s, 1, 1, '2'); print "result = ".$result."\n"; - $this->assertEquals('Bad string syntax to evaluate: new abc__forbiddenstring__(\'whoami\')', $result, 'The string was not detected as evil'); + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $s = 'new ReflectionFunction(\'abc\')'; $result = (string) dol_eval($s, 1, 1, '2'); print "result = ".$result."\n"; - $this->assertEquals('Bad string syntax to evaluate: new __forbiddenstring__(\'abc\')', $result, 'The string was not detected as evil'); - + $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'The string was not detected as evil'); $result = dol_eval('$a=function() { }; $a', 1, 1, '0'); // result of dol_eval may be an object Closure print "result5 = ".json_encode($result)."\n"; diff --git a/test/phpunit/WebsiteTest.php b/test/phpunit/WebsiteTest.php index bbf80cad4c5..0bdfdb5ca44 100644 --- a/test/phpunit/WebsiteTest.php +++ b/test/phpunit/WebsiteTest.php @@ -145,6 +145,12 @@ class WebsiteTest extends CommonClassTest print __METHOD__." result checkPHPCode=".$result."\n"; $this->assertEquals($result, 0, 'checkPHPCode detect string as dangerous when it is legitimate'); + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 0, 'checkPHPCode detect string as dangerous when it is legitimate'); + // Dangerous From c1e3fbc2a0e51d22e1e33480bcb8f34fdbe95b56 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 23 Dec 2024 16:30:50 +0100 Subject: [PATCH 129/185] Trans --- htdocs/projet/list.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 9170ba31ed3..77eda021f11 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -256,12 +256,12 @@ foreach ($object->fields as $key => $val) { include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_array_fields.tpl.php'; // Add non object fields to fields for list -$arrayfields['s.nom'] = array('label' => $langs->trans("ThirdParty"), 'checked' => 1, 'position' => 21, 'enabled' => (!isModEnabled('societe') ? 0 : 1)); +$arrayfields['s.nom'] = array('label' => "ThirdParty", 'checked' => 1, 'position' => 21, 'enabled' => (!isModEnabled('societe') ? 0 : 1)); $arrayfields['s.name_alias'] = array('label' => "AliasNameShort", 'checked' => 0, 'position' => 22); $arrayfields['co.country_code'] = array('label' => "Country", 'checked' => -1, 'position' => 23); -$arrayfields['commercial'] = array('label' => $langs->trans("SaleRepresentativesOfThirdParty"), 'checked' => 0, 'position' => 25); -$arrayfields['c.assigned'] = array('label' => $langs->trans("AssignedTo"), 'checked' => 1, 'position' => 120); -$arrayfields['opp_weighted_amount'] = array('label' => $langs->trans('OpportunityWeightedAmountShort'), 'checked' => 0, 'enabled' => (!getDolGlobalString('PROJECT_USE_OPPORTUNITIES') ? 0 : 1), 'position' => 106); +$arrayfields['commercial'] = array('label' => "SaleRepresentativesOfThirdParty", 'checked' => 0, 'position' => 25); +$arrayfields['c.assigned'] = array('label' => "AssignedTo", 'checked' => 1, 'position' => 120); +$arrayfields['opp_weighted_amount'] = array('label' => 'OpportunityWeightedAmountShort', 'checked' => 0, 'enabled' => (!getDolGlobalString('PROJECT_USE_OPPORTUNITIES') ? 0 : 1), 'position' => 106); $arrayfields['u.login'] = array('label' => "Author", 'checked' => -1, 'position' => 165); // Force some fields according to search_usage filter... if (GETPOST('search_usage_opportunity')) { From 7f00738618f0cbd8e85581abab32e3c7c3ff4a08 Mon Sep 17 00:00:00 2001 From: ems-co Date: Mon, 23 Dec 2024 19:35:12 +0300 Subject: [PATCH 130/185] Update card.php --- htdocs/societe/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 53842b8b2d8..73ebdc36467 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1388,7 +1388,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio if (getDolGlobalString('THIRDPARTY_SUPPLIER_BY_DEFAULT')) { $default = 1; } - print $form->selectyesno("fournisseur", (GETPOSTINT('fournisseur') != '' ? GETPOSTINT('fournisseur') : (GETPOST("type") == '' ? $default : $object->fournisseur)), 1, 0, (GETPOST("type") == '' ? 1 : 0), 1); + print $form->selectyesno("fournisseur", ((GETPOST("type") == '' ? $default : $object->fournisseur)), 1, 0, (GETPOST("type") == '' ? 1 : 0), 1); print ''; From 56d21d0d0dc8d3e58b2db93eb34f47f7995636c9 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 23 Dec 2024 23:22:47 +0100 Subject: [PATCH 131/185] Debug v21 --- htdocs/core/tpl/objectline_create.tpl.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 4cf2258fded..96cfc189c13 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -1317,7 +1317,7 @@ if (!empty($usemargins) && $user->hasRight('margins', 'creer')) { jQuery("#select_type").val(-1); jQuery("#select_type").addClass("placeholder"); - jQuery("#select_type").trigger("change"); + /* jQuery("#select_type").trigger("change"); // Disabled. This create troubles. Never mind if the rester of combo is not done when using an ajax select_type combo. We don't use it because we are not able to call a focus on a change event of this combo. */ jQuery("#prod_entry_mode_free").prop('checked',false).change(); jQuery("#prod_entry_mode_predef").prop('checked',true).change(); From fb11f6114d774690c2e5269e41aa085602b5ee89 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 24 Dec 2024 00:03:11 +0100 Subject: [PATCH 132/185] Disable to avoid duplicated feature --- htdocs/install/mysql/data/llx_c_type_contact.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/install/mysql/data/llx_c_type_contact.sql b/htdocs/install/mysql/data/llx_c_type_contact.sql index 07178dacdcd..8fe53ba25ea 100644 --- a/htdocs/install/mysql/data/llx_c_type_contact.sql +++ b/htdocs/install/mysql/data/llx_c_type_contact.sql @@ -120,4 +120,4 @@ insert into llx_c_type_contact (element, source, code, libelle, active ) values insert into llx_c_type_contact (element, source, code, libelle, active ) values ('conferenceorbooth', 'external', 'RESPONSIBLE', 'Booth responsible', 1); -- Thirdparty -insert into llx_c_type_contact (element, source, code, libelle, active ) values ('societe', 'internal', 'SALESREPTHIRD', 'Sales Representative', 1); +--Disabled. The salerepresentativ insert into llx_c_type_contact (element, source, code, libelle, active ) values ('societe', 'internal', 'SALESREPTHIRD', 'Sales Representative', 1); From 885235d96351453b90319c005fab3c2fcef8a604 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 24 Dec 2024 00:11:56 +0100 Subject: [PATCH 133/185] Trans --- htdocs/install/mysql/data/llx_c_type_contact.sql | 2 +- htdocs/langs/en_US/companies.lang | 4 ++-- htdocs/langs/en_US/main.lang | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/htdocs/install/mysql/data/llx_c_type_contact.sql b/htdocs/install/mysql/data/llx_c_type_contact.sql index 8fe53ba25ea..7271ba2d38b 100644 --- a/htdocs/install/mysql/data/llx_c_type_contact.sql +++ b/htdocs/install/mysql/data/llx_c_type_contact.sql @@ -120,4 +120,4 @@ insert into llx_c_type_contact (element, source, code, libelle, active ) values insert into llx_c_type_contact (element, source, code, libelle, active ) values ('conferenceorbooth', 'external', 'RESPONSIBLE', 'Booth responsible', 1); -- Thirdparty ---Disabled. The salerepresentativ insert into llx_c_type_contact (element, source, code, libelle, active ) values ('societe', 'internal', 'SALESREPTHIRD', 'Sales Representative', 1); +insert into llx_c_type_contact (element, source, code, libelle, active ) values ('societe', 'external', 'SALESREPTHIRD', 'Sales Representative', 1); diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index c9671fe7503..70c3b20e471 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -33,8 +33,8 @@ CountryIsInEEC=Country is inside the European Economic Community PriceFormatInCurrentLanguage=Price display format in the current language and currency ThirdPartyName=Third-party name ThirdPartyEmail=Third-party email -ThirdParty=Third-party -ThirdParties=Third-parties +ThirdParty=Third party +ThirdParties=Third parties ThirdPartyProspects=Prospects ThirdPartyProspectsStats=Prospects ThirdPartyCustomers=Customers diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 6e85fabaa63..ad6c2a99b74 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -1149,6 +1149,7 @@ ContactDefault_project_task=Task ContactDefault_propal=Proposal ContactDefault_supplier_proposal=Supplier Proposal ContactDefault_ticket=Ticket +ContactDefault_societe=Third party ContactAddedAutomatically=Contact added from third-party contact roles More=More ShowDetails=Show details From b27f98ebb39ccd0c0969a9f8f3f7dd47247a7354 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 24 Dec 2024 00:27:15 +0100 Subject: [PATCH 134/185] Complete #32292 #32434 --- htdocs/core/class/html.form.class.php | 4 +++- htdocs/product/list.php | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 555778e7124..c8965d32c6a 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5128,7 +5128,7 @@ class Form $resql = $this->db->query($sql); if ($resql && $this->db->num_rows($resql) > 0) { if ($showempty) { - $return .= ''; + $return .= ''; } while ($res = $this->db->fetch_object($resql)) { @@ -5144,6 +5144,8 @@ class Form } } $return .= ''; + + $return .= ajax_combobox($htmlname); } return $return; } diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 0f7d57db40c..030410ced4f 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -583,6 +583,7 @@ if ($search_vatrate) { if (dol_strlen($canvas) > 0) { $sql .= " AND p.canvas = '".$db->escape($canvas)."'"; } + // Search for tag/category ($searchCategoryProductList is an array of ID) if (!empty($searchCategoryProductList)) { $searchCategoryProductSqlList = array(); @@ -641,9 +642,10 @@ if ($search_accountancy_code_buy_intra) { if ($search_accountancy_code_buy_export) { $sql .= natural_search($alias_product_perentity . '.accountancy_code_buy_export', clean_account($search_accountancy_code_buy_export)); } -if (getDolGlobalString('PRODUCT_USE_UNITS') && $search_units) { +if (getDolGlobalString('PRODUCT_USE_UNITS') && $search_units && $search_units != '-1') { $sql .= natural_search('cu.rowid', $search_units); } + // Add where from extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks From 6c33f973d86a571df2ca3f60f7c6af98b403057c Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 24 Dec 2024 00:36:51 +0100 Subject: [PATCH 135/185] Fix warning --- htdocs/core/lib/invoice2.lib.php | 57 +++++++++++++++++--------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/htdocs/core/lib/invoice2.lib.php b/htdocs/core/lib/invoice2.lib.php index 98566c95d51..288a1f5a014 100644 --- a/htdocs/core/lib/invoice2.lib.php +++ b/htdocs/core/lib/invoice2.lib.php @@ -231,6 +231,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte while ($cpt < $num) { $obj = $db->fetch_object($resql); + $fac = null; if ($mode == 'invoice') { $fac = new Facture($db); } elseif ($mode == 'order') { @@ -241,37 +242,39 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $fac = new Expedition($db); } - $result = $fac->fetch($obj->rowid); - if ($result > 0) { - $outputlangs = $langs; - if (!empty($newlangid)) { - if ($outputlangs->defaultlang != $newlangid) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlangid); + if ($fac) { + $result = $fac->fetch($obj->rowid); + if ($result > 0) { + $outputlangs = $langs; + if (!empty($newlangid)) { + if ($outputlangs->defaultlang != $newlangid) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlangid); + } } - } - $filename = $dir_output.'/'.$fac->ref.'/'.$fac->ref.'.pdf'; - if ($regenerate || !dol_is_file($filename)) { - if ($usestdout) { - print "Build PDF for document ".$obj->ref." - Lang = ".$outputlangs->defaultlang."\n"; - } - $result = $fac->generateDocument($regenerate ? $regenerate : $fac->model_pdf, $outputlangs); - } else { - if ($usestdout) { - print "PDF for document ".$obj->ref." already exists\n"; + $filename = $dir_output.'/'.$fac->ref.'/'.$fac->ref.'.pdf'; + if ($regenerate || !dol_is_file($filename)) { + if ($usestdout) { + print "Build PDF for document ".$obj->ref." - Lang = ".$outputlangs->defaultlang."\n"; + } + $result = $fac->generateDocument($regenerate ? $regenerate : $fac->model_pdf, $outputlangs); + } else { + if ($usestdout) { + print "PDF for document ".$obj->ref." already exists\n"; + } } + + // Add file into files array + $files[] = $filename; } - // Add file into files array - $files[] = $filename; - } - - if ($result <= 0) { - $error++; - if ($usestdout) { - print "Error: Failed to build PDF for document ".($fac->ref ? $fac->ref : ' id '.$obj->rowid)."\n"; - } else { - dol_syslog("Failed to build PDF for document ".($fac->ref ? $fac->ref : ' id '.$obj->rowid), LOG_ERR); + if ($result <= 0) { + $error++; + if ($usestdout) { + print "Error: Failed to build PDF for document ".($fac->ref ? $fac->ref : ' id '.$obj->rowid)."\n"; + } else { + dol_syslog("Failed to build PDF for document ".($fac->ref ? $fac->ref : ' id '.$obj->rowid), LOG_ERR); + } } } From 5f065840f273aa5164fcf1fc83c12d84de91e480 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 24 Dec 2024 00:56:22 +0100 Subject: [PATCH 136/185] Copy code manually code to close #32423 without the syntax error. --- htdocs/core/lib/modulebuilder.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/modulebuilder.lib.php b/htdocs/core/lib/modulebuilder.lib.php index eff2df330a2..67d57193729 100644 --- a/htdocs/core/lib/modulebuilder.lib.php +++ b/htdocs/core/lib/modulebuilder.lib.php @@ -411,7 +411,7 @@ function rebuildObjectSql($destdir, $module, $objectname, $newmask, $readdir = ' foreach ($object->fields as $key => $val) { $i++; if (!empty($val['index'])) { - $texttoinsert .= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD INDEX idx_".strtolower($module).'_'.strtolower($objectname)."_".$key." (".$key.");"; + $texttoinsert .= "ALTER TABLE llx_".strtolower($module).'_'.strtolower($objectname)." ADD ".($key == 'ref' ? "UNIQUE INDEX uk_" : "INDEX idx_").strtolower($module).'_'.strtolower($objectname)."_".$key." (".$key.($key == 'ref' && array_key_exists('entity', $object->fields) ? ", entity" : "").");"; $texttoinsert .= "\n"; } if (!empty($val['foreignkey'])) { From 89cddfa330bbd755b5d75eb381ff428b327906ba Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 24 Dec 2024 00:58:08 +0100 Subject: [PATCH 137/185] fix warning --- htdocs/core/lib/invoice2.lib.php | 56 +++++++++++++++----------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/htdocs/core/lib/invoice2.lib.php b/htdocs/core/lib/invoice2.lib.php index 288a1f5a014..72703a72fc4 100644 --- a/htdocs/core/lib/invoice2.lib.php +++ b/htdocs/core/lib/invoice2.lib.php @@ -242,39 +242,37 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $fac = new Expedition($db); } - if ($fac) { - $result = $fac->fetch($obj->rowid); - if ($result > 0) { - $outputlangs = $langs; - if (!empty($newlangid)) { - if ($outputlangs->defaultlang != $newlangid) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlangid); - } + $result = $fac->fetch($obj->rowid); + if ($result > 0) { + $outputlangs = $langs; + if (!empty($newlangid)) { + if ($outputlangs->defaultlang != $newlangid) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlangid); } - $filename = $dir_output.'/'.$fac->ref.'/'.$fac->ref.'.pdf'; - if ($regenerate || !dol_is_file($filename)) { - if ($usestdout) { - print "Build PDF for document ".$obj->ref." - Lang = ".$outputlangs->defaultlang."\n"; - } - $result = $fac->generateDocument($regenerate ? $regenerate : $fac->model_pdf, $outputlangs); - } else { - if ($usestdout) { - print "PDF for document ".$obj->ref." already exists\n"; - } + } + $filename = $dir_output.'/'.$fac->ref.'/'.$fac->ref.'.pdf'; + if ($regenerate || !dol_is_file($filename)) { + if ($usestdout) { + print "Build PDF for document ".$obj->ref." - Lang = ".$outputlangs->defaultlang."\n"; + } + $result = $fac->generateDocument($regenerate ? $regenerate : $fac->model_pdf, $outputlangs); + } else { + if ($usestdout) { + print "PDF for document ".$obj->ref." already exists\n"; } - - // Add file into files array - $files[] = $filename; } - if ($result <= 0) { - $error++; - if ($usestdout) { - print "Error: Failed to build PDF for document ".($fac->ref ? $fac->ref : ' id '.$obj->rowid)."\n"; - } else { - dol_syslog("Failed to build PDF for document ".($fac->ref ? $fac->ref : ' id '.$obj->rowid), LOG_ERR); - } + // Add file into files array + $files[] = $filename; + } + + if ($result <= 0) { + $error++; + if ($usestdout) { + print "Error: Failed to build PDF for document ".($fac->ref ? $fac->ref : ' id '.$obj->rowid)."\n"; + } else { + dol_syslog("Failed to build PDF for document ".($fac->ref ? $fac->ref : ' id '.$obj->rowid), LOG_ERR); } } From 7a825d59ab8d4a9d27cd1a19e8e498918505a7a5 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Tue, 24 Dec 2024 03:10:47 +0100 Subject: [PATCH 138/185] Debug v21 --- htdocs/fourn/class/fournisseur.product.class.php | 6 +++--- htdocs/product/list.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index d7db51a8523..f76e2ce690f 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -1133,8 +1133,8 @@ class ProductFournisseur extends Product $out = ''; $langs->load("suppliers"); if (count($productFournList) > 0) { - $out .= '
'.$langs->trans("Module").''.$langs->trans("ImportableDatas").'
'; $titleofmodule = $objimport->array_import_module[$key]['module']->getName(); + print '
'; // Special case for import common to module/services if (in_array($objimport->array_import_code[$key], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) { $titleofmodule = $langs->trans("ProductOrService"); } - print $titleofmodule; + print dolPrintHTML($titleofmodule); print ''; $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[$key]); $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity); - print img_object($objimport->array_import_module[$key]['module']->getName(), $entityicon).' '; - print $objimport->array_import_label[$key]; + $label = $objimport->array_import_label[$key]; + print '
'; + print img_object($objimport->array_import_module[$key]['module']->getName(), $entityicon, 'class="pictofixedwidth"'); + print dolPrintHtml($label); + print '
'; print '
'; if ($objimport->array_import_perms[$key]) { print ''.img_picto($langs->trans("NewImport"), 'next', 'class="fa-15"').''; diff --git a/htdocs/langs/en_US/companies.lang b/htdocs/langs/en_US/companies.lang index ad0813153e1..bff22a33e9f 100644 --- a/htdocs/langs/en_US/companies.lang +++ b/htdocs/langs/en_US/companies.lang @@ -383,8 +383,8 @@ ExportCardToFormat=Export card to format ContactNotLinkedToCompany=Contact not linked to any third party DolibarrLogin=Dolibarr login NoDolibarrAccess=No Dolibarr access -ExportDataset_company_1=Third-parties (companies/foundations/physical people) and their properties -ExportDataset_company_2=Contacts and their properties +ExportDataset_company_1=Third-parties (organizations/natural persons) and attributes +ExportDataset_company_2=Third-parties additional contacts/addresses and attributes ExportDataset_company_3=Third-parties payment modes (bank accounts) ImportDataset_company_1=Third-parties and their properties ImportDataset_company_2=Third-parties additional contacts/addresses and attributes diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index b198e461b82..5db98f3af5c 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -1712,7 +1712,7 @@ select.flat.selectlimit { -webkit-line-clamp: 2; overflow: hidden; } -.twolinesmax { +.twolinesmax, .twolinesmax-normallineheight { /* To be used into a
into a td for example */ display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; @@ -1720,6 +1720,9 @@ select.flat.selectlimit { height: auto !important; word-break: break-word; } +.twolinesmax-normallineheight { + line-height: normal; +} .tenlinesmax { display: -webkit-box; -webkit-box-orient: vertical; @@ -4481,8 +4484,8 @@ table.tableforfield td, .tagtr.table-border-row .tagtd { } table.liste td, table.noborder td, div.noborder form div, table.tableforservicepart1 td, table.tableforservicepart2 td { padding: 6px 10px 6px 12px; /* t r b l */ - /* line-height: 22px; This create trouble on cell login on list of last events of a contract*/ - height: 30px; + /* line-height: 22px; This create trouble on cell login on list of last events of a contract */ + height: 32px; } table.liste tr.trkanban td { padding: 12px 15px 12px 15px; /* t r b l */ diff --git a/htdocs/theme/md/main_menu_fa_icons.inc.php b/htdocs/theme/md/main_menu_fa_icons.inc.php index d5373467280..a08b85c27c1 100644 --- a/htdocs/theme/md/main_menu_fa_icons.inc.php +++ b/htdocs/theme/md/main_menu_fa_icons.inc.php @@ -107,14 +107,15 @@ div.mainmenu.generic4::before { text-align: center; } -.menu_titre .em092 { + +.em092 { font-size: 0.92em; } -.menu_titre .em088 { +.em088 { font-size: 0.88em; } -.menu_titre .em080 { +.em080 { font-size: 0.80em; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index c1c1ff04592..5d31a78fe22 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -1863,7 +1863,7 @@ select.flat.selectlimit { -webkit-line-clamp: 2; overflow: hidden; } -.twolinesmax { +.twolinesmax, .twolinesmax-normallineheight { /* To be used into a
into a td for example */ display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; @@ -1871,6 +1871,9 @@ select.flat.selectlimit { height: auto !important; word-break: break-word; } +.twolinesmax-normallineheight { + line-height: normal; +} .tenlinesmax { display: -webkit-box; -webkit-box-orient: vertical; @@ -4515,7 +4518,7 @@ table.liste th, table.noborder th, table.noborder tr.liste_titre td, table.nobor table.liste td, table.noborder td, div.noborder form div, table.tableforservicepart1 td, table.tableforservicepart2 td { padding: 4px 8px 4px 10px; /* t r b l */ - height: 22px; + height: 28px; } table.liste tr.trkanban td { padding: 12px 15px 12px 15px; /* t r b l */ From f35c0115c5a9ef8dd14877d339f191340755c05e Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 18 Dec 2024 12:29:57 +0100 Subject: [PATCH 079/185] Add MAIN_LIST_SHOW_REF_EXT to help debug --- htdocs/societe/list.php | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index 6a81aeede43..aaa88687467 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -85,6 +85,7 @@ $search_id = GETPOST("search_id", 'int'); $search_nom = trim(GETPOST("search_nom", 'restricthtml')); $search_alias = trim(GETPOST("search_alias", 'restricthtml')); $search_nom_only = trim(GETPOST("search_nom_only", 'restricthtml')); +$search_ref_ext = trim(GETPOST("search_ref_ext", 'restricthtml')); $search_barcode = trim(GETPOST("search_barcode", 'alpha')); $search_customer_code = trim(GETPOST('search_customer_code', 'alpha')); $search_supplier_code = trim(GETPOST('search_supplier_code', 'alpha')); @@ -287,7 +288,8 @@ $arrayfields = array( 's.rowid' => array('label' => "TechnicalID", 'position' => 1, 'checked' => -1, 'enabled' => 1), 's.nom' => array('label' => "ThirdPartyName", 'position' => 2, 'checked' => 1), 's.name_alias' => array('label' => "AliasNameShort", 'position' => 3, 'checked' => 1), - 's.barcode' => array('label' => "Gencod", 'position' => 5, 'checked' => 1, 'enabled' => (isModEnabled('barcode'))), + 's.ref_ext' => array('label' => "RefExt", 'position' => 4, 'checked' => -1, 'enabled' => getDolGlobalInt('MAIN_LIST_SHOW_REF_EXT')), + 's.barcode' => array('label' => "Gencod", 'position' => 5, 'checked' => 1, 'enabled' => isModEnabled('barcode')), 's.code_client' => array('label' => "CustomerCodeShort", 'position' => 10, 'checked' => $checkedcustomercode), 's.code_fournisseur' => array('label' => "SupplierCodeShort", 'position' => 11, 'checked' => $checkedsuppliercode, 'enabled' => (isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))), 's.code_compta' => array('label' => "CustomerAccountancyCodeShort", 'position' => 13, 'checked' => $checkedcustomeraccountcode), @@ -411,6 +413,7 @@ if (empty($reshook)) { $search_id = ''; $search_nom = ''; $search_alias = ''; + $search_ref_ext = ''; $search_categ_cus = 0; $search_categ_sup = 0; $searchCategoryCustomerOperator = 0; @@ -562,7 +565,7 @@ if ($resql) { // Build and execute select // -------------------------------------------------------------------- -$sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.barcode, s.address, s.town, s.zip, s.datec, s.code_client, s.code_fournisseur, s.logo,"; +$sql = "SELECT s.rowid, s.nom as name, s.name_alias, s.ref_ext, s.barcode, s.address, s.town, s.zip, s.datec, s.code_client, s.code_fournisseur, s.logo,"; $sql .= " s.entity,"; $sql .= " st.libelle as stcomm, st.picto as stcomm_picto, s.fk_stcomm as stcomm_id, s.fk_prospectlevel, s.prefix_comm, s.client, s.fournisseur, s.canvas, s.status as status, s.note_private, s.note_public,"; $sql .= " s.email, s.phone, s.phone_mobile, s.fax, s.url, s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4 as idprof4, s.idprof5 as idprof5, s.idprof6 as idprof6, s.tva_intra, s.fk_pays,"; @@ -715,6 +718,9 @@ if (empty($arrayfields['s.name_alias']['checked']) && $search_nom) { if ($search_nom_only) { $sql .= natural_search("s.nom", $search_nom_only); } +if ($search_ref_ext) { + $sql .= natural_search("s.ref_ext", $search_ref_ext); +} if ($search_customer_code) { $sql .= natural_search("s.code_client", $search_customer_code); } @@ -970,6 +976,9 @@ if ($search_nom != '') { if ($search_alias != '') { $param .= "&search_alias=".urlencode($search_alias); } +if ($search_ref_ext != '') { + $param .= "&search_ref_ext=".urlencode($search_ref_ext); +} if ($search_address != '') { $param .= '&search_address='.urlencode($search_address); } @@ -1335,6 +1344,11 @@ if (!empty($arrayfields['s.name_alias']['checked'])) { print ''; print '
'; + print ''; + print ''; @@ -1619,6 +1633,11 @@ if (!empty($arrayfields['s.name_alias']['checked'])) { print_liste_field_titre($arrayfields['s.name_alias']['label'], $_SERVER["PHP_SELF"], "s.name_alias", "", $param, "", $sortfield, $sortorder); $totalarray['nbfield']++; } +if (!empty($arrayfields['s.ref_ext']['checked'])) { + // @phan-suppress-next-line PhanTypeInvalidDimOffset + print_liste_field_titre($arrayfields['s.ref_ext']['label'], $_SERVER["PHP_SELF"], "s.ref_ext", "", $param, "", $sortfield, $sortorder); + $totalarray['nbfield']++; +} if (!empty($arrayfields['s.barcode']['checked'])) { print_liste_field_titre($arrayfields['s.barcode']['label'], $_SERVER["PHP_SELF"], "s.barcode", $param, '', '', $sortfield, $sortorder); $totalarray['nbfield']++; @@ -1807,6 +1826,7 @@ while ($i < $imaxinloop) { $companystatic->id = $obj->rowid; $companystatic->name = $obj->name; $companystatic->name_alias = $obj->name_alias; + $companystatic->ref_ext = $obj->ref_ext; $companystatic->logo = $obj->logo; $companystatic->barcode = $obj->barcode; $companystatic->canvas = $obj->canvas; @@ -1899,6 +1919,15 @@ while ($i < $imaxinloop) { $totalarray['nbfield']++; } } + // Ref ext + if (!empty($arrayfields['s.ref_ext']['checked'])) { + print ''; + print dol_escape_htmltag($companystatic->ref_ext); + print "'.dol_escape_htmltag($companystatic->barcode).''; if ($objimport->array_import_perms[$key]) { From 6145b2acef3dec5799d7c29b307ec374a3842f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 18 Dec 2024 18:01:13 +0100 Subject: [PATCH 083/185] fix CI --- htdocs/core/lib/website2.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index ef67cd4ca04..01abafc8a11 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -783,7 +783,7 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring) if (!$error) { if (preg_match('/\*\/\s*\(/ims', $phpfullcodestring)) { $error++; - setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpmethod), null, 'errors'); + setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $phpfullcodestring), null, 'errors'); } } From 55fe6f9caa2f22dc66e55c3f6e6d50060322598d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Wed, 18 Dec 2024 18:06:08 +0100 Subject: [PATCH 084/185] fix CI --- htdocs/core/lib/website2.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index 01abafc8a11..18b55bc4a32 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -783,7 +783,7 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring) if (!$error) { if (preg_match('/\*\/\s*\(/ims', $phpfullcodestring)) { $error++; - setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $phpfullcodestring), null, 'errors'); + setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", "exec/*...*/ ('ls')"), null, 'errors'); } } From 7f4b2b08b44757fb5a66129021f1e854a5fa792b Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 18 Dec 2024 19:00:33 +0100 Subject: [PATCH 085/185] Complete phpunit and tests to avoid use of non expected function --- htdocs/comm/card.php | 50 +++++++------- htdocs/core/lib/functions.lib.php | 11 ++- htdocs/core/lib/website2.lib.php | 25 +++++-- test/phpunit/AllTests.php | 2 + test/phpunit/SecurityLoginTest.php | 106 +++++++++++++++++++++++++++++ test/phpunit/SecurityTest.php | 46 +++---------- test/phpunit/WebsiteTest.php | 29 +++++++- 7 files changed, 200 insertions(+), 69 deletions(-) create mode 100644 test/phpunit/SecurityLoginTest.php diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 57ce524af6b..5ed10dc2bd1 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -1712,35 +1712,37 @@ if ($object->id > 0) { } // Add invoice - if ($user->socid == 0) { - if (isModEnabled('deplacement') && $object->status == 1) { - $langs->load("trips"); - print ''; - } + if (isModEnabled('deplacement') && $object->status == 1) { + $langs->load("trips"); + print ''; + } - if (isModEnabled('invoice') && $object->status == 1) { - if (!$user->hasRight('facture', 'creer')) { - $langs->load("bills"); - print ''; + if (isModEnabled('invoice') && $object->status == 1) { + if (!$user->hasRight('facture', 'creer')) { + $langs->load("bills"); + print ''; + } else { + $langs->loadLangs(array("orders", "bills")); + + if ($object->client != 0 && $object->client != 2) { + print ''; } else { - $langs->loadLangs(array("orders", "bills")); - - if (isModEnabled('order')) { - if ($object->client != 0 && $object->client != 2) { - if (!empty($orders2invoice) && $orders2invoice > 0) { - print ''; - } else { - print ''; - } - } else { - print ''; - } - } + print ''; + } + } + } + if (isModEnabled('invoice') && $object->status == 1) { + if ($user->hasRight('facture', 'creer')) { + if (isModEnabled('order')) { if ($object->client != 0 && $object->client != 2) { - print ''; + if (!empty($orders2invoice) && $orders2invoice > 0) { + print ''; + } else { + print ''; + } } else { - print ''; + print ''; } } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index a3849578d8b..6f47d171761 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -10586,6 +10586,7 @@ function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1' while ($scheck && $savescheck != $scheck) { $savescheck = $scheck; $scheck = preg_replace('/->[a-zA-Z0-9_]+\(/', '->__METHOD__', $scheck); // accept parenthesis in '...->method(...' + $scheck = preg_replace('/::[a-zA-Z0-9_]+\(/', '->__METHOD__', $scheck); // accept parenthesis in '...::method(...' $scheck = preg_replace('/^\(/', '__PARENTHESIS__ ', $scheck); // accept parenthesis in '(...'. Must replace with __PARENTHESIS__ with a space after to allow following substitutions $scheck = preg_replace('/\s\(/', '__PARENTHESIS__ ', $scheck); // accept parenthesis in '... (' like in 'if ($a == 1)'. Must replace with __PARENTHESIS__ with a space after to allow following substitutions $scheck = preg_replace('/^!?[a-zA-Z0-9_]+\(/', '__FUNCTION__', $scheck); // accept parenthesis in 'function(' and '!function(' @@ -10646,22 +10647,26 @@ function dol_eval($s, $returnvalue = 1, $hideerrors = 1, $onlysimplestring = '1' $forbiddenphpstrings = array('$$', '$_', '}['); $forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', '_SESSION', '_COOKIE', '_GET', '_POST', '_REQUEST', 'ReflectionFunction')); + // We list all forbidden function as keywords we don't want to see (we don't mind it if is "kewyord(" or just "keyword", we don't want "keyword" at all) $forbiddenphpfunctions = array(); // @phpcs:ignore $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("base64"."_"."decode", "rawurl"."decode", "url"."decode", "str"."_rot13", "hex"."2bin")); // name of forbidden functions are split to avoid false positive - $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "require", "include", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask")); $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("override_function", "session_id", "session_create_id", "session_regenerate_id")); $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("get_defined_functions", "get_defined_vars", "get_defined_constants", "get_declared_classes")); - $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("function", "call_user_func")); + $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("function", "call_user_func", "call_user_func_array")); $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include", "require_once", "include_once")); $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("exec", "passthru", "shell_exec", "system", "proc_open", "popen")); $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("dol_eval", "executeCLI", "verifCond")); // native dolibarr functions $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("eval", "create_function", "assert", "mb_ereg_replace")); // function with eval capabilities $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("dol_compress_dir", "dol_decode", "dol_delete_file", "dol_delete_dir", "dol_delete_dir_recursive", "dol_copy", "archiveOrBackupFile")); // more dolibarr functions + $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask")); + $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include")); $forbiddenphpmethods = array('invoke', 'invokeArgs'); // Method of ReflectionFunction to execute a function - $forbiddenphpregex = 'global\s+\$|\b('.implode('|', $forbiddenphpfunctions).')\b'; + $forbiddenphpregex = 'global\s*\$'; + $forbiddenphpregex .= '|'; + $forbiddenphpregex .= '\b('.implode('|', $forbiddenphpfunctions).')\b'; $forbiddenphpmethodsregex = '->('.implode('|', $forbiddenphpmethods).')'; diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index ef67cd4ca04..78a5e6a0029 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -722,13 +722,15 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring) // Then check forbidden commands if (!$error) { - $forbiddenphpstrings = array('$$', '}['); - $forbiddenphpstrings = array_merge($forbiddenphpstrings, array('ReflectionFunction')); + $forbiddenphpstrings = array('$$', '$_', '}['); + //$forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', '_SESSION', '_COOKIE', '_GET', '_POST', '_REQUEST', 'ReflectionFunction')); + $forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', 'ReflectionFunction')); $forbiddenphpfunctions = array(); + //$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("base64"."_"."decode", "rawurl"."decode", "url"."decode", "str"."_rot13", "hex"."2bin")); // name of forbidden functions are split to avoid false positive $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("override_function", "session_id", "session_create_id", "session_regenerate_id")); $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("get_defined_functions", "get_defined_vars", "get_defined_constants", "get_declared_classes")); - $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("call_user_func")); + $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("call_user_func", "call_user_func_array")); //$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include", "require_once", "include_once")); if (!getDolGlobalString('WEBSITE_PHP_ALLOW_EXEC')) { // If option is not on, we disallow functions to execute commands $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("exec", "passthru", "shell_exec", "system", "proc_open", "popen")); @@ -736,8 +738,10 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring) $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("eval", "create_function", "assert", "mb_ereg_replace")); // function with eval capabilities } if (!getDolGlobalString('WEBSITE_PHP_ALLOW_WRITE')) { // If option is not on, we disallow functions to write files + $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("dol_compress_dir", "dol_decode", "dol_delete_file", "dol_delete_dir", "dol_delete_dir_recursive", "dol_copy", "archiveOrBackupFile")); // more dolibarr functions $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "mkdir", "rmdir", "symlink", "touch", "unlink", "umask")); } + //$forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("require", "include")); $forbiddenphpmethods = array('invoke', 'invokeArgs'); // Method of ReflectionFunction to execute a function @@ -748,13 +752,22 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring) break; } } - foreach ($forbiddenphpfunctions as $forbiddenphpfunction) { - if (preg_match('/'.$forbiddenphpfunction.'\s*\(/ims', $phpfullcodestring)) { + /* replaced with next block + foreach ($forbiddenphpfunctions as $forbiddenphpfunction) { // Check "function(" but also "'function'(" and "function (" + if (preg_match('/'.$forbiddenphpfunction.'[\'\s]*\(/ims', $phpfullcodestring)) { + $error++; + setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpfunction), null, 'errors'); + break; + } + }*/ + foreach ($forbiddenphpfunctions as $forbiddenphpfunction) { // Check "function" whatever is "function(" or "function'(" or "function (" or "function" + if (preg_match('/\b'.$forbiddenphpfunction.'\b/ims', $phpfullcodestring)) { $error++; setEventMessages($langs->trans("DynamicPHPCodeContainsAForbiddenInstruction", $forbiddenphpfunction), null, 'errors'); break; } } + foreach ($forbiddenphpmethods as $forbiddenphpmethod) { if (preg_match('/->'.$forbiddenphpmethod.'/ims', $phpfullcodestring)) { $error++; @@ -803,7 +816,7 @@ function checkPHPCode(&$phpfullcodestringold, &$phpfullcodestring) } } - // No need to block $conf->global->aaa() because PHP try to run method aaa an not function into $conf->global->aaa. + // No need to block $conf->global->aaa() because PHP try to run the method aaa of $conf->global and not the function into $conf->global->aaa. // Then check if installmodules does not block dynamic PHP code change. if ($phpfullcodestringold != $phpfullcodestring) { diff --git a/test/phpunit/AllTests.php b/test/phpunit/AllTests.php index 12e58357aa4..ae5b2c03595 100644 --- a/test/phpunit/AllTests.php +++ b/test/phpunit/AllTests.php @@ -134,6 +134,8 @@ class AllTests $suite->addTestSuite('SecurityTest'); require_once dirname(__FILE__).'/SecurityGETPOSTTest.php'; $suite->addTestSuite('SecurityGETPOSTTest'); + require_once dirname(__FILE__).'/SecurityLoginTest.php'; + $suite->addTestSuite('SecurityLoginTest'); require_once dirname(__FILE__).'/UserTest.php'; $suite->addTestSuite('UserTest'); diff --git a/test/phpunit/SecurityLoginTest.php b/test/phpunit/SecurityLoginTest.php new file mode 100644 index 00000000000..2e4d190567c --- /dev/null +++ b/test/phpunit/SecurityLoginTest.php @@ -0,0 +1,106 @@ + + * Copyright (C) 2023 Alexandre Janniaux + * Copyright (C) 2024 Frédéric France + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * or see https://www.gnu.org/ + */ + +/** + * \file test/phpunit/SecurityTest.php + * \ingroup test + * \brief PHPUnit test + * \remarks To run this script as CLI: phpunit filename.php + */ + +global $conf,$user,$langs,$db; +//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver +//require_once 'PHPUnit/Autoload.php'; + +if (! defined('NOREQUIRESOC')) { + define('NOREQUIRESOC', '1'); +} +if (! defined('NOCSRFCHECK')) { + define('NOCSRFCHECK', '1'); +} +if (! defined('NOTOKENRENEWAL')) { + define('NOTOKENRENEWAL', '1'); +} +if (! defined('NOREQUIREMENU')) { + define('NOREQUIREMENU', '1'); // If there is no menu to show +} +if (! defined('NOREQUIREHTML')) { + define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php +} +if (! defined('NOREQUIREAJAX')) { + define('NOREQUIREAJAX', '1'); +} +if (! defined("NOLOGIN")) { + define("NOLOGIN", '1'); // If this page is public (can be called outside logged session) +} +if (! defined("NOSESSION")) { + define("NOSESSION", '1'); +} + +require_once dirname(__FILE__).'/../../htdocs/main.inc.php'; // We force include of main.inc.php instead of master.inc.php even if we are in CLI mode because it contains a lot of security components we want to test. +require_once dirname(__FILE__).'/../../htdocs/core/lib/security.lib.php'; +require_once dirname(__FILE__).'/../../htdocs/core/lib/security2.lib.php'; +require_once dirname(__FILE__).'/CommonClassTest.class.php'; + +if (empty($user->id)) { + print "Load permissions for admin user nb 1\n"; + $user->fetch(1); + $user->loadRights(); +} +$conf->global->MAIN_DISABLE_ALL_MAILS = 1; + + +/** + * Class for PHPUnit tests + * + * @backupGlobals disabled + * @backupStaticAttributes enabled + * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. + */ +class SecurityLoginTest extends CommonClassTest +{ + /** + * testCheckLoginPassEntity + * + * @return void + */ + public function testCheckLoginPassEntity() + { + $login = checkLoginPassEntity('loginbidon', 'passwordbidon', 1, array('dolibarr')); + print __METHOD__." login=".$login."\n"; + $this->assertEquals($login, ''); + + $login = checkLoginPassEntity('admin', 'passwordbidon', 1, array('dolibarr')); + print __METHOD__." login=".$login."\n"; + $this->assertEquals($login, ''); + + $login = checkLoginPassEntity('admin', 'admin', 1, array('dolibarr')); // Should works because admin/admin exists + print __METHOD__." login=".$login."\n"; + $this->assertEquals($login, 'admin', 'The test to check if pass of user "admin" is "admin" has failed'); + + $login = checkLoginPassEntity('admin', 'admin', 1, array('http','dolibarr')); // Should work because of second authentication method + print __METHOD__." login=".$login."\n"; + $this->assertEquals($login, 'admin'); + + $login = checkLoginPassEntity('admin', 'admin', 1, array('forceuser')); + print __METHOD__." login=".$login."\n"; + $this->assertEquals('', $login, 'Error'); // Expected '' because should failed because login 'auto' does not exists + } +} diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 294d1596fec..9b5db827bc3 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -636,13 +636,13 @@ class SecurityTest extends CommonClassTest $this->assertEquals('Bad string syntax to evaluate: new __forbiddenstring__(\'abc\')', $result); - $result = (string) dol_eval('$a=function() { }; $a;', 1, 1, '0'); - print "result5 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $result = dol_eval('$a=function() { }; $a', 1, 1, '0'); // result of dol_eval may be an object Closure + print "result5 = ".json_encode($result)."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result)); - $result = (string) dol_eval('$a=function() { }; $a;', 1, 1, '1'); - print "result6 = ".$result."\n"; - $this->assertStringContainsString('Bad string syntax to evaluate', $result); + $result = dol_eval('$a=function() { }; $a();', 1, 1, '1'); + print "result6 = ".json_encode($result)."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result)); $result = (string) dol_eval('$a=exec("ls");', 1, 1); print "result7 = ".$result."\n"; @@ -723,6 +723,11 @@ class SecurityTest extends CommonClassTest $result = (string) dol_eval('($a = "ex") && ($b = "ec") && ($cmd = "$a$b") && $cmd ("curl localhost:5555")', 1, 0); print "result22 = ".$result."\n"; $this->assertStringContainsString('Bad string syntax to evaluate', $result, 'Test 22'); + + + $result = (string) dol_eval('\'exec\'("aaa")', 1, 0); + print "result1 = ".$result."\n"; + $this->assertStringContainsString('Bad string syntax to evaluate', json_encode($result), 'Cant find the string Bad string syntaxwhen i should'); } /** @@ -966,33 +971,4 @@ class SecurityTest extends CommonClassTest return 0; } - - - /** - * testCheckLoginPassEntity - * - * @return void - */ - public function testCheckLoginPassEntity() - { - $login = checkLoginPassEntity('loginbidon', 'passwordbidon', 1, array('dolibarr')); - print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, ''); - - $login = checkLoginPassEntity('admin', 'passwordbidon', 1, array('dolibarr')); - print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, ''); - - $login = checkLoginPassEntity('admin', 'admin', 1, array('dolibarr')); // Should works because admin/admin exists - print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, 'admin', 'The test to check if pass of user "admin" is "admin" has failed'); - - $login = checkLoginPassEntity('admin', 'admin', 1, array('http','dolibarr')); // Should work because of second authentication method - print __METHOD__." login=".$login."\n"; - $this->assertEquals($login, 'admin'); - - $login = checkLoginPassEntity('admin', 'admin', 1, array('forceuser')); - print __METHOD__." login=".$login."\n"; - $this->assertEquals('', $login, 'Error'); // Expected '' because should failed because login 'auto' does not exists - } } diff --git a/test/phpunit/WebsiteTest.php b/test/phpunit/WebsiteTest.php index a067202ef85..bbf80cad4c5 100644 --- a/test/phpunit/WebsiteTest.php +++ b/test/phpunit/WebsiteTest.php @@ -132,11 +132,22 @@ class WebsiteTest extends CommonClassTest */ public function testCheckPHPCode() { - global $user; + global $conf, $user; // Force permission so this is not the permission that will affect result of checkPHPCode $user->rights->website->writephp = 1; + // Legitimate + + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 0, 'checkPHPCode detect string as dangerous when it is legitimate'); + + + // Dangerous + $t = ''; $s = ''; $result = checkPHPCode($t, $s); @@ -155,11 +166,27 @@ class WebsiteTest extends CommonClassTest print __METHOD__." result checkPHPCode=".$result."\n"; $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + $t = ''; $s = ';").($_^"/"); ?>'; $result = checkPHPCode($t, $s); print __METHOD__." result checkPHPCode=".$result."\n"; $this->assertEquals($result, 1, 'checkPHPCode did not detect the string was dangerous'); + + // Dangerous but legitimate due to option WEBSITE_PHP_ALLOW_EXEC + + $conf->global->WEBSITE_PHP_ALLOW_EXEC = 1; + + $t = ''; + $s = ''; + $result = checkPHPCode($t, $s); + print __METHOD__." result checkPHPCode=".$result."\n"; + $this->assertEquals($result, 0, 'checkPHPCode did not accept the exec. it should when WEBSITE_PHP_ALLOW_EXEC is set.'); } /** From 8bab8f90c7167cb87ec2465426af9a90eae30996 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 18 Dec 2024 19:47:53 +0100 Subject: [PATCH 086/185] Debug v21 - Must use USF --- htdocs/comm/action/card.php | 6 ++-- htdocs/core/class/html.form.class.php | 48 ++++++++++++++++----------- htdocs/societe/card.php | 4 +-- htdocs/societe/list.php | 2 +- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index e7f8a9b1139..b00fe376ee1 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1546,8 +1546,8 @@ if ($action == 'create') { $listofuserid[$firstelem['id']]['transparency'] = (GETPOSTISSET('transparency') ? GETPOST('transparency', 'alpha') : 0); // 0 by default when refreshing } } - print '
'; - print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'AND u.statut != 0', 1, $listofuserid, $listofcontactid, $listofotherid); + print '
'; + print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid); print '
'; print '
'.$langs->trans("ActionAssignedTo").''; print '
'; - print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'AND u.statut != 0', 1, $listofuserid, $listofcontactid, $listofotherid); + print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid); print '
'; /*if (in_array($user->id,array_keys($listofuserid))) { diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index a291083bf62..a47f07f1703 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2228,7 +2228,13 @@ class Form $sql .= " AND u.fk_soc IS NULL"; } if (!empty($morefilter)) { - $sql .= " " . $morefilter; + $errormessage = ''; + $sql .= forgeSQLFromUniversalSearchCriteria($morefilter, $errormessage); + if ($errormessage) { + $this->errors[] = $errormessage; + dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); + return -1; + } } //Add hook to filter on user (for example on usergroup define in custom modules) @@ -2425,28 +2431,28 @@ class Form * Return select list of users. Selected users are stored into session. * List of users are provided into $_SESSION['assignedtouser']. * - * @param string $action Value for $action - * @param string $htmlname Field name in form - * @param int<0,1> $show_empty 0=list without the empty value, 1=add empty value - * @param int[] $exclude Array list of users id to exclude - * @param int<0,1> $disabled If select list must be disabled - * @param int[]|string $include Array list of users id to include or 'hierarchy' to have only supervised users - * @param int[]|int $enableonly Array list of users id to be enabled. All other must be disabled - * @param string $force_entity '0' or Ids of environment to force - * @param int $maxlength Maximum length of string into list (0=no limit) - * @param int<0,1> $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status - * @param string $morefilter Add more filters into sql request - * @param int $showproperties Show properties of each attendees - * @param int[] $listofuserid Array with properties of each user - * @param int[] $listofcontactid Array with properties of each contact - * @param int[] $listofotherid Array with properties of each other contact - * @return string HTML select string + * @param string $action Value for $action + * @param string $htmlname Field name in form + * @param int<0,1> $show_empty 0=list without the empty value, 1=add empty value + * @param int[] $exclude Array list of users id to exclude + * @param int<0,1> $disabled If select list must be disabled + * @param int[]|''|'hierarchy'|'hierarchyme' $include Array list of users id to include or 'hierarchy' to have only supervised users + * @param int[]|int $enableonly Array list of users id to be enabled. All other must be disabled + * @param string $force_entity '0' or Ids of environment to force + * @param int $maxlength Maximum length of string into list (0=no limit) + * @param int<0,1> $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status + * @param string $morefilter Add more filters into sql request (Example: '(employee:=:1)'). This value must not come from user input. + * @param int $showproperties Show properties of each attendees + * @param int[] $listofuserid Array with properties of each user + * @param int[] $listofcontactid Array with properties of each contact + * @param int[] $listofotherid Array with properties of each other contact + * @return string HTML select string * @see select_dolgroups() */ public function select_dolusers_forevent($action = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = array(), $enableonly = array(), $force_entity = '0', $maxlength = 0, $showstatus = 0, $morefilter = '', $showproperties = 0, $listofuserid = array(), $listofcontactid = array(), $listofotherid = array()) { // phpcs:enable - global $langs; + global $langs, $user; $userstatic = new User($this->db); $out = ''; @@ -2480,7 +2486,11 @@ class Form $out .= ' (' . $langs->trans("Owner") . ')'; } if ($nbassignetouser > 1 && $action != 'view') { - $out .= ' '; + if ($user->hasRight('agenda', 'allactions', 'create') || $userstatic->id != $user->id) { + // If user has all permission, he should be ableto remove a assignee. + // If user has not all permission, he can onlyremove assignee of other (he can't remove itself) + $out .= ' '; + } } // Show my availability if ($showproperties) { diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index e4a3c6c47d5..9e149817d83 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -1960,7 +1960,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio print '
'.$form->editfieldkey('AllocateCommercial', 'commercial_id', '', $object, 0).''; // TODO Use select_doluser in multiselect mode - $userlist = $form->select_dolusers($selected, '', 0, null, 0, '', '', '0', 0, 0, 'AND u.statut = 1', 0, '', '', 0, 2); + $userlist = $form->select_dolusers($selected, '', 0, null, 0, '', '', '0', 0, 0, 'u.statut:=:1', 0, '', '', 0, 2); // Note: If user has no right to "see all thirdparties", we force selection of sale representative to him, so after creation he can see the record. $selected = (GETPOSTISARRAY('commercial') ? GETPOST('commercial', 'array:int') : (GETPOSTINT('commercial') > 0 ? array(GETPOSTINT('commercial')) : array($user->id))); print img_picto('', 'user').$form->multiselectarray('commercial', $userlist, $selected, 0, 0, 'quatrevingtpercent widthcentpercentminusx', 0, 0); @@ -2812,7 +2812,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio print '
'.$form->editfieldkey('AllocateCommercial', 'commercial_id', '', $object, 0).''; - $userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'AND u.statut = 1', 0, '', '', 0, 1); + $userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'u.statut:=:1', 0, '', '', 0, 1); $arrayselected = GETPOST('commercial', 'array'); if (empty($arrayselected)) { $arrayselected = $object->getSalesRepresentatives($user, 1); diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index aaa88687467..70fe8a2f34f 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -1290,7 +1290,7 @@ if (empty($type) || $type == 'f') { } // If the user can view prospects other than his' -$userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'AND u.statut = 1', 0, '', '', 0, 1); +$userlist = $form->select_dolusers('', '', 0, null, 0, '', '', 0, 0, 0, 'u.statut:=:1', 0, '', '', 0, 1); $userlist[-2] = $langs->trans("NoSalesRepresentativeAffected"); if ($user->hasRight("societe", "client", "voir") || $socid) { $moreforfilter .= '
'; From 93884e3424afc6addea5810608bfce0de1bba1cc Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 18 Dec 2024 20:23:21 +0100 Subject: [PATCH 087/185] Fix on auto event, can't change the owner of event. --- htdocs/comm/action/card.php | 3 ++- htdocs/core/class/html.form.class.php | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index b00fe376ee1..338e63e5728 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -2164,7 +2164,8 @@ if ($id > 0) { print '
'.$langs->trans("ActionAssignedTo").''; print '
'; - print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid); + $canremoveowner = ($object->type != 'systemauto'); + print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, array(), 0, '', array(), 0, 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid, $canremoveowner); print '
'; /*if (in_array($user->id,array_keys($listofuserid))) { diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index a47f07f1703..a0e1cd1985b 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2446,10 +2446,11 @@ class Form * @param int[] $listofuserid Array with properties of each user * @param int[] $listofcontactid Array with properties of each contact * @param int[] $listofotherid Array with properties of each other contact + * @param int $canremoveowner 1 if we can remove owner, 0=no way * @return string HTML select string * @see select_dolgroups() */ - public function select_dolusers_forevent($action = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = array(), $enableonly = array(), $force_entity = '0', $maxlength = 0, $showstatus = 0, $morefilter = '', $showproperties = 0, $listofuserid = array(), $listofcontactid = array(), $listofotherid = array()) + public function select_dolusers_forevent($action = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = array(), $enableonly = array(), $force_entity = '0', $maxlength = 0, $showstatus = 0, $morefilter = '', $showproperties = 0, $listofuserid = array(), $listofcontactid = array(), $listofotherid = array(), $canremoveowner = 1) { // phpcs:enable global $langs, $user; @@ -2485,8 +2486,21 @@ class Form $ownerid = $value['id']; $out .= ' (' . $langs->trans("Owner") . ')'; } + // Add picto to delete owner/assignee if ($nbassignetouser > 1 && $action != 'view') { - if ($user->hasRight('agenda', 'allactions', 'create') || $userstatic->id != $user->id) { + $canremoveassignee = 1; + if ($i == 0) { + // We are on the owner of the event + if (!$canremoveowner) { + $canremoveassignee = 0; + } + if ($userstatic->id == $user->id && !$user->hasRight('agenda', 'allactions', 'create')) { + $canremoveassignee = 0; // Can't remove myself if i am the owner + } + } else { + // We are not on the owner of the event but on a secondary assignee + } + if ($canremoveassignee) { // If user has all permission, he should be ableto remove a assignee. // If user has not all permission, he can onlyremove assignee of other (he can't remove itself) $out .= ' '; From 50695e4dcf6ec0a3a63cc94c96bedfc3947fea62 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Wed, 18 Dec 2024 21:19:15 +0100 Subject: [PATCH 088/185] Debug v21 --- htdocs/comm/action/card.php | 32 +++++++++++++++------------ htdocs/core/class/html.form.class.php | 9 ++++---- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 338e63e5728..2e02f37ebec 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1811,7 +1811,7 @@ if ($action == 'create') { print "\n".''; +//print 'Click'; + print "\n"; diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 16db52a9770..4099d762745 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -798,7 +798,7 @@ Notes=Notes AddNewLine=Add new line AddFile=Add file FreeZone=Free-text product -FreeLineOfType=Free-text item, type: +FreeLineOfType=Free-text item, type CloneMainAttributes=Clone object with its main attributes ReGeneratePDF=Re-generate PDF PDFMerge=PDF Merge diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 5db98f3af5c..e6b4e156a26 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -748,8 +748,12 @@ input:-webkit-autofill { /* CSS for placeholder */ .placeholder { color: #ccc; } +select.placeholder { color: #ccc; } ::-webkit-input-placeholder { color: #ccc; } input:-moz-placeholder { color: #ccc; } +select.placeholder option:not(.opacitymediumbycolor):not(.opacitymedium) { + color: var(--colortext); +} input[name=price], input[name=weight], input[name=volume], input[name=surface], input[name=sizeheight], input[name=net_measure], select[name=incoterm_id] { margin-right: 6px; } fieldset { @@ -766,6 +770,7 @@ input#onlinepaymenturl, input#directdownloadlink { opacity: 0.7; } + .formconsumeproduce { background: #f3f3f3; padding: 20px 0px 0px 0px; diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index 5d31a78fe22..b333f13f1ca 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -933,11 +933,15 @@ input[type=checkbox], input[type=radio] { /* CSS for placeholder */ .placeholder { color: #ccc; } +select.placeholder { color: #ccc; } ::-webkit-input-placeholder { color:#ccc; } :-moz-placeholder { color:#bbb; } /* firefox 18- */ ::-moz-placeholder { color:#bbb; } /* firefox 19+ */ :-ms-input-placeholder { color:#ccc; } /* ie */ input:-moz-placeholder { color:#ccc; } +select.placeholder option:not(.opacitymediumbycolor):not(.opacitymedium) { + color: var(--colortext); +} input[name=price], input[name=weight], input[name=volume], input[name=surface], input[name=sizeheight], input[name=net_measure], select[name=incoterm_id] { margin-right: 6px; } fieldset { @@ -4490,7 +4494,7 @@ tr.liste_titre_filter td.liste_titre { padding-top: 4px; padding-bottom: 3px; } -.liste_titre_create td, .liste_titre_create th, .liste_titre_create .tagtd +.liste_titre_create td:not(.linecoldescription), .liste_titre_create th, .liste_titre_create .tagtd { border-top-width: 1px; border-top-color: var(--colortopbordertitle1); @@ -4512,6 +4516,10 @@ tr#trlinefordates td { border-top-style: solid; } +td.linecoldescription { + padding: 6px 10px 6px 12px !important; /* t r b l */ +} + table.liste th, table.noborder th, table.noborder tr.liste_titre td, table.noborder tr.box_titre td { padding: 8px 8px 8px 10px; /* t r b l */ } From d31612dbc2606331705abed76ce5052d2bf40927 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Thu, 19 Dec 2024 07:19:59 +0100 Subject: [PATCH 091/185] FIX #32402 Social Contribution - Update - Drop the attached employee --- htdocs/compta/sociales/card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/sociales/card.php b/htdocs/compta/sociales/card.php index 1c503429393..67ede36a989 100644 --- a/htdocs/compta/sociales/card.php +++ b/htdocs/compta/sociales/card.php @@ -2,7 +2,7 @@ /* Copyright (C) 2004-2020 Laurent Destailleur * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2016-2018 Frédéric France - * Copyright (C) 2017-2022 Alexandre Spangaro + * Copyright (C) 2017-2024 Alexandre Spangaro * Copyright (C) 2021 Gauthier VERDOL * * This program is free software; you can redistribute it and/or modify @@ -203,7 +203,7 @@ if (empty($reshook)) { $object->periode = $dateperiod; $object->period = $dateperiod; $object->amount = $amount; - $object->fk_user = $fk_user; + $object->fk_user = $fk_user; $object->mode_reglement_id = GETPOSTINT('mode_reglement_id'); $object->fk_account = GETPOSTINT('fk_account'); $object->fk_project = GETPOSTINT('fk_project'); @@ -239,7 +239,7 @@ if (empty($reshook)) { $object->periode = $dateperiod; $object->period = $dateperiod; $object->amount = $amount; - $object->fk_user = $fk_user; + // $object->fk_user = $fk_user; $result = $object->update($user); if ($result <= 0) { From 4aba65eaeb5d42da07b15dbe58146d6fbdc6215a Mon Sep 17 00:00:00 2001 From: Irvine Fleith Date: Thu, 19 Dec 2024 08:40:56 +0100 Subject: [PATCH 092/185] fix(facture): when updating, subtype should not be trimmed as it is an int not a string --- htdocs/compta/facture/class/facture.class.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 4779029d174..0723255b101 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2451,9 +2451,6 @@ class Facture extends CommonInvoice if (empty($this->type)) { $this->type = self::TYPE_STANDARD; } - if (isset($this->subtype)) { - $this->subtype = trim($this->subtype); - } if (isset($this->ref)) { $this->ref = trim($this->ref); } From 68103bc42806228542f878017dd293edebdb1881 Mon Sep 17 00:00:00 2001 From: Christophe Battarel Date: Thu, 19 Dec 2024 11:13:40 +0100 Subject: [PATCH 093/185] add fetch before validate in comments --- htdocs/modulebuilder/template/class/myobject.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index cd06cb211ef..ac31dc344dd 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -284,7 +284,9 @@ class MyObject extends CommonObject { $resultcreate = $this->createCommon($user, $notrigger); - //$resultvalidate = $this->validate($user, $notrigger); + // uncomment lines below if you want to validate object after creation + // $this->fetch($this->id); // needed to retrieve some fields (ie date_creation for masked ref) + // $resultcreate = $this->validate($user, $notrigger); return $resultcreate; } From e6d3dbeebcd792e6226de52623b83982b7562031 Mon Sep 17 00:00:00 2001 From: Hystepik Date: Thu, 19 Dec 2024 12:01:00 +0100 Subject: [PATCH 094/185] New add file cache in memory lib --- htdocs/core/lib/memory.lib.php | 56 ++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/memory.lib.php b/htdocs/core/lib/memory.lib.php index 239b9f26f1d..78523378ec3 100644 --- a/htdocs/core/lib/memory.lib.php +++ b/htdocs/core/lib/memory.lib.php @@ -63,10 +63,11 @@ $shmoffset = 1000; // Max number of entries found into a language file. If too l * @param string $memoryid Memory id of shared area * @param mixed $data Data to save. It must not be a null value. * @param int $expire ttl in seconds, 0 never expire + * @param int $filecache 1 Enable file cache if no other session cache available, 0 Disabled (default) * @return int Return integer <0 if KO, 0 if nothing is done, Nb of bytes written if OK * @see dol_getcache() */ -function dol_setcache($memoryid, $data, $expire = 0) +function dol_setcache($memoryid, $data, $expire = 0, $filecache = 0) { global $conf; @@ -124,6 +125,31 @@ function dol_setcache($memoryid, $data, $expire = 0) } elseif (getDolGlobalInt('MAIN_OPTIMIZE_SPEED') & 0x02) { // This is a really not reliable cache ! Use Memcached instead. // Using shmop $result = dol_setshmop($memoryid, $data, $expire); + } elseif ($filecache > 0) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; + $now = dol_now(); + $memoryid = session_name().'_'.$memoryid; + $dircache = 'dolcache'; + $pathcache = DOL_DATA_ROOT.'/'.$dircache; + if (!dol_is_dir($pathcache)) { + $result = dol_mkdir($pathcache); + if ($result < 0) { + return $result; + } + } + if ($expire != 0) { + $expire = dol_time_plus_duree($now, $expire, 's'); + } + + $cachedata = array("expire" => $expire, "data" => $data); + $cachejson = dolEncrypt(json_encode($cachedata)); + if (!dol_is_file($pathcache.'/'.$memoryid.'.cache')) { + $result = file_put_contents($pathcache.'/'.$memoryid.'.cache', $cachejson); + } else { + return 0; + } } else { // No intersession cache system available, we use at least the perpage cache $conf->cache['cachememory_'.$memoryid] = $data; @@ -137,10 +163,11 @@ function dol_setcache($memoryid, $data, $expire = 0) * Read a memory area shared by all users, all sessions on server * * @param string $memoryid Memory id of shared area + * @param int $filecache 1 Enable file cache if no other session cache available, 0 Disabled (default) * @return int|mixed Return integer <0 if KO, data if OK, null if not found into cache or no caching feature enabled * @see dol_setcache() */ -function dol_getcache($memoryid) +function dol_getcache($memoryid, $filecache = 0) { global $conf; @@ -203,6 +230,31 @@ function dol_getcache($memoryid) // Using shmop $data = dol_getshmop($memoryid); return $data; + } elseif ($filecache > 0) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php'; + require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; + $now = dol_now(); + $memoryid = session_name().'_'.$memoryid; + $dircache = 'dolcache'; + $pathcache = DOL_DATA_ROOT.'/'.$dircache; + if (!dol_is_file($pathcache.'/'.$memoryid.'.cache')) { + return null; + } + $data = file_get_contents($pathcache.'/'.$memoryid.'.cache'); + if (!$data) { + return -1; + } + $json = json_decode(dolDecrypt($data)); + if ($json->expire > $now) { + return $json->data; + } else { + $result = dol_delete_file($pathcache.'/'.$memoryid.'.cache'); + if (!$result) { + return -2; + } + } + return null; } else { // No intersession cache system available, we use at least the perpage cache if (isset($conf->cache['cachememory_'.$memoryid])) { From e070a3eda44d2375d9f21772875ed4010a4769ec Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 19 Dec 2024 12:22:10 +0100 Subject: [PATCH 095/185] FIX broken feature, check if module is enabled --- htdocs/core/class/commonobject.class.php | 9 +++++++++ htdocs/product/class/product.class.php | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index b04f5430adc..5c8fb1cfebf 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4847,6 +4847,15 @@ abstract class CommonObject $haschild = 0; foreach ($arraytoscan as $table => $element) { //print $id.'-'.$table.'-'.$elementname.'
'; + + // Check if module is enabled (to avoid error if tables of module not created) + if (isset($element['enabled']) && !empty($element['enabled'])) { + $enabled = (int) dol_eval($element['enabled'], 1); + if (empty($enabled)) { + continue; + } + } + // Check if element can be deleted $sql = "SELECT COUNT(*) as nb"; $sql .= " FROM ".$this->db->prefix().$table." as c"; diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 24ed27c5bf7..dce65ae8696 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -87,9 +87,9 @@ class Product extends CommonObject 'contratdet' => array('name' => 'Contract', 'parent' => 'contrat', 'parentkey' => 'fk_contrat'), 'facture_fourn_det' => array('name' => 'SupplierInvoice', 'parent' => 'facture_fourn', 'parentkey' => 'fk_facture_fourn'), 'commande_fournisseurdet' => array('name' => 'SupplierOrder', 'parent' => 'commande_fournisseur', 'parentkey' => 'fk_commande'), - 'mrp_production' => array('name' => 'Mo', 'parent' => 'mrp_mo', 'parentkey' => 'fk_mo' ), - 'bom_bom' => array('name' => 'BOM'), - 'bom_bomline' => array('name' => 'BOMLine', 'parent' => 'bom_bom', 'parentkey' => 'fk_bom'), + 'mrp_production' => array('name' => 'Mo', 'parent' => 'mrp_mo', 'parentkey' => 'fk_mo', 'enabled' => 'isModEnabled("mrp")'), + 'bom_bom' => array('name' => 'BOM', 'enabled' => 'isModEnabled("bom")'), + 'bom_bomline' => array('name' => 'BOMLine', 'parent' => 'bom_bom', 'parentkey' => 'fk_bom', 'enabled' => 'isModEnabled("bom")'), ); /** From 425c23d28cafc1ada9c2090eac219f3a604320f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20PASCAL?= Date: Thu, 19 Dec 2024 15:38:19 +0100 Subject: [PATCH 096/185] fix: fetch action linked object --- htdocs/core/class/commonobject.class.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 59d71a5bf36..232a3b6893b 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -3832,7 +3832,7 @@ abstract class CommonObject $num = $this->db->num_rows($resql); $i = 0; while ($i < $num) { - $obj = $this->db->fetch_object($resql); + $obj = $this->db->fetch_object($resql); if ($justsource || $justtarget) { if ($justsource) { $this->linkedObjectsIds[$obj->targettype][$obj->rowid] = $obj->fk_target; @@ -3892,8 +3892,12 @@ abstract class CommonObject $classpath = 'adherents/class'; $module = 'adherent'; } elseif ($objecttype == 'contact') { - $module = 'societe'; - } + $module = 'societe'; + } elseif ($objecttype == 'action') { + $module = 'agenda'; + $subelement = 'actionComm'; + } + // Set classfile $classfile = strtolower($subelement); $classname = ucfirst($subelement); From 4222ac9a036effefe5d0f9576d304f370dd48740 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 19 Dec 2024 17:10:13 +0100 Subject: [PATCH 097/185] Fix phpstan --- htdocs/core/tpl/login.tpl.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/tpl/login.tpl.php b/htdocs/core/tpl/login.tpl.php index a9af96af82a..7b9029cf6b8 100644 --- a/htdocs/core/tpl/login.tpl.php +++ b/htdocs/core/tpl/login.tpl.php @@ -285,9 +285,9 @@ if ($disablenofollow) { file->main_authentication) || $conf->file->main_authentication != 'googleoauth') { ?>
- + " name="username" class="flat input-icon-user minwidth150" value="" tabindex="1" autofocus="autofocus" autocapitalize="off" autocomplete="on" spellcheck="false" autocorrect="off" /> From f8d267d69cc94fa229181acd48083a1024bd3c56 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 19 Dec 2024 17:17:27 +0100 Subject: [PATCH 098/185] Complete #32382 --- htdocs/document.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/document.php b/htdocs/document.php index f0e60549d1c..c870c1cca1e 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -103,7 +103,7 @@ $original_file = GETPOST('file', 'alphanohtml'); $hashp = GETPOST('hashp', 'aZ09'); $modulepart = GETPOST('modulepart', 'alpha'); $urlsource = GETPOST('urlsource', 'alpha'); -$entity = GETPOSTINT('entity'); +$entity = GETPOSTINT('entity') ? GETPOSTINT('entity') : $conf->entity; // Security check if (empty($modulepart) && empty($hashp)) { From 1350c60e7754771c085184bced3945da59facd6d Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 19 Dec 2024 17:29:33 +0100 Subject: [PATCH 099/185] Fix cti --- htdocs/comm/action/card.php | 4 ++-- htdocs/core/class/html.form.class.php | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 2e02f37ebec..010f405e549 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -1820,7 +1820,7 @@ if ($action == 'create') { $("#addreminder").prop("checked", true); // Set period with default reminder period - $("[name=\"offsetvalue\"]").val(\'' . dol_escape_js($reminderDefaultOffset) . '\'); + $("[name=\"offsetvalue\"]").val(\'' . dol_escape_js((string) $reminderDefaultOffset) . '\'); $("#select_offsetunittype_duration").select2("destroy"); $("#select_offsetunittype_duration").val(\''.dol_escape_js($reminderDefaultUnit).'\'); $("#select_offsetunittype_duration").select2(); @@ -1832,7 +1832,7 @@ if ($action == 'create') { // Set default reminder mail model $("#select_actioncommsendmodel_mail").closest("tr").show(); $("#select_actioncommsendmodel_mail").select2("destroy"); - $("#select_actioncommsendmodel_mail").val(\''.dol_escape_js($reminderDefaultEmailModel).'\'); + $("#select_actioncommsendmodel_mail").val(\''.dol_escape_js((string) $reminderDefaultEmailModel).'\'); $("#select_actioncommsendmodel_mail").select2(); } }); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index bb482bbf433..555778e7124 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -2237,7 +2237,11 @@ class Form if ($errormessage) { $this->errors[] = $errormessage; dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); - return -1; + if ($outputmode == 0) { + return 'Error bad param $morefilter'; + } else { + return array(); + } } } From 992807ef2a8835fe9a581cd2936cd2d74589ff10 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 19 Dec 2024 17:42:16 +0100 Subject: [PATCH 100/185] Fix setting date_creation --- htdocs/core/class/commonobject.class.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 28422a2d77f..74696c58966 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -10333,6 +10333,7 @@ abstract class CommonObject if (array_key_exists('date_creation', $fieldvalues) && empty($fieldvalues['date_creation'])) { $fieldvalues['date_creation'] = $this->db->idate($now); + $this->date_creation = $this->db->idate($now); } if (array_key_exists('fk_user_creat', $fieldvalues) && !($fieldvalues['fk_user_creat'] > 0)) { $fieldvalues['fk_user_creat'] = $user->id; From d321f4cc7d0264ffebe3a760373d036a0cffcbc8 Mon Sep 17 00:00:00 2001 From: Codered741 Date: Thu, 19 Dec 2024 12:22:58 -0500 Subject: [PATCH 101/185] response to issue #32292 --- htdocs/product/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 0f7d57db40c..5922e0f18d1 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -119,7 +119,7 @@ $search_accountancy_code_buy_intra = GETPOST("search_accountancy_code_buy_intra" $search_accountancy_code_buy_export = GETPOST("search_accountancy_code_buy_export", 'alpha'); $search_import_key = GETPOST("search_import_key", 'alpha'); $search_finished = GETPOST("search_finished"); -$search_units = GETPOST('search_units', 'alpha'); +$search_units = GETPOST('search_units', 'int'); $type = GETPOST("type", 'alpha'); // Show/hide child product variants From ee119254030fed51982e9fca127e987722a56979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Thu, 19 Dec 2024 18:28:21 +0100 Subject: [PATCH 102/185] fix --- build/phpstan/phpstan-baseline.neon | 6 ------ htdocs/societe/canvas/individual/tpl/card_view.tpl.php | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index 1c7672653e5..a00105a79b3 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -30462,12 +30462,6 @@ parameters: count: 1 path: ../../htdocs/societe/canvas/individual/tpl/card_edit.tpl.php - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/societe/canvas/individual/tpl/card_view.tpl.php - - message: '#^Variable \$objcanvas might not be defined\.$#' identifier: variable.undefined diff --git a/htdocs/societe/canvas/individual/tpl/card_view.tpl.php b/htdocs/societe/canvas/individual/tpl/card_view.tpl.php index 2c0a6277ac4..07e2afc2ae0 100644 --- a/htdocs/societe/canvas/individual/tpl/card_view.tpl.php +++ b/htdocs/societe/canvas/individual/tpl/card_view.tpl.php @@ -17,12 +17,15 @@ */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var DoliDB $db * @var FormFile $formfile * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { From 3cedf2ee5473ed0b02847390d76437087d1fcbec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Thu, 19 Dec 2024 18:47:07 +0100 Subject: [PATCH 103/185] fix CI --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 49f32592868..86f862c0edd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,7 @@ repos: exclude: | (?x)^(htdocs/includes/.*)$ # This checks that yaml files are correct - args: [--branch, develop, --pattern, \d+.0$] + args: [--branch, develop, --pattern, \d+.0] - id: check-yaml args: [--unsafe] # This checks that json files are correct From dbcc1980610af1e71540d3071b90392fabad4e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Thu, 19 Dec 2024 18:51:40 +0100 Subject: [PATCH 104/185] fix CI --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 86f862c0edd..5f75f64fc16 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,6 @@ repos: exclude: | (?x)^(htdocs/includes/.*)$ # This checks that yaml files are correct - args: [--branch, develop, --pattern, \d+.0] - id: check-yaml args: [--unsafe] # This checks that json files are correct From 62bd14a68d7bd5082f8374c5e8f26fae658384fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Thu, 19 Dec 2024 18:54:51 +0100 Subject: [PATCH 105/185] fix ci branch 20.0 --- .pre-commit-config.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 16b24c1eeb6..6c5643e6e78 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,7 +24,6 @@ repos: exclude: | (?x)^(htdocs/includes/.*)$ # This checks that yaml files are correct - args: [--branch, develop, --pattern, \d+.0$] - id: check-yaml args: [--unsafe] # This checks that json files are correct From 840166462e5db4a4da813ee51015578b66ffdc7b Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Thu, 19 Dec 2024 19:40:03 +0100 Subject: [PATCH 106/185] Revert --- htdocs/document.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/document.php b/htdocs/document.php index c870c1cca1e..f0e60549d1c 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -103,7 +103,7 @@ $original_file = GETPOST('file', 'alphanohtml'); $hashp = GETPOST('hashp', 'aZ09'); $modulepart = GETPOST('modulepart', 'alpha'); $urlsource = GETPOST('urlsource', 'alpha'); -$entity = GETPOSTINT('entity') ? GETPOSTINT('entity') : $conf->entity; +$entity = GETPOSTINT('entity'); // Security check if (empty($modulepart) && empty($hashp)) { From 50d137a5eadd68ea259ee9daea1f7edb44a9df81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Thu, 19 Dec 2024 21:01:00 +0100 Subject: [PATCH 107/185] fix phpstan --- build/phpstan/phpstan-baseline.neon | 24 ------------------- .../canvas/product/tpl/card_create.tpl.php | 7 ++++-- .../canvas/service/tpl/card_create.tpl.php | 3 +++ .../canvas/individual/tpl/card_create.tpl.php | 3 +++ .../canvas/individual/tpl/card_edit.tpl.php | 3 +++ 5 files changed, 14 insertions(+), 26 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index a00105a79b3..e201b947306 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -24864,12 +24864,6 @@ parameters: count: 1 path: ../../htdocs/product/canvas/product/actions_card_product.class.php - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/product/canvas/product/tpl/card_create.tpl.php - - message: '#^Variable \$refalreadyexists might not be defined\.$#' identifier: variable.undefined @@ -24894,12 +24888,6 @@ parameters: count: 2 path: ../../htdocs/product/canvas/service/tpl/card_create.tpl.php - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/product/canvas/service/tpl/card_create.tpl.php - - message: '#^Variable \$refalreadyexists might not be defined\.$#' identifier: variable.undefined @@ -30450,18 +30438,6 @@ parameters: count: 3 path: ../../htdocs/societe/canvas/company/tpl/card_view.tpl.php - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/societe/canvas/individual/tpl/card_create.tpl.php - - - - message: '#^Variable \$canvas might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/societe/canvas/individual/tpl/card_edit.tpl.php - - message: '#^Variable \$objcanvas might not be defined\.$#' identifier: variable.undefined diff --git a/htdocs/product/canvas/product/tpl/card_create.tpl.php b/htdocs/product/canvas/product/tpl/card_create.tpl.php index 5e4621b24c1..50781358e58 100644 --- a/htdocs/product/canvas/product/tpl/card_create.tpl.php +++ b/htdocs/product/canvas/product/tpl/card_create.tpl.php @@ -1,6 +1,6 @@ - * Copyright (C) 2024 Frédéric France +/* Copyright (C) 2010-2018 Regis Houssin + * Copyright (C) 2024 Frédéric France * * 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 @@ -16,10 +16,13 @@ * along with this program. If not, see . */ /** + * @var Canvas $this * @var Conf $conf * @var Form $form * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/product/canvas/service/tpl/card_create.tpl.php b/htdocs/product/canvas/service/tpl/card_create.tpl.php index 875b790e688..7ba6e018972 100644 --- a/htdocs/product/canvas/service/tpl/card_create.tpl.php +++ b/htdocs/product/canvas/service/tpl/card_create.tpl.php @@ -16,10 +16,13 @@ * along with this program. If not, see . */ /** + * @var Canvas $this * @var Conf $conf * @var Form $form * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/societe/canvas/individual/tpl/card_create.tpl.php b/htdocs/societe/canvas/individual/tpl/card_create.tpl.php index ebd3dcb6e01..0620678fc02 100644 --- a/htdocs/societe/canvas/individual/tpl/card_create.tpl.php +++ b/htdocs/societe/canvas/individual/tpl/card_create.tpl.php @@ -18,12 +18,15 @@ */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var DoliDB $db * @var FormFile $formfile * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/societe/canvas/individual/tpl/card_edit.tpl.php b/htdocs/societe/canvas/individual/tpl/card_edit.tpl.php index d21880eb303..3964a8a7491 100644 --- a/htdocs/societe/canvas/individual/tpl/card_edit.tpl.php +++ b/htdocs/societe/canvas/individual/tpl/card_edit.tpl.php @@ -18,12 +18,15 @@ */ /** + * @var Canvas $this * @var Conf $conf * @var CommonObject $this * @var DoliDB $db * @var FormFile $formfile * @var Translate $langs * @var User $user + * + * @var string $canvas */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { From 7ba7a975a1250759b1e0b0daff303481a56aade9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Thu, 19 Dec 2024 21:57:14 +0100 Subject: [PATCH 108/185] fix phpstan --- build/phpstan/phpstan-baseline.neon | 24 ------------------- htdocs/core/lib/functions.lib.php | 1 + .../canvas/product/tpl/card_create.tpl.php | 1 + .../canvas/product/tpl/card_edit.tpl.php | 2 +- .../canvas/product/tpl/card_view.tpl.php | 2 +- .../canvas/service/tpl/card_create.tpl.php | 3 ++- .../canvas/service/tpl/card_edit.tpl.php | 2 +- .../canvas/service/tpl/card_view.tpl.php | 2 +- 8 files changed, 8 insertions(+), 29 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index e201b947306..971443ca523 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -24864,12 +24864,6 @@ parameters: count: 1 path: ../../htdocs/product/canvas/product/actions_card_product.class.php - - - message: '#^Variable \$refalreadyexists might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/product/canvas/product/tpl/card_create.tpl.php - - message: '#^Property ActionsCardService\:\:\$field_list has no type specified\.$#' identifier: missingType.property @@ -24882,24 +24876,6 @@ parameters: count: 1 path: ../../htdocs/product/canvas/service/actions_card_service.class.php - - - message: '#^Cannot access property \$control on mixed\.$#' - identifier: property.nonObject - count: 2 - path: ../../htdocs/product/canvas/service/tpl/card_create.tpl.php - - - - message: '#^Variable \$refalreadyexists might not be defined\.$#' - identifier: variable.undefined - count: 1 - path: ../../htdocs/product/canvas/service/tpl/card_create.tpl.php - - - - message: '#^Variable \$this might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/product/canvas/service/tpl/card_create.tpl.php - - message: '#^Negated boolean expression is always true\.$#' identifier: booleanNot.alwaysTrue diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 6f47d171761..ef0e68c369e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1567,6 +1567,7 @@ function dol_get_object_properties($obj, $properties = []) * @param T $object Object to clone * @param int $native 0=Full isolation method, 1=Native PHP method, 2=Full isolation method keeping only scalar and array properties (recommended) * @return T Clone object + * * @see https://php.net/manual/language.oop5.cloning.php * @phan-suppress PhanTypeExpectedObjectPropAccess */ diff --git a/htdocs/product/canvas/product/tpl/card_create.tpl.php b/htdocs/product/canvas/product/tpl/card_create.tpl.php index 50781358e58..1f750f1108a 100644 --- a/htdocs/product/canvas/product/tpl/card_create.tpl.php +++ b/htdocs/product/canvas/product/tpl/card_create.tpl.php @@ -23,6 +23,7 @@ * @var User $user * * @var string $canvas + * @var int $refalreadyexists */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/product/canvas/product/tpl/card_edit.tpl.php b/htdocs/product/canvas/product/tpl/card_edit.tpl.php index b6a95262e0d..12482210934 100644 --- a/htdocs/product/canvas/product/tpl/card_edit.tpl.php +++ b/htdocs/product/canvas/product/tpl/card_edit.tpl.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2010-2018 Regis Houssin * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify diff --git a/htdocs/product/canvas/product/tpl/card_view.tpl.php b/htdocs/product/canvas/product/tpl/card_view.tpl.php index 3cf61f55d2f..e7b26f58762 100644 --- a/htdocs/product/canvas/product/tpl/card_view.tpl.php +++ b/htdocs/product/canvas/product/tpl/card_view.tpl.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2010-2018 Regis Houssin * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify diff --git a/htdocs/product/canvas/service/tpl/card_create.tpl.php b/htdocs/product/canvas/service/tpl/card_create.tpl.php index 7ba6e018972..6266cdbda47 100644 --- a/htdocs/product/canvas/service/tpl/card_create.tpl.php +++ b/htdocs/product/canvas/service/tpl/card_create.tpl.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2010-2018 Regis Houssin * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify @@ -23,6 +23,7 @@ * @var User $user * * @var string $canvas + * @var int $refalreadyexists */ // Protection to avoid direct call of template if (empty($conf) || !is_object($conf)) { diff --git a/htdocs/product/canvas/service/tpl/card_edit.tpl.php b/htdocs/product/canvas/service/tpl/card_edit.tpl.php index eb40955a200..a95415aac72 100644 --- a/htdocs/product/canvas/service/tpl/card_edit.tpl.php +++ b/htdocs/product/canvas/service/tpl/card_edit.tpl.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2010-2018 Regis Houssin * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify diff --git a/htdocs/product/canvas/service/tpl/card_view.tpl.php b/htdocs/product/canvas/service/tpl/card_view.tpl.php index 2b48f913b0e..b5fd7372b39 100644 --- a/htdocs/product/canvas/service/tpl/card_view.tpl.php +++ b/htdocs/product/canvas/service/tpl/card_view.tpl.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2010-2018 Regis Houssin * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify From a6de5d6d5c2d30725a0db39f313bb75213bbd526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 20 Dec 2024 12:14:09 +0100 Subject: [PATCH 109/185] fix phpstan --- build/phpstan/phpstan-baseline.neon | 12 ------------ htdocs/core/tpl/objectline_view.tpl.php | 2 ++ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index 1c7672653e5..823aa736e05 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -16908,18 +16908,6 @@ parameters: count: 1 path: ../../htdocs/core/tpl/objectline_view.tpl.php - - - message: '#^Variable \$action might not be defined\.$#' - identifier: variable.undefined - count: 2 - path: ../../htdocs/core/tpl/objectline_view.tpl.php - - - - message: '#^Variable \$i might not be defined\.$#' - identifier: variable.undefined - count: 5 - path: ../../htdocs/core/tpl/objectline_view.tpl.php - - message: '#^Variable \$objp might not be defined\.$#' identifier: variable.undefined diff --git a/htdocs/core/tpl/objectline_view.tpl.php b/htdocs/core/tpl/objectline_view.tpl.php index 9e34f4ba39f..93bc95c0a12 100644 --- a/htdocs/core/tpl/objectline_view.tpl.php +++ b/htdocs/core/tpl/objectline_view.tpl.php @@ -52,6 +52,8 @@ * @var Translate $langs * @var User $user * + * @var string $action + * @var int $i * @var 0|1 $forceall * @var int $num * @var 0|1 $senderissupplier From 57cc09db4878375ca49a9b6e9b990068b79c6e07 Mon Sep 17 00:00:00 2001 From: Gouttfi Date: Fri, 20 Dec 2024 13:04:06 +0100 Subject: [PATCH 110/185] FIX : chore doc : update wrong URL for DCO --- .github/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index d898628013e..a992c0a13f6 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -36,7 +36,7 @@ Definition: As the Developer: -1. Check you agree with the terms of the [DCO - Developer's Certificate of Origin](https://github.com/Dolibarr/dolibarr/DCO) +1. Check you agree with the terms of the [DCO - Developer's Certificate of Origin](https://github.com/Dolibarr/dolibarr/blob/develop/DCO) 2. [Fork](https://help.github.com/articles/fork-a-repo) the [GitHub repository](https://github.com/Dolibarr/dolibarr). 3. Clone your fork. 4. Choose a branch(See the [Branches](#branches) section below). From 895c16090ba332b4cc525148050dc1f001e877fc Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 20 Dec 2024 13:54:59 +0100 Subject: [PATCH 111/185] Disable the mege when not required --- htdocs/core/lib/invoice2.lib.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/invoice2.lib.php b/htdocs/core/lib/invoice2.lib.php index bf2e51a47fd..c4d4d34f727 100644 --- a/htdocs/core/lib/invoice2.lib.php +++ b/htdocs/core/lib/invoice2.lib.php @@ -47,9 +47,10 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; * @param string $paymentbankid Only if payment on this bank account id * @param int[] $thirdpartiesid List of thirdparties id when using filter=excludethirdpartiesid or filter=onlythirdpartiesid * @param string $fileprefix Prefix to add into filename of generated PDF + * @param int $donotmerge 0=Default, 1=Disable the merge so do only the regeneration of PDFs. * @return int Error code */ -function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, $usestdout, $regenerate = '', $filesuffix = '', $paymentbankid = '', $thirdpartiesid = [], $fileprefix = 'mergedpdf') +function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, $usestdout, $regenerate = '', $filesuffix = '', $paymentbankid = '', $thirdpartiesid = [], $fileprefix = 'mergedpdf', $donotmerge = 0) { $sql = "SELECT DISTINCT f.rowid, f.ref"; $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; @@ -216,6 +217,9 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $cpt++; } + if ($donotmerge) { + return 1; + } // Define format of output PDF $formatarray = pdf_getFormat($langs); From a3bd2954072e51fddedbe54e35d2af3b17fc4151 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 20 Dec 2024 14:16:58 +0100 Subject: [PATCH 112/185] Trans --- htdocs/langs/en_US/products.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 2d8d05e9761..ededc52cbfc 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -209,6 +209,7 @@ unitL=Liter unitT=ton unitKG=kg unitG=Gram +unitGAL=gallon unitMG=mg unitLB=pound unitOZ=ounce From 3fc800b1b26d3b17ae55b95769d5d88b2e3fff7c Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 20 Dec 2024 14:42:22 +0100 Subject: [PATCH 113/185] Fix nomerge mode --- htdocs/core/lib/invoice2.lib.php | 45 ++++++++++++++++++++------ scripts/invoices/rebuild_merge_pdf.php | 25 ++++++++++---- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/htdocs/core/lib/invoice2.lib.php b/htdocs/core/lib/invoice2.lib.php index c4d4d34f727..9ee10a71cd7 100644 --- a/htdocs/core/lib/invoice2.lib.php +++ b/htdocs/core/lib/invoice2.lib.php @@ -48,12 +48,30 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; * @param int[] $thirdpartiesid List of thirdparties id when using filter=excludethirdpartiesid or filter=onlythirdpartiesid * @param string $fileprefix Prefix to add into filename of generated PDF * @param int $donotmerge 0=Default, 1=Disable the merge so do only the regeneration of PDFs. + * @param string $mode 'invoice' for invoices, 'proposal' for proposal, ... * @return int Error code */ -function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, $usestdout, $regenerate = '', $filesuffix = '', $paymentbankid = '', $thirdpartiesid = [], $fileprefix = 'mergedpdf', $donotmerge = 0) +function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, $usestdout, $regenerate = '', $filesuffix = '', $paymentbankid = '', $thirdpartiesid = [], $fileprefix = 'mergedpdf', $donotmerge = 0, $mode = 'invoice') { + if ($mode == 'invoice') { + $table = "facture"; + $dir_output = $conf->facture->dir_output; + $date = "datef"; + } elseif ($mode == 'order') { + $table = "commande"; + $dir_output = $conf->commande->dir_output; + $date = "date"; + } elseif ($mode == 'proposal') { + $table = "propal"; + $dir_output = $conf->propal->dir_output; + $date = "date"; + } else { + print "Bad value for mode"; + return -1; + } + $sql = "SELECT DISTINCT f.rowid, f.ref"; - $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; + $sql .= " FROM ".MAIN_DB_PREFIX.$table." as f"; $sqlwhere = ''; $sqlorder = ''; if (in_array('all', $filter)) { @@ -66,10 +84,11 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $sqlwhere .= " AND"; } $sqlwhere .= " f.fk_statut > 0"; - $sqlwhere .= " AND f.datef >= '".$db->idate($dateafterdate)."'"; - $sqlwhere .= " AND f.datef <= '".$db->idate($datebeforedate)."'"; + $sqlwhere .= " AND f.".$db->sanitize($date)." >= '".$db->idate($dateafterdate)."'"; + $sqlwhere .= " AND f.".$db->sanitize($date)." <= '".$db->idate($datebeforedate)."'"; $sqlorder = " ORDER BY f.datef ASC"; } + // Filter for invoices only if (in_array('nopayment', $filter)) { $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON f.rowid = pf.fk_facture"; if (empty($sqlwhere)) { @@ -80,6 +99,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $sqlwhere .= " f.fk_statut > 0"; $sqlwhere .= " AND pf.fk_paiement IS NULL"; } + // Filter for invoices only if (in_array('payments', $filter) || in_array('bank', $filter)) { $sql .= ", ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."paiement as p"; if (in_array('bank', $filter)) { @@ -103,6 +123,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte } $sqlorder = " ORDER BY p.datep ASC"; } + // Filter for invoices only if (in_array('nodeposit', $filter)) { if (empty($sqlwhere)) { $sqlwhere = ' WHERE '; @@ -111,6 +132,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte } $sqlwhere .= ' type <> 3'; } + // Filter for invoices only if (in_array('noreplacement', $filter)) { if (empty($sqlwhere)) { $sqlwhere = ' WHERE '; @@ -119,6 +141,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte } $sqlwhere .= ' type <> 1'; } + // Filter for invoices only if (in_array('nocreditnote', $filter)) { if (empty($sqlwhere)) { $sqlwhere = ' WHERE '; @@ -168,9 +191,6 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte if ($resql = $db->query($sql)) { $num = $db->num_rows($resql); $cpt = 0; - $oldemail = ''; - $message = ''; - $total = ''; if ($num) { // First loop on each resultset to build PDF @@ -179,7 +199,14 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte while ($cpt < $num) { $obj = $db->fetch_object($resql); - $fac = new Facture($db); + if ($mode == 'invoice') { + $fac = new Facture($db); + } elseif ($mode == 'order') { + $fac = new Commande($db); + } elseif ($mode == 'proposal') { + $fac = new Propal($db); + } + $result = $fac->fetch($obj->rowid); if ($result > 0) { $outputlangs = $langs; @@ -189,7 +216,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $outputlangs->setDefaultLang($newlangid); } } - $filename = $conf->facture->dir_output.'/'.$fac->ref.'/'.$fac->ref.'.pdf'; + $filename = $dir_output.'/'.$fac->ref.'/'.$fac->ref.'.pdf'; if ($regenerate || !dol_is_file($filename)) { if ($usestdout) { print "Build PDF for invoice ".$obj->ref." - Lang = ".$outputlangs->defaultlang."\n"; diff --git a/scripts/invoices/rebuild_merge_pdf.php b/scripts/invoices/rebuild_merge_pdf.php index d7ee2915281..d493ddb8aad 100755 --- a/scripts/invoices/rebuild_merge_pdf.php +++ b/scripts/invoices/rebuild_merge_pdf.php @@ -83,12 +83,15 @@ if (!empty($dolibarr_main_db_readonly)) { exit(1); } + $diroutputpdf = $conf->invoice->dir_output.'/temp'; + $newlangid = 'en_EN'; // To force a new lang id $filter = array(); $regenerate = ''; // Ask regenerate (contains name of model to use) $option = ''; $fileprefix = 'mergedpdf'; +$nomerge = 0; $dateafterdate = ''; $datebeforedate = ''; $paymentdateafter = ''; @@ -113,6 +116,7 @@ foreach ($argv as $key => $value) { print 'Use prefix for filename '.$fileprefix.".\n"; } + $reg = array(); if (preg_match('/^regenerate=(.*)/i', $value, $reg)) { if (!in_array($reg[1], array('', '0', 'no'))) { $found = true; @@ -120,6 +124,14 @@ foreach ($argv as $key => $value) { print 'Regeneration of PDF is requested with template '.$regenerate."\n"; } } + if (preg_match('/^regeneratenomerge=(.*)/i', $value, $reg)) { + if (!in_array($reg[1], array('', '0', 'no'))) { + $found = true; + $regenerate = $reg[1]; + $nomerge = 1; + print 'Regeneration (without merge) of PDF is requested with template '.$regenerate."\n"; + } + } if ($value == 'filter=all') { $found = true; @@ -136,7 +148,7 @@ foreach ($argv as $key => $value) { $dateafterdate = dol_stringtotime($argv[$key + 1]); $datebeforedate = dol_stringtotime($argv[$key + 2]); - print 'Rebuild PDF for invoices validated between '.dol_print_date($dateafterdate, 'day', 'gmt')." and ".dol_print_date($datebeforedate, 'day', 'gmt').".\n"; + print 'Rebuild PDF for documents validated between '.dol_print_date($dateafterdate, 'day', 'gmt')." and ".dol_print_date($datebeforedate, 'day', 'gmt').".\n"; } if ($value == 'filter=payments') { @@ -150,7 +162,7 @@ foreach ($argv as $key => $value) { print 'Error: Bad date format or value'."\n"; exit(1); } - 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"; + 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"; } if ($value == 'filter=nopayment') { @@ -158,7 +170,7 @@ foreach ($argv as $key => $value) { $option .= (empty($option) ? '' : '_').'nopayment'; $filter[] = 'nopayment'; - print 'Rebuild PDF for invoices with no payment done yet.'."\n"; + print 'Rebuild PDF for ivoices with no payment done yet.'."\n"; } if ($value == 'filter=bank') { @@ -244,7 +256,8 @@ if (in_array('bank', $filter) && in_array('nopayment', $filter)) { // Define SQL and SQL request to select invoices // Use $filter, $dateafterdate, datebeforedate, $paymentdateafter, $paymentdatebefore -$result = rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, 1, $regenerate, $option, (string) $paymentonbankid, $thirdpartiesid, $fileprefix); + +$result = rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, 1, $regenerate, $option, (string) $paymentonbankid, $thirdpartiesid, $fileprefix, $nomerge); // -------------------- END OF YOUR CODE -------------------- @@ -269,7 +282,7 @@ function rebuild_merge_pdf_usage() { global $script_file; - print "Rebuild PDF files for some invoices and merge PDF files into one.\n"; + print "Rebuild PDF files for some invoices and/or merge PDF files into one.\n"; print "\n"; print "To build/merge PDF for invoices in a date range:\n"; print "Usage: ".$script_file." filter=date dateafter datebefore\n"; @@ -286,7 +299,7 @@ function rebuild_merge_pdf_usage() print "To exclude deposit invoices, use filter=nodeposit\n"; print "To exclude some thirdparties, use filter=excludethirdparties id1,id2...\n"; print "To limit to some thirdparties, use filter=onlythirdparties id1,id2...\n"; - print "To regenerate existing PDF, use regenerate=templatename\n"; + print "To regenerate existing PDF, use regenerate=templatename or regeneratenomerge=templatename\n"; print "To generate invoices in a language, use lang=xx_XX\n"; print "To set prefix of generated file name, use prefix=myfileprefix\n"; print "\n"; From 35e935f4be0b13c2164428d0f544fc7e0c3a0bc7 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 20 Dec 2024 15:21:38 +0100 Subject: [PATCH 114/185] debug rebuild_merge_pdf --- htdocs/core/lib/invoice2.lib.php | 31 +++++++++++++++++++++----- scripts/invoices/rebuild_merge_pdf.php | 19 +++++++++++----- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/htdocs/core/lib/invoice2.lib.php b/htdocs/core/lib/invoice2.lib.php index 9ee10a71cd7..e8aa401ad0e 100644 --- a/htdocs/core/lib/invoice2.lib.php +++ b/htdocs/core/lib/invoice2.lib.php @@ -54,17 +54,38 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php'; function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, $usestdout, $regenerate = '', $filesuffix = '', $paymentbankid = '', $thirdpartiesid = [], $fileprefix = 'mergedpdf', $donotmerge = 0, $mode = 'invoice') { if ($mode == 'invoice') { + require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php"; + require_once DOL_DOCUMENT_ROOT."/core/modules/facture/modules_facture.php"; + $table = "facture"; $dir_output = $conf->facture->dir_output; $date = "datef"; + + if ($diroutputpdf == 'auto') { + $diroutputpdf = $conf->invoice->dir_output.'/temp'; + } } elseif ($mode == 'order') { + require_once DOL_DOCUMENT_ROOT."/commande/class/commande.class.php"; + require_once DOL_DOCUMENT_ROOT."/core/modules/commande/modules_commande.php"; + $table = "commande"; - $dir_output = $conf->commande->dir_output; + $dir_output = $conf->order->dir_output; $date = "date"; + + if ($diroutputpdf == 'auto') { + $diroutputpdf = $conf->order->dir_output.'/temp'; + } } elseif ($mode == 'proposal') { + require_once DOL_DOCUMENT_ROOT."/comm/propal/class/propal.class.php"; + require_once DOL_DOCUMENT_ROOT."/core/modules/propale/modules_propale.php"; + $table = "propal"; $dir_output = $conf->propal->dir_output; $date = "date"; + + if ($diroutputpdf == 'auto') { + $diroutputpdf = $conf->propal->dir_output.'/temp'; + } } else { print "Bad value for mode"; return -1; @@ -219,12 +240,12 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $filename = $dir_output.'/'.$fac->ref.'/'.$fac->ref.'.pdf'; if ($regenerate || !dol_is_file($filename)) { if ($usestdout) { - print "Build PDF for invoice ".$obj->ref." - Lang = ".$outputlangs->defaultlang."\n"; + print "Build PDF for document ".$obj->ref." - Lang = ".$outputlangs->defaultlang."\n"; } $result = $fac->generateDocument($regenerate ? $regenerate : $fac->model_pdf, $outputlangs); } else { if ($usestdout) { - print "PDF for invoice ".$obj->ref." already exists\n"; + print "PDF for document ".$obj->ref." already exists\n"; } } @@ -235,9 +256,9 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte if ($result <= 0) { $error++; if ($usestdout) { - print "Error: Failed to build PDF for invoice ".($fac->ref ? $fac->ref : ' id '.$obj->rowid)."\n"; + print "Error: Failed to build PDF for document ".($fac->ref ? $fac->ref : ' id '.$obj->rowid)."\n"; } else { - dol_syslog("Failed to build PDF for invoice ".($fac->ref ? $fac->ref : ' id '.$obj->rowid), LOG_ERR); + dol_syslog("Failed to build PDF for document ".($fac->ref ? $fac->ref : ' id '.$obj->rowid), LOG_ERR); } } diff --git a/scripts/invoices/rebuild_merge_pdf.php b/scripts/invoices/rebuild_merge_pdf.php index d493ddb8aad..277418f7a99 100755 --- a/scripts/invoices/rebuild_merge_pdf.php +++ b/scripts/invoices/rebuild_merge_pdf.php @@ -43,10 +43,9 @@ if (substr($sapi_type, 0, 3) == 'cgi') { require_once $path."../../htdocs/master.inc.php"; require_once DOL_DOCUMENT_ROOT.'/core/lib/functionscli.lib.php'; // After this $db is an opened handler to database. We close it at end of file. -require_once DOL_DOCUMENT_ROOT."/compta/facture/class/facture.class.php"; -require_once DOL_DOCUMENT_ROOT."/core/modules/facture/modules_facture.php"; require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"; require_once DOL_DOCUMENT_ROOT.'/core/lib/invoice2.lib.php'; + /** * @var Conf $conf * @var DoliDB $db @@ -84,14 +83,14 @@ if (!empty($dolibarr_main_db_readonly)) { } -$diroutputpdf = $conf->invoice->dir_output.'/temp'; - $newlangid = 'en_EN'; // To force a new lang id $filter = array(); $regenerate = ''; // Ask regenerate (contains name of model to use) $option = ''; $fileprefix = 'mergedpdf'; $nomerge = 0; +$mode = 'invoice'; + $dateafterdate = ''; $datebeforedate = ''; $paymentdateafter = ''; @@ -116,6 +115,13 @@ foreach ($argv as $key => $value) { print 'Use prefix for filename '.$fileprefix.".\n"; } + if (preg_match('/^mode=/i', $value)) { + $found = true; + $valarray = explode('=', $value); + $mode = $valarray[1]; + print 'Use mode '.$fileprefix.".\n"; + } + $reg = array(); if (preg_match('/^regenerate=(.*)/i', $value, $reg)) { if (!in_array($reg[1], array('', '0', 'no'))) { @@ -254,10 +260,11 @@ if (in_array('bank', $filter) && in_array('nopayment', $filter)) { exit(1); } +$diroutputpdf = 'auto'; + // Define SQL and SQL request to select invoices // Use $filter, $dateafterdate, datebeforedate, $paymentdateafter, $paymentdatebefore - -$result = rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, 1, $regenerate, $option, (string) $paymentonbankid, $thirdpartiesid, $fileprefix, $nomerge); +$result = rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filter, $dateafterdate, $datebeforedate, $paymentdateafter, $paymentdatebefore, 1, $regenerate, $option, (string) $paymentonbankid, $thirdpartiesid, $fileprefix, $nomerge, $mode); // -------------------- END OF YOUR CODE -------------------- From f81cdfbcf0ad46ab8f5a63c255c0d752f4731fb2 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 20 Dec 2024 15:38:59 +0100 Subject: [PATCH 115/185] debug rebuild_merge_pdf --- htdocs/core/lib/invoice2.lib.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/invoice2.lib.php b/htdocs/core/lib/invoice2.lib.php index e8aa401ad0e..fe0b67937fa 100644 --- a/htdocs/core/lib/invoice2.lib.php +++ b/htdocs/core/lib/invoice2.lib.php @@ -81,7 +81,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $table = "propal"; $dir_output = $conf->propal->dir_output; - $date = "date"; + $date = "datep"; if ($diroutputpdf == 'auto') { $diroutputpdf = $conf->propal->dir_output.'/temp'; @@ -107,7 +107,7 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $sqlwhere .= " f.fk_statut > 0"; $sqlwhere .= " AND f.".$db->sanitize($date)." >= '".$db->idate($dateafterdate)."'"; $sqlwhere .= " AND f.".$db->sanitize($date)." <= '".$db->idate($datebeforedate)."'"; - $sqlorder = " ORDER BY f.datef ASC"; + $sqlorder = " ORDER BY ".$db->sanitize($date)." ASC"; } // Filter for invoices only if (in_array('nopayment', $filter)) { From b9e8cbc80b44109b9ceaece3cf0db4f56c1ad4fb Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 20 Dec 2024 15:41:26 +0100 Subject: [PATCH 116/185] Doc --- scripts/invoices/rebuild_merge_pdf.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/invoices/rebuild_merge_pdf.php b/scripts/invoices/rebuild_merge_pdf.php index 277418f7a99..c636f9e129a 100755 --- a/scripts/invoices/rebuild_merge_pdf.php +++ b/scripts/invoices/rebuild_merge_pdf.php @@ -289,29 +289,29 @@ function rebuild_merge_pdf_usage() { global $script_file; - print "Rebuild PDF files for some invoices and/or merge PDF files into one.\n"; + print "Rebuild PDF files for some invoices/orders/proposals and/or merge PDF files into one.\n"; print "\n"; - print "To build/merge PDF for invoices in a date range:\n"; - print "Usage: ".$script_file." filter=date dateafter datebefore\n"; + print "To build/merge PDF for all documents, use filter=all\n"; + print "Usage: ".$script_file." mode=invoice filter=all\n"; + print "To build/merge PDF for documents in a date range:\n"; + print "Usage: ".$script_file." mode=invoice filter=date dateafter datebefore\n"; print "To build/merge PDF for invoices with at least one payment in a date range:\n"; - print "Usage: ".$script_file." filter=payments dateafter datebefore\n"; + print "Usage: ".$script_file." mode=invoice filter=payments dateafter datebefore\n"; print "To build/merge PDF for invoices with at least one payment onto a bank account:\n"; - print "Usage: ".$script_file." filter=bank bankref\n"; - print "To build/merge PDF for all invoices, use filter=all\n"; - print "Usage: ".$script_file." filter=all\n"; + print "Usage: ".$script_file." mode=invoice filter=bank bankref\n"; print "To build/merge PDF for invoices with no payments, use filter=nopayment\n"; - print "Usage: ".$script_file." filter=nopayment\n"; + print "Usage: ".$script_file." mode=invoice filter=nopayment\n"; print "To exclude credit notes, use filter=nocreditnote\n"; print "To exclude replacement invoices, use filter=noreplacement\n"; print "To exclude deposit invoices, use filter=nodeposit\n"; print "To exclude some thirdparties, use filter=excludethirdparties id1,id2...\n"; print "To limit to some thirdparties, use filter=onlythirdparties id1,id2...\n"; print "To regenerate existing PDF, use regenerate=templatename or regeneratenomerge=templatename\n"; - print "To generate invoices in a language, use lang=xx_XX\n"; + print "To generate documents in a given language, use lang=xx_XX\n"; print "To set prefix of generated file name, use prefix=myfileprefix\n"; print "\n"; - print "Example: ".$script_file." filter=payments 20080101 20081231 lang=fr_FR regenerate=crabe\n"; - print "Example: ".$script_file." filter=all lang=en_US\n"; + print "Example: ".$script_file." mode=invoice filter=payments 20080101 20081231 lang=fr_FR regenerate=crabe\n"; + print "Example: ".$script_file." mode=invoice filter=all lang=en_US\n"; print "\n"; print "Note that some filters can be cumulated.\n"; } From 3cefab32d51e66cea31f97e60341a0bb58906573 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Fri, 20 Dec 2024 15:57:51 +0100 Subject: [PATCH 117/185] Debug for shipment --- htdocs/core/lib/invoice2.lib.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/htdocs/core/lib/invoice2.lib.php b/htdocs/core/lib/invoice2.lib.php index fe0b67937fa..98566c95d51 100644 --- a/htdocs/core/lib/invoice2.lib.php +++ b/htdocs/core/lib/invoice2.lib.php @@ -86,6 +86,17 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte if ($diroutputpdf == 'auto') { $diroutputpdf = $conf->propal->dir_output.'/temp'; } + } elseif ($mode == 'shipment') { + require_once DOL_DOCUMENT_ROOT."/expedition/class/expedition.class.php"; + require_once DOL_DOCUMENT_ROOT."/core/modules/expedition/modules_expedition.php"; + + $table = "propal"; + $dir_output = $conf->shipment->dir_output; + $date = "date"; + + if ($diroutputpdf == 'auto') { + $diroutputpdf = $conf->shipment->dir_output.'/temp'; + } } else { print "Bad value for mode"; return -1; @@ -226,6 +237,8 @@ function rebuild_merge_pdf($db, $langs, $conf, $diroutputpdf, $newlangid, $filte $fac = new Commande($db); } elseif ($mode == 'proposal') { $fac = new Propal($db); + } elseif ($mode == 'shipment') { + $fac = new Expedition($db); } $result = $fac->fetch($obj->rowid); From 4f439bd7355dc5c8a65af93dca1e9604d8ea1ff3 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Sat, 21 Dec 2024 07:09:14 +0100 Subject: [PATCH 118/185] FIX #32408 Dict - module Event organisation is stable now --- htdocs/admin/dict.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index d40c143e0ed..d5492e16956 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -8,7 +8,7 @@ * Copyright (C) 2011 Remy Younes * Copyright (C) 2012-2015 Marcos García * Copyright (C) 2012 Christophe Battarel - * Copyright (C) 2011-2023 Alexandre Spangaro + * Copyright (C) 2011-2024 Alexandre Spangaro * Copyright (C) 2015 Ferran Marcet * Copyright (C) 2016 Raphaël Doursenaud * Copyright (C) 2019-2022 Frédéric France @@ -711,10 +711,8 @@ if ($id == DICT_TYPE_CONTACT) { 'supplier_proposal' => img_picto('', 'supplier_proposal', 'class="pictofixedwidth"').$langs->trans('SupplierProposal'), 'order_supplier' => img_picto('', 'supplier_order', 'class="pictofixedwidth"').$langs->trans('SupplierOrder'), 'invoice_supplier' => img_picto('', 'supplier_invoice', 'class="pictofixedwidth"').$langs->trans('SupplierBill'), + 'conferenceorbooth' => img_picto('', 'eventorganization', 'class="pictofixedwidth"').$langs->trans('ConferenceOrBooth'), ); - if (getDolGlobalString('MAIN_FEATURES_LEVEL') && getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { - $elementList['conferenceorbooth'] = img_picto('', 'eventorganization', 'class="pictofixedwidth"').$langs->trans('ConferenceOrBooth'); - } complete_elementList_with_modules($elementList); From 76194aca11d0ebe552aae3281e4504a3f03eb7d6 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Sun, 22 Dec 2024 07:20:36 +0100 Subject: [PATCH 119/185] FIX GETPOST "$check" parameter can't be empty --- htdocs/adherents/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index a7942735250..ab5fe37bff3 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -1299,7 +1299,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) { // EMail print '
'.(getDolGlobalString("ADHERENT_MAIL_REQUIRED") ? '' : '').$langs->trans("EMail").(getDolGlobalString("ADHERENT_MAIL_REQUIRED") ? '' : '').''.img_picto('', 'object_email', 'class="pictofixedwidth"').'email).'">
'.img_picto('', 'object_email', 'class="pictofixedwidth"').'email).'">
'.$form->editfieldkey('Web', 'member_url', GETPOST('member_url', 'alpha'), $object, 0).'
'; - $out .= ''; + $out .= '
'.($showunitprice ? $langs->trans("Price").' '.$langs->trans("HT") : '').'
'; + $out .= ''; $out .= ''; $out .= ''; $out .= ''; @@ -1142,7 +1142,7 @@ class ProductFournisseur extends Product $out .= ''; $out .= ''; $out .= ''; - $out .= ''; + $out .= ''; } $out .= '
'.($showunitprice ? $langs->trans("Price").' '.$langs->trans("HT") : '').''.($showunitprice ? $langs->trans("QtyMin") : '').''.$langs->trans("Supplier").''.$langs->trans("SupplierRef").'
'.($showunitprice ? price($productFourn->fourn_unitprice * (1 - $productFourn->fourn_remise_percent / 100) - $productFourn->fourn_remise) : '').''.($showunitprice ? $productFourn->fourn_qty : '').''.$productFourn->getSocNomUrl(1, 'supplier', $maxlen, $notooltip).''.$productFourn->fourn_ref.'
'.dolPrintHTML($productFourn->fourn_ref).'
'; } else { diff --git a/htdocs/product/list.php b/htdocs/product/list.php index 287e00cd4c9..895e804968e 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -2033,7 +2033,7 @@ while ($i < $imaxinloop) { } } - // Number of buy prices + // Number of buy prices - Vendor prices if (!empty($arrayfields['p.numbuyprice']['checked'])) { print '
'; if ($product_static->status_buy && $usercancreadprice) { From d4edb471a8449e8579f14a9c5a669b9cef47e328 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Tue, 24 Dec 2024 11:57:59 +0100 Subject: [PATCH 139/185] fix: warning in monthly agenda when user have no color and AGENDA_NO_TRANSPARENT_ON_NOT_BUSY=1 --- htdocs/comm/action/index.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 6f24008c7ad..44f51e14b30 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -1965,9 +1965,14 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa $nextindextouse++; // Prepare to use next color } } - //print '|'.($color).'='.($idusertouse?$idusertouse:0).'='.$colorindex.'
'; - // Define color // @suppress-next-line PhanPluginPrintfIncompatibleArgumentType - $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]); + if (isset($theme_datacolor[$colorindex])) { + $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]); + } elseif (!empty(getDolGlobalString('THEME_ELDY_BACKBODY'))) { + require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; + $color = colorArrayToHex(explode(',', getDolGlobalString('THEME_ELDY_BACKBODY'))); + } else { + $color = "ffffff"; + } } $cssclass = $cssclass.' eventday_'.$ymd; @@ -2339,7 +2344,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa function dol_color_minus($color, $minus, $minusunit = 16) { $newcolor = $color; - if ($minusunit == 16) { + if ($minusunit == 16 && is_array($newcolor)) { $newcolor[0] = dechex(max(min(hexdec($newcolor[0]) - $minus, 15), 0)); $newcolor[2] = dechex(max(min(hexdec($newcolor[2]) - $minus, 15), 0)); $newcolor[4] = dechex(max(min(hexdec($newcolor[4]) - $minus, 15), 0)); From c4255f6a8c7c24203212491bf3fbf9608a6a8697 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Tue, 24 Dec 2024 12:58:46 +0100 Subject: [PATCH 140/185] fix: warning in monthly agenda when user have no color and AGENDA_NO_TRANSPARENT_ON_NOT_BUSY=1 --- htdocs/comm/action/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 44f51e14b30..eb47132692b 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -1967,7 +1967,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa } if (isset($theme_datacolor[$colorindex])) { $color = sprintf("%02x%02x%02x", $theme_datacolor[$colorindex][0], $theme_datacolor[$colorindex][1], $theme_datacolor[$colorindex][2]); - } elseif (!empty(getDolGlobalString('THEME_ELDY_BACKBODY'))) { + } elseif (getDolGlobalString('THEME_ELDY_BACKBODY')) { require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; $color = colorArrayToHex(explode(',', getDolGlobalString('THEME_ELDY_BACKBODY'))); } else { From 3571e645468a8d8410024756801f9aab6f68d70b Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Tue, 24 Dec 2024 16:02:43 +0100 Subject: [PATCH 141/185] fix: warning undefined var --- htdocs/comm/action/card.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/comm/action/card.php b/htdocs/comm/action/card.php index 30c71c6e01a..7f7da4ee7c7 100644 --- a/htdocs/comm/action/card.php +++ b/htdocs/comm/action/card.php @@ -123,6 +123,7 @@ $formactions = new FormActions($db); // Load object if ($id > 0 && $action != 'add') { $ret = $object->fetch($id); + $ret1 = 0; if ($ret > 0) { $ret = $object->fetch_optionals(); $ret1 = $object->fetch_userassigned(); From 0d94d67cc2b00a9ff65889331848fc16a5103602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20France?= Date: Wed, 25 Dec 2024 10:19:53 +0100 Subject: [PATCH 142/185] fix phpstan --- build/phpstan/phpstan-baseline.neon | 42 ------------------- .../facture/class/facture-rec.class.php | 14 +++---- htdocs/compta/facture/class/facture.class.php | 26 ++++++------ 3 files changed, 20 insertions(+), 62 deletions(-) diff --git a/build/phpstan/phpstan-baseline.neon b/build/phpstan/phpstan-baseline.neon index 5a23163c6d9..a3ec7716200 100644 --- a/build/phpstan/phpstan-baseline.neon +++ b/build/phpstan/phpstan-baseline.neon @@ -5592,12 +5592,6 @@ parameters: count: 3 path: ../../htdocs/compta/facture/class/facture-rec.class.php - - - message: '#^Parameter \#1 \$qty of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/compta/facture/class/facture-rec.class.php - - message: '#^Parameter \#1 \$vatrate of function getLocalTaxesFromRate expects int\|string, float given\.$#' identifier: argument.type @@ -5610,12 +5604,6 @@ parameters: count: 1 path: ../../htdocs/compta/facture/class/facture-rec.class.php - - - message: '#^Parameter \#2 \$pu of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/compta/facture/class/facture-rec.class.php - - message: '#^Property CommonObject\:\:\$array_options \(array\\) in isset\(\) is not nullable\.$#' identifier: isset.property @@ -5670,12 +5658,6 @@ parameters: count: 3 path: ../../htdocs/compta/facture/class/facture.class.php - - - message: '#^Parameter \#1 \$qty of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 2 - path: ../../htdocs/compta/facture/class/facture.class.php - - message: '#^Parameter \#1 \$substitutionarray of function complete_substitutions_array expects array\, array\ given\.$#' identifier: argument.type @@ -5688,42 +5670,18 @@ parameters: count: 2 path: ../../htdocs/compta/facture/class/facture.class.php - - - message: '#^Parameter \#15 \$pu_devise of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 2 - path: ../../htdocs/compta/facture/class/facture.class.php - - message: '#^Parameter \#2 \$alreadypaid of method CommonInvoice\:\:getLibStatut\(\) expects int, float given\.$#' identifier: argument.type count: 1 path: ../../htdocs/compta/facture/class/facture.class.php - - - message: '#^Parameter \#2 \$pu of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 2 - path: ../../htdocs/compta/facture/class/facture.class.php - - message: '#^Parameter \#4 \$txtva of method Facture\:\:addline\(\) expects float, string given\.$#' identifier: argument.type count: 1 path: ../../htdocs/compta/facture/class/facture.class.php - - - message: '#^Parameter \#5 \$uselocaltax1_rate of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/compta/facture/class/facture.class.php - - - - message: '#^Parameter \#6 \$uselocaltax2_rate of function calcul_price_total expects float, string given\.$#' - identifier: argument.type - count: 1 - path: ../../htdocs/compta/facture/class/facture.class.php - - message: '#^Property CommonInvoice\:\:\$close_code \(string\) in isset\(\) is not nullable\.$#' identifier: isset.property diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 056d34018fc..f011ecc05ab 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -975,14 +975,14 @@ class FactureRec extends CommonInvoice if (empty($remise_percent)) { $remise_percent = 0; } - $qty = price2num($qty); - $pu_ht = price2num($pu_ht); - $pu_ttc = price2num($pu_ttc); + $qty = (float) price2num($qty); + $pu_ht = (float) price2num($pu_ht); + $pu_ttc = (float) price2num($pu_ttc); if (!preg_match('/\((.*)\)/', $txtva)) { $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' } - $txlocaltax1 = price2num($txlocaltax1); - $txlocaltax2 = price2num($txlocaltax2); + $txlocaltax1 = (float) price2num($txlocaltax1); + $txlocaltax2 = (float) price2num($txlocaltax2); if (empty($txtva)) { $txtva = 0; } @@ -1183,8 +1183,8 @@ class FactureRec extends CommonInvoice if (!preg_match('/\((.*)\)/', (string) $txtva)) { $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' } - $txlocaltax1 = price2num($txlocaltax1); - $txlocaltax2 = price2num($txlocaltax2); + $txlocaltax1 = (float) price2num($txlocaltax1); + $txlocaltax2 = (float) price2num($txlocaltax2); if (empty($txlocaltax1)) { $txlocaltax1 = 0; } diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 3ccd5441aa1..0d1435fa918 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -3946,16 +3946,16 @@ class Facture extends CommonInvoice } $remise_percent = (float) price2num($remise_percent); - $qty = price2num($qty); - $pu_ht = price2num($pu_ht); - $pu_ht_devise = price2num($pu_ht_devise); - $pu_ttc = price2num($pu_ttc); - $pa_ht = price2num($pa_ht); + $qty = (float) price2num($qty); + $pu_ht = (float) price2num($pu_ht); + $pu_ht_devise = (float) price2num($pu_ht_devise); + $pu_ttc = (float) price2num($pu_ttc); + $pa_ht = (float) price2num($pa_ht); if (!preg_match('/\((.*)\)/', (string) $txtva)) { $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' } - $txlocaltax1 = price2num($txlocaltax1); - $txlocaltax2 = price2num($txlocaltax2); + $txlocaltax1 = (float) price2num($txlocaltax1); + $txlocaltax2 = (float) price2num($txlocaltax2); if ($price_base_type == 'HT') { $pu = $pu_ht; @@ -4208,15 +4208,15 @@ class Facture extends CommonInvoice } $remise_percent = (float) price2num($remise_percent); - $qty = price2num($qty); - $pu = price2num($pu); - $pu_ht_devise = price2num($pu_ht_devise); - $pa_ht = price2num($pa_ht); + $qty = (float) price2num($qty); + $pu = (float) price2num($pu); + $pu_ht_devise = (float) price2num($pu_ht_devise); + $pa_ht = (float) price2num($pa_ht); if (!preg_match('/\((.*)\)/', (string) $txtva)) { $txtva = price2num($txtva); // $txtva can have format '5.0(XXX)' or '5' } - $txlocaltax1 = (float) price2num($txlocaltax1); - $txlocaltax2 = (float) price2num($txlocaltax2); + $txlocaltax1 = (float) price2num($txlocaltax1); + $txlocaltax2 = (float) price2num($txlocaltax2); // Check parameters if ($type < 0) { From 3eacf583db55b9ef476ab9b17d03fcfee4b73a77 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Thu, 26 Dec 2024 11:38:38 +0100 Subject: [PATCH 143/185] FIX #32467 --- htdocs/core/class/doleditor.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index b8f63e352fc..302e60bfc9b 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -160,6 +160,8 @@ class DolEditor $found = 0; $out = ''; + $this->content = ($this->content ?? ''); // to avoid htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated + if (in_array($this->tool, array('textarea', 'ckeditor'))) { $found = 1; //$out.= '
'; print '
'; -print img_picto('', 'globe-americas', 'class="pictofixedwidth"'); -print $form->select_country($mysoc->country_id, 'country_id', '', 0); -if ($user->admin) { - print info_admin($langs->trans("YouCanChangeValuesForThisListFromDictionarySetup"), 1); -} -print '
'; $state_id = 0; if (getDolGlobalString('MAIN_INFO_SOCIETE_STATE')) { @@ -487,12 +494,6 @@ print img_picto('', 'state', 'class="pictofixedwidth"'); print $formcompany->select_state($state_id, $mysoc->country_code, 'state_id', 'maxwidth200onsmartphone minwidth300'); print '
'; -print img_picto('', 'multicurrency', 'class="pictofixedwidth"'); -print $form->selectCurrency($conf->currency, "currency"); -print '
'; print img_picto('', 'object_phoning', '', 0, 0, 0, '', 'pictofixedwidth'); @@ -604,6 +605,16 @@ if ($mysoc->country_code) { } print '
'; +print '
'; +print ''; +print '
'; @@ -714,16 +725,6 @@ if ($langs->transcountry("ProfId10", $mysoc->country_code) != '-') { print '
'; -print ''; -print '
'; -print '
'; print '
'; From 472809c7a8f9b7740b969731e9160aafd9f25eef Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Sat, 28 Dec 2024 17:38:05 +0100 Subject: [PATCH 158/185] Code comment --- htdocs/core/js/lib_head.js.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/js/lib_head.js.php b/htdocs/core/js/lib_head.js.php index b498bc3fdbb..3d1814a97ba 100644 --- a/htdocs/core/js/lib_head.js.php +++ b/htdocs/core/js/lib_head.js.php @@ -1040,11 +1040,11 @@ function document_preview(file, type, title) }; img.src = file; - } + /* This function is local to document_preview. Variables like file, type, title, object_width and object_height are global inside this function */ function show_preview(mode) { - /* console.log("mode="+mode+" file="+file+" type="+type+" width="+width+" height="+height); */ + /* console.log("mode="+mode+" file="+file+" type="+type+" title=title+" width="+width+" height="+height); */ var newElem = ''; optionsbuttons = {} From 754ffee0e98d1914ad1ed09af635631c3e543177 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Sat, 28 Dec 2024 17:43:41 +0100 Subject: [PATCH 159/185] Better fix for quote injection into URL or js popup title. To report into PR #30915 too. --- htdocs/core/lib/functions.lib.php | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index ccef917b658..4ca014f9be4 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1806,6 +1806,20 @@ function dol_escape_js($stringtoescape, $mode = 0, $noescapebackslashn = 0) return strtr($stringtoescape, $substitjs); } +/** + * Returns text escaped by RFC 3986 for inclusion into a clicable link. + * This method can be used on the ...in links like href="javascript:..." because when clicking on such links, the browserfirst decode the strind + * and then interpret content that can be javascript. + * Usage of this escapement should be limited to links href="javascript:...". For common URL, use urlencode instead. + * + * @param string $stringtoescape String to escape + * @return string Escaped string. + */ +function dol_escape_uri($stringtoescape) +{ + return rawurlencode($stringtoescape); +} + /** * Returns text escaped for inclusion into javascript code * @@ -11593,12 +11607,13 @@ function getAdvancedPreviewUrl($modulepart, $relativepath, $alldata = 0, $param if ($isAllowedForPreview) { $tmpurl = DOL_URL_ROOT.'/document.php?modulepart='.urlencode($modulepart).'&attachment=0&file='.urlencode($relativepath).($param ? '&'.$param : ''); $title = $langs->transnoentities("Preview"); - //$title = '%27-alert(document.domain)-%27'; - //$tmpurl = 'file='.urlencode("'-alert(document.domain)-'_small.jpg"); + //$title = '%27-alert(document.domain)-%27'; // An example of js injection into a corrupted title string, that should be blocked by the dol_escape_uri(). + //$tmpurl = 'file='.urlencode("'-alert(document.domain)-'_small.jpg"); // An example of tmpurl that should be blocked by the dol_escape_uri() - // We need to urlencode the parameter after the dol_escape_js($tmpurl) because $tmpurl may contain n url with param file=abc%27def if file has a ' inside. - // and when we click on href with this javascript string, a urlcode is done by browser, converted the %27 of file param - return 'javascript:document_preview(\''.urlencode(dol_escape_js($tmpurl)).'\', \''.urlencode(dol_mimetype($relativepath)).'\', \''.urlencode(dol_escape_js($title)).'\')'; + // We need to do a dol_escape_uri() on the full string after the javascript: because such parts are the URI and when we click on such links, a RFC3986 decode is done, + // by the browser, converting the %27 (like when having param file=abc%27def), or when having a corrupted title), into a ', BEFORE interpreting the content that can be a js code. + // Using the dol_escape_uri guarantee that we encode for URI so decode retrieve original expected value. + return 'javascript:'.dol_escape_uri('document_preview(\''.dol_escape_js($tmpurl).'\', \''.dol_escape_js(dol_mimetype($relativepath)).'\', \''.dol_escape_js($title).'\')'); } else { return ''; } From 130b01befec84a7df790f4a12a70c4e8de698836 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Sun, 29 Dec 2024 17:12:50 +0100 Subject: [PATCH 160/185] FIX #32479 --- htdocs/core/class/html.formprojet.class.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/core/class/html.formprojet.class.php b/htdocs/core/class/html.formprojet.class.php index fe15a87d323..f817c7b98bb 100644 --- a/htdocs/core/class/html.formprojet.class.php +++ b/htdocs/core/class/html.formprojet.class.php @@ -102,7 +102,7 @@ class FormProjets extends Form $placeholder = ''; if ($selected && empty($selected_input_value)) { - require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php'; + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $project = new Project($this->db); $project->fetch($selected); $selected_input_value = $project->ref; @@ -160,7 +160,7 @@ class FormProjets extends Form // phpcs:enable global $user, $conf, $langs; - require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php'; + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; if (empty($htmlid)) { $htmlid = $htmlname; @@ -350,7 +350,7 @@ class FormProjets extends Form { global $user, $conf, $langs; - require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php'; + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; if (is_null($usertofilter)) { $usertofilter = $user; @@ -796,10 +796,12 @@ class FormProjets extends Form '2' => '2', ); + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $tmpproject = new Project($this->db); foreach ($statustohow as $key => $value) { - $tmpproject->statut = $key; + $tmpproject->statut = $key; // deprecated + $tmpproject->status = $key; $options[$value] = $tmpproject->getLibStatut($short); } From 691b542b4d558c87357e7bc1f09f6e1604fe20b3 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Sun, 29 Dec 2024 19:45:13 +0100 Subject: [PATCH 161/185] Debug v21 --- htdocs/comm/mailing/card.php | 12 ++++++------ htdocs/core/class/doleditor.class.php | 13 +++++++++---- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php index 933308581b8..b36538b2a68 100644 --- a/htdocs/comm/mailing/card.php +++ b/htdocs/comm/mailing/card.php @@ -889,7 +889,7 @@ if ($action == 'create') { // aaa print '
'; // wysiwyg editor require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('bodyemail', GETPOST('bodyemail', 'restricthtmlallowunvalid'), '', 600, 'dolibarr_mailings', '', true, true, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%'); + $doleditor = new DolEditor('bodyemail', GETPOST('bodyemail', 'restricthtmlallowunvalid'), '', 600, 'dolibarr_mailings', '', true, -1, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%'); $doleditor->Create(); print '
'; @@ -1174,7 +1174,7 @@ if ($action == 'create') { // aaa } if (($object->status == 0 || $object->status == 1 || $object->status == 2) && $user->hasRight('mailing', 'creer')) { - if (isModEnabled('fckeditor') && getDolGlobalString('FCKEDITOR_ENABLE_MAILING') && $object->messtype != 'sms') { + if (isModEnabled('fckeditor') && getDolGlobalInt('FCKEDITOR_ENABLE_MAILING') && $object->messtype != 'sms') { print ''.$langs->trans("Edit").''; } else { print ''.$langs->trans("EditWithTextEditor").''; @@ -1329,7 +1329,7 @@ if ($action == 'create') { // aaa $readonly = 1; // wysiwyg editor require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', false, true, !getDolGlobalString('FCKEDITOR_ENABLE_MAILING') ? 0 : 1, 20, '90%', $readonly); + $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', false, -1, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%', $readonly); $doleditor->Create(); } else { print dol_htmlentitiesbr($object->body); @@ -1548,19 +1548,19 @@ if ($action == 'create') { // aaa if ($action == 'edit') { // wysiwyg editor require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, true, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%'); + $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, -1, getDolGlobalInt('FCKEDITOR_ENABLE_MAILING'), 20, '90%'); $doleditor->Create(); } if ($action == 'edittxt') { // wysiwyg editor require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, true, 0, 20, '90%'); + $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, -1, 0, 20, '90%'); $doleditor->Create(); } if ($action == 'edithtml') { // HTML source editor require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, true, 'ace', 20, '90%'); + $doleditor = new DolEditor('bodyemail', $object->body, '', 600, 'dolibarr_mailings', '', true, -1, 'ace', 20, '90%'); $doleditor->Create(0, '', false, 'HTML Source', 'php'); } diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index 567c8240077..8f2c9faf506 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -100,10 +100,10 @@ class DolEditor * @param string $content Content of WYSIWYG field * @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 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 the toolbar set to use ('dolibarr_details[_encoded]'=the less featured, 'dolibarr_notes[_encoded]' for notes content, 'dolibarr_mailings[_encoded]' for emailing content, 'dolibarr_readonly'). * @param string $toolbarlocation Deprecated. Not used * @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 a local media filemanager. If false, only external images URL can be added into content, or images saved inline with src="data:..." with a cut/paste. * @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". * @param int $rows Size of rows for textarea tool @@ -112,11 +112,16 @@ class DolEditor * @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 */ - public function __construct($htmlname, $content, $width = '', $height = 200, $toolbarname = 'Basic', $toolbarlocation = 'In', $toolbarstartexpanded = false, $uselocalbrowser = 1, $okforextendededitor = true, $rows = 0, $cols = '', $readonly = 0, $poscursor = array()) + public function __construct($htmlname, $content, $width = '', $height = 200, $toolbarname = 'Basic', $toolbarlocation = 'In', $toolbarstartexpanded = false, $uselocalbrowser = -1, $okforextendededitor = true, $rows = 0, $cols = '', $readonly = 0, $poscursor = array()) { global $conf; - dol_syslog(get_class($this)."::DolEditor htmlname=".$htmlname." width=".$width." height=".$height." toolbarname=".$toolbarname); + dol_syslog(get_class($this)."::DolEditor htmlname=".$htmlname." width=".$width." height=".$height." toolbarname=".$toolbarname." uselocalbrowser=".$uselocalbrowser); + + if ($uselocalbrowser === -1) { + // This may not be supported by new generation of WYSIWYG editors. + $uselocalbrowser = getDolGlobalInt("WYSIWYG_ALLOW_UPLOAD_MEDIA_FILES"); + } if (!$rows) { $rows = round($height / 20); From 90c2c18ce084347ae14c6c6882f358e1857acd6f Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Sun, 29 Dec 2024 20:14:21 +0100 Subject: [PATCH 162/185] Debug v21 --- htdocs/core/lib/website2.lib.php | 35 +++++++----------- .../LICENSE | 0 .../README.md | 0 .../containers/.dolibarr | 0 .../containers/.htaccess | 0 .../containers/htmlheader.html | 1 - .../containers/javascript.js.php | 0 .../containers/manifest.json.php | 0 .../containers/robots.txt | 0 .../containers/styles.css.php | 0 .../containers/wrapper.php | 0 .../medias/image/websitekey/article.png | Bin .../medias/image/websitekey/bg.png | Bin .../medias/image/websitekey/happy-man.png | Bin .../website_pages.sql | 0 .../LICENSE | 0 .../README.md | 0 .../containers/.dolibarr | 0 .../containers/.htaccess | 0 .../containers/htmlheader.html | 1 - .../containers/javascript.js.php | 0 .../containers/manifest.json.php | 0 .../containers/robots.txt | 0 .../containers/styles.css.php | 0 .../containers/wrapper.php | 0 .../website_pages.sql | 0 .../LICENSE | 0 .../README.md | 0 .../containers/.dolibarr | 0 .../containers/.htaccess | 0 .../containers/htmlheader.html | 1 - .../containers/javascript.js.php | 0 .../containers/manifest.json.php | 0 .../containers/robots.txt | 0 .../containers/styles.css.php | 0 .../containers/wrapper.php | 0 .../alex-haney-CAhjZmVk5H4-unsplash.jpg | Bin .../brett-jordan-8xt8-HIFqc8-unsplash.jpg | Bin .../louis-hansel-dphM2U1xq0U-unsplash.jpg | Bin .../lucas-swennen-1W_MyJSRLuQ-unsplash.jpg | Bin .../luisa-brimble-aFzg83dvnAI-unsplash.jpg | Bin ...riscilla-du-preez-W3SEyZODn8U-unsplash.jpg | Bin .../rod-long-I79Pgmhmy5M-unsplash.jpg | Bin .../charles-deluvio-FdDkfYFHqe4-unsplash.jpg | Bin .../daan-evers-tKN1WXrzQ3s-unsplash.jpg | Bin ...arhad-ibrahimzade-ZipYER3NLhY-unsplash.jpg | Bin ...arhad-ibrahimzade-isHUj3N0194-unsplash.jpg | Bin .../dinner/keriliwi-c3mFafsFz2w-unsplash.jpg | Bin .../briana-tozour-V_Nkf1E-vYA-unsplash.jpg | Bin .../luisa-brimble-aFzg83dvnAI-unsplash.jpg | Bin ...riscilla-du-preez-W3SEyZODn8U-unsplash.jpg | Bin .../header/rod-long-I79Pgmhmy5M-unsplash.jpg | Bin ...arhad-ibrahimzade-D5c9ZciQy_I-unsplash.jpg | Bin ...arhad-ibrahimzade-MGKqxm6u2bc-unsplash.jpg | Bin .../louis-hansel-cH5IPjaAYyo-unsplash.jpg | Bin .../louis-hansel-rheOvfxOlOA-unsplash.jpg | Bin .../ivan-torres-MQUqbmszGGM-unsplash.jpg | Bin .../jason-leung-O67LZfeyYBk-unsplash.jpg | Bin .../jay-wennington-N_Y88TWmGwA-unsplash.jpg | Bin .../website_pages.sql | 0 htdocs/website/index.php | 1 + 61 files changed, 14 insertions(+), 25 deletions(-) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/LICENSE (100%) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/README.md (100%) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/containers/.dolibarr (100%) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/containers/.htaccess (100%) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/containers/htmlheader.html (99%) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/containers/javascript.js.php (100%) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/containers/manifest.json.php (100%) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/containers/robots.txt (100%) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/containers/styles.css.php (100%) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/containers/wrapper.php (100%) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/medias/image/websitekey/article.png (100%) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/medias/image/websitekey/bg.png (100%) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/medias/image/websitekey/happy-man.png (100%) rename htdocs/install/doctemplates/websites/{website_template-homesubmenu => website_template-homesubmenu_dev}/website_pages.sql (100%) rename htdocs/install/doctemplates/websites/{website_template-noimg => website_template-noimg_dev}/LICENSE (100%) rename htdocs/install/doctemplates/websites/{website_template-noimg => website_template-noimg_dev}/README.md (100%) rename htdocs/install/doctemplates/websites/{website_template-noimg => website_template-noimg_dev}/containers/.dolibarr (100%) rename htdocs/install/doctemplates/websites/{website_template-noimg => website_template-noimg_dev}/containers/.htaccess (100%) rename htdocs/install/doctemplates/websites/{website_template-noimg => website_template-noimg_dev}/containers/htmlheader.html (99%) rename htdocs/install/doctemplates/websites/{website_template-noimg => website_template-noimg_dev}/containers/javascript.js.php (100%) rename htdocs/install/doctemplates/websites/{website_template-noimg => website_template-noimg_dev}/containers/manifest.json.php (100%) rename htdocs/install/doctemplates/websites/{website_template-noimg => website_template-noimg_dev}/containers/robots.txt (100%) rename htdocs/install/doctemplates/websites/{website_template-noimg => website_template-noimg_dev}/containers/styles.css.php (100%) rename htdocs/install/doctemplates/websites/{website_template-noimg => website_template-noimg_dev}/containers/wrapper.php (100%) rename htdocs/install/doctemplates/websites/{website_template-noimg => website_template-noimg_dev}/website_pages.sql (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/LICENSE (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/README.md (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/containers/.dolibarr (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/containers/.htaccess (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/containers/htmlheader.html (99%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/containers/javascript.js.php (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/containers/manifest.json.php (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/containers/robots.txt (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/containers/styles.css.php (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/containers/wrapper.php (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/alex-haney-CAhjZmVk5H4-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/breakfast/brett-jordan-8xt8-HIFqc8-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/breakfast/louis-hansel-dphM2U1xq0U-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/breakfast/lucas-swennen-1W_MyJSRLuQ-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/breakfast/luisa-brimble-aFzg83dvnAI-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/breakfast/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/breakfast/rod-long-I79Pgmhmy5M-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/charles-deluvio-FdDkfYFHqe4-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/daan-evers-tKN1WXrzQ3s-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/dinner/farhad-ibrahimzade-ZipYER3NLhY-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/dinner/farhad-ibrahimzade-isHUj3N0194-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/dinner/keriliwi-c3mFafsFz2w-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/header/briana-tozour-V_Nkf1E-vYA-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/header/luisa-brimble-aFzg83dvnAI-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/header/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/header/rod-long-I79Pgmhmy5M-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/lunch/farhad-ibrahimzade-D5c9ZciQy_I-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/lunch/farhad-ibrahimzade-MGKqxm6u2bc-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/lunch/louis-hansel-cH5IPjaAYyo-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/lunch/louis-hansel-rheOvfxOlOA-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/slide/ivan-torres-MQUqbmszGGM-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/slide/jason-leung-O67LZfeyYBk-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/medias/image/websitekey/slide/jay-wennington-N_Y88TWmGwA-unsplash.jpg (100%) rename htdocs/install/doctemplates/websites/{website_template-restaurant => website_template-restaurant_dev}/website_pages.sql (100%) diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index c82484fc056..adb2cec459a 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -574,16 +574,9 @@ function showWebsiteTemplates(Website $website) { global $conf, $langs, $form, $user; + // We want only one directory for dir of website templates. If an external module need to provide a template, the template must be copied into this directory + // when module is enabled. $dirthemes = array('/doctemplates/websites'); - /* - if (!empty($conf->modules_parts['websitetemplates'])) { - foreach ($conf->modules_parts['websitetemplates'] as $reldir) { - $dirthemes = array_merge($dirthemes, (array) ($reldir.'doctemplates/websites')); - } - } - */ - $dirthemes = array_unique($dirthemes); - // Now dir_themes=array('/themes') or dir_themes=array('/theme','/mymodule/theme') $colspan = 2; @@ -612,49 +605,47 @@ function showWebsiteTemplates(Website $website) if (count($dirthemes)) { $i = 0; foreach ($dirthemes as $dir) { - if (preg_match('/^\/doctemplates\//', $dir)) { - $dirtheme = DOL_DATA_ROOT.$dir; // This include loop on $conf->file->dol_document_root - } else { - $dirtheme = dol_buildpath($dir); // This include loop on $conf->file->dol_document_root - } + $dirtheme = DOL_DATA_ROOT.$dir; + if (is_dir($dirtheme)) { $handle = opendir($dirtheme); if (is_resource($handle)) { while (($subdir = readdir($handle)) !== false) { //var_dump($dirtheme.'/'.$subdir); - if (is_file($dirtheme."/".$subdir) && substr($subdir, 0, 1) != '.' && substr($subdir, 0, 3) != 'CVS' && preg_match('/\.zip$/i', $subdir)) { + if (dol_is_file($dirtheme."/".$subdir) && substr($subdir, 0, 1) != '.' && substr($subdir, 0, 3) != 'CVS' && preg_match('/\.zip$/i', $subdir)) { $subdirwithoutzip = preg_replace('/\.zip$/i', '', $subdir); + $subdirwithoutzipwithoutver = preg_replace('/(_exp|_dev)$/i', '', $subdirwithoutzip); // Disable not stable themes (dir ends with _exp or _dev) - if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2 && preg_match('/_dev$/i', $subdir)) { + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 2 && preg_match('/_dev$/i', $subdirwithoutzip)) { continue; } - if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1 && preg_match('/_exp$/i', $subdir)) { + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') < 1 && preg_match('/_exp$/i', $subdirwithoutzip)) { continue; } print '
'; $templatedir = $dirtheme."/".$subdir; - $file = $dirtheme."/".$subdirwithoutzip.".jpg"; - $url = DOL_URL_ROOT.'/viewimage.php?modulepart=doctemplateswebsite&file='.$subdirwithoutzip.".jpg"; + $file = $dirtheme."/".$subdirwithoutzipwithoutver.".jpg"; + $url = DOL_URL_ROOT.'/viewimage.php?modulepart=doctemplateswebsite&file='.$subdirwithoutzipwithoutver.".jpg"; if (!file_exists($file)) { $url = DOL_URL_ROOT.'/public/theme/common/nophoto.png'; } - $originalfile = basename($file); + $originalimgfile = basename($file); $entity = $conf->entity; $modulepart = 'doctemplateswebsite'; $cache = ''; $title = $file; $ret = ''; - $urladvanced = getAdvancedPreviewUrl($modulepart, $originalfile, 1, '&entity='.$entity); + $urladvanced = getAdvancedPreviewUrl($modulepart, $originalimgfile, 1, '&entity='.$entity); if (!empty($urladvanced)) { $ret .= ''; } else { - $ret .= ''; + $ret .= ''; } print $ret; print ''.$title.''; diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/LICENSE b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/LICENSE similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/LICENSE rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/LICENSE diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/README.md b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/README.md similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/README.md rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/README.md diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/.dolibarr b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/.dolibarr similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/.dolibarr rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/.dolibarr diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/.htaccess b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/.htaccess similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/.htaccess rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/.htaccess diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/htmlheader.html b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/htmlheader.html similarity index 99% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/htmlheader.html rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/htmlheader.html index 0de0b36283f..6511ce086fd 100644 --- a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/htmlheader.html +++ b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/htmlheader.html @@ -3,4 +3,3 @@ - diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/javascript.js.php b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/javascript.js.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/javascript.js.php rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/javascript.js.php diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/manifest.json.php b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/manifest.json.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/manifest.json.php rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/manifest.json.php diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/robots.txt b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/robots.txt similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/robots.txt rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/robots.txt diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/styles.css.php b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/styles.css.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/styles.css.php rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/styles.css.php diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/wrapper.php b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/wrapper.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/containers/wrapper.php rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/containers/wrapper.php diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/medias/image/websitekey/article.png b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/medias/image/websitekey/article.png similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/medias/image/websitekey/article.png rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/medias/image/websitekey/article.png diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/medias/image/websitekey/bg.png b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/medias/image/websitekey/bg.png similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/medias/image/websitekey/bg.png rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/medias/image/websitekey/bg.png diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/medias/image/websitekey/happy-man.png b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/medias/image/websitekey/happy-man.png similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/medias/image/websitekey/happy-man.png rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/medias/image/websitekey/happy-man.png diff --git a/htdocs/install/doctemplates/websites/website_template-homesubmenu/website_pages.sql b/htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/website_pages.sql similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-homesubmenu/website_pages.sql rename to htdocs/install/doctemplates/websites/website_template-homesubmenu_dev/website_pages.sql diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/LICENSE b/htdocs/install/doctemplates/websites/website_template-noimg_dev/LICENSE similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/LICENSE rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/LICENSE diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/README.md b/htdocs/install/doctemplates/websites/website_template-noimg_dev/README.md similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/README.md rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/README.md diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/.dolibarr b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/.dolibarr similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/.dolibarr rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/.dolibarr diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/.htaccess b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/.htaccess similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/.htaccess rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/.htaccess diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/htmlheader.html b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/htmlheader.html similarity index 99% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/htmlheader.html rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/htmlheader.html index a58ea695524..719eb1ebc61 100644 --- a/htdocs/install/doctemplates/websites/website_template-noimg/containers/htmlheader.html +++ b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/htmlheader.html @@ -3,4 +3,3 @@ --> - diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/javascript.js.php b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/javascript.js.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/javascript.js.php rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/javascript.js.php diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/manifest.json.php b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/manifest.json.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/manifest.json.php rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/manifest.json.php diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/robots.txt b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/robots.txt similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/robots.txt rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/robots.txt diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/styles.css.php b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/styles.css.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/styles.css.php rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/styles.css.php diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/containers/wrapper.php b/htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/wrapper.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/containers/wrapper.php rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/containers/wrapper.php diff --git a/htdocs/install/doctemplates/websites/website_template-noimg/website_pages.sql b/htdocs/install/doctemplates/websites/website_template-noimg_dev/website_pages.sql similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-noimg/website_pages.sql rename to htdocs/install/doctemplates/websites/website_template-noimg_dev/website_pages.sql diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/LICENSE b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/LICENSE similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/LICENSE rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/LICENSE diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/README.md b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/README.md similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/README.md rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/README.md diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/.dolibarr b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/.dolibarr similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/.dolibarr rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/.dolibarr diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/.htaccess b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/.htaccess similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/.htaccess rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/.htaccess diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/htmlheader.html b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/htmlheader.html similarity index 99% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/htmlheader.html rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/htmlheader.html index 41e782b5934..94c8271c490 100644 --- a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/htmlheader.html +++ b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/htmlheader.html @@ -3,4 +3,3 @@ - diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/javascript.js.php b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/javascript.js.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/javascript.js.php rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/javascript.js.php diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/manifest.json.php b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/manifest.json.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/manifest.json.php rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/manifest.json.php diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/robots.txt b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/robots.txt similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/robots.txt rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/robots.txt diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/styles.css.php b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/styles.css.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/styles.css.php rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/styles.css.php diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/containers/wrapper.php b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/wrapper.php similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/containers/wrapper.php rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/containers/wrapper.php diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/alex-haney-CAhjZmVk5H4-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/alex-haney-CAhjZmVk5H4-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/alex-haney-CAhjZmVk5H4-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/alex-haney-CAhjZmVk5H4-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/brett-jordan-8xt8-HIFqc8-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/brett-jordan-8xt8-HIFqc8-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/brett-jordan-8xt8-HIFqc8-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/brett-jordan-8xt8-HIFqc8-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/louis-hansel-dphM2U1xq0U-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/louis-hansel-dphM2U1xq0U-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/louis-hansel-dphM2U1xq0U-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/louis-hansel-dphM2U1xq0U-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/lucas-swennen-1W_MyJSRLuQ-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/lucas-swennen-1W_MyJSRLuQ-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/lucas-swennen-1W_MyJSRLuQ-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/lucas-swennen-1W_MyJSRLuQ-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/luisa-brimble-aFzg83dvnAI-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/luisa-brimble-aFzg83dvnAI-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/luisa-brimble-aFzg83dvnAI-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/luisa-brimble-aFzg83dvnAI-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/rod-long-I79Pgmhmy5M-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/rod-long-I79Pgmhmy5M-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/breakfast/rod-long-I79Pgmhmy5M-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/breakfast/rod-long-I79Pgmhmy5M-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/charles-deluvio-FdDkfYFHqe4-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/charles-deluvio-FdDkfYFHqe4-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/charles-deluvio-FdDkfYFHqe4-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/charles-deluvio-FdDkfYFHqe4-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/daan-evers-tKN1WXrzQ3s-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/daan-evers-tKN1WXrzQ3s-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/daan-evers-tKN1WXrzQ3s-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/daan-evers-tKN1WXrzQ3s-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/dinner/farhad-ibrahimzade-ZipYER3NLhY-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/dinner/farhad-ibrahimzade-ZipYER3NLhY-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/dinner/farhad-ibrahimzade-ZipYER3NLhY-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/dinner/farhad-ibrahimzade-ZipYER3NLhY-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/dinner/farhad-ibrahimzade-isHUj3N0194-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/dinner/farhad-ibrahimzade-isHUj3N0194-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/dinner/farhad-ibrahimzade-isHUj3N0194-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/dinner/farhad-ibrahimzade-isHUj3N0194-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/dinner/keriliwi-c3mFafsFz2w-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/dinner/keriliwi-c3mFafsFz2w-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/dinner/keriliwi-c3mFafsFz2w-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/dinner/keriliwi-c3mFafsFz2w-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/briana-tozour-V_Nkf1E-vYA-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/briana-tozour-V_Nkf1E-vYA-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/briana-tozour-V_Nkf1E-vYA-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/briana-tozour-V_Nkf1E-vYA-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/luisa-brimble-aFzg83dvnAI-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/luisa-brimble-aFzg83dvnAI-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/luisa-brimble-aFzg83dvnAI-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/luisa-brimble-aFzg83dvnAI-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/priscilla-du-preez-W3SEyZODn8U-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/rod-long-I79Pgmhmy5M-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/rod-long-I79Pgmhmy5M-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/header/rod-long-I79Pgmhmy5M-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/header/rod-long-I79Pgmhmy5M-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/farhad-ibrahimzade-D5c9ZciQy_I-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/farhad-ibrahimzade-D5c9ZciQy_I-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/farhad-ibrahimzade-D5c9ZciQy_I-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/farhad-ibrahimzade-D5c9ZciQy_I-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/farhad-ibrahimzade-MGKqxm6u2bc-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/farhad-ibrahimzade-MGKqxm6u2bc-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/farhad-ibrahimzade-MGKqxm6u2bc-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/farhad-ibrahimzade-MGKqxm6u2bc-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/louis-hansel-cH5IPjaAYyo-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/louis-hansel-cH5IPjaAYyo-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/louis-hansel-cH5IPjaAYyo-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/louis-hansel-cH5IPjaAYyo-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/louis-hansel-rheOvfxOlOA-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/louis-hansel-rheOvfxOlOA-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/lunch/louis-hansel-rheOvfxOlOA-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/lunch/louis-hansel-rheOvfxOlOA-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/slide/ivan-torres-MQUqbmszGGM-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/slide/ivan-torres-MQUqbmszGGM-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/slide/ivan-torres-MQUqbmszGGM-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/slide/ivan-torres-MQUqbmszGGM-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/slide/jason-leung-O67LZfeyYBk-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/slide/jason-leung-O67LZfeyYBk-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/slide/jason-leung-O67LZfeyYBk-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/slide/jason-leung-O67LZfeyYBk-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/slide/jay-wennington-N_Y88TWmGwA-unsplash.jpg b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/slide/jay-wennington-N_Y88TWmGwA-unsplash.jpg similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/medias/image/websitekey/slide/jay-wennington-N_Y88TWmGwA-unsplash.jpg rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/medias/image/websitekey/slide/jay-wennington-N_Y88TWmGwA-unsplash.jpg diff --git a/htdocs/install/doctemplates/websites/website_template-restaurant/website_pages.sql b/htdocs/install/doctemplates/websites/website_template-restaurant_dev/website_pages.sql similarity index 100% rename from htdocs/install/doctemplates/websites/website_template-restaurant/website_pages.sql rename to htdocs/install/doctemplates/websites/website_template-restaurant_dev/website_pages.sql diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 81dcb2f1dab..300ac8f0b83 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -4216,6 +4216,7 @@ if ($action == 'createsite') { print '
'; } +// Page view to import a website template if ($action == 'importsite') { print ''; print '
'; From 85547f759478aee56a2fd53a0a52c2ce891fb225 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 00:50:33 +0100 Subject: [PATCH 163/185] Debug v21 --- htdocs/core/class/html.form.class.php | 2 +- .../product/mod_codeproduct_elephant.php | 18 +++++++++--------- htdocs/product/admin/product.php | 10 +++++----- htdocs/societe/admin/societe.php | 16 ++++++++-------- htdocs/societe/card.php | 2 +- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index c8965d32c6a..d974af0f986 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1486,7 +1486,7 @@ class Form * 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. * @param string|int<0,1> $showempty Add an empty field (Can be '1' or text 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 nature in combolist (customer, prospect or supplier) * @param int $forcecombo Force to use standard HTML select component without beautification * @param array}> $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @param string $filterkey Filter on key value diff --git a/htdocs/core/modules/product/mod_codeproduct_elephant.php b/htdocs/core/modules/product/mod_codeproduct_elephant.php index b0932e24308..da6475dc401 100644 --- a/htdocs/core/modules/product/mod_codeproduct_elephant.php +++ b/htdocs/core/modules/product/mod_codeproduct_elephant.php @@ -88,7 +88,7 @@ class mod_codeproduct_elephant extends ModeleProductCode $texte .= ''; $texte .= ''; $texte .= ''; - $texte .= ''; + $texte .= '
'; $tooltip = $langs->trans("GenericMaskCodes", $langs->transnoentities("Product"), $langs->transnoentities("Product")); $tooltip .= $langs->trans("GenericMaskCodes3"); @@ -97,16 +97,16 @@ class mod_codeproduct_elephant extends ModeleProductCode //$tooltip .= '
'.$langs->trans("GenericMaskCodes5b"); // Parametrage du prefix customers - $texte .= ''; - $texte .= ''; + $texte .= ''; + $texte .= ''; $texte .= ''; $texte .= ''; // Parametrage du prefix suppliers - $texte .= ''; - $texte .= ''; + $texte .= ''; + $texte .= ''; $texte .= ''; $texte .= '
'.$langs->trans("Mask").' ('.$langs->trans("ProductCodeModel").'):'.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).'
'.$langs->trans("ProductCodeModel").''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).' 
'.$langs->trans("Mask").' ('.$langs->trans("ServiceCodeModel").'):'.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).'
'.$langs->trans("ServiceCodeModel").''.$form->textwithpicto('', $tooltip, 1, 'help', 'valignmiddle', 0, 3, $this->name).'
'; @@ -171,7 +171,7 @@ class mod_codeproduct_elephant extends ModeleProductCode */ public function getNextValue($objproduct = null, $type = -1) { - global $db, $conf; + global $db; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; @@ -203,7 +203,7 @@ class mod_codeproduct_elephant extends ModeleProductCode $now = dol_now(); if (getDolGlobalString('PRODUCT_ELEPHANT_ADD_WHERE')) { - $where = ' AND ('.dol_string_nospecial(dol_string_unaccent($conf->global->PRODUCT_ELEPHANT_ADD_WHERE), '_', array(',', '@', '"', "|", ";", ":")).')'; + $where = ' AND ('.dol_string_nospecial(dol_string_unaccent(getDolGlobalString('PRODUCT_ELEPHANT_ADD_WHERE')), '_', array(',', '@', '"', "|", ";", ":")).')'; } $numFinal = get_next_value($db, $mask, 'product', $field, $where, '', $now); @@ -268,10 +268,10 @@ class mod_codeproduct_elephant extends ModeleProductCode // Get Mask value $mask = ''; if ($type == 0) { - $mask = !getDolGlobalString('PRODUCT_ELEPHANT_MASK_PRODUCT') ? '' : $conf->global->PRODUCT_ELEPHANT_MASK_PRODUCT; + $mask = getDolGlobalString('PRODUCT_ELEPHANT_MASK_PRODUCT'); } if ($type == 1) { - $mask = !getDolGlobalString('PRODUCT_ELEPHANT_MASK_SERVICE') ? '' : $conf->global->PRODUCT_ELEPHANT_MASK_SERVICE; + $mask = getDolGlobalString('PRODUCT_ELEPHANT_MASK_SERVICE'); } if (!$mask) { $this->error = 'NotConfigured'; diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 3d7e56c8de8..aecd2477b21 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -675,11 +675,11 @@ if (empty($conf->use_javascript_ajax)) { print ''; $arrval = array( '0' => $langs->trans("No"), - '1' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 1).')', - '2' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')', - '3' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')', + '1' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 1).'', + '2' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 2).'', + '3' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 3).'', ); - print $form->selectarray("activate_usesearchtoselectproduct", $arrval, $conf->global->PRODUIT_USE_SEARCH_TO_SELECT); + print $form->selectarray("activate_usesearchtoselectproduct", $arrval, getDolGlobalInt('PRODUIT_USE_SEARCH_TO_SELECT'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth125imp maxwidth400'); print ''; } print ''; @@ -708,7 +708,7 @@ print $form->selectarray( 0, 0, '', - 'minwidth100imp maxwidth400', + 'minwidth125imp maxwidth400', 1 ); print ''; diff --git a/htdocs/societe/admin/societe.php b/htdocs/societe/admin/societe.php index 7daf29d6ca7..8d2af81cabb 100644 --- a/htdocs/societe/admin/societe.php +++ b/htdocs/societe/admin/societe.php @@ -837,11 +837,11 @@ if (!$conf->use_javascript_ajax) { } else { print ''; $arrval = array('0' => $langs->trans("No"), - '1' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 1).')', - '2' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')', - '3' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')', + '1' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 1).'', + '2' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 2).'', + '3' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 3).'', ); - print $form->selectarray("activate_COMPANY_USE_SEARCH_TO_SELECT", $arrval, getDolGlobalString('COMPANY_USE_SEARCH_TO_SELECT'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth75imp'); + print $form->selectarray("activate_COMPANY_USE_SEARCH_TO_SELECT", $arrval, getDolGlobalString('COMPANY_USE_SEARCH_TO_SELECT'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth75imp maxwidth400'); print ''; print ''; print ""; @@ -858,11 +858,11 @@ if (!$conf->use_javascript_ajax) { } else { print ''; $arrval = array('0' => $langs->trans("No"), - '1' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 1).')', - '2' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 2).')', - '3' => $langs->trans("Yes").' ('.$langs->trans("NumberOfKeyToSearch", 3).')', + '1' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 1).'', + '2' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 2).'', + '3' => $langs->trans("Yes").' - '.$langs->trans("NumberOfKeyToSearch", 3).'', ); - print $form->selectarray("activate_CONTACT_USE_SEARCH_TO_SELECT", $arrval, getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth75imp'); + print $form->selectarray("activate_CONTACT_USE_SEARCH_TO_SELECT", $arrval, getDolGlobalString('CONTACT_USE_SEARCH_TO_SELECT'), 0, 0, 0, '', 0, 0, 0, '', 'minwidth75imp maxwidth400'); print ''; print ''; print ""; diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 62791808401..12675e6d369 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -2888,7 +2888,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($canvasdisplayactio 'name' => 'soc_origin', 'label' => $langs->trans('MergeOriginThirdparty'), 'type' => 'other', - 'value' => $form->select_company('', 'soc_origin', '', 'SelectThirdParty', 0, 0, array(), 0, 'minwidth200', '', '', 1, array(), false, array($object->id)) + 'value' => $form->select_company('', 'soc_origin', '', 'SelectThirdParty', 1, 0, array(), 0, 'minwidth200', '', '', 1, array(), false, array($object->id)) ) ); From 5d0758c02c150ae1aa6b2c820821b741ecf8264c Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 00:57:03 +0100 Subject: [PATCH 164/185] Debug v21 --- htdocs/core/class/html.form.class.php | 2 ++ htdocs/societe/ajax/company.php | 1 + 2 files changed, 3 insertions(+) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index d974af0f986..81653feaa85 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1506,6 +1506,8 @@ class Form global $user, $langs; global $hookmanager; + $langs->loadLangs(array("companies", "suppliers")); + $out = ''; $num = 0; $outarray = array(); diff --git a/htdocs/societe/ajax/company.php b/htdocs/societe/ajax/company.php index 36d7a284d74..51f33f87f6f 100644 --- a/htdocs/societe/ajax/company.php +++ b/htdocs/societe/ajax/company.php @@ -44,6 +44,7 @@ if (!defined('NOREQUIRESOC')) { // Load Dolibarr environment require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; + /** * @var Conf $conf * @var DoliDB $db From 938e0380f495fd9237fdc2acb31c5a6a001c3519 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 01:26:53 +0100 Subject: [PATCH 165/185] Doc --- htdocs/core/lib/functionsnumtoword.lib.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/lib/functionsnumtoword.lib.php b/htdocs/core/lib/functionsnumtoword.lib.php index 967644efaaf..77df277209a 100644 --- a/htdocs/core/lib/functionsnumtoword.lib.php +++ b/htdocs/core/lib/functionsnumtoword.lib.php @@ -153,11 +153,12 @@ function dol_convertToWord($num, $langs, $currency = '', $centimes = false) /** * Function to return number or amount in text. * - * @deprecated * @param float $numero Number to convert * @param Translate $langs Language * @param string $numorcurrency 'number' or 'amount' * @return string|int Text of the number or -1 in case TOO LONG (more than 1000000000000.99) + * + * @deprecated Use dol_convertToWord instead */ function dolNumberToWord($numero, $langs, $numorcurrency = 'number') { From 152050d1a8b3c73b440d19a7b0e6e8f81a7abd00 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 03:14:20 +0100 Subject: [PATCH 166/185] Debug v21 --- README-FR.md | 1 + README.md | 1 + htdocs/core/lib/invoice.lib.php | 11 ++++++----- htdocs/don/index.php | 2 +- htdocs/margin/agentMargins.php | 2 +- htdocs/margin/checkMargins.php | 4 ++-- htdocs/margin/customerMargins.php | 2 +- htdocs/margin/productMargins.php | 2 +- htdocs/website/index.php | 26 +++++++++++++++++++++----- 9 files changed, 35 insertions(+), 16 deletions(-) diff --git a/README-FR.md b/README-FR.md index c1c474f2597..34ca2f596f1 100644 --- a/README-FR.md +++ b/README-FR.md @@ -1,6 +1,7 @@ # DOLIBARR ERP & CRM ![Downloads per day](https://img.shields.io/sourceforge/dw/dolibarr.svg) +![Docker hub pulls](https://img.shields.io/docker/pulls/dolibarr/dolibarr.svg) [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg?style=flat-square)](https://php.net/) [![GitHub release](https://img.shields.io/github/v/release/Dolibarr/dolibarr)](https://github.com/Dolibarr/dolibarr) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5521/badge)](https://bestpractices.coreinfrastructure.org/projects/5521) diff --git a/README.md b/README.md index c5870358438..136f946a257 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # DOLIBARR ERP & CRM ![Downloads per day](https://img.shields.io/sourceforge/dw/dolibarr.svg) +![Docker hub pulls](https://img.shields.io/docker/pulls/dolibarr/dolibarr.svg) [![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.1-8892BF.svg?style=flat-square)](https://php.net/) [![GitHub release](https://img.shields.io/github/v/release/Dolibarr/dolibarr)](https://github.com/Dolibarr/dolibarr) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/5521/badge)](https://bestpractices.coreinfrastructure.org/projects/5521) diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index fd21d5462b2..84f3b42937f 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -905,6 +905,7 @@ function getCustomerInvoiceLatestEditTable($maxCount = 5, $socid = 0) $objectstatic->ref = $obj->ref; $objectstatic->paye = $obj->paye; $objectstatic->statut = $obj->status; + $objectstatic->status = $obj->status; $objectstatic->total_ht = $obj->total_ht; $objectstatic->total_tva = $obj->total_tva; $objectstatic->total_ttc = $obj->total_ttc; @@ -938,7 +939,7 @@ function getCustomerInvoiceLatestEditTable($maxCount = 5, $socid = 0) // Load amount of existing payment of invoice (needed for complete status) $payment = $objectstatic->getSommePaiement(); - $result .= ''.$objectstatic->getLibStatut(5, $payment).''; + $result .= ''.$objectstatic->getLibStatut(3, $payment).''; $result .= ''; @@ -1048,11 +1049,11 @@ function getPurchaseInvoiceLatestEditTable($maxCount = 5, $socid = 0) $result .= ''.$companystatic->getNomUrl(1, 'supplier').''; - $result .= ''.dol_print_date($db->jdate($obj->datec), 'day').''; + $result .= 'jdate($obj->datec), 'dayhour').'">'.dol_print_date($db->jdate($obj->datec), 'day').''; $result .= ''.price($obj->total_ttc).''; - $result .= ''.$objectstatic->getLibStatut(5).''; + $result .= ''.$objectstatic->getLibStatut(3).''; $result .= ''; @@ -1305,8 +1306,6 @@ function getPurchaseInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) $num = $db->num_rows($resql); $othernb = 0; - $formfile = new FormFile($db); - print '
'; print ''; @@ -1326,7 +1325,9 @@ function getPurchaseInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) print ''; print ''; print "\n"; + $societestatic = new Societe($db); + if ($num) { $i = 0; $total = $total_ttc = $totalam = 0; diff --git a/htdocs/don/index.php b/htdocs/don/index.php index 6775c5263e1..2df4cdbdcfe 100644 --- a/htdocs/don/index.php +++ b/htdocs/don/index.php @@ -257,7 +257,7 @@ if ($resql) { print ''; // Date - print ''; + print ''; print ''; diff --git a/htdocs/margin/agentMargins.php b/htdocs/margin/agentMargins.php index a31ac92d1ed..95c4ba1ad06 100644 --- a/htdocs/margin/agentMargins.php +++ b/htdocs/margin/agentMargins.php @@ -259,7 +259,7 @@ if ($result) { $i = 0; print '
'; - print '
'.$langs->trans("Paid").' 
'.dol_print_date($db->jdate($obj->datem), 'day').'jdate($obj->datem), 'day').'">'.dol_print_date($db->jdate($obj->datem), 'day').''.$donation_static->LibStatut($obj->fk_statut, 5).'
'."\n"; + print '
'."\n"; print ''; if ($agentid > 0) { diff --git a/htdocs/margin/checkMargins.php b/htdocs/margin/checkMargins.php index d497b845c3d..391d12958bc 100644 --- a/htdocs/margin/checkMargins.php +++ b/htdocs/margin/checkMargins.php @@ -279,7 +279,7 @@ if ($result) { $selectedfields = ''; print '
'; - print '
'."\n"; + print '
'."\n"; print ''; print ''; @@ -288,7 +288,7 @@ if ($result) { print ''; print ''; print ''; - print ''; diff --git a/htdocs/margin/customerMargins.php b/htdocs/margin/customerMargins.php index e9b3c3b2cf8..1ec4b367601 100644 --- a/htdocs/margin/customerMargins.php +++ b/htdocs/margin/customerMargins.php @@ -329,7 +329,7 @@ if ($result) { $i = 0; print '
'; - print '
'."\n"; + print '
'."\n"; print ''; if (!empty($client)) { diff --git a/htdocs/margin/productMargins.php b/htdocs/margin/productMargins.php index 9dd60cfa769..97d1a5a3f92 100644 --- a/htdocs/margin/productMargins.php +++ b/htdocs/margin/productMargins.php @@ -279,7 +279,7 @@ if ($result) { $i = 0; print '
'; - print '
'."\n"; + print '
'."\n"; print ''; if ($id > 0) { diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 300ac8f0b83..46d428bac93 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -454,6 +454,11 @@ if ($action == 'setwebsiteoffline' && $usercanedit) { exit; } if ($action == 'seteditinline') { // Test on permission not required here + if (!getDolGlobalString('WEBSITE_EDITINLINE_SAVE_CKEDITOR_EDIT')) { + // Show warning for feature not yet ready + setEventMessages($langs->trans("FeatureNotYetAvailable"), null, 'warnings'); + } + dolibarr_set_const($db, 'WEBSITE_EDITINLINE', 1); //dolibarr_set_const($db, 'WEBSITE_SUBCONTAINERSINLINE', 0); // Force disable of 'Include dynamic content' header("Location: ".$_SERVER["PHP_SELF"].'?website='.urlencode(GETPOST('website')).'&pageid='.GETPOSTINT('pageid')); @@ -3544,8 +3549,10 @@ if (!GETPOST('hide_websitemenu')) { isEditingEnabled = true; // Trigger the function when clicking outside the elements with contenteditable=true attribute + // so we can save the change. $(document).on(\'click\', function(e) { var target = $(e.target); + // Check if the click is outside the elements with contenteditable=true attribute if (!target.closest(\'[contenteditable="true"]\').length) { // Repeat through the elements with contenteditable="true" attribute @@ -3553,6 +3560,7 @@ if (!GETPOST('hide_websitemenu')) { var idToUse = $(this).attr(\'id\'); var elementType = $(this).prop("tagName").toLowerCase(); // Get the tag name (div, section, footer...) var instance = CKEDITOR.instances[idToUse]; + // Check if the element has been modified if ($(this).hasClass(\'modified\')) { var content = instance.getData(); @@ -3561,13 +3569,18 @@ if (!GETPOST('hide_websitemenu')) { // Retrieving the content and ID of the element var elementId = $(this).attr(\'id\'); - // Sending data via AJAX + '; + if (getDolGlobalString('WEBSITE_EDITINLINE_SAVE_CKEDITOR_EDIT')) { + print ' + console.log("A change has been detected, we send new content for update with ajax"); + + // Sending data via AJAX to update section $.ajax({ type: \'POST\', url: \'' . DOL_URL_ROOT . '/core/ajax/editinline.php\', data: { - website_ref: \''.$website->ref.'\', - page_id: \'' . $websitepage->id . '\', + website_ref: \''.dol_escape_js($website->ref).'\', + page_id: \'' . ((int) $websitepage->id) . '\', content: content, element_id: elementId, element_type: elementType, @@ -3598,6 +3611,11 @@ if (!GETPOST('hide_websitemenu')) { }, 2000); } }); + '; + } else { + print 'console.log("A change has been detected, but saving is not enabled by option WEBSITE_EDITINLINE_SAVE_CKEDITOR_EDIT, so no ajax update is done");'; + } + print ' $(this).removeClass(\'modified\'); } @@ -4896,8 +4914,6 @@ if ($action == 'preview') { if ($action == 'editfile' || $action == 'file_manager' || $action == 'convertimgwebp' || $action == 'confirmconvertimgwebp') { print ''."\n"; print '

'; - //print '
'.$langs->trans("FeatureNotYetAvailable").''; - $module = 'medias'; $formalreadyopen = 2; // So the form to submit a new file will not be open another time inside the core/tpl/filemanager.tpl.php From f708d2e184da8b2ab6c59fa002aa88f881965571 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 03:26:15 +0100 Subject: [PATCH 167/185] Debug v21 --- htdocs/margin/checkMargins.php | 39 +++++++++++++++++++++++++++----- htdocs/margin/productMargins.php | 2 +- htdocs/theme/eldy/global.inc.php | 2 +- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/htdocs/margin/checkMargins.php b/htdocs/margin/checkMargins.php index 391d12958bc..8f71eb09bb9 100644 --- a/htdocs/margin/checkMargins.php +++ b/htdocs/margin/checkMargins.php @@ -282,26 +282,39 @@ if ($result) { print '
'."\n"; print ''; + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } print ''; print ''; print ''; print ''; print ''; print ''; - print ''; + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } print "\n"; print ''; + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'maxwidthsearch center '); + } print_liste_field_titre("Ref", $_SERVER["PHP_SELF"], "f.ref", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("Description", $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder); print_liste_field_titre("UnitPriceHT", $_SERVER["PHP_SELF"], "d.subprice", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre($labelcostprice, $_SERVER["PHP_SELF"], "d.buy_price_ht", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre("Qty", $_SERVER["PHP_SELF"], "d.qty", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre("AmountTTC", $_SERVER["PHP_SELF"], "d.total_ht", "", $param, '', $sortfield, $sortorder, 'right '); - print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'maxwidthsearch center '); + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"], "", '', $param, '', $sortfield, $sortorder, 'maxwidthsearch center '); + } print "\n"; $i = 0; @@ -309,6 +322,11 @@ if ($result) { $objp = $db->fetch_object($result); print ''; + + if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } + print ''; - print ''; + + if (!getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) { + print ''; + } print "\n"; $i++; } + if ($num == 0) { + print ''; + } + print "
'; $result_inner = $invoicestatic->fetch($objp->invoiceid); if ($result_inner < 0) { @@ -349,13 +367,22 @@ if ($result) { print ''; print ''.price($objp->total_ht).''; print '
'; + print ''.$langs->trans("NoRecordFound").''; + print '
"; print "
"; diff --git a/htdocs/margin/productMargins.php b/htdocs/margin/productMargins.php index 97d1a5a3f92..dac098bf848 100644 --- a/htdocs/margin/productMargins.php +++ b/htdocs/margin/productMargins.php @@ -126,7 +126,7 @@ print ''; // Product print ''; print ''; // Categories diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index e6b4e156a26..1262a2c50b6 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -5613,7 +5613,7 @@ table.table-fiche-title .col-title div.titre > span:not(.print-barre-liste) { } table.table-fiche-title, div.fiche>table.table-fiche-title { - margin-bottom: 18px; + margin-bottom: 12px; } .table-list-of-attached-files, .table-list-of-links { margin-bottom: 0 !important; From c4889d3a09554bf143c9ec70ff2939d337f2c5fe Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 04:00:36 +0100 Subject: [PATCH 168/185] Debug v21 --- htdocs/bom/bom_card.php | 2 +- htdocs/theme/eldy/global.inc.php | 6 ++++-- htdocs/theme/md/style.css.php | 6 ++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php index 7d1ffa9e609..702c0f68e9b 100644 --- a/htdocs/bom/bom_card.php +++ b/htdocs/bom/bom_card.php @@ -585,7 +585,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea $tmparray = $object->product->getSellPrice($mysoc, $mysoc); $manufacturedvalued = $tmparray['pu_ht'] * $object->qty; } - print ''; + print ''; // Other attributes include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php'; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 1262a2c50b6..38f856e8555 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -4412,10 +4412,12 @@ table.liste tr:last-child th:last-child { border-bottom-right-radius: px; } -table#tablelines tr:last-of-type td:first-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td { +table#tablelines tr:last-of-type td:first-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td, +table#tablelinesservice tr:last-of-type td:first-child, table#tablelinesservice tr#trlinefordates, table#tablelinesservice tr#trlinefordates td { border-bottom-left-radius: px; } -table#tablelines tr:last-of-type td:last-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td { +table#tablelines tr:last-of-type td:last-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td, +table#tablelinesservice tr:last-of-type td:last-child, table#tablelinesservice tr#trlinefordates, table#tablelinesservice tr#trlinefordates td { border-bottom-right-radius: px; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index b333f13f1ca..621f27e1090 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -4478,10 +4478,12 @@ table.liste tr:last-child th:last-child { border-bottom-right-radius: px; } -table#tablelines tr:last-of-type td:first-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td { +table#tablelines tr:last-of-type td:first-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td, +table#tablelinesservice tr:last-of-type td:first-child, table#tablelinesservice tr#trlinefordates, table#tablelinesservice tr#trlinefordates td { border-bottom-left-radius: px; } -table#tablelines tr:last-of-type td:last-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td { +table#tablelines tr:last-of-type td:last-child, table#tablelines tr#trlinefordates, table#tablelines tr#trlinefordates td, +table#tablelinesservice tr:last-of-type td:last-child, table#tablelinesservice tr#trlinefordates, table#tablelinesservice tr#trlinefordates td { border-bottom-right-radius: px; } From 4954e84d560923b3a54d19b5d10dd15a96483101 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 04:53:07 +0100 Subject: [PATCH 169/185] Debug v21 --- htdocs/core/lib/functions.lib.php | 2 +- htdocs/datapolicy/admin/setup.php | 37 +++++++++++++++---- htdocs/datapolicy/class/datapolicy.class.php | 25 +++++++------ .../datapolicy/class/datapolicycron.class.php | 11 +++++- htdocs/langs/en_US/datapolicy.lang | 6 ++- 5 files changed, 57 insertions(+), 24 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 0b3d5c1ef13..933a07f6d22 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1429,7 +1429,7 @@ function dol_include_once($relpath, $classname = '') * @param int $type 0=Used for a Filesystem path, * 1=Used for an URL path (output relative), * 2=Used for an URL path (output full path using same host that current url), - * 3=Used for an URL path (output full path using host defined into $dolibarr_main_url_root of conf file) + * 3=Used for an URL path (output full path using host defined into $dolibarr_main_url_root of conf file, for an access from internet) * @param int $returnemptyifnotfound 0:If $type==0 and if file was not found into alternate dir, return default path into main dir (no test on it) * 1:If $type==0 and if file was not found into alternate dir, return empty string * 2:If $type==0 and if file was not found into alternate dir, test into main dir, return default path if found, empty string if not found diff --git a/htdocs/datapolicy/admin/setup.php b/htdocs/datapolicy/admin/setup.php index ea3ae94a6d5..5351f256011 100644 --- a/htdocs/datapolicy/admin/setup.php +++ b/htdocs/datapolicy/admin/setup.php @@ -156,21 +156,37 @@ $head = datapolicyAdminPrepareHead(); print dol_get_fiche_head($head, 'settings', '', -1, ''); // Setup page goes here -print ''.$langs->trans("datapolicySetupPage").'
'; -// print $form->textwithpicto('', $langs->trans('DATAPOLICY_Tooltip_SETUP')); +print ''.$langs->trans("datapolicySetupPage").''; +print $form->textwithpicto('', $langs->trans('DATAPOLICY_Tooltip_SETUP', $langs->trans("DATAPOLICYJob"), $langs->transnoentities("CronList"))); +print '
'; +print '
'; print '
'; +// TODO Show the last date of execution of the job DATAPOLICYJob if ($action == 'edit') { print ''; print ''; print ''; - print '
'.$langs->trans('ProductOrService').''; -print img_picto('', 'product').$form->select_produits(($id > 0 ? $id : ''), 'id', '', 20, 0, 1, 2, '', 1, array(), 0, 'All', 0, '', 0, '', null, 1); +print img_picto('', 'product', 'class="pictofixedwidth"').$form->select_produits(($id > 0 ? $id : ''), 'id', '', 20, 0, 1, 2, '', 1, array(), 0, '', 0, '', 0, '', null, 1); print '
'.$langs->trans("ManufacturingGeneratedValue").''.price($manufacturedvalued).'
'.$langs->trans("ManufacturingGeneratedValue").''.price($manufacturedvalued).'
'; - //print ''; + print '
'; // You can use div-table-responsive-no-min if you don't need reserved height for your table + print '
'.$langs->trans("Parameter").'
'; + + print ''; + print ''; + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { + print ''; + } + print ''; foreach ($arrayofparameters as $title => $tab) { - print ''; + print ''; + print ''; + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { + print ''; + } + print ''; + foreach ($tab as $key => $val) { print ''; + print ''; + if (getDolGlobalInt('MAIN_FEATURES_LEVEL') >= 2) { + print ''; + } + + print ''; } } print '
'.$langs->trans("DelayForAnonymization").''.$langs->trans("DelayForDeletion").'
'.$langs->trans($title).'
'.$langs->trans($title).'
'; print $val['picto']; @@ -184,11 +200,19 @@ if ($action == 'edit') { } print ''; print ajax_combobox($key); - print '
'; + print $langs->trans("FeatureNotYetAvailable"); + print '
'; + print '
'; print $form->buttonsSaveCancel("Save", ''); @@ -196,7 +220,6 @@ if ($action == 'edit') { print '
'; } else { print ''; - //print ''; foreach ($arrayofparameters as $title => $tab) { print ''; diff --git a/htdocs/datapolicy/class/datapolicy.class.php b/htdocs/datapolicy/class/datapolicy.class.php index 8421b84c924..21a19ae7ec6 100644 --- a/htdocs/datapolicy/class/datapolicy.class.php +++ b/htdocs/datapolicy/class/datapolicy.class.php @@ -21,6 +21,7 @@ * \file datapolicy/class/datapolicy.class.php * \ingroup datapolicy * \brief Class to manage feature of Data Policy module. + * This class file is not used. */ include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; include_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; @@ -61,7 +62,7 @@ class DataPolicy */ public function getAllContactNotInformed() { - global $langs, $conf, $db, $user; + global $langs, $conf, $db; $langs->load("companies"); @@ -69,9 +70,9 @@ class DataPolicy $sql .= " FROM ".MAIN_DB_PREFIX."socpeople as c"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON c.fk_soc = s.rowid"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople_extrafields as spe ON spe.fk_object = c.rowid"; - $sql .= " WHERE (c.statut=1 AND c.no_email=0 AND (spe.datapolicy_consentement=0 OR spe.datapolicy_consentement IS NULL) AND (spe.datapolicy_opposition_traitement=0 OR spe.datapolicy_opposition_traitement IS NULL) AND (spe.datapolicy_opposition_prospection=0 OR spe.datapolicy_opposition_prospection IS NULL))"; + $sql .= " WHERE (c.statut = 1 AND c.no_email = 0 AND (spe.datapolicy_consentement = 0 OR spe.datapolicy_consentement IS NULL) AND (spe.datapolicy_opposition_traitement = 0 OR spe.datapolicy_opposition_traitement IS NULL) AND (spe.datapolicy_opposition_prospection = 0 OR spe.datapolicy_opposition_prospection IS NULL))"; $sql .= " AND spe.datapolicy_send IS NULL"; - $sql .= " AND c.entity=".$conf->entity; + $sql .= " AND c.entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -99,16 +100,16 @@ class DataPolicy */ public function getAllCompaniesNotInformed() { - global $langs, $conf, $db, $user; + global $langs, $conf, $db; $langs->load("companies"); $sql = "SELECT s.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."societe as s"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe_extrafields as se ON se.fk_object = s.rowid"; - $sql .= " WHERE s.statut=0 AND (se.datapolicy_consentement=0 OR se.datapolicy_consentement IS NULL) AND (se.datapolicy_opposition_traitement=0 OR se.datapolicy_opposition_traitement IS NULL) AND (se.datapolicy_opposition_prospection=0 OR se.datapolicy_opposition_prospection IS NULL)"; + $sql .= " WHERE s.statut = 0 AND (se.datapolicy_consentement = 0 OR se.datapolicy_consentement IS NULL) AND (se.datapolicy_opposition_traitement = 0 OR se.datapolicy_opposition_traitement IS NULL) AND (se.datapolicy_opposition_prospection = 0 OR se.datapolicy_opposition_prospection IS NULL)"; $sql .= " AND se.datapolicy_send IS NULL"; - $sql .= " AND s.entity=".$conf->entity; + $sql .= " AND s.entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -136,16 +137,16 @@ class DataPolicy */ public function getAllAdherentsNotInformed() { - global $langs, $conf, $db, $user; + global $langs, $conf, $db; $langs->load("adherent"); $sql = "SELECT a.rowid"; $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."adherent_extrafields as ae ON ae.fk_object = a.rowid"; - $sql .= " WHERE a.statut=0 AND (ae.datapolicy_consentement=0 OR ae.datapolicy_consentement IS NULL) AND (ae.datapolicy_opposition_traitement=0 OR ae.datapolicy_opposition_traitement IS NULL) AND (ae.datapolicy_opposition_prospection=0 OR ae.datapolicy_opposition_prospection IS NULL)"; + $sql .= " WHERE a.statut = 0 AND (ae.datapolicy_consentement = 0 OR ae.datapolicy_consentement IS NULL) AND (ae.datapolicy_opposition_traitement=0 OR ae.datapolicy_opposition_traitement IS NULL) AND (ae.datapolicy_opposition_prospection=0 OR ae.datapolicy_opposition_prospection IS NULL)"; $sql .= " AND ae.datapolicy_send IS NULL"; - $sql .= " AND a.entity=".$conf->entity; + $sql .= " AND a.entity = ".((int) $conf->entity); $resql = $this->db->query($sql); if ($resql) { $num = $this->db->num_rows($resql); @@ -174,7 +175,7 @@ class DataPolicy */ public static function sendMailDataPolicyContact($contact) { - global $langs, $conf, $db, $user; + global $langs, $db, $user; $error = 0; @@ -252,7 +253,7 @@ class DataPolicy */ public static function sendMailDataPolicyCompany($societe) { - global $langs, $conf, $db, $user; + global $langs, $db, $user; $error = 0; @@ -327,7 +328,7 @@ class DataPolicy */ public static function sendMailDataPolicyAdherent($adherent) { - global $langs, $conf, $db, $user; + global $langs, $db, $user; $error = 0; diff --git a/htdocs/datapolicy/class/datapolicycron.class.php b/htdocs/datapolicy/class/datapolicycron.class.php index d2b8d88a1fa..6b588eda92c 100644 --- a/htdocs/datapolicy/class/datapolicycron.class.php +++ b/htdocs/datapolicy/class/datapolicycron.class.php @@ -468,6 +468,7 @@ class DataPolicyCron $this->db->begin(); + // Loop on each type of data foreach ($arrayofparameters as $key => $params) { if (getDolGlobalInt($key) > 0) { // @phan-suppress-next-line PhanPluginPrintfVariableFormatString @@ -488,10 +489,12 @@ class DataPolicyCron $object->fetch($obj->rowid); $object->id = $obj->rowid; - $action = 'anonymize'; // TODO Offer also action "delete" in setup of module + $action = 'anonymize'; // TODO Offer also action "delete" in the setup of the module + // Manage action 'anonymize' if ($action == 'anonymize') { - if ($object->isObjectUsed($obj->rowid) == 0) { // If object to clean is used + if ($object->isObjectUsed($obj->rowid) == 0) { // If object to clean is not used + // Loop on each field to anonymize foreach ($params['fields_anonym'] as $field => $val) { if ($val == 'MAKEANONYMOUS') { $object->$field = $field.'-anonymous-'.$obj->rowid; // @phpstan-ignore-line @@ -499,7 +502,10 @@ class DataPolicyCron $object->$field = $val; } } + + // Update record $result = $object->update($obj->rowid, $user); + if ($result > 0) { $errormsg = $object->error; $error++; @@ -508,6 +514,7 @@ class DataPolicyCron } } + // Manage action 'deletion' if ($action == 'delete') { // If object to clean is not used $result = $object->delete($user); if ($result < 0) { diff --git a/htdocs/langs/en_US/datapolicy.lang b/htdocs/langs/en_US/datapolicy.lang index 7cbc85b7475..73c23f457ee 100644 --- a/htdocs/langs/en_US/datapolicy.lang +++ b/htdocs/langs/en_US/datapolicy.lang @@ -18,7 +18,7 @@ Module4100Desc = Module to manage Data Privacy (Conformity with the GDPR) # Administration page datapolicySetup = Module Data Privacy Policy Setup Deletion = Deletion of data -datapolicySetupPage = Depending on the laws of your countries (Example Article 5 of the GDPR), personal data must be kept for a period not exceeding the duration the data is needed for the purpose for which it was collected, except for archival purposes.
The deletion will be done automatically after a certain duration without events (the duration which you will have indicated below). +datapolicySetupPage = Depending on the laws of your countries (Example Article 5 of the GDPR), personal data must be kept for a period not exceeding the duration the data is needed for the purpose for which it was collected, except for archival purposes.
This module will make an anonymization automatically after a certain duration without events (the duration which you will have indicated below) and if the object has no existing business object children. NB_MONTHS = %s months ONE_YEAR = 1 year NB_YEARS = %s years @@ -33,12 +33,14 @@ DATAPOLICY_CONTACT_PROSPECT_CLIENT = Prospect/Customer DATAPOLICY_CONTACT_NIPROSPECT_NICLIENT = Nor prospect/Nor customer DATAPOLICY_CONTACT_FOURNISSEUR = Supplier DATAPOLICY_ADHERENT = Member -DATAPOLICY_Tooltip_SETUP=Define the delay with no interaction after which you want the record to be automatically purged. +DATAPOLICY_Tooltip_SETUP=The anonymization is done by the scheduled job "%s" ran by the module "%s", so this module must be enabled and working correctly. SendAgreementText = You can send a GDPR email to all your relevant contacts (who have not yet received an email and for which you have not registered anything about their GDPR agreement). To do this, use the following button. SendAgreement = Send emails AllAgreementSend = All emails have been sent TXTLINKDATAPOLICYACCEPT = Text for the link "agreement" TXTLINKDATAPOLICYREFUSE = Text for the link "disagreement" +DelayForAnonymization=Delay for anonymization +DelayForDeletion=Delay for deletion # Extrafields DATAPOLICY_BLOCKCHECKBOX = GDPR : Processing of personal data DATAPOLICY_consentement = Consent obtained for the processing of personal data From f7cdd5fd084ad24e7bcebcaa01affe891d507dc4 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 11:43:38 +0100 Subject: [PATCH 170/185] Debug v21 --- htdocs/datapolicy/lib/datapolicy.lib.php | 2 +- htdocs/langs/en_US/datapolicy.lang | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/datapolicy/lib/datapolicy.lib.php b/htdocs/datapolicy/lib/datapolicy.lib.php index 5d24333e0e4..a11e4bcbfbc 100644 --- a/htdocs/datapolicy/lib/datapolicy.lib.php +++ b/htdocs/datapolicy/lib/datapolicy.lib.php @@ -38,7 +38,7 @@ function datapolicyAdminPrepareHead() $head = array(); $head[$h][0] = DOL_URL_ROOT."/datapolicy/admin/setup.php"; - $head[$h][1] = $langs->trans("Deletion"); + $head[$h][1] = $langs->trans("DataAnonymization"); $head[$h][2] = 'settings'; $h++; diff --git a/htdocs/langs/en_US/datapolicy.lang b/htdocs/langs/en_US/datapolicy.lang index 73c23f457ee..38a4f48f39f 100644 --- a/htdocs/langs/en_US/datapolicy.lang +++ b/htdocs/langs/en_US/datapolicy.lang @@ -17,7 +17,8 @@ Module4100Name = Data Privacy Policy Module4100Desc = Module to manage Data Privacy (Conformity with the GDPR) # Administration page datapolicySetup = Module Data Privacy Policy Setup -Deletion = Deletion of data +DataDeletion=Deletion of data +DataAnonymization=Anonymization of data datapolicySetupPage = Depending on the laws of your countries (Example Article 5 of the GDPR), personal data must be kept for a period not exceeding the duration the data is needed for the purpose for which it was collected, except for archival purposes.
This module will make an anonymization automatically after a certain duration without events (the duration which you will have indicated below) and if the object has no existing business object children. NB_MONTHS = %s months ONE_YEAR = 1 year From a8f2e842b266e65b1d9d159375be44564656f22b Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 11:50:47 +0100 Subject: [PATCH 171/185] Debug v21 --- htdocs/comm/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/comm/card.php b/htdocs/comm/card.php index 5ed10dc2bd1..cce00f8b832 100644 --- a/htdocs/comm/card.php +++ b/htdocs/comm/card.php @@ -376,7 +376,7 @@ if ($object->id > 0) { } if ($object->client) { - $langs->load("compta"); + $langs->loadLangs(array("compta", "accountancy")); print '
\n"; + print '\n"; // User print ''; // Label @@ -909,12 +912,12 @@ if ($id > 0) { print '
'.$langs->trans("Parameter").'
'.$langs->trans($title).'
'; print $langs->trans('CustomerCode').''; From c0e83d0f18c6579442862a056517e8dca0289cfb Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 12:51:46 +0100 Subject: [PATCH 172/185] Prepare v21 --- build/makepack-dolibarr.pl | 177 +++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 88 deletions(-) diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index 629672d06c4..9370d504627 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -4,7 +4,7 @@ # \brief Dolibarr package builder (tgz, zip, rpm, deb, exe, aps) # \author (c)2004-2023 Laurent Destailleur # -# This is list of constant you can set to have generated packages moved into a specific dir: +# This is list of constant you can set to have generated packages moved into a specific dir: #DESTIBETARC='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/lastbuild' #DESTISTABLE='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/stable' #DESTIMODULES='/media/HDDATA1_LD/Mes Sites/Web/Admin1/wwwroot/files/modules' @@ -129,7 +129,7 @@ if (! $TEMP || ! -d $TEMP) { print "$PROG.$Extension aborted.\n"; sleep 2; exit 2; -} +} $BUILDROOT="$TEMP/buildroot"; @@ -172,7 +172,7 @@ $newbuild = $BUILD; $newbuild =~ s/(dev|alpha)/1/gi; # dev $newbuild =~ s/beta(.?)/2/gi; # beta (we want beta1, beta2, betax to be same package name) $newbuild =~ s/rc(.?)/3/gi; # rc (we want rc1, rc2, rcx to be same package name) -if ($newbuild !~ /-/) { $newbuild.='-4'; } # finale is same than rc. +if ($newbuild !~ /-/) { $newbuild.='-4'; } # finale is same than rc. # now newbuild is 0-1 or 0-4 for example. Note that for native package (see debian/source/format), we should not use a dash part but to get a better version management $build = $newbuild; $build =~ s/-.*$//g; @@ -190,8 +190,8 @@ for (0..@ARGV-1) { if ($ARGV[$_] =~ /^-*target=(\w+)/i) { $target=$1; $batch=1; } if ($ARGV[$_] =~ /^-*desti=(.+)/i) { $DESTI=$1; } if ($ARGV[$_] =~ /^-*prefix=(.+)/i) { - $PREFIX=$1; - $FILENAMESNAPSHOT.="-".$PREFIX; + $PREFIX=$1; + $FILENAMESNAPSHOT.="-".$PREFIX; } } if ($ENV{"DESTIBETARC"} && $BUILD =~ /[a-z]/i) { $DESTI = $ENV{"DESTIBETARC"}; } # Force output dir if env DESTIBETARC is defined @@ -210,7 +210,7 @@ print "Target directory (DESTI) : $DESTI\n"; # Choose package targets #----------------------- if ($target) { - if ($target eq "ALL") { + if ($target eq "ALL") { foreach my $key (@LISTETARGET) { if ($key ne 'SNAPSHOT' && $key ne 'SF' && $key ne 'ASSO') { $CHOOSEDTARGET{$key}=1; } } @@ -236,10 +236,10 @@ else { printf(" %2d - %-14s (%s)\n",$cpt,"ASSO (publish)","Need ".$REQUIREMENTPUBLISH{"ASSO"}); $cpt=99; printf(" %2d - %-14s (%s)\n",$cpt,"SF (publish)","Need ".$REQUIREMENTPUBLISH{"SF"}); - + # Ask which target to build print "Choose one target number or several separated with space (0 - ".$cpt."): "; - $NUM_SCRIPT=; + $NUM_SCRIPT=; chomp($NUM_SCRIPT); if ($NUM_SCRIPT !~ /^[0-9\s]+$/) { @@ -286,11 +286,11 @@ foreach my $target (sort keys %CHOOSEDTARGET) { print "Error: You asked creation of several rpms. Because all rpm have same name, you must defined an environment variable DESTI to tell packager where it can create subdirs for each generated package.\n"; exit; } - $atleastonerpm=1; - } - foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target})) + $atleastonerpm=1; + } + foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target})) { - # Test + # Test print "Test requirement for target $target: Search '$req'... "; $newreq=$req; $newparam=''; if ($newreq eq 'zip') { $newparam.='-h'; } @@ -299,12 +299,12 @@ foreach my $target (sort keys %CHOOSEDTARGET) { print "Test command ".$cmd."... "; $ret=`$cmd`; $coderetour=$?; $coderetour2=$coderetour>>8; - if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) { + if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) { # Not found error, we try in PROGPATH $ret=`"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`; $coderetour=$?; $coderetour2=$coderetour>>8; $REQUIREMENTTARGET{$target}="$PROGPATH/$ALTERNATEPATH{$req}/$req"; - } + } if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/))) { # Not found error @@ -333,7 +333,7 @@ $nbofpublishneedchangelog=0; foreach my $target (sort keys %CHOOSEDTARGET) { if ($target eq '-CHKSUM') { $nbofpublishneedchangelog++; } if ($CHOOSEDTARGET{$target} < 0) { next; } - if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP' && $target ne '-CHKSUM') + if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP' && $target ne '-CHKSUM') { $nboftargetneedbuildroot++; } @@ -397,10 +397,10 @@ if ($nboftargetok) { print "Go to directory $SOURCE\n"; $olddir=getcwd(); chdir("$SOURCE"); - + print "Clean $SOURCE/htdocs/includes/autoload.php\n"; $ret=`rm -f $SOURCE/htdocs/includes/autoload.php`; - + $ret=`git ls-files . --exclude-standard --others`; if ($ret) { @@ -409,7 +409,7 @@ if ($nboftargetok) { print "Canceled.\n"; exit; } - + print 'Create xml check file with md5 checksum with command php '.$SOURCE.'/build/generate_filelist_xml.php release='.$MAJOR.'.'.$MINOR.'.'.$BUILD."\n"; $ret=`php $SOURCE/build/generate_filelist_xml.php release=$MAJOR.$MINOR.$BUILD`; print $ret."\n"; @@ -427,13 +427,13 @@ if ($nboftargetok) { print "Go to directory $SOURCE\n"; $olddir=getcwd(); chdir("$SOURCE"); - + print 'Run git tag -a -m "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'" "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'"'."\n"; $ret=`git tag -a -m "$MAJOR.$MINOR.$BUILD" "$MAJOR.$MINOR.$BUILD" 2>&1`; if ($ret =~ /(already exists|existe déjà)/) { print "WARNING: Tag ".$MAJOR.'.'.$MINOR.'.'.$BUILD." already exists. Overwrite (y/N) ? "; - $QUESTIONOVERWRITETAG=; + $QUESTIONOVERWRITETAG=; chomp($QUESTIONOVERWRITETAG); if ($QUESTIONOVERWRITETAG =~ /(o|y)/) { @@ -452,7 +452,7 @@ if ($nboftargetok) { } chdir("$olddir"); } - + # Update buildroot if required #----------------------------- if ($nboftargetneedbuildroot) @@ -462,7 +462,7 @@ if ($nboftargetok) { print "Delete directory $BUILDROOT\n"; $ret=`rm -fr "$BUILDROOT"`; - + mkdir "$BUILDROOT"; mkdir "$BUILDROOT/$PROJECT"; print "Copy $SOURCE into $BUILDROOT/$PROJECT\n"; @@ -491,7 +491,7 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$PROJECT/phpstan.neon.dist`; $ret=`rm -f $BUILDROOT/$PROJECT/pom.xml`; $ret=`rm -f $BUILDROOT/$PROJECT/README-*.md`; - + $ret=`rm -fr $BUILDROOT/$PROJECT/build/html`; $ret=`rm -f $BUILDROOT/$PROJECT/build/Doli*-*`; $ret=`rm -f $BUILDROOT/$PROJECT/build/dolibarr_*.deb`; @@ -507,6 +507,7 @@ if ($nboftargetok) { $ret=`rm -f $BUILDROOT/$PROJECT/build/dolibarr-*.xz`; $ret=`rm -f $BUILDROOT/$PROJECT/build/dolibarr-*.zip`; $ret=`rm -f $BUILDROOT/$PROJECT/build/doxygen/doxygen_warnings.log`; + $ret=`rm -fr $BUILDROOT/$PROJECT/build/phpstan/phpstan`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/cache.manifest`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/conf/conf.php`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/conf/conf.php.mysql`; @@ -560,20 +561,20 @@ if ($nboftargetok) { $ret=`rm -f $BUILDROOT/$PROJECT/doc/images/dolibarr_screenshot11.png`; $ret=`rm -f $BUILDROOT/$PROJECT/doc/images/dolibarr_screenshot12.png`; - # Security to avoid to package data files + # Security to avoid to package data files print "Remove documents dir\n"; $ret=`rm -fr $BUILDROOT/$PROJECT/document`; $ret=`rm -fr $BUILDROOT/$PROJECT/documents`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/document`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/documents`; - + print "Remove subdir of custom dir\n"; print "find $BUILDROOT/$PROJECT/htdocs/custom/* -type d -exec rm -fr {} \\;\n"; $ret=`find $BUILDROOT/$PROJECT/htdocs/custom/* -type d -exec rm -fr {} \\; >/dev/null 2>&1`; # For custom we want to remove all subdirs but not files print "find $BUILDROOT/$PROJECT/htdocs/custom/* -type l -exec rm -fr {} \\;\n"; $ret=`find $BUILDROOT/$PROJECT/htdocs/custom/* -type l -exec rm -fr {} \\; >/dev/null 2>&1`; # For custom we want to remove all subdirs, even symbolic links, but not files - # Removed known external modules to avoid any error when packaging from env where external modules are tested + # Removed known external modules to avoid any error when packaging from env where external modules are tested $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/abricot*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/accountingexport*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/allscreens*`; @@ -599,15 +600,15 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/timesheet*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/webmail*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/theme/common/fontawesome-5/svgs`; - + # Removed other test files $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/public/test`; $ret=`rm -fr $BUILDROOT/$PROJECT/test`; $ret=`rm -fr $BUILDROOT/$PROJECT/Thumbs.db $BUILDROOT/$PROJECT/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/*/*/Thumbs.db`; $ret=`rm -f $BUILDROOT/$PROJECT/.cvsignore $BUILDROOT/$PROJECT/*/.cvsignore $BUILDROOT/$PROJECT/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/*/*/.cvsignore`; $ret=`rm -f $BUILDROOT/$PROJECT/.gitignore $BUILDROOT/$PROJECT/*/.gitignore $BUILDROOT/$PROJECT/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/*/*/.gitignore`; - - # Removed files installed by the awful composer + + # Removed files installed by the awful composer $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/geoip/sample*.*`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/bin`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/ckeditor/ckeditor/adapters`; # Keep this removal in case we embed libraries @@ -642,7 +643,7 @@ if ($nboftargetok) { $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/vendor`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/webmozart`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/autoload.php`; - + $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/sabre/sabre/bin`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/sabre/sabre/*/bin`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/sabre/sabre/*/*/bin`; @@ -652,14 +653,14 @@ if ($nboftargetok) { # Build package for each target #------------------------------ - foreach my $target (sort keys %CHOOSEDTARGET) + foreach my $target (sort keys %CHOOSEDTARGET) { if ($CHOOSEDTARGET{$target} < 0) { next; } if ($target eq '-CHKSUM') { next; } - + print "\nBuild package for target $target\n"; - if ($target eq 'SNAPSHOT') + if ($target eq 'SNAPSHOT') { $NEWDESTI=$DESTI; @@ -683,13 +684,13 @@ if ($nboftargetok) { next; } - if ($target eq 'TGZ') + if ($target eq 'TGZ') { $NEWDESTI=$DESTI; if ($NEWDESTI =~ /stable/) { mkdir($DESTI.'/standard'); - if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; } + if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; } } print "Remove target $FILENAMETGZ.tgz...\n"; @@ -703,7 +704,7 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$FILENAMETGZ/build/exe`; $ret=`rm -fr $BUILDROOT/$FILENAMETGZ/htdocs/includes/ckeditor/_source`; # We can't remove it with exclude file, we need it for some tarball packages - + print "Compress $FILENAMETGZ into $FILENAMETGZ.tgz...\n"; $cmd="tar --exclude-vcs --exclude-from \"$BUILDROOT/$PROJECT/build/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$BUILDROOT/$FILENAMETGZ.tgz\" $FILENAMETGZ"; print "$cmd\n"; @@ -715,14 +716,14 @@ if ($nboftargetok) { next; } - if ($target eq 'XZ') + if ($target eq 'XZ') { $NEWDESTI=$DESTI; if ($NEWDESTI =~ /stable/) { mkdir($DESTI.'/standard'); if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; } - } + } print "Remove target $FILENAMEXZ.xz...\n"; unlink("$NEWDESTI/$FILENAMEXZ.xz"); @@ -735,7 +736,7 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$FILENAMEXZ/build/exe`; $ret=`rm -fr $BUILDROOT/$FILENAMEXZ/htdocs/includes/ckeditor/_source`; # We can't remove it with exclude file, we need it for some tarball packages - + print "Compress $FILENAMEXZ into $FILENAMEXZ.xz...\n"; print "Go to directory $BUILDROOT\n"; @@ -751,15 +752,15 @@ if ($nboftargetok) { $ret=`mv "$BUILDROOT/$FILENAMEXZ.xz" "$NEWDESTI/$FILENAMEXZ.xz"`; next; } - - if ($target eq 'ZIP') + + if ($target eq 'ZIP') { $NEWDESTI=$DESTI; if ($NEWDESTI =~ /stable/) { mkdir($DESTI.'/standard'); if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; } - } + } print "Remove target $FILENAMEZIP.zip...\n"; unlink("$NEWDESTI/$FILENAMEZIP.zip"); @@ -782,14 +783,14 @@ if ($nboftargetok) { print $cmd."\n"; $ret= `$cmd`; chdir("$olddir"); - + # Move to final dir print "Move $FILENAMEZIP.zip to $NEWDESTI/$FILENAMEZIP.zip\n"; $ret=`mv "$BUILDROOT/$FILENAMEZIP.zip" "$NEWDESTI/$FILENAMEZIP.zip"`; next; } - - if ($target =~ /RPM/) # Linux only + + if ($target =~ /RPM/) # Linux only { $NEWDESTI=$DESTI; $subdir="package_rpm_generic"; @@ -800,7 +801,7 @@ if ($nboftargetok) { { mkdir($DESTI.'/'.$subdir); if (-d $DESTI.'/'.$subdir) { $NEWDESTI=$DESTI.'/'.$subdir; } - } + } if ($RPMDIR eq "") { $RPMDIR=$ENV{'HOME'}."/rpmbuild"; } @@ -813,7 +814,7 @@ if ($nboftargetok) { print "Create directory $BUILDROOT/$FILENAMETGZ2\n"; $ret=`rm -fr $BUILDROOT/$FILENAMETGZ2`; - + print "Copy $BUILDROOT/$PROJECT to $BUILDROOT/$FILENAMETGZ2\n"; $cmd="cp -pr '$BUILDROOT/$PROJECT' '$BUILDROOT/$FILENAMETGZ2'"; $ret=`$cmd`; @@ -839,7 +840,7 @@ if ($nboftargetok) { if ($target =~ /FEDO/i) { $BUILDFICSRC="${FILENAME}_fedora.spec"; } if ($target =~ /MAND/i) { $BUILDFICSRC="${FILENAME}_mandriva.spec"; } if ($target =~ /OPEN/i) { $BUILDFICSRC="${FILENAME}_opensuse.spec"; } - + use Date::Language; $lang=Date::Language->new('English'); $datestring = $lang->time2str("%a %b %e %Y", time); @@ -857,7 +858,7 @@ if ($nboftargetok) { } close SPECFROM; close SPECTO; - + print "Copy patch file to $RPMDIR/SOURCES\n"; $ret=`cp "$SOURCE/build/rpm/dolibarr-forrpm.patch" "$RPMDIR/SOURCES"`; $ret=`chmod 644 $RPMDIR/SOURCES/dolibarr-forrpm.patch`; @@ -879,14 +880,14 @@ if ($nboftargetok) { next; } - if ($target eq 'DEB') + if ($target eq 'DEB') { $NEWDESTI=$DESTI; if ($NEWDESTI =~ /stable/) { mkdir($DESTI.'/package_debian-ubuntu'); if (-d $DESTI.'/package_debian-ubuntu') { $NEWDESTI=$DESTI.'/package_debian-ubuntu'; } - } + } $olddir=getcwd(); @@ -967,13 +968,13 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/jquery/plugins/select2/LICENSE`; $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/mike42/escpos-php/LICENSE.md`; $ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/mobiledetect/mobiledetectlib/LICENSE.txt`; - + # Removed files we don't need (already removed) #$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/ckeditor/ckeditor/_source`; - + # Rename upstream changelog to match debian rules $ret=`mv $BUILDROOT/$PROJECT.tmp/ChangeLog $BUILDROOT/$PROJECT.tmp/changelog`; - + # Prepare source package (init debian dir) print "Create directory $BUILDROOT/$PROJECT.tmp/debian\n"; $ret=`mkdir "$BUILDROOT/$PROJECT.tmp/debian"`; @@ -1011,7 +1012,7 @@ if ($nboftargetok) { $ret=`cp -f "$SOURCE/build/debian/dolibarr.postrm" "$BUILDROOT/$PROJECT.tmp/debian"`; $ret=`cp -f "$SOURCE/build/debian/dolibarr.templates" "$BUILDROOT/$PROJECT.tmp/debian"`; $ret=`cp -f "$SOURCE/build/debian/install.forced.php.install" "$BUILDROOT/$PROJECT.tmp/debian"`; - + # Set owners and permissions #print "Set owners on files/dir\n"; #$ret=`chown -R root.root $BUILDROOT/$PROJECT.tmp`; @@ -1042,8 +1043,8 @@ if ($nboftargetok) { $ret=`$cmd`; $cmd="find $BUILDROOT/$PROJECT.tmp/scripts -name '*.sh' -type f -exec chmod 755 {} \\; "; $ret=`$cmd`; - - + + print "Rename directory $BUILDROOT/$PROJECT.tmp into $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build\n"; $cmd="mv $BUILDROOT/$PROJECT.tmp $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build"; $ret=`$cmd`; @@ -1051,14 +1052,14 @@ if ($nboftargetok) { print "Go into directory $BUILDROOT\n"; chdir("$BUILDROOT"); - + # We need a tarball to be able to build "quilt" debian package (not required for native but we need patch so it is not a native) print "Compress $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build into $BUILDROOT/$FILENAMEDEBNATIVE.orig.tar.gz...\n"; $cmd="tar --exclude-vcs --exclude-from \"$BUILDROOT/$PROJECT/build/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$BUILDROOT/$FILENAMEDEBNATIVE.orig.tar.gz\" $PROJECT-$MAJOR.$MINOR.$build"; print $cmd."\n"; $ret=`$cmd`; - # Creation of source package + # Creation of source package print "Go into directory $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build\n"; chdir("$BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build"); #$cmd="dpkg-source -b $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build"; @@ -1077,12 +1078,12 @@ if ($nboftargetok) { $ret=`mv $BUILDROOT/*_all.deb "$NEWDESTI/"`; $ret=`mv $BUILDROOT/*.dsc "$NEWDESTI/"`; $ret=`mv $BUILDROOT/*.orig.tar.gz "$NEWDESTI/"`; - #$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`; # xz file is generated when build/debian/sources/option + #$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`; # xz file is generated when build/debian/sources/option $ret=`mv $BUILDROOT/*.debian.tar.gz "$NEWDESTI/"`; $ret=`mv $BUILDROOT/*.changes "$NEWDESTI/"`; next; } - + if ($target eq 'EXEDOLIWAMP') { $NEWDESTI=$DESTI; @@ -1090,22 +1091,22 @@ if ($nboftargetok) { { mkdir($DESTI.'/package_windows'); if (-d $DESTI.'/package_windows') { $NEWDESTI=$DESTI.'/package_windows'; } - } + } print "Remove target $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe...\n"; unlink "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"; - + if ($OS eq 'windows') { print "Check that ISCC.exe is in your PATH.\n"; } else { print "Check that in your Wine setup, you have created a Z: drive that point to your / directory.\n"; } - + $SOURCEBACK=$SOURCE; $SOURCEBACK =~ s/\//\\/g; print "Prepare file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" from \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.iss\"\n"; - + #$ret=`cat "$SOURCE/build/exe/doliwamp/doliwamp.iss" | sed -e 's/__FILENAMEEXEDOLIWAMP__/$FILENAMEEXEDOLIWAMP/g' > "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`; open(IN, '<' . $SOURCE."/build/exe/doliwamp/doliwamp.iss") or die $!; open(OUT, '>' . "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss") or die $!; @@ -1118,7 +1119,7 @@ if ($nboftargetok) { close(OUT); print "Compil exe $FILENAMEEXEDOLIWAMP.exe file from iss file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" on OS $OS\n"; - + if ($OS eq 'windows') { $cmd= "ISCC.exe \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\""; } else { @@ -1132,26 +1133,26 @@ if ($nboftargetok) { print "Move \"$SOURCE\\build\\$FILENAMEEXEDOLIWAMP.exe\" to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n"; rename("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe","$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"); print "Move $SOURCE/build/$FILENAMEEXEDOLIWAMP.exe to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n"; - + use File::Copy; #$ret=`mv "$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe" "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"`; $ret=move("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe", "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"); - + print "Remove tmp file $SOURCE/build/exe/doliwamp/doliwamp.tmp.iss\n"; #$ret=`rm "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`; $ret=unlink("$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"); - + next; } } # Publish package for each target #-------------------------------- - foreach my $target (sort keys %CHOOSEDPUBLISH) + foreach my $target (sort keys %CHOOSEDPUBLISH) { if ($CHOOSEDPUBLISH{$target} < 0) { next; } - + print "\nList of files to publish (BUILD=$BUILD)\n"; %filestoscansf=( "$DESTI/signatures/filelist-$MAJOR.$MINOR.$BUILD.xml"=>'none', # none means it won't be published on SF @@ -1209,26 +1210,26 @@ if ($nboftargetok) { print "\n"; } - if ($target eq 'SF' || $target eq 'ASSO') + if ($target eq 'SF' || $target eq 'ASSO') { print "\n"; - + if ($target eq 'SF') { $PUBLISH = $PUBLISHSTABLE; } if ($target eq 'ASSO' && $BUILD =~ /[a-z]/i) { $PUBLISH = $PUBLISHBETARC.'/lastbuild'; } if ($target eq 'ASSO' && $BUILD =~ /^[0-9]+$/) { $PUBLISH = $PUBLISHBETARC.'/stable'; } - + $NEWPUBLISH=$PUBLISH; print "Publish to target $NEWPUBLISH. Click enter or CTRL+C...\n"; # Ask which target to build - $NUM_SCRIPT=; + $NUM_SCRIPT=; chomp($NUM_SCRIPT); print "Create empty dir /tmp/emptydir. We need it to create target dir using rsync.\n"; $ret=`mkdir -p "/tmp/emptydir/"`; - + %filestoscan=%filestoscansf; - + foreach my $file (sort keys %filestoscan) { $found=0; @@ -1238,30 +1239,30 @@ if ($nboftargetok) { if ($target eq 'SF') { if ($filestoscan{$file} eq 'none') { next; - } + } $destFolder="$NEWPUBLISH/$filestoscan{$file}/".$MAJOR.'.'.$MINOR.'.'.$BUILD; } elsif ($target eq 'ASSO' and $NEWPUBLISH =~ /stable/) { $destFolder="$NEWPUBLISH/$filestoscanstableasso{$file}"; - } + } elsif ($target eq 'ASSO' and $NEWPUBLISH !~ /stable/) { $destFolder="$NEWPUBLISH"; - } + } else # No more used { $dirnameonly=$file; - $dirnameonly =~ s/.*\/([^\/]+)\/[^\/]+$/$1/; + $dirnameonly =~ s/.*\/([^\/]+)\/[^\/]+$/$1/; $filenameonly=$file; - $filenameonly =~ s/.*\/[^\/]+\/([^\/])+$/$1/; + $filenameonly =~ s/.*\/[^\/]+\/([^\/])+$/$1/; $destFolder="$NEWPUBLISH/$dirnameonly"; } print "\n"; print "Publish file ".$file." to ".$destFolder."\n"; - # mkdir + # mkdir #my $ssh = Net::SSH::Perl->new("frs.sourceforge.net"); - #$ssh->login("$user","$pass"); + #$ssh->login("$user","$pass"); #use String::ShellQuote qw( shell_quote ); #$ssh->cmd('mkdir '.shell_quote($destFolder).' && exit'); @@ -1270,20 +1271,20 @@ if ($nboftargetok) { #$sftp->mkdir($destFolder) #$command="ssh eldy,dolibarr\@frs.sourceforge.net mkdir -p \"$destFolder\""; - #print "$command\n"; + #print "$command\n"; #my $ret=`$command 2>&1`; $command="rsync -s -e 'ssh' --recursive /tmp/emptydir/ \"".$destFolder."\""; - print "$command\n"; + print "$command\n"; my $ret=`$command 2>&1`; $command="rsync -s -e 'ssh' \"$file\" \"".$destFolder."\""; - print "$command\n"; + print "$command\n"; my $ret2=`$command 2>&1`; print "$ret2\n"; } } - } + } } print "\n----- Summary -----\n"; From e2c4f42093c77519aad3f82f7040929987f98c2b Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 14:57:55 +0100 Subject: [PATCH 173/185] Trans --- htdocs/langs/en_US/languages.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/en_US/languages.lang b/htdocs/langs/en_US/languages.lang index 4ea49a160fa..9fd4ad9ce0e 100644 --- a/htdocs/langs/en_US/languages.lang +++ b/htdocs/langs/en_US/languages.lang @@ -125,6 +125,7 @@ Language_uk_UA=Ukrainian Language_ur_PK=Urdu Language_uz_UZ=Uzbek Language_vi_VN=Vietnamese +Language_wo_SN=Wolof Language_zh_CN=Chinese Language_zh_TW=Chinese (Taiwan) Language_zh_HK=Chinese (Hong Kong) From 4ec331a201e04ea50e0c2f3fc64eca1b28155d73 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 15:57:52 +0100 Subject: [PATCH 174/185] Debug v21 --- htdocs/compta/facture/prelevement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/prelevement.php b/htdocs/compta/facture/prelevement.php index 503c21af370..6d74a72e2c3 100644 --- a/htdocs/compta/facture/prelevement.php +++ b/htdocs/compta/facture/prelevement.php @@ -1108,7 +1108,7 @@ if ($object->id > 0) { } // Date - print ''.dol_print_date($db->jdate($obj->date_demande), 'day')."'.dol_print_date($db->jdate($obj->date_demande), 'day', 'tzuserrel')."'; From 647238b94618b887486f66ad0bf25fe2a673d55d Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 16:50:22 +0100 Subject: [PATCH 175/185] Debug v21 --- htdocs/compta/facture/prelevement.php | 47 ++++------------- htdocs/core/class/commoninvoice.class.php | 62 +++++++++++++++++++++-- htdocs/langs/en_US/salaries.lang | 1 - 3 files changed, 69 insertions(+), 41 deletions(-) diff --git a/htdocs/compta/facture/prelevement.php b/htdocs/compta/facture/prelevement.php index 6d74a72e2c3..50a513a994f 100644 --- a/htdocs/compta/facture/prelevement.php +++ b/htdocs/compta/facture/prelevement.php @@ -300,7 +300,6 @@ if ($object->id > 0) { if ($object->paid) { $resteapayer = 0; } - $resteapayeraffiche = $resteapayer; if ($type == 'bank-transfer') { if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) { // Not recommended @@ -333,7 +332,7 @@ if ($object->id > 0) { $author = new User($db); if (!empty($object->user_creation_id)) { $author->fetch($object->user_creation_id); - } elseif (!empty($object->fk_user_author)) { + } elseif (!empty($object->fk_user_author)) { // For backward compatibility $author->fetch($object->fk_user_author); } @@ -348,28 +347,8 @@ if ($object->id > 0) { $numclosed = 0; // How many Direct debit or Credit transfer open requests ? - - $sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande"; - $sql .= " , pfd.date_traite as date_traite"; - $sql .= " , pfd.amount"; - $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd"; - if ($type == 'bank-transfer') { - $sql .= " WHERE fk_facture_fourn = ".((int) $object->id); - } else { - $sql .= " WHERE fk_facture = ".((int) $object->id); - } - $sql .= " AND pfd.traite = 0"; - $sql .= " AND pfd.type = 'ban'"; - $sql .= " ORDER BY pfd.date_demande DESC"; - - $resql = $db->query($sql); - if ($resql) { - $num = $db->num_rows($resql); - $numopen = $num; - } else { - dol_print_error($db); - } - + $listofopendirectdebitorcredittransfer = $object->getListOfOpenDirectDebitOrCreditTransfer($type); + $numopen = count($listofopendirectdebitorcredittransfer); print dol_get_fiche_head($head, 'standingorders', $title, -1, ($type == 'bank-transfer' ? 'supplier_invoice' : 'bill')); @@ -795,11 +774,7 @@ if ($object->id > 0) { print '
'; - //print ''; - //print ''; - //print ''; // Bank Transfer Amount - //print ''; - - //print '
'. print $langs->trans('CustomerIBAN').' '; - //print ''; // if societe rib in model invoice, we preselect it $selectedRib = ''; @@ -826,16 +801,16 @@ if ($object->id > 0) { print img_warning($langs->trans("NoDefaultIBANFound")); } - //print '
'; - print '     '; - //print ''; + print '     '; print ''; - //print '
'; // Button print '

'; @@ -849,7 +824,7 @@ if ($object->id > 0) { if (getDolGlobalString('STRIPE_SEPA_DIRECT_DEBIT_SHOW_OLD_BUTTON')) { // This is hidden, prefer to use mode enabled with STRIPE_SEPA_DIRECT_DEBIT // TODO Replace this with a checkbox for each payment mode: "Send request to XXX immediately..." print "
"; - //add stripe sepa button + // Add stripe sepa button $buttonlabel = $langs->trans("MakeWithdrawRequestStripe"); print ''; print ''; diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index 748d7e8bc50..c54b9d149a4 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -154,9 +154,13 @@ abstract class CommonInvoice extends CommonObject */ public $sumcreditnote_multicurrency; /** - * @var string + * @var int|float|string May be used for status */ public $remaintopay; + /** + * @var int May be used for status + */ + public $nbofopendirectdebitorcredittransfer; /** * @var int @@ -486,6 +490,55 @@ abstract class CommonInvoice extends CommonObject } } + /** + * Return list of open direct debit or credit transfer + * + * @param string $type 'bank-transfer' or 'direct-debit' + * @return array Array with list of payments + */ + public function getListOfOpenDirectDebitOrCreditTransfer($type) + { + $listofopendirectdebitorcredittransfer = array(); + + // TODO Add a cache to store array of open requests for each invoice ID + + $sql = "SELECT pfd.rowid, pfd.traite, pfd.date_demande as date_demande, pfd.date_traite as date_traite, pfd.amount"; + $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_demande as pfd"; + if ($type == 'bank-transfer') { + $sql .= " WHERE fk_facture_fourn = ".((int) $this->id); + } else { + $sql .= " WHERE fk_facture = ".((int) $this->id); + } + $sql .= " AND pfd.traite = 0"; + $sql .= " AND pfd.type = 'ban'"; + $sql .= " ORDER BY pfd.date_demande DESC"; + + $resql = $this->db->query($sql); + if ($resql) { + $num = $this->db->num_rows($resql); + $i = 0; + while ($i < $num) { + $obj = $this->db->fetch_object($resql); + if ($obj) { + $listofopendirectdebitorcredittransfer[] = array( + 'id' => $obj->rowid, + 'invoiceid' => (int) $this->id, + 'date' => $this->db->jdate($obj->date_demande), + 'amount' => $obj->amount + ); + } + + $i++; + } + } else { + $this->error = $this->db->lasterror(); + } + + $this->nbofopendirectdebitorcredittransfer = $num; + + return $listofopendirectdebitorcredittransfer; + } + /** * Return list of payments * @@ -849,7 +902,7 @@ abstract class CommonInvoice extends CommonObject */ public function getLibStatut($mode = 0, $alreadypaid = -1) { - return $this->LibStatut($this->paye, $this->status, $mode, $alreadypaid, $this->type); + return $this->LibStatut($this->paye, $this->status, $mode, $alreadypaid, $this->type, $this->nbofopendirectdebitorcredittransfer); } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -861,9 +914,10 @@ abstract class CommonInvoice extends CommonObject * @param int $mode 0=long label, 1=short label, 2=Picto + short label, 3=Picto, 4=Picto + long label, 5=short label + picto, 6=long label + picto * @param integer $alreadypaid 0=No payment already done, >0=Some payments were already done (we recommend to put here amount paid if you have it, -1 otherwise) * @param int $type Type invoice. If -1, we use $this->type + * @param int $nbofopendirectdebitorcredittransfer Nb of open direct debit or credit transfer * @return string Label of status */ - public function LibStatut($paye, $status, $mode = 0, $alreadypaid = -1, $type = -1) + public function LibStatut($paye, $status, $mode = 0, $alreadypaid = -1, $type = -1, $nbofopendirectdebitorcredittransfer = 0) { // phpcs:enable global $langs, $hookmanager; @@ -892,7 +946,7 @@ abstract class CommonInvoice extends CommonObject $labelStatus = $langs->transnoentitiesnoconv('BillStatusClosedPaidPartially'); $labelStatusShort = $langs->transnoentitiesnoconv('Bill'.$prefix.'StatusClosedPaidPartially'); $statusType = 'status9'; - } elseif ($alreadypaid == 0) { + } elseif ($alreadypaid == 0 && $nbofopendirectdebitorcredittransfer == 0) { $labelStatus = $langs->transnoentitiesnoconv('BillStatusNotPaid'); $labelStatusShort = $langs->transnoentitiesnoconv('Bill'.$prefix.'StatusNotPaid'); $statusType = 'status1'; diff --git a/htdocs/langs/en_US/salaries.lang b/htdocs/langs/en_US/salaries.lang index 202c88c7d18..2987021be4e 100644 --- a/htdocs/langs/en_US/salaries.lang +++ b/htdocs/langs/en_US/salaries.lang @@ -29,7 +29,6 @@ FillFieldFirst=Fill employee field first UpdateAmountWithLastSalary=Set amount of last salary MakeTransferRequest=Make transfer request VirementOrder=Credit transfer request -BankTransferAmount=Amount of credit transfer WithdrawalReceipt=Credit transfer order OrderWaiting=Pending order FillEndOfMonth=Fill with end of month From 56571b09ecf79910ba3006b0116cf493490800e0 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 16:59:16 +0100 Subject: [PATCH 176/185] Debug v21 --- htdocs/holiday/card_group.php | 2 +- htdocs/salaries/card.php | 9 ++++++--- htdocs/salaries/virement_request.php | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/htdocs/holiday/card_group.php b/htdocs/holiday/card_group.php index 10b0d02d497..34b5f24109e 100644 --- a/htdocs/holiday/card_group.php +++ b/htdocs/holiday/card_group.php @@ -521,7 +521,7 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { $sql = 'SELECT u.rowid, u.lastname, u.firstname, u.login, u.photo FROM '.MAIN_DB_PREFIX.'user as u'; $sql .= ' WHERE 1 = 1'; - $sql .= !empty($morefilter) ? $morefilter : ''; + $sql .= empty($morefilter) ? '' : $morefilter; $userlist = array(); $userstatic = new User($db); diff --git a/htdocs/salaries/card.php b/htdocs/salaries/card.php index f395d0011d6..9bbf3f4b97c 100644 --- a/htdocs/salaries/card.php +++ b/htdocs/salaries/card.php @@ -467,6 +467,8 @@ if ($action == "update_extras" && $permissiontoadd) { $object->array_options['options_'.$attributekey] = GETPOST($attributekeylong, 'alpha'); } + $triggermodname = 'SALARY_MODIFY'; + $result = $object->insertExtraFields(empty($triggermodname) ? '' : $triggermodname, $user); if ($result > 0) { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); @@ -477,6 +479,7 @@ if ($action == "update_extras" && $permissiontoadd) { } } + /* * View */ @@ -577,7 +580,7 @@ if ($action == 'create' && $permissiontoadd) { print '
'; print $form->editfieldkey('Employee', 'fk_user', '', $object, 0, 'string', '', 1).''; $noactive = 0; // We keep active and unactive users - print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers(GETPOSTINT('fk_user'), 'fk_user', 1, '', 0, '', '', 0, 0, 0, 'AND employee=1', 0, '', 'maxwidth300', $noactive); + print img_picto('', 'user', 'class="pictofixedwidth"').$form->select_dolusers(GETPOSTINT('fk_user'), 'fk_user', 1, '', 0, '', '', 0, 0, 0, 'employee:=:1', 0, '', 'maxwidth300', $noactive); print '
'; if ($action == 'edit') { - print '"; } else { print ""; - print ''; } diff --git a/htdocs/salaries/virement_request.php b/htdocs/salaries/virement_request.php index 71adbc34e3b..de001535e3f 100644 --- a/htdocs/salaries/virement_request.php +++ b/htdocs/salaries/virement_request.php @@ -276,12 +276,12 @@ print '
'; print '
'.$langs->trans("DateStartPeriod").""; + print '
'.$langs->trans("DateStartPeriod").""; print $form->selectDate($object->datesp, 'datesp', 0, 0, 0, 'datesp', 1); print "
' . $langs->trans("DateStartPeriod") . ''; + print '' . $langs->trans("DateStartPeriod") . ''; print dol_print_date($object->datesp, 'day'); print '
'; if ($action == 'edit') { - print '"; } else { print ""; - print ''; } From 08c676731271b9f39ce719ff5ca0491ac6b46ee7 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 17:57:30 +0100 Subject: [PATCH 177/185] Fix the fetch of ModelMail. --- htdocs/core/class/html.formmail.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index c9475f163ab..7eabcd349ff 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -2436,7 +2436,10 @@ class ModelMail extends CommonObject */ public function fetch($id, $ref = null, $noextrafields = 0, $nolines = 0) { - $result = $this->fetchCommon($id, $ref, '', $noextrafields); + // The table llx_c_mail_template has no field ref. The field ref was named "label" instead. So we change the call to fetchCommon. + //$result = $this->fetchCommon($id, $ref, '', $noextrafields); + $result = $this->fetchCommon($id, '', "AND t.label = '".$this->db->escape($ref)."'", $noextrafields); + if ($result > 0 && !empty($this->table_element_line) && empty($nolines)) { $this->fetchLines($noextrafields); } From 42137dd55deec02c4f6b39c661d3b2f4562ae493 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 17:59:20 +0100 Subject: [PATCH 178/185] Code comment --- htdocs/core/class/html.formmail.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 7eabcd349ff..22238016c61 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -2436,7 +2436,7 @@ class ModelMail extends CommonObject */ public function fetch($id, $ref = null, $noextrafields = 0, $nolines = 0) { - // The table llx_c_mail_template has no field ref. The field ref was named "label" instead. So we change the call to fetchCommon. + // The table llx_c_email_templates has no field ref. The field ref was named "label" instead. So we change the call to fetchCommon. //$result = $this->fetchCommon($id, $ref, '', $noextrafields); $result = $this->fetchCommon($id, '', "AND t.label = '".$this->db->escape($ref)."'", $noextrafields); From 95032a8d1d908a64c5be7ede233a03af610904ab Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 18:13:30 +0100 Subject: [PATCH 179/185] Fix syntax error --- htdocs/core/class/html.formmail.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index 22238016c61..3f09d2816f7 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -2438,7 +2438,7 @@ class ModelMail extends CommonObject { // The table llx_c_email_templates has no field ref. The field ref was named "label" instead. So we change the call to fetchCommon. //$result = $this->fetchCommon($id, $ref, '', $noextrafields); - $result = $this->fetchCommon($id, '', "AND t.label = '".$this->db->escape($ref)."'", $noextrafields); + $result = $this->fetchCommon($id, '', " AND t.label = '".$this->db->escape($ref)."'", $noextrafields); if ($result > 0 && !empty($this->table_element_line) && empty($nolines)) { $this->fetchLines($noextrafields); From 54fea8510524331c12a670dedee8fa0fdfb6e141 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 18:25:05 +0100 Subject: [PATCH 180/185] Fix bad balance of transaction --- htdocs/website/class/website.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index c8c6c71ee3e..4e5d9d8e8f9 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1820,6 +1820,8 @@ class Website extends CommonObject */ public function setTemplateName($name_template) { + $this->db->begin(); + $sql = "UPDATE ".$this->db->prefix()."website SET"; $sql .= " name_template = '".$this->db->escape($name_template)."'"; $sql .= " WHERE rowid = ".(int) $this->id; From 0fda35a920b13e329001dd03f1e35f8388b21e13 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 18:38:42 +0100 Subject: [PATCH 181/185] Debug v21 --- htdocs/admin/website.php | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/htdocs/admin/website.php b/htdocs/admin/website.php index 52275a3f80b..8979ee62e67 100644 --- a/htdocs/admin/website.php +++ b/htdocs/admin/website.php @@ -456,6 +456,8 @@ if ($id) { print ''; print ''; + + print '
'; print '
'.$langs->trans("DateStartPeriod").""; + print '
'.$langs->trans("DateStartPeriod").""; print $form->selectDate($object->datesp, 'datesp', 0, 0, 0, 'datesp', 1); print "
' . $langs->trans("DateStartPeriod") . ''; + print '' . $langs->trans("DateStartPeriod") . ''; print dol_print_date($object->datesp, 'day'); print '
'; // Form to add a new line @@ -471,12 +473,12 @@ if ($id) { // dans les dictionnaires de donnees $valuetoshow = ucfirst($fieldlist[$field]); // By default $valuetoshow = $langs->trans($valuetoshow); // try to translate - $align = ''; + $css = ''; if ($fieldlist[$field] == 'lang') { $valuetoshow = $langs->trans("Language"); } if ($valuetoshow != '') { - print '
'; + print ''; if (!empty($tabhelp[$id][$value]) && preg_match('/^http(s*):/i', $tabhelp[$id][$value])) { print ''.$valuetoshow.' '.img_help(1, $valuetoshow).''; } elseif (!empty($tabhelp[$id][$value])) { @@ -523,6 +525,8 @@ if ($id) { } print '
'; + print '
'; + print ''; @@ -631,15 +635,24 @@ if ($id) { foreach ($fieldlist as $field => $value) { $showfield = 1; $fieldname = $fieldlist[$field]; - $align = "left"; + $css = ""; + if ($fieldlist[$field] == 'description') { + $css .= ' tdoverflowmax300'; + } if (in_array($fieldname, array('pageviews_total', 'pageviews_previous_month'))) { - $align = 'right'; + $css = 'right'; + } + if ($fieldlist[$field] == 'date_creation') { + $css .= ' nowraponall'; + } + if ($fieldlist[$field] == 'lastaccess') { + $css .= ' nowraponall'; } $valuetoshow = $obj->$fieldname; // Show value for field if ($showfield) { - print ''.$valuetoshow.''; + print ''.$valuetoshow.''; } } } From 8a80ee0a5be226f4fcdb958aab590319bdb5f563 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 18:40:02 +0100 Subject: [PATCH 182/185] Debug v21 --- htdocs/langs/en_US/website.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/website.lang b/htdocs/langs/en_US/website.lang index fc793f5cf2a..629d5a114cf 100644 --- a/htdocs/langs/en_US/website.lang +++ b/htdocs/langs/en_US/website.lang @@ -88,7 +88,7 @@ WebsiteAccount=Website account WebsiteAccounts=Website accounts AddWebsiteAccount=Create web site account BackToListForThirdParty=Back to list for the third parties -DisableSiteFirst=Disable website first +DisableSiteFirst=Put website offline first MyContainerTitle=My web site title AnotherContainer=This is how to include content of another page/container (you may have an error here if you enable dynamic code because the embedded subcontainer may not exists) SorryWebsiteIsCurrentlyOffLine=Sorry, this website is currently off line. Please comme back later... From 2eaa7a27a962152782e81b99dc69b86c77de7e31 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 19:14:44 +0100 Subject: [PATCH 183/185] Debug v21 --- htdocs/website/class/website.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index 4e5d9d8e8f9..7ebe585c1f9 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1245,15 +1245,17 @@ class Website extends CommonObject dol_mkdir($conf->website->dir_temp.'/'.$object->ref); $filename = basename($pathtofile); + $reg = array(); if (!preg_match('/^website_(.*)-(.*)$/', $filename, $reg)) { $this->errors[] = 'Bad format for filename '.$filename.'. Must be website_XXX-VERSION.'; return -3; } + // Uncompress the zip $result = dol_uncompress($pathtofile, $conf->website->dir_temp.'/'.$object->ref); if (!empty($result['error'])) { - $this->errors[] = 'Failed to unzip file '.$pathtofile.'.'; + $this->errors[] = 'Failed to unzip file '.$pathtofile; return -4; } From e556dfe60484f350462d2fc6b8b6fd14e89a1969 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 20:49:50 +0100 Subject: [PATCH 184/185] Debug v21 --- htdocs/core/class/html.form.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 81653feaa85..3e9aff3b1f1 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -689,7 +689,7 @@ class Form $paramfortooltipimg = ($extracss ? ' class="' . $extracss . '"' : '') . ($extrastyle ? ' style="' . $extrastyle . '"' : ''); // Attribute to put on td text tag } if ($tooltipon == 1 || $tooltipon == 3) { - $paramfortooltiptd = ' class="' . ($tooltipon == 3 ? 'cursorpointer ' : '') . $classfortooltip . ' inline-block' . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '" '; + $paramfortooltiptd = ' class="' . ($tooltipon == 3 ? 'cursorpointer ' : '') . $classfortooltip . ($tag != 'td' ? ' inline-block' : '') . ($extracss ? ' ' . $extracss : '') . '" style="padding: 0px;' . ($extrastyle ? ' ' . $extrastyle : '') . '" '; if ($tooltiptrigger == '') { $paramfortooltiptd .= ' title="' . ($noencodehtmltext ? $htmltext : dol_escape_htmltag($htmltext, 1)) . '"'; // Attribute to put on td tag to store tooltip } else { From 7b69b6c17b276058f492eab46cd026c8cb1bdf15 Mon Sep 17 00:00:00 2001 From: "Laurent Destailleur (aka Eldy)" Date: Mon, 30 Dec 2024 21:05:21 +0100 Subject: [PATCH 185/185] FIX we should not allow to validate negative invoice if invoice is not a credit note. --- htdocs/compta/facture/card.php | 5 +++- htdocs/fourn/facture/card.php | 44 ++++++++++++++++++++++++++++++---- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 8352fac6d48..9f66c23211d 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -2166,6 +2166,7 @@ if (empty($reshook)) { $price_ht_devise = ''; $price_ttc = ''; $price_ttc_devise = ''; + $price_min = ''; $price_min_ttc = ''; @@ -5837,7 +5838,9 @@ if ($action == 'create') { } // Validate - if ($object->status == Facture::STATUS_DRAFT && count($object->lines) > 0 && ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION) && (getDolGlobalString('FACTURE_ENABLE_NEGATIVE') || $object->total_ttc >= 0)) || ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) { + if ($object->status == Facture::STATUS_DRAFT && count($object->lines) > 0 + && ((($object->type == Facture::TYPE_STANDARD || $object->type == Facture::TYPE_REPLACEMENT || $object->type == Facture::TYPE_DEPOSIT || $object->type == Facture::TYPE_PROFORMA || $object->type == Facture::TYPE_SITUATION) && (getDolGlobalString('FACTURE_ENABLE_NEGATIVE') || $object->total_ttc >= 0)) + || ($object->type == Facture::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) { if ($usercanvalidate) { unset($params['attr']['title']); print dolGetButtonAction($langs->trans('Validate'), '', 'default', $_SERVER["PHP_SELF"].'?facid='.$object->id.'&action=valid&token='.newToken(), '', true, $params); diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 1506bc57e17..873a4a7b9a2 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -1591,12 +1591,26 @@ if (empty($reshook)) { $idprod = GETPOSTINT('idprod'); } + $price_ht = ''; + $price_ht_devise = ''; + $price_ttc = ''; + $price_ttc_devise = ''; + + if (GETPOST('price_ht') !== '') { + $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); + } + if (GETPOST('multicurrency_price_ht') !== '') { + $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); + } + if (GETPOST('price_ttc') !== '') { + $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2); + } + if (GETPOST('multicurrency_price_ttc') !== '') { + $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2); + } + $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); // Can be '1.2' or '1.2 (CODE)' - $price_ht = price2num(GETPOST('price_ht'), 'MU', 2); - $price_ht_devise = price2num(GETPOST('multicurrency_price_ht'), 'CU', 2); - $price_ttc = price2num(GETPOST('price_ttc'), 'MU', 2); - $price_ttc_devise = price2num(GETPOST('multicurrency_price_ttc'), 'CU', 2); $qty = price2num(GETPOST('qty'.$predef, 'alpha'), 'MS'); $remise_percent = (GETPOSTISSET('remise_percent'.$predef) ? price2num(GETPOST('remise_percent'.$predef, 'alpha'), '', 2) : 0); @@ -1623,6 +1637,24 @@ if (empty($reshook)) { setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('Type')), null, 'errors'); $error++; } + + if ($prod_entry_mode == 'free' && (!GETPOST('idprodfournprice') || GETPOST('idprodfournprice') == '-1') && (($price_ht < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) || $price_ht == '') && (($price_ht_devise < 0 && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) || $price_ht_devise == '') && $price_ttc === '' && $price_ttc_devise === '' && $object->type != FactureFournisseur::TYPE_CREDIT_NOTE) { // Unit price can be 0 but not '' + if (($price_ht < 0 || $price_ttc < 0) && !getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE_LINES')) { + $langs->load("errors"); + if ($object->type == $object::TYPE_DEPOSIT) { + // Using negative lines on deposit lead to headach and blocking problems when you want to consume them. + setEventMessages($langs->trans("ErrorLinesCantBeNegativeOnDeposits"), null, 'errors'); + } else { + setEventMessages($langs->trans("ErrorFieldCantBeNegativeOnInvoice", $langs->transnoentitiesnoconv("UnitPriceHT"), $langs->transnoentitiesnoconv("CustomerAbsoluteDiscountShort")), null, 'errors'); + } + $error++; + } else { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("UnitPriceHT")), null, 'errors'); + $error++; + } + } + + if ($prod_entry_mode == 'free' && GETPOST('price_ht') === '' && GETPOST('price_ttc') === '' && $price_ht_devise === '') { // Unit price can be 0 but not '' setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('UnitPrice')), null, 'errors'); $error++; @@ -4034,7 +4066,9 @@ if ($action == 'create') { } // Validate - if ($action != 'confirm_edit' && $object->status == FactureFournisseur::STATUS_DRAFT) { + if ($action != 'confirm_edit' && $object->status == FactureFournisseur::STATUS_DRAFT && count($object->lines) > 0 + && ((($object->type == FactureFournisseur::TYPE_STANDARD || $object->type == FactureFournisseur::TYPE_REPLACEMENT || $object->type == FactureFournisseur::TYPE_DEPOSIT || $object->type == FactureFournisseur::TYPE_PROFORMA || $object->type == FactureFournisseur::TYPE_SITUATION) && (getDolGlobalString('SUPPLIER_INVOICE_ENABLE_NEGATIVE') || $object->total_ttc >= 0)) + || ($object->type == FactureFournisseur::TYPE_CREDIT_NOTE && $object->total_ttc <= 0))) { if (count($object->lines)) { if ($usercanvalidate) { print '