From 165d34ec56d12e29b79ab12235d7ca9bffcd9dbb Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Fri, 29 Oct 2021 12:49:27 +0200 Subject: [PATCH 01/64] Fix: Import don't work if extrafield is separator --- htdocs/core/modules/modAdherent.class.php | 2 +- htdocs/core/modules/modBom.class.php | 4 ++-- htdocs/core/modules/modCommande.class.php | 4 ++-- htdocs/core/modules/modFournisseur.class.php | 8 ++++---- htdocs/core/modules/modProduct.class.php | 4 ++-- htdocs/core/modules/modProjet.class.php | 2 +- htdocs/core/modules/modPropale.class.php | 4 ++-- htdocs/core/modules/modResource.class.php | 2 +- htdocs/core/modules/modService.class.php | 2 +- htdocs/core/modules/modSociete.class.php | 4 ++-- htdocs/core/modules/modUser.class.php | 2 +- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/htdocs/core/modules/modAdherent.class.php b/htdocs/core/modules/modAdherent.class.php index 074969451c1..a3942220286 100644 --- a/htdocs/core/modules/modAdherent.class.php +++ b/htdocs/core/modules/modAdherent.class.php @@ -349,7 +349,7 @@ class modAdherent extends DolibarrModules $this->import_fields_array[$r]['a.fk_soc'] = "ThirdParty"; } // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'adherent' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'adherent' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modBom.class.php b/htdocs/core/modules/modBom.class.php index 18f46fda70f..febc6135fab 100644 --- a/htdocs/core/modules/modBom.class.php +++ b/htdocs/core/modules/modBom.class.php @@ -352,7 +352,7 @@ class modBom extends DolibarrModules // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'bom_bom' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'bom_bom' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { @@ -422,7 +422,7 @@ class modBom extends DolibarrModules ]; // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'bom_bomline' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'bom_bomline' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modCommande.class.php b/htdocs/core/modules/modCommande.class.php index 4275d806d40..6e486420328 100644 --- a/htdocs/core/modules/modCommande.class.php +++ b/htdocs/core/modules/modCommande.class.php @@ -322,7 +322,7 @@ class modCommande extends DolibarrModules // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'commande' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { @@ -404,7 +404,7 @@ class modCommande extends DolibarrModules } // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commandedet' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'commandedet' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php index 5d71a5abdc8..4150ab019b3 100644 --- a/htdocs/core/modules/modFournisseur.class.php +++ b/htdocs/core/modules/modFournisseur.class.php @@ -541,7 +541,7 @@ class modFournisseur extends DolibarrModules } // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'facture_fourn' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { @@ -628,7 +628,7 @@ class modFournisseur extends DolibarrModules } // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'facture_fourn_det' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'facture_fourn_det' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { @@ -717,7 +717,7 @@ class modFournisseur extends DolibarrModules // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseur' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'commande_fournisseur' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { @@ -794,7 +794,7 @@ class modFournisseur extends DolibarrModules } // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'commande_fournisseurdet' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'commande_fournisseurdet' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modProduct.class.php b/htdocs/core/modules/modProduct.class.php index 37cda4b7b30..1736abef905 100644 --- a/htdocs/core/modules/modProduct.class.php +++ b/htdocs/core/modules/modProduct.class.php @@ -636,7 +636,7 @@ class modProduct extends DolibarrModules // Add extra fields $import_extrafield_sample = array(); - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'product' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'product' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { @@ -797,7 +797,7 @@ class modProduct extends DolibarrModules // Add extra fields $import_extrafield_sample = array(); - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'product_fournisseur_price' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'product_fournisseur_price' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index 7acbb2bfb68..621d799d4f6 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -296,7 +296,7 @@ class modProjet extends DolibarrModules $this->import_tables_array[$r] = array('t'=>MAIN_DB_PREFIX.'projet_task', 'extra'=>MAIN_DB_PREFIX.'projet_task_extrafields'); // List of tables to insert into (insert done in same order) $this->import_fields_array[$r] = array('t.fk_projet'=>'ProjectRef*', 't.ref'=>'RefTask*', 't.label'=>'LabelTask*', 't.dateo'=>"DateStart", 't.datee'=>"DateEnd", 't.planned_workload'=>"PlannedWorkload", 't.progress'=>"Progress", 't.note_private'=>"NotePrivate", 't.note_public'=>"NotePublic", 't.datec'=>"DateCreation"); // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'projet_task' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'projet_task' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modPropale.class.php b/htdocs/core/modules/modPropale.class.php index eb589fc1759..becab61f862 100644 --- a/htdocs/core/modules/modPropale.class.php +++ b/htdocs/core/modules/modPropale.class.php @@ -302,7 +302,7 @@ class modPropale extends DolibarrModules } // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'propal' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'propal' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { @@ -386,7 +386,7 @@ class modPropale extends DolibarrModules } // Add extra fields $import_extrafield_sample = []; - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'propaldet' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'propaldet' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modResource.class.php b/htdocs/core/modules/modResource.class.php index 6f2d3f8d409..7a042cf5ff7 100644 --- a/htdocs/core/modules/modResource.class.php +++ b/htdocs/core/modules/modResource.class.php @@ -268,7 +268,7 @@ class modResource extends DolibarrModules $this->import_tables_array[$r] = array('r'=>MAIN_DB_PREFIX.'resource', 'extra'=>MAIN_DB_PREFIX.'resource_extrafields'); // List of tables to insert into (insert done in same order) $this->import_fields_array[$r] = array('r.ref'=>"ResourceFormLabel_ref*", 'r.fk_code_type_resource'=>'ResourceTypeCode', 'r.description'=>'ResourceFormLabel_description', 'r.note_private'=>"NotePrivate", 'r.note_public'=>"NotePublic", 'r.asset_number'=>'AssetNumber', 'r.datec'=>'DateCreation'); // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'resource' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'resource' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index 21a26bdc750..60383bf3bea 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -584,7 +584,7 @@ class modService extends DolibarrModules } // Add extra fields $import_extrafield_sample = array(); - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'product' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'product' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index 7c3d93499e4..41d21874c31 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -496,7 +496,7 @@ class modSociete extends DolibarrModules $this->import_fields_array[$r] += array('s.accountancy_code_sell'=>'ProductAccountancySellCode', 's.accountancy_code_buy'=>'ProductAccountancyBuyCode'); } // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'societe' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'societe' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { @@ -674,7 +674,7 @@ class modSociete extends DolibarrModules 's.note_public' => "NotePublic" ); // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'socpeople' AND entity IN (0, ".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'socpeople' AND entity IN (0, ".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on an old database (during a migration for example) while ($obj = $this->db->fetch_object($resql)) { diff --git a/htdocs/core/modules/modUser.class.php b/htdocs/core/modules/modUser.class.php index e54ac7bd440..47cd04ecd26 100644 --- a/htdocs/core/modules/modUser.class.php +++ b/htdocs/core/modules/modUser.class.php @@ -298,7 +298,7 @@ class modUser extends DolibarrModules 'u.statut'=>'Status' ); // Add extra fields - $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'user' AND entity IN (0,".$conf->entity.")"; + $sql = "SELECT name, label, fieldrequired FROM ".MAIN_DB_PREFIX."extrafields WHERE type != 'separate' AND elementtype = 'user' AND entity IN (0,".$conf->entity.")"; $resql = $this->db->query($sql); if ($resql) { // This can fail when class is used on old database (during migration for example) while ($obj = $this->db->fetch_object($resql)) { From 0aa7e7df886767bb9fadb3cf78cf8acf2ee4ee37 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Mar 2022 00:33:24 +0100 Subject: [PATCH 02/64] Fix translation on ticket --- htdocs/takepos/receipt.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/takepos/receipt.php b/htdocs/takepos/receipt.php index 627a6c99565..b834ff64d0a 100644 --- a/htdocs/takepos/receipt.php +++ b/htdocs/takepos/receipt.php @@ -48,7 +48,7 @@ if (!isset($action)) { } include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; -$langs->loadLangs(array("main", "cashdesk", "companies")); +$langs->loadLangs(array("main", "bills", "cashdesk", "companies")); $place = (GETPOST('place', 'aZ09') ? GETPOST('place', 'aZ09') : 0); // $place is id of table for Bar or Restaurant @@ -68,7 +68,7 @@ if (empty($user->rights->takepos->run)) { top_httphead('text/html'); if ($place > 0) { - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture where ref='(PROV-POS".$_SESSION["takeposterminal"]."-".$place.")'"; + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture where ref='(PROV-POS".$db->escape($_SESSION["takeposterminal"]."-".$place).")'"; $resql = $db->query($sql); $obj = $db->fetch_object($resql); if ($obj) { @@ -79,6 +79,7 @@ $object = new Facture($db); $object->fetch($facid); // Call to external receipt modules if exist +$parameters = array(); $hookmanager->initHooks(array('takeposfrontend'), $facid); $reshook = $hookmanager->executeHooks('TakeposReceipt', $parameters, $object); if (!empty($hookmanager->resPrint)) { From 70a18bc15adec60768e9874b93da85e52f4df47b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Mar 2022 01:28:47 +0100 Subject: [PATCH 03/64] FIX creation of the shipment if order contains services --- htdocs/expedition/class/expedition.class.php | 25 ++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 64f0e00d6f8..eb0a5999f29 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -370,13 +370,15 @@ class Expedition extends CommonObject // Insert of lines $num = count($this->lines); for ($i = 0; $i < $num; $i++) { - if (!isset($this->lines[$i]->detail_batch)) { // no batch management - if ($this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->rang, $this->lines[$i]->array_options) <= 0) { - $error++; - } - } else { // with batch management - if ($this->create_line_batch($this->lines[$i], $this->lines[$i]->array_options) <= 0) { - $error++; + if (empty($this->lines[$i]->product_type) || !empty($conf->global->STOCK_SUPPORTS_SERVICES)) { + if (!isset($this->lines[$i]->detail_batch)) { // no batch management + if ($this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty, $this->lines[$i]->rang, $this->lines[$i]->array_options) <= 0) { + $error++; + } + } else { // with batch management + if ($this->create_line_batch($this->lines[$i], $this->lines[$i]->array_options) <= 0) { + $error++; + } } } } @@ -916,6 +918,7 @@ class Expedition extends CommonObject // Copy the rang of the order line to the expedition line $line->rang = $orderline->rang; + $line->product_type = $orderline->product_type; if (!empty($conf->stock->enabled) && !empty($orderline->fk_product)) { $fk_product = $orderline->fk_product; @@ -968,6 +971,8 @@ class Expedition extends CommonObject } $this->lines[$num] = $line; + + return 1; } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -2602,6 +2607,12 @@ class ExpeditionLigne extends CommonObjectLine */ public $product_desc; + /** + * Type of the product. 0 for product, 1 for service + * @var int + */ + public $product_type = 0; + /** * @var int rang of line */ From bd288f980d271ad8ebb9c24646d5d654e733af90 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Mar 2022 14:52:47 +0100 Subject: [PATCH 04/64] FIX On large proposal or invoice, fix n(n+1) sql into a n sql. --- htdocs/comm/propal/class/propal.class.php | 16 +++++++++++----- htdocs/commande/class/commande.class.php | 15 +++++++++++---- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index fd3bbfe7171..26c01ebd044 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -552,10 +552,11 @@ class Propal extends CommonObject * @param int $origin_id Depend on global conf MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION can be Id of origin object (aka line id), else object id * @param double $pu_ht_devise Unit price in currency * @param int $fk_remise_except Id discount if line is from a discount + * @param int $noupdateafterinsertline No update after insert of line * @return int >0 if OK, <0 if KO * @see add_product() */ - public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $fk_product = 0, $remise_percent = 0.0, $price_base_type = 'HT', $pu_ttc = 0.0, $info_bits = 0, $type = 0, $rang = -1, $special_code = 0, $fk_parent_line = 0, $fk_fournprice = 0, $pa_ht = 0, $label = '', $date_start = '', $date_end = '', $array_options = 0, $fk_unit = null, $origin = '', $origin_id = 0, $pu_ht_devise = 0, $fk_remise_except = 0) + public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $fk_product = 0, $remise_percent = 0.0, $price_base_type = 'HT', $pu_ttc = 0.0, $info_bits = 0, $type = 0, $rang = -1, $special_code = 0, $fk_parent_line = 0, $fk_fournprice = 0, $pa_ht = 0, $label = '', $date_start = '', $date_end = '', $array_options = 0, $fk_unit = null, $origin = '', $origin_id = 0, $pu_ht_devise = 0, $fk_remise_except = 0, $noupdateafterinsertline = 0) { global $mysoc, $conf, $langs; @@ -744,7 +745,9 @@ class Propal extends CommonObject } // Mise a jour informations denormalisees au niveau de la propale meme - $result = $this->update_price(1, 'auto', 0, $mysoc); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + if (empty($noupdateafterinsertline)) { + $result = $this->update_price(1, 'auto', 0, $mysoc); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + } if ($result > 0) { $this->db->commit(); @@ -1007,7 +1010,7 @@ class Propal extends CommonObject */ public function create($user, $notrigger = 0) { - global $conf, $hookmanager; + global $conf, $hookmanager, $mysoc; $error = 0; $now = dol_now(); @@ -1236,7 +1239,10 @@ class Propal extends CommonObject $line->array_options, $line->fk_unit, $origintype, - $originid + $originid, + 0, + 0, + 1 ); if ($result < 0) { @@ -1265,7 +1271,7 @@ class Propal extends CommonObject if (!$error) { // Mise a jour infos denormalisees - $resql = $this->update_price(1); + $resql = $this->update_price(1, 'auto', 0, $mysoc); if ($resql) { $action = 'update'; diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 48b7e499dbb..429996ee314 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -872,7 +872,7 @@ class Commande extends CommonOrder */ public function create($user, $notrigger = 0) { - global $conf, $langs; + global $conf, $langs, $mysoc; $error = 0; // Clean parameters @@ -1039,7 +1039,8 @@ class Commande extends CommonOrder $origintype, $originid, 0, - $line->ref_ext + $line->ref_ext, + 1 ); if ($result < 0) { if ($result != self::STOCK_NOT_ENOUGH_FOR_ORDER) { @@ -1056,6 +1057,8 @@ class Commande extends CommonOrder } } + $result = $this->update_price(1, 'auto', 0, $mysoc); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + // update ref $initialref = '(PROV'.$this->id.')'; if (!empty($this->ref)) { @@ -1433,6 +1436,7 @@ class Commande extends CommonOrder * @param int $origin_id Depend on global conf MAIN_CREATEFROM_KEEP_LINE_ORIGIN_INFORMATION can be Id of origin object (aka line id), else object id * @param double $pu_ht_devise Unit price in currency * @param string $ref_ext line external reference + * @param int $noupdateafterinsertline No update after insert of line * @return int >0 if OK, <0 if KO * * @see add_product() @@ -1442,7 +1446,7 @@ class Commande extends CommonOrder * par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,produit) * et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue) */ - public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $fk_product = 0, $remise_percent = 0, $info_bits = 0, $fk_remise_except = 0, $price_base_type = 'HT', $pu_ttc = 0, $date_start = '', $date_end = '', $type = 0, $rang = -1, $special_code = 0, $fk_parent_line = 0, $fk_fournprice = null, $pa_ht = 0, $label = '', $array_options = 0, $fk_unit = null, $origin = '', $origin_id = 0, $pu_ht_devise = 0, $ref_ext = '') + public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0, $txlocaltax2 = 0, $fk_product = 0, $remise_percent = 0, $info_bits = 0, $fk_remise_except = 0, $price_base_type = 'HT', $pu_ttc = 0, $date_start = '', $date_end = '', $type = 0, $rang = -1, $special_code = 0, $fk_parent_line = 0, $fk_fournprice = null, $pa_ht = 0, $label = '', $array_options = 0, $fk_unit = null, $origin = '', $origin_id = 0, $pu_ht_devise = 0, $ref_ext = '', $noupdateafterinsertline = 0) { global $mysoc, $conf, $langs, $user; @@ -1653,7 +1657,10 @@ class Commande extends CommonOrder } // Mise a jour informations denormalisees au niveau de la commande meme - $result = $this->update_price(1, 'auto', 0, $mysoc); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + if (empty($noupdateafterinsertline)) { + $result = $this->update_price(1, 'auto', 0, $mysoc); // This method is designed to add line from user input so total calculation must be done using 'auto' mode. + } + if ($result > 0) { $this->db->commit(); return $this->line->id; From d76e002822b6f34628a11ed41f26db8e4f644671 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Mar 2022 15:17:03 +0100 Subject: [PATCH 05/64] Fix explanation on setup page --- htdocs/admin/receiptprinter.php | 21 +++++++++------------ htdocs/langs/en_US/receiptprinter.lang | 2 +- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/htdocs/admin/receiptprinter.php b/htdocs/admin/receiptprinter.php index a2758304527..cb625dbe039 100644 --- a/htdocs/admin/receiptprinter.php +++ b/htdocs/admin/receiptprinter.php @@ -304,7 +304,15 @@ if ($mode == 'config' && $user->admin) { print ''; print ''.$langs->trans("Name").''; print ''.$langs->trans("Type").''; - print ''.$langs->trans("Profile").''; + print ''; + $htmltext = $langs->trans("PROFILE_DEFAULT").' = '.$langs->trans("PROFILE_DEFAULT_HELP").'
'; + $htmltext .= $langs->trans("PROFILE_SIMPLE").' = '.$langs->trans("PROFILE_SIMPLE_HELP").'
'; + $htmltext .= $langs->trans("PROFILE_EPOSTEP").' = '.$langs->trans("PROFILE_EPOSTEP_HELP").'
'; + $htmltext .= $langs->trans("PROFILE_P822D").' = '.$langs->trans("PROFILE_P822D_HELP").'
'; + $htmltext .= $langs->trans("PROFILE_STAR").' = '.$langs->trans("PROFILE_STAR_HELP").'
'; + + print $form->textwithpicto($langs->trans("Profile"), $htmltext); + print ''; print ''.$langs->trans("Parameters").''; print ''; print "\n"; @@ -386,17 +394,6 @@ if ($mode == 'config' && $user->admin) { print ''; print '
'; - - - print load_fiche_titre($langs->trans("ReceiptPrinterProfileDesc"), '', '')."\n"; - - print ''."\n"; - print ''; - print ''; - print ''; - print ''; - print ''; - print '
'.$langs->trans("PROFILE_DEFAULT").':'.$langs->trans("PROFILE_DEFAULT_HELP").'
'.$langs->trans("PROFILE_SIMPLE").':'.$langs->trans("PROFILE_SIMPLE_HELP").'
'.$langs->trans("PROFILE_EPOSTEP").':'.$langs->trans("PROFILE_EPOSTEP_HELP").'
'.$langs->trans("PROFILE_P822D").':'.$langs->trans("PROFILE_P822D_HELP").'
'.$langs->trans("PROFILE_STAR").':'.$langs->trans("PROFILE_STAR_HELP").'
'; } // mode = template diff --git a/htdocs/langs/en_US/receiptprinter.lang b/htdocs/langs/en_US/receiptprinter.lang index 284c4fa61fa..eb115682726 100644 --- a/htdocs/langs/en_US/receiptprinter.lang +++ b/htdocs/langs/en_US/receiptprinter.lang @@ -7,7 +7,7 @@ TestSentToPrinter=Test Sent To Printer %s ReceiptPrinter=Receipt printers ReceiptPrinterDesc=Setup of receipt printers ReceiptPrinterTemplateDesc=Setup of Templates -ReceiptPrinterTypeDesc=Description of Receipt Printer's type +ReceiptPrinterTypeDesc=Example of possible values for the field "Parameters" according to the type of driver ReceiptPrinterProfileDesc=Description of Receipt Printer's Profile ListPrinters=List of Printers SetupReceiptTemplate=Template Setup From 035bc32323077cb6f1b461aa1b80d07012c31208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9=20Courtier?= Date: Tue, 1 Mar 2022 16:14:31 +0100 Subject: [PATCH 06/64] Correction of the modification on the fly of the table llx_product_fournisseur_price by an addition in the script creation of the table as well as in the script of version upgrade from 12 ->13 --- htdocs/install/mysql/migration/11.0.0-12.0.0.sql | 2 ++ .../mysql/tables/llx_product_fournisseur_price.sql | 2 +- htdocs/product/admin/product.php | 8 ++++---- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql index 02eb3c77d4d..a58f175e2fc 100644 --- a/htdocs/install/mysql/migration/11.0.0-12.0.0.sql +++ b/htdocs/install/mysql/migration/11.0.0-12.0.0.sql @@ -43,6 +43,8 @@ create table llx_commande_fournisseur_dispatch_extrafields ALTER TABLE llx_commande_fournisseur_dispatch_extrafields ADD INDEX idx_commande_fournisseur_dispatch_extrafields (fk_object); +ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging double(24,8) DEFAULT 1; + UPDATE llx_accounting_system SET fk_country = NULL, active = 0 WHERE pcg_version = 'SYSCOHADA'; create table llx_c_shipment_package_type diff --git a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql index 7e61a2df6b1..faccd8d2002 100644 --- a/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql +++ b/htdocs/install/mysql/tables/llx_product_fournisseur_price.sql @@ -50,7 +50,7 @@ create table llx_product_fournisseur_price import_key varchar(14), -- Import key delivery_time_days integer, supplier_reputation varchar(10), - + packaging double(24,8) DEFAULT 1, fk_multicurrency integer, multicurrency_code varchar(255), multicurrency_tx double(24,8) DEFAULT 1, diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 4ef011b28fc..239dba36a7a 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -150,7 +150,7 @@ if ($action == 'other') if ($value) { $sql_test = "SELECT count(desc_fourn) as cpt FROM ".MAIN_DB_PREFIX."product_fournisseur_price WHERE 1"; $resql = $db->query($sql_test); - if (!$resql && $db->lasterrno == 'DB_ERROR_NOSUCHFIELD') // if the field does not exist, we create it + if (!$resql && $db->lasterrno() == 'DB_ERROR_NOSUCHFIELD') // if the field does not exist, we create it { $sql_new = "ALTER TABLE ".MAIN_DB_PREFIX."product_fournisseur_price ADD COLUMN desc_fourn text"; $resql_new = $db->query($sql_new); @@ -162,10 +162,10 @@ if ($action == 'other') if ($value) { $sql_test = "SELECT count(packaging) as cpt FROM ".MAIN_DB_PREFIX."product_fournisseur_price WHERE 1"; $resql = $db->query($sql_test); - if (!$resql && $db->lasterrno == 'DB_ERROR_NOSUCHFIELD') // if the field does not exist, we create it + + if ($resql) // if the field does not exist, we create it { - $sql_new = "ALTER TABLE ".MAIN_DB_PREFIX."product_fournisseur_price ADD COLUMN packaging double(24,8) DEFAULT 1"; - $resql_new = $db->query($sql_new); + dol_syslog( $db->lasterrno(),LOG_ERR); } } } From f1af7ca2f226e5a0e33f20b52d66db784bb9552c Mon Sep 17 00:00:00 2001 From: noec764 <58433943+noec764@users.noreply.github.com> Date: Tue, 1 Mar 2022 16:17:32 +0100 Subject: [PATCH 07/64] Update product.php --- htdocs/product/admin/product.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 239dba36a7a..7c4172f7977 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -163,7 +163,7 @@ if ($action == 'other') $sql_test = "SELECT count(packaging) as cpt FROM ".MAIN_DB_PREFIX."product_fournisseur_price WHERE 1"; $resql = $db->query($sql_test); - if ($resql) // if the field does not exist, we create it + if ($resql < 0) { dol_syslog( $db->lasterrno(),LOG_ERR); } From 5c3b0847c23711678847a7c6373d26d498d7c75c Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Tue, 1 Mar 2022 15:20:28 +0000 Subject: [PATCH 08/64] Fixing style errors. --- htdocs/product/admin/product.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 7c4172f7977..222e9ffc41f 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -165,7 +165,7 @@ if ($action == 'other') if ($resql < 0) { - dol_syslog( $db->lasterrno(),LOG_ERR); + dol_syslog($db->lasterrno(), LOG_ERR); } } } From 2a48dd349e7de0d4a38e448b0d2ecbe25e968075 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Mar 2022 16:38:06 +0100 Subject: [PATCH 09/64] Fix #hunterb03d4415-d4f9-48c8-9ae2-d3aa248027b5 --- htdocs/admin/emailcollector_list.php | 4 +-- htdocs/admin/mails_templates.php | 2 +- htdocs/admin/menus/edit.php | 6 ++--- htdocs/bom/bom_list.php | 2 +- .../compta/cashcontrol/cashcontrol_list.php | 4 +-- htdocs/compta/facture/list.php | 4 +-- htdocs/compta/resultat/result.php | 8 +++--- htdocs/core/boxes/box_scheduled_jobs.php | 2 +- htdocs/core/class/commonobject.class.php | 18 ++++++------- htdocs/core/class/extrafields.class.php | 14 +++++----- htdocs/core/class/html.form.class.php | 2 +- htdocs/core/class/html.formother.class.php | 8 +++--- htdocs/core/class/menu.class.php | 2 +- htdocs/core/class/translate.class.php | 4 +-- htdocs/core/customreports.php | 10 +++---- htdocs/core/lib/functions.lib.php | 26 +++++++++++++------ .../core/tpl/admin_extrafields_view.tpl.php | 2 +- .../tpl/extrafields_list_array_fields.tpl.php | 4 +-- .../tpl/extrafields_list_print_fields.tpl.php | 2 +- .../conferenceorbooth_list.php | 4 +-- .../conferenceorboothattendee_list.php | 4 +-- htdocs/hrm/evaluation_list.php | 4 +-- htdocs/hrm/job_list.php | 4 +-- htdocs/hrm/position.php | 4 +-- htdocs/hrm/position_list.php | 4 +-- htdocs/hrm/skill_card.php | 4 +-- htdocs/hrm/skill_list.php | 4 +-- .../knowledgerecord_list.php | 4 +-- htdocs/mrp/mo_list.php | 4 +-- htdocs/partnership/partnership_list.php | 4 +-- htdocs/product/inventory/list.php | 4 +-- htdocs/product/list.php | 4 +-- htdocs/product/stock/list.php | 4 +-- htdocs/product/stock/productlot_list.php | 4 +-- htdocs/projet/class/task.class.php | 1 + htdocs/projet/list.php | 4 +-- .../recruitmentcandidature_list.php | 4 +-- .../recruitmentjobposition_list.php | 4 +-- htdocs/salaries/list.php | 4 +-- htdocs/salaries/payments.php | 4 +-- htdocs/ticket/list.php | 4 +-- htdocs/workstation/workstation_list.php | 6 ++--- test/phpunit/SecurityTest.php | 24 +++++++++++++++-- 43 files changed, 135 insertions(+), 104 deletions(-) diff --git a/htdocs/admin/emailcollector_list.php b/htdocs/admin/emailcollector_list.php index af137a1ecdb..9e93dd78b86 100644 --- a/htdocs/admin/emailcollector_list.php +++ b/htdocs/admin/emailcollector_list.php @@ -109,11 +109,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = dol_eval($val['visible'], 1); + $visible = dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'] ); } diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index fb3a1ccf702..803f3b74536 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -1034,7 +1034,7 @@ if ($resql) { continue; // It means this is a type of template not into elementList (may be because enabled condition of this type is false because module is not enabled) } // Test on 'enabled' - if (!dol_eval($obj->enabled, 1)) { + if (!dol_eval($obj->enabled, 1, 1, '1')) { $i++; continue; // Email template not qualified } diff --git a/htdocs/admin/menus/edit.php b/htdocs/admin/menus/edit.php index 02c46d8ca35..a9e2fe9287f 100644 --- a/htdocs/admin/menus/edit.php +++ b/htdocs/admin/menus/edit.php @@ -464,7 +464,7 @@ if ($action == 'create') { } print ''; print ''.$langs->trans('DetailMenuIdParent'); - print ', '.$langs->trans("Example").': fk_mainmenu=abc&fk_leftmenu=def'; + print ', '.$langs->trans("Example").': fk_mainmenu=abc&fk_leftmenu=def'; print ''; // Niveau @@ -496,7 +496,7 @@ if ($action == 'create') { print ''.$langs->trans('Enabled').''; print ''.$langs->trans('DetailEnabled'); if (!empty($menu->enabled)) { - print ' ('.$langs->trans("ConditionIsCurrently").': '.yn(dol_eval($menu->enabled, 1)).')'; + print ' ('.$langs->trans("ConditionIsCurrently").': '.yn(dol_eval($menu->enabled, 1, 1, '1')).')'; } print ''; @@ -504,7 +504,7 @@ if ($action == 'create') { print ''.$langs->trans('Rights').''; print ''.$langs->trans('DetailRight'); if (!empty($menu->perms)) { - print ' ('.$langs->trans("ConditionIsCurrently").': '.yn(dol_eval($menu->perms, 1)).')'; + print ' ('.$langs->trans("ConditionIsCurrently").': '.yn(dol_eval($menu->perms, 1, 1, '1')).')'; } print ''; diff --git a/htdocs/bom/bom_list.php b/htdocs/bom/bom_list.php index 3cc0dc1753a..48798db9b8f 100644 --- a/htdocs/bom/bom_list.php +++ b/htdocs/bom/bom_list.php @@ -106,7 +106,7 @@ foreach ($object->fields as $key => $val) { $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/compta/cashcontrol/cashcontrol_list.php b/htdocs/compta/cashcontrol/cashcontrol_list.php index 89781fcb211..7822819c06a 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_list.php +++ b/htdocs/compta/cashcontrol/cashcontrol_list.php @@ -104,11 +104,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 0e3acc45d25..35318174999 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -261,14 +261,14 @@ if (getDolGlobalString("INVOICE_USE_SITUATION") && $conf->global->INVOICE_USE_RE foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $newkey = ''; if (array_key_exists($key, $arrayfields)) { $newkey = $key; } elseif (array_key_exists('t.'.$key, $arrayfields)) { $newkey = 't.'.$key; } elseif (array_key_exists('f.'.$key, $arrayfields)) { $newkey = 'f.'.$key; } elseif (array_key_exists('s.'.$key, $arrayfields)) { $newkey = 's.'.$key; } if ($newkey) { $arrayfields[$newkey] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help' => empty($val['help']) ? '' : $val['help'], ); diff --git a/htdocs/compta/resultat/result.php b/htdocs/compta/resultat/result.php index 635531ab86b..c296d4037e5 100644 --- a/htdocs/compta/resultat/result.php +++ b/htdocs/compta/resultat/result.php @@ -334,7 +334,7 @@ if ($modecompta == 'CREANCES-DETTES') { //var_dump($result); //$r = $AccCat->calculate($result); - $r = dol_eval($result, 1); + $r = dol_eval($result, 1, 1, '1'); //var_dump($r); print ''.price($r).''; @@ -353,7 +353,7 @@ if ($modecompta == 'CREANCES-DETTES') { $result = strtr($formula, $vars); //$r = $AccCat->calculate($result); - $r = dol_eval($result, 1); + $r = dol_eval($result, 1, 1, 1); print ''.price($r).''; $sommes[$code]['N'] += $r; @@ -367,7 +367,7 @@ if ($modecompta == 'CREANCES-DETTES') { $result = strtr($formula, $vars); //$r = $AccCat->calculate($result); - $r = dol_eval($result, 1); + $r = dol_eval($result, 1, 1, 1); print ''.price($r).''; $sommes[$code]['M'][$k] += $r; @@ -381,7 +381,7 @@ if ($modecompta == 'CREANCES-DETTES') { $result = strtr($formula, $vars); //$r = $AccCat->calculate($result); - $r = dol_eval($result, 1); + $r = dol_eval($result, 1, 1, 1); print ''.price($r).''; $sommes[$code]['M'][$k] += $r; diff --git a/htdocs/core/boxes/box_scheduled_jobs.php b/htdocs/core/boxes/box_scheduled_jobs.php index 94695034cce..f2195659654 100644 --- a/htdocs/core/boxes/box_scheduled_jobs.php +++ b/htdocs/core/boxes/box_scheduled_jobs.php @@ -102,7 +102,7 @@ class box_scheduled_jobs extends ModeleBoxes while ($i < $num) { $objp = $this->db->fetch_object($result); - if (dol_eval($objp->test, 1, 1)) { + if (dol_eval($objp->test, 1, 1, '')) { $nextrun = $this->db->jdate($objp->datenextrun); if (empty($nextrun)) { $nextrun = $this->db->jdate($objp->datestart); diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 4b3d6fca2d3..179f1255306 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -5675,12 +5675,12 @@ abstract class CommonObject $enabled = 1; if (isset($this->fields[$key]['enabled'])) { - $enabled = dol_eval($this->fields[$key]['enabled'], 1); + $enabled = dol_eval($this->fields[$key]['enabled'], 1, 1, '1'); } /*$perms = 1; if (isset($this->fields[$key]['perms'])) { - $perms = dol_eval($this->fields[$key]['perms'], 1); + $perms = dol_eval($this->fields[$key]['perms'], 1, 1, '1'); }*/ if (empty($enabled)) { continue; @@ -5836,7 +5836,7 @@ abstract class CommonObject if (!empty($extrafields) && !empty($extrafields->attributes[$this->table_element]['computed'][$key])) { //var_dump($conf->disable_compute); if (empty($conf->disable_compute)) { - $this->array_options["options_".$key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0); + $this->array_options["options_".$key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0, ''); } } } @@ -5967,7 +5967,7 @@ abstract class CommonObject if (!empty($attrfieldcomputed)) { if (!empty($conf->global->MAIN_STORE_COMPUTED_EXTRAFIELDS)) { - $value = dol_eval($attrfieldcomputed, 1, 0); + $value = dol_eval($attrfieldcomputed, 1, 0, ''); dol_syslog($langs->trans("Extrafieldcomputed")." sur ".$attributeLabel."(".$value.")", LOG_DEBUG); $new_array_options[$key] = $value; } else { @@ -6334,7 +6334,7 @@ abstract class CommonObject if (!empty($attrfieldcomputed)) { if (!empty($conf->global->MAIN_STORE_COMPUTED_EXTRAFIELDS)) { - $value = dol_eval($attrfieldcomputed, 1, 0); + $value = dol_eval($attrfieldcomputed, 1, 0, ''); dol_syslog($langs->trans("Extrafieldcomputed")." sur ".$attributeLabel."(".$value.")", LOG_DEBUG); $this->array_options["options_".$key] = $value; } else { @@ -7188,7 +7188,7 @@ abstract class CommonObject if ($computed) { // Make the eval of compute string //var_dump($computed); - $value = dol_eval($computed, 1, 0); + $value = dol_eval($computed, 1, 0, ''); } if (empty($morecss)) { @@ -7713,7 +7713,7 @@ abstract class CommonObject // Test on 'enabled' ('enabled' is different than 'list' = 'visibility') $enabled = 1; if ($enabled && isset($extrafields->attributes[$this->table_element]['enabled'][$key])) { - $enabled = dol_eval($extrafields->attributes[$this->table_element]['enabled'][$key], 1); + $enabled = dol_eval($extrafields->attributes[$this->table_element]['enabled'][$key], 1, 1, '1'); } if (empty($enabled)) { continue; @@ -7721,12 +7721,12 @@ abstract class CommonObject $visibility = 1; if ($visibility && isset($extrafields->attributes[$this->table_element]['list'][$key])) { - $visibility = dol_eval($extrafields->attributes[$this->table_element]['list'][$key], 1); + $visibility = dol_eval($extrafields->attributes[$this->table_element]['list'][$key], 1, 1, '1'); } $perms = 1; if ($perms && isset($extrafields->attributes[$this->table_element]['perms'][$key])) { - $perms = dol_eval($extrafields->attributes[$this->table_element]['perms'][$key], 1); + $perms = dol_eval($extrafields->attributes[$this->table_element]['perms'][$key], 1, 1, '1'); } if (($mode == 'create') && abs($visibility) != 1 && abs($visibility) != 3) { diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 2b827d06f36..ff45a028d51 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -915,9 +915,9 @@ class ExtraFields $unique = $this->attributes[$extrafieldsobjectkey]['unique'][$key]; $required = $this->attributes[$extrafieldsobjectkey]['required'][$key]; $param = $this->attributes[$extrafieldsobjectkey]['param'][$key]; - $perms = dol_eval($this->attributes[$extrafieldsobjectkey]['perms'][$key], 1); + $perms = dol_eval($this->attributes[$extrafieldsobjectkey]['perms'][$key], 1, 1, '1'); $langfile = $this->attributes[$extrafieldsobjectkey]['langfile'][$key]; - $list = dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1); + $list = dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1, 1, '1'); $totalizable = $this->attributes[$extrafieldsobjectkey]['totalizable'][$key]; $help = $this->attributes[$extrafieldsobjectkey]['help'][$key]; $hidden = (empty($list) ? 1 : 0); // If empty, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller) @@ -1505,9 +1505,9 @@ class ExtraFields $unique = $this->attributes[$extrafieldsobjectkey]['unique'][$key]; $required = $this->attributes[$extrafieldsobjectkey]['required'][$key]; $param = $this->attributes[$extrafieldsobjectkey]['param'][$key]; - $perms = dol_eval($this->attributes[$extrafieldsobjectkey]['perms'][$key], 1); + $perms = dol_eval($this->attributes[$extrafieldsobjectkey]['perms'][$key], 1, 1, '1'); $langfile = $this->attributes[$extrafieldsobjectkey]['langfile'][$key]; - $list = dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1); + $list = dol_eval($this->attributes[$extrafieldsobjectkey]['list'][$key], 1, 1, '1'); $help = $this->attributes[$extrafieldsobjectkey]['help'][$key]; $hidden = (empty($list) ? 1 : 0); // If $list empty, we are sure it is hidden, otherwise we show. If it depends on mode (view/create/edit form or list, this must be filtered by caller) } else { @@ -1959,17 +1959,17 @@ class ExtraFields $enabled = 1; if (isset($this->attributes[$object->table_element]['enabled'][$key])) { // 'enabled' is often a condition on module enabled or not - $enabled = dol_eval($this->attributes[$object->table_element]['enabled'][$key], 1); + $enabled = dol_eval($this->attributes[$object->table_element]['enabled'][$key], 1, 1, '1'); } $visibility = 1; if (isset($this->attributes[$object->table_element]['list'][$key])) { // 'list' is option for visibility - $visibility = dol_eval($this->attributes[$object->table_element]['list'][$key], 1); + $visibility = dol_eval($this->attributes[$object->table_element]['list'][$key], 1, 1, '1'); } $perms = 1; if (isset($this->attributes[$object->table_element]['perms'][$key])) { - $perms = dol_eval($this->attributes[$object->table_element]['perms'][$key], 1); + $perms = dol_eval($this->attributes[$object->table_element]['perms'][$key], 1, 1, '1'); } if (empty($enabled)) { continue; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index f25c9aad9d3..975e6ed86ea 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -7424,7 +7424,7 @@ class Form if (!empty($objecttmp->fields)) { // For object that declare it, it is better to use declared fields (like societe, contact, ...) $tmpfieldstoshow = ''; foreach ($objecttmp->fields as $key => $val) { - if (!dol_eval($val['enabled'], 1, 1)) { + if (!dol_eval($val['enabled'], 1, 1, 1, '1')) { continue; } if (!empty($val['showoncombobox'])) { diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index aa0e5486761..6dae77dffa4 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -1501,10 +1501,10 @@ class FormOther 'parent', 'photo', 'socialnetworks', 'webservices_url', 'webservices_key'))) { continue; } - if (isset($val['enabled']) && !dol_eval($val['enabled'], 1)) { + if (isset($val['enabled']) && !dol_eval($val['enabled'], 1, 1, '1')) { continue; } - if (isset($val['visible']) && !dol_eval($val['visible'], 1)) { + if (isset($val['visible']) && !dol_eval($val['visible'], 1, 1, '1')) { continue; } if (preg_match('/^fk_/', $key) && !preg_match('/^fk_statu/', $key)) { @@ -1575,10 +1575,10 @@ class FormOther 'parent', 'photo', 'socialnetworks', 'webservices_url', 'webservices_key'))) { continue; } - if (isset($val['enabled']) && !dol_eval($val['enabled'], 1)) { + if (isset($val['enabled']) && !dol_eval($val['enabled'], 1, 1, '1')) { continue; } - if (isset($val['visible']) && !dol_eval($val['visible'], 1)) { + if (isset($val['visible']) && !dol_eval($val['visible'], 1, 1, '1')) { continue; } if (preg_match('/^fk_/', $key) && !preg_match('/^fk_statu/', $key)) { diff --git a/htdocs/core/class/menu.class.php b/htdocs/core/class/menu.class.php index e88ec701320..eab31288cca 100644 --- a/htdocs/core/class/menu.class.php +++ b/htdocs/core/class/menu.class.php @@ -119,7 +119,7 @@ class Menu { $nb = 0; foreach ($this->liste as $val) { - //if (dol_eval($val['enabled'], 1)) $nb++; + //if (dol_eval($val['enabled'], 1, 1, '1')) $nb++; if (!empty($val['enabled'])) { $nb++; // $val['enabled'] is already evaluated to 0 or 1, no need for dol_eval() } diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index f881447cd67..5bfdbc7e0f1 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -656,7 +656,7 @@ class Translate return $str; } else { // Translation is not available - //if ($key[0] == '$') { return dol_eval($key,1); } + //if ($key[0] == '$') { return dol_eval($key, 1, 1, '1'); } return $this->getTradFromKey($key); } } @@ -722,7 +722,7 @@ class Translate return $str; } else { if ($key[0] == '$') { - return dol_eval($key, 1); + return dol_eval($key, 1, 1, '1'); } return $this->getTradFromKey($key); } diff --git a/htdocs/core/customreports.php b/htdocs/core/customreports.php index fafd1c015e8..0ff8ebc4e64 100644 --- a/htdocs/core/customreports.php +++ b/htdocs/core/customreports.php @@ -371,7 +371,7 @@ print '
'; print '
'.$langs->trans("StatisticsOn").'
'; $newarrayoftype = array(); foreach ($arrayoftype as $key => $val) { - if (dol_eval($val['enabled'], 1)) { + if (dol_eval($val['enabled'], 1, 1, '1')) { $newarrayoftype[$key] = $arrayoftype[$key]; } if ($val['langs']) { @@ -402,7 +402,7 @@ print '
'; // Add measures into array print '
'; foreach ($object->fields as $key => $val) { - if (!empty($val['isameasure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1))) { + if (!empty($val['isameasure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1, 1, '1'))) { $arrayofmesures['t.'.$key.'-sum'] = $langs->trans($val['label']).' ('.$langs->trans("Sum").')'; $arrayofmesures['t.'.$key.'-average'] = $langs->trans($val['label']).' ('.$langs->trans("Average").')'; $arrayofmesures['t.'.$key.'-min'] = $langs->trans($val['label']).' ('.$langs->trans("Minimum").')'; @@ -412,7 +412,7 @@ foreach ($object->fields as $key => $val) { // Add extrafields to Measures if ($object->isextrafieldmanaged) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key]) && (!isset($extrafields->attributes[$object->table_element]['enabled'][$key]) || dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1))) { + if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key]) && (!isset($extrafields->attributes[$object->table_element]['enabled'][$key]) || dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1, 1, '1'))) { $arrayofmesures['te.'.$key.'-sum'] = $langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' ('.$langs->trans("Sum").')'; $arrayofmesures['te.'.$key.'-average'] = $langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' ('.$langs->trans("Average").')'; $arrayofmesures['te.'.$key.'-min'] = $langs->trans($extrafields->attributes[$object->table_element]['label'][$key]).' ('.$langs->trans("Minimum").')'; @@ -443,7 +443,7 @@ if ($mode == 'grid') { // YAxis print '
'; foreach ($object->fields as $key => $val) { - if (empty($val['measure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1))) { + if (empty($val['measure']) && (!isset($val['enabled']) || dol_eval($val['enabled'], 1, 1, '1'))) { if (in_array($key, array('id', 'rowid', 'entity', 'last_main_doc', 'extraparams'))) { continue; } @@ -464,7 +464,7 @@ if ($mode == 'grid') { // Add measure from extrafields if ($object->isextrafieldmanaged) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { - if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key]) && (!isset($extrafields->attributes[$object->table_element]['enabled'][$key]) || dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1))) { + if (!empty($extrafields->attributes[$object->table_element]['totalizable'][$key]) && (!isset($extrafields->attributes[$object->table_element]['enabled'][$key]) || dol_eval($extrafields->attributes[$object->table_element]['enabled'][$key], 1, 1, '1'))) { $arrayofyaxis['te.'.$key] = array('label' => $extrafields->attributes[$object->table_element]['label'][$key], 'position' => (int) $extrafields->attributes[$object->table_element]['pos'][$key]); } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 513534ba38c..c6476f98a11 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8188,12 +8188,13 @@ function verifCond($strToEvaluate) * Replace eval function to add more security. * This function is called by verifCond() or trans() and transnoentitiesnoconv(). * - * @param string $s String to evaluate - * @param int $returnvalue 0=No return (used to execute eval($a=something)). 1=Value of eval is returned (used to eval($something)). - * @param int $hideerrors 1=Hide errors - * @return mixed Nothing or return result of eval + * @param string $s String to evaluate + * @param int $returnvalue 0=No return (used to execute eval($a=something)). 1=Value of eval is returned (used to eval($something)). + * @param int $hideerrors 1=Hide errors + * @param string $onlysimplestring Accept only simple string with char 'a-z0-9\s$_->&|='; + * @return mixed Nothing or return result of eval */ -function dol_eval($s, $returnvalue = 0, $hideerrors = 1) +function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1') { // Only global variables can be changed by eval function and returned to caller global $db, $langs, $user, $conf, $website, $websitepage; @@ -8205,9 +8206,18 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1) global $obj; // To get $obj used into list when dol_eval is used for computed fields and $obj is not yet $object global $soc; // For backward compatibility - // Replace dangerous char (used for RCE), we allow only PHP variable testing. + // Test dangerous char (used for RCE), we allow only PHP variable testing. + if ($onlysimplestring == '1') { + //print preg_quote('$_->&|', '/'); + if (preg_match('/[^a-z0-9\s'.preg_quote('$_->&|=', '/').']/i', $s)) { + return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s; + } + } if (strpos($s, '`') !== false) { - return 'Bad string syntax to evaluate: '.$s; + return 'Bad string syntax to evaluate (backtick char is forbidden): '.$s; + } + if (strpos($s, '.') !== false) { + return 'Bad string syntax to evaluate (dot char is forbidden): '.$s; } // We block use of php exec or php file functions @@ -8215,7 +8225,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1) $forbiddenphpstrings = array_merge($forbiddenphpstrings, array('_ENV', '_SESSION', '_COOKIE', '_GET', '_POST', '_REQUEST')); $forbiddenphpfunctions = array("exec", "passthru", "shell_exec", "system", "proc_open", "popen", "eval", "dol_eval", "executeCLI"); - $forbiddenphpfunctions = array_merge($forbiddenphpfunctions, array("fopen", "file_put_contents", "fputs", "fputscsv", "fwrite", "fpassthru", "unlink", "mkdir", "rmdir", "symlink", "touch", "umask")); + $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("function", "call_user_func")); $forbiddenphpregex = 'global\s+\$|\b('.implode('|', $forbiddenphpfunctions).')\b'; diff --git a/htdocs/core/tpl/admin_extrafields_view.tpl.php b/htdocs/core/tpl/admin_extrafields_view.tpl.php index d1145229db7..369f60ea201 100644 --- a/htdocs/core/tpl/admin_extrafields_view.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_view.tpl.php @@ -73,7 +73,7 @@ print "\n"; if (isset($extrafields->attributes[$elementtype]['type']) && is_array($extrafields->attributes[$elementtype]['type']) && count($extrafields->attributes[$elementtype]['type'])) { foreach ($extrafields->attributes[$elementtype]['type'] as $key => $value) { - /*if (! dol_eval($extrafields->attributes[$elementtype]['enabled'][$key], 1)) { + /*if (! dol_eval($extrafields->attributes[$elementtype]['enabled'][$key], 1, 1, '1')) { // TODO Uncomment this to exclude extrafields of modules not enabled. Add a link to "Show extrafields disabled" // continue; }*/ diff --git a/htdocs/core/tpl/extrafields_list_array_fields.tpl.php b/htdocs/core/tpl/extrafields_list_array_fields.tpl.php index 36eeee89627..b704891da16 100644 --- a/htdocs/core/tpl/extrafields_list_array_fields.tpl.php +++ b/htdocs/core/tpl/extrafields_list_array_fields.tpl.php @@ -23,9 +23,9 @@ if (!empty($extrafieldsobjectkey)) { // $extrafieldsobject is the $object->table $arrayfields[$extrafieldsobjectprefix.$key] = array( 'label' => $extrafields->attributes[$extrafieldsobjectkey]['label'][$key], 'type' => $extrafields->attributes[$extrafieldsobjectkey]['type'][$key], - 'checked' => ((dol_eval($extrafields->attributes[$extrafieldsobjectkey]['list'][$key], 1) <= 0) ? 0 : 1), + 'checked' => ((dol_eval($extrafields->attributes[$extrafieldsobjectkey]['list'][$key], 1, 1, '1') <= 0) ? 0 : 1), 'position' => $extrafields->attributes[$extrafieldsobjectkey]['pos'][$key], - 'enabled' => (abs((int) $extrafields->attributes[$extrafieldsobjectkey]['list'][$key]) != 3 && dol_eval($extrafields->attributes[$extrafieldsobjectkey]['perms'][$key], 1)), + 'enabled' => (abs((int) $extrafields->attributes[$extrafieldsobjectkey]['list'][$key]) != 3 && dol_eval($extrafields->attributes[$extrafieldsobjectkey]['perms'][$key], 1, 1, '1')), 'langfile' => $extrafields->attributes[$extrafieldsobjectkey]['langfile'][$key], 'help' => $extrafields->attributes[$extrafieldsobjectkey]['help'][$key], ); diff --git a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php index 80d6cd7da56..00c2739e3f8 100644 --- a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php +++ b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php @@ -38,7 +38,7 @@ if (!empty($extrafieldsobjectkey) && !empty($extrafields->attributes[$extrafield //var_dump($extrafields->attributes[$extrafieldsobjectkey]['computed'][$key]); //var_dump($obj); //var_dump($extrafields->attributes[$extrafieldsobjectkey]['computed'][$key]); - $value = dol_eval($extrafields->attributes[$extrafieldsobjectkey]['computed'][$key], 1); + $value = dol_eval($extrafields->attributes[$extrafieldsobjectkey]['computed'][$key], 1, 1, '0'); //var_dump($value); } diff --git a/htdocs/eventorganization/conferenceorbooth_list.php b/htdocs/eventorganization/conferenceorbooth_list.php index d105ad05c43..943205adca2 100644 --- a/htdocs/eventorganization/conferenceorbooth_list.php +++ b/htdocs/eventorganization/conferenceorbooth_list.php @@ -114,11 +114,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/eventorganization/conferenceorboothattendee_list.php b/htdocs/eventorganization/conferenceorboothattendee_list.php index e084c68cfe7..ab2699187b2 100644 --- a/htdocs/eventorganization/conferenceorboothattendee_list.php +++ b/htdocs/eventorganization/conferenceorboothattendee_list.php @@ -122,11 +122,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/hrm/evaluation_list.php b/htdocs/hrm/evaluation_list.php index 35189f11b87..ad99573b096 100644 --- a/htdocs/hrm/evaluation_list.php +++ b/htdocs/hrm/evaluation_list.php @@ -114,11 +114,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/hrm/job_list.php b/htdocs/hrm/job_list.php index 55363d729b5..7644ea1fd0f 100644 --- a/htdocs/hrm/job_list.php +++ b/htdocs/hrm/job_list.php @@ -114,11 +114,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/hrm/position.php b/htdocs/hrm/position.php index d36d352e895..253945e6c5a 100644 --- a/htdocs/hrm/position.php +++ b/htdocs/hrm/position.php @@ -357,11 +357,11 @@ function DisplayPositionList() foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.' . $key] = array( 'label' => $val['label'], 'checked' => (($visible < 0) ? 0 : 1), - 'enabled' => ($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled' => ($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position' => $val['position'], 'help' => isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/hrm/position_list.php b/htdocs/hrm/position_list.php index 1585ed1e03f..13315a2a9bc 100644 --- a/htdocs/hrm/position_list.php +++ b/htdocs/hrm/position_list.php @@ -114,11 +114,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/hrm/skill_card.php b/htdocs/hrm/skill_card.php index a06cf40952a..7c63bb2cff7 100644 --- a/htdocs/hrm/skill_card.php +++ b/htdocs/hrm/skill_card.php @@ -538,11 +538,11 @@ if ($action != "create" && $action != "edit") { foreach ($objectline->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.' . $key] = array( 'label' => $val['label'], 'checked' => (($visible < 0) ? 0 : 1), - 'enabled' => ($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled' => ($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position' => $val['position'], 'help' => isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/hrm/skill_list.php b/htdocs/hrm/skill_list.php index 1fc5440e589..8ef800b3ffc 100644 --- a/htdocs/hrm/skill_list.php +++ b/htdocs/hrm/skill_list.php @@ -114,11 +114,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/knowledgemanagement/knowledgerecord_list.php b/htdocs/knowledgemanagement/knowledgerecord_list.php index aed45b1db26..c4440028e49 100644 --- a/htdocs/knowledgemanagement/knowledgerecord_list.php +++ b/htdocs/knowledgemanagement/knowledgerecord_list.php @@ -114,11 +114,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/mrp/mo_list.php b/htdocs/mrp/mo_list.php index e5648cad5f7..6e15a71e517 100644 --- a/htdocs/mrp/mo_list.php +++ b/htdocs/mrp/mo_list.php @@ -109,11 +109,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/partnership/partnership_list.php b/htdocs/partnership/partnership_list.php index 89394960632..dc9958fa3df 100644 --- a/htdocs/partnership/partnership_list.php +++ b/htdocs/partnership/partnership_list.php @@ -118,11 +118,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/product/inventory/list.php b/htdocs/product/inventory/list.php index 41e43fdf433..c4548b3aa66 100644 --- a/htdocs/product/inventory/list.php +++ b/htdocs/product/inventory/list.php @@ -102,11 +102,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/product/list.php b/htdocs/product/list.php index a3ec599dea8..26dbf18e439 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -244,11 +244,11 @@ $arrayfields = array( /*foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = dol_eval($val['visible'], 1); + $visible = dol_eval($val['visible'], 1, 1, '1'); $arrayfields['p.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'] ); } diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index 8f24fb9c110..93c963e0065 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -117,11 +117,11 @@ $arrayfields = array( foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : 'help' ); diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index e5a8b05902e..92172643096 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -104,11 +104,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = dol_eval($val['visible'], 1); + $visible = dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'] ); } diff --git a/htdocs/projet/class/task.class.php b/htdocs/projet/class/task.class.php index 56db0bd2a64..3eeb1bb1e4c 100644 --- a/htdocs/projet/class/task.class.php +++ b/htdocs/projet/class/task.class.php @@ -27,6 +27,7 @@ */ 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.'/projet/class/project.class.php'; diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index cc9099b463b..36c2fc942b5 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -182,11 +182,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = dol_eval($val['visible'], 1); + $visible = dol_eval($val['visible'], 1, 1, '1'); $arrayfields['p.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/recruitment/recruitmentcandidature_list.php b/htdocs/recruitment/recruitmentcandidature_list.php index f16b8c3dcf9..05cf56636ea 100644 --- a/htdocs/recruitment/recruitmentcandidature_list.php +++ b/htdocs/recruitment/recruitmentcandidature_list.php @@ -151,11 +151,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = dol_eval($val['visible'], 1); + $visible = dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'] ); } diff --git a/htdocs/recruitment/recruitmentjobposition_list.php b/htdocs/recruitment/recruitmentjobposition_list.php index f0935bc8798..c4a43d0bab4 100644 --- a/htdocs/recruitment/recruitmentjobposition_list.php +++ b/htdocs/recruitment/recruitmentjobposition_list.php @@ -153,11 +153,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/salaries/list.php b/htdocs/salaries/list.php index 7a8b3ebca10..2e77c29cd01 100644 --- a/htdocs/salaries/list.php +++ b/htdocs/salaries/list.php @@ -134,11 +134,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/salaries/payments.php b/htdocs/salaries/payments.php index 77cbae397f0..58f5546216f 100644 --- a/htdocs/salaries/payments.php +++ b/htdocs/salaries/payments.php @@ -129,11 +129,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index b2548807be4..f489c9218fc 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -136,11 +136,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help'=> isset($val['help']) ? $val['help'] : '' ); diff --git a/htdocs/workstation/workstation_list.php b/htdocs/workstation/workstation_list.php index 25dcc44de65..0d17232c9db 100644 --- a/htdocs/workstation/workstation_list.php +++ b/htdocs/workstation/workstation_list.php @@ -108,11 +108,11 @@ $arrayfields = array(); foreach ($object->fields as $key => $val) { // If $val['visible']==0, then we never show the field if (!empty($val['visible'])) { - $visible = (int) dol_eval($val['visible'], 1); + $visible = (int) dol_eval($val['visible'], 1, 1, '1'); $arrayfields['t.'.$key] = array( 'label'=>$val['label'], 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>$val['position'], 'help' => empty($val['help']) ? '' : $val['help'] ); @@ -130,7 +130,7 @@ $arrayfields['wug.fk_usergroup'] = array( $arrayfields['wr.fk_resource'] = array( 'label'=>$langs->trans('Resources'), 'checked'=>(($visible < 0) ? 0 : 1), - 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1)), + 'enabled'=>($visible != 3 && dol_eval($val['enabled'], 1, 1, '1')), 'position'=>1001, 'help' => empty($val['help']) ? '' : $val['help'] ); diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 15e4eaa8bda..a687e6adbd7 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -875,11 +875,18 @@ class SecurityTest extends PHPUnit\Framework\TestCase include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; include_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; - $result=dol_eval('(($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"', 1, 1); + + $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=dol_eval($s, 1, 1, ''); print "result = ".$result."\n"; $this->assertEquals('Parent project not found', $result); - $result=dol_eval('$a=function() { }; $a;', 1, 1); + $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=dol_eval($s, 1, 1, ''); + print "result = ".$result."\n"; + $this->assertEquals('Parent project not found', $result); + + $result=dol_eval('$a=function() { }; $a;', 1, 1, ''); print "result = ".$result."\n"; $this->assertContains('Bad string syntax to evaluate', $result); @@ -898,5 +905,18 @@ class SecurityTest extends PHPUnit\Framework\TestCase $result=dol_eval('`ls`', 1, 0); print "result = ".$result."\n"; $this->assertContains('Bad string syntax to evaluate', $result); + + $result=dol_eval("('ex'.'ec')('echo abc')", 1, 0); + print "result = ".$result."\n"; + $this->assertContains('Bad string syntax to evaluate', $result); + + // Case with param onlysimplestring = 1 + $result=dol_eval('1 && $conf->abc->doesnotexist1 && $conf->def->doesnotexist1', 1, 0); // Should return false and not a 'Bad string syntax to evaluate ...' + print "result = ".$result."\n"; + $this->assertFalse($result); + + $result=dol_eval("(\$a.'aa')", 1, 0); + print "result = ".$result."\n"; + $this->assertContains('Bad string syntax to evaluate', $result); } } From 29eec8444e315233d3f632b3171ce50e26f4d3d5 Mon Sep 17 00:00:00 2001 From: John Livingston Date: Tue, 1 Mar 2022 16:41:07 +0100 Subject: [PATCH 10/64] Fix: update status_batch documentation $product->status_batch has a new possible value that was not documented. --- 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 8e61663d339..0e0058130ac 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -272,7 +272,7 @@ class Product extends CommonObject public $fk_default_bom; /** - * We must manage lot/batch number, sell-by date and so on : '1':yes '0':no + * We must manage lot/batch number, sell-by date and so on : '0':no, '1':yes, '2": yes with unique serial number * * @var int */ From 237b6fc9226e1c3e87d68ddce1f2dc9229473f63 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Mar 2022 17:07:28 +0100 Subject: [PATCH 11/64] Fix value recommended --- htdocs/admin/system/security.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index 9321fa11c12..eb3a6d7c884 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -444,7 +444,7 @@ print '
'; print 'MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = '.(empty($conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': 1)' : $conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES)."
"; print '
'; -print 'MAIN_SECURITY_CSRF_WITH_TOKEN = '.(empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': 2)' : $conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN)."
"; +print 'MAIN_SECURITY_CSRF_WITH_TOKEN = '.(empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN).'   ('.$langs->trans("Recommended").': 2)'."
"; print '
'; print 'MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL = '.(empty($conf->global->MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or").' 0)' : $conf->global->MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL)."
"; From b79ad197ec3760f844e37a8d52f63ea47ea162a1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Mar 2022 17:29:22 +0100 Subject: [PATCH 12/64] FIX Missing the field date start/end in export supplier invoice/order --- htdocs/core/modules/modFournisseur.class.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php index 0f730f773bb..a9760c62c04 100644 --- a/htdocs/core/modules/modFournisseur.class.php +++ b/htdocs/core/modules/modFournisseur.class.php @@ -293,7 +293,8 @@ class modFournisseur extends DolibarrModules 'f.rowid'=>"InvoiceId", 'f.ref'=>"InvoiceRef", 'f.ref_supplier'=>"RefSupplier", 'f.datec'=>"InvoiceDateCreation", 'f.datef'=>"DateInvoice", 'f.date_lim_reglement'=>'DateMaxPayment', 'f.total_ht'=>"TotalHT", 'f.total_ttc'=>"TotalTTC", 'f.total_tva'=>"TotalVAT", 'f.paye'=>"InvoicePaid", 'f.fk_statut'=>'InvoiceStatus', 'f.note_public'=>"InvoiceNote", 'fd.rowid'=>'LineId', 'fd.description'=>"LineDescription", 'fd.tva_tx'=>"LineVATRate", 'fd.qty'=>"LineQty", 'fd.remise_percent'=>"Discount", 'fd.total_ht'=>"LineTotalHT", - 'fd.total_ttc'=>"LineTotalTTC", 'fd.tva'=>"LineTotalVAT", 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.fk_product'=>'ProductId', + 'fd.total_ttc'=>"LineTotalTTC", 'fd.tva'=>"LineTotalVAT", 'fd.date_start'=>"DateStart", 'fd.date_end'=>"DateEnd", 'fd.special_code'=>'SpecialCode', + 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.fk_product'=>'ProductId', 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel', 'p.accountancy_code_buy'=>'ProductAccountancyBuyCode', 'project.rowid'=>'ProjectId', 'project.ref'=>'ProjectRef', 'project.title'=>'ProjectLabel' ); @@ -314,7 +315,8 @@ class modFournisseur extends DolibarrModules 's.nom'=>'Text', 'ps.nom'=>'Text', 's.address'=>'Text', 's.zip'=>'Text', 's.town'=>'Text', 'c.code'=>'Text', 's.phone'=>'Text', 's.siren'=>'Text', 's.siret'=>'Text', 's.ape'=>'Text', 's.idprof4'=>'Text', 's.idprof5'=>'Text', 's.idprof6'=>'Text', 's.code_compta'=>'Text', 's.code_compta_fournisseur'=>'Text', 's.tva_intra'=>'Text', 'f.ref'=>"Text", 'f.ref_supplier'=>"Text", 'f.datec'=>"Date", 'f.datef'=>"Date", 'f.date_lim_reglement'=>'Date', 'f.total_ht'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.total_tva'=>"Numeric", 'f.paye'=>"Boolean", 'f.fk_statut'=>'Status', 'f.note_public'=>"Text", 'fd.description'=>"Text", 'fd.tva_tx'=>"Text", - 'fd.qty'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.tva'=>"Numeric", 'fd.product_type'=>'Numeric', 'fd.fk_product'=>'List:product:label', + 'fd.qty'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.tva'=>"Numeric", 'fd.date_start'=>"Date", 'fd.date_end'=>"Date", 'fd.special_code'=>"Numeric", + 'fd.product_type'=>'Numeric', 'fd.fk_product'=>'List:product:label', 'p.ref'=>'Text', 'p.label'=>'Text', 'project.ref'=>'Text', 'project.title'=>'Text' ); $this->export_entities_array[$r] = array( @@ -322,7 +324,8 @@ class modFournisseur extends DolibarrModules 's.ape'=>'company', 's.idprof4'=>'company', 's.idprof5'=>'company', 's.idprof6'=>'company', 's.code_compta'=>'company', 's.code_compta_fournisseur'=>'company', 's.tva_intra'=>'company', 'f.rowid'=>"invoice", 'f.ref'=>"invoice", 'f.ref_supplier'=>"invoice", 'f.datec'=>"invoice", 'f.datef'=>"invoice", 'f.date_lim_reglement'=>'invoice', 'f.total_ht'=>"invoice", 'f.total_ttc'=>"invoice", 'f.total_tva'=>"invoice", 'f.paye'=>"invoice", 'f.fk_statut'=>'invoice', 'f.note_public'=>"invoice", 'fd.rowid'=>'invoice_line', 'fd.description'=>"invoice_line", 'fd.tva_tx'=>"invoice_line", 'fd.qty'=>"invoice_line", - 'fd.remise_percent'=>"invoice_line", 'fd.total_ht'=>"invoice_line", 'fd.total_ttc'=>"invoice_line", 'fd.tva'=>"invoice_line", 'fd.product_type'=>'invoice_line', 'fd.fk_product'=>'product', + 'fd.remise_percent'=>"invoice_line", 'fd.total_ht'=>"invoice_line", 'fd.total_ttc'=>"invoice_line", 'fd.tva'=>"invoice_line", 'fd.date_start'=>"invoice_line", 'fd.date_end'=>"invoice_line", 'fd.special_code'=>"invoice_line", + 'fd.product_type'=>'invoice_line', 'fd.fk_product'=>'product', 'p.ref'=>'product', 'p.label'=>'product', 'p.accountancy_code_buy'=>'product', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project' ); $this->export_dependencies_array[$r] = array('invoice_line'=>'fd.rowid', 'product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them @@ -432,7 +435,8 @@ class modFournisseur extends DolibarrModules 'f.total_ht'=>"TotalHT", 'f.total_ttc'=>"TotalTTC", 'f.total_tva'=>"TotalVAT", 'f.fk_statut'=>'Status', 'f.date_valid'=>'DateValidation', 'f.date_approve'=>'DateApprove', 'f.date_approve2'=>'DateApprove2', 'f.note_public'=>"NotePublic", 'f.note_private'=>"NotePrivate", 'uv.login'=>'UserValidation', 'ua1.login'=>'ApprovedBy', 'ua2.login'=>'ApprovedBy2', 'fd.rowid'=>'LineId', 'fd.description'=>"LineDescription", 'fd.tva_tx'=>"LineVATRate", 'fd.qty'=>"LineQty", 'fd.remise_percent'=>"Discount", 'fd.total_ht'=>"LineTotalHT", 'fd.total_ttc'=>"LineTotalTTC", - 'fd.total_tva'=>"LineTotalVAT", 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.ref'=>'RefSupplier', 'fd.fk_product'=>'ProductId', + 'fd.total_tva'=>"LineTotalVAT", 'fd.date_start'=>"DateStart", 'fd.date_end'=>"DateEnd", 'fd.special_code'=>'SpecialCode', + 'fd.product_type'=>'TypeOfLineServiceOrProduct', 'fd.ref'=>'RefSupplier', 'fd.fk_product'=>'ProductId', 'p.ref'=>'ProductRef', 'p.label'=>'ProductLabel', 'project.rowid'=>'ProjectId', 'project.ref'=>'ProjectRef', 'project.title'=>'ProjectLabel' ); if (!empty($conf->multicurrency->enabled)) { @@ -452,13 +456,15 @@ class modFournisseur extends DolibarrModules 'f.date_creation'=>"Date", 'f.date_commande'=>"Date", 'f.date_livraison'=>"Date", 'f.total_ht'=>"Numeric", 'f.total_ttc'=>"Numeric", 'f.total_tva'=>"Numeric", 'f.fk_statut'=>'Status', 'f.date_valid'=>'Date', 'f.date_approve'=>'Date', 'f.date_approve2'=>'Date', 'f.note_public'=>"Text", 'f.note_private'=>"Text", 'fd.description'=>"Text", 'fd.tva_tx'=>"Numeric", 'fd.qty'=>"Numeric", 'fd.remise_percent'=>"Numeric", 'fd.total_ht'=>"Numeric", 'fd.total_ttc'=>"Numeric", 'fd.total_tva'=>"Numeric", + 'fd.date_start'=>"Date", 'fd.date_end'=>"Date", 'fd.special_code'=>"Numeric", 'fd.product_type'=>'Numeric', 'fd.ref'=>'Text', 'fd.fk_product'=>'List:product:label', 'p.ref'=>'Text', 'p.label'=>'Text', 'project.ref'=>'Text', 'project.title'=>'Text' ); $this->export_entities_array[$r] = array( 's.rowid'=>"company", 's.nom'=>'company', 'ps.nom'=>'company', 's.address'=>'company', 's.zip'=>'company', 's.town'=>'company', 'c.code'=>'company', 's.phone'=>'company', 's.siren'=>'company', 's.siret'=>'company', 's.ape'=>'company', 's.idprof4'=>'company', 's.idprof5'=>'company', 's.idprof6'=>'company', 's.tva_intra'=>'company', 'uv.login'=>'user', 'ua1.login'=>'user', 'ua2.login'=>'user', 'fd.rowid'=>'order_line', 'fd.description'=>"order_line", 'fd.tva_tx'=>"order_line", 'fd.qty'=>"order_line", 'fd.remise_percent'=>"order_line", - 'fd.total_ht'=>"order_line", 'fd.total_ttc'=>"order_line", 'fd.total_tva'=>"order_line", 'fd.product_type'=>'order_line', 'fd.ref'=>'order_line', 'fd.fk_product'=>'product', + 'fd.total_ht'=>"order_line", 'fd.total_ttc'=>"order_line", 'fd.total_tva'=>"order_line", 'fd.date_start'=>"order_line", 'fd.date_end'=>"order_line", 'fd.special_code'=>"order_line", + 'fd.product_type'=>'order_line', 'fd.ref'=>'order_line', 'fd.fk_product'=>'product', 'p.ref'=>'product', 'p.label'=>'product', 'project.rowid'=>'project', 'project.ref'=>'project', 'project.title'=>'project' ); $this->export_dependencies_array[$r] = array('order_line'=>'fd.rowid', 'product'=>'fd.rowid'); // To add unique key if we ask a field of a child to avoid the DISTINCT to discard them From 1ece554c9241335c0ca0c7ed803b67c9577fba07 Mon Sep 17 00:00:00 2001 From: John Livingston Date: Tue, 1 Mar 2022 17:39:38 +0100 Subject: [PATCH 13/64] Fix: typo in template name There was a typo in generated HTML comment. --- htdocs/adherents/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/asset/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/bom/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/comm/propal/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/commande/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/compta/facture/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/compta/facture/tpl/linkedobjectblockForRec.tpl.php | 2 +- htdocs/contrat/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/don/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/eventorganization/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/expedition/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/expensereport/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/fichinter/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php | 2 +- .../template/core/tpl/linkedobjectblock_myobject.tpl.php | 2 +- htdocs/mrp/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/reception/tpl/linkedobjectblock.tpl.php | 2 +- htdocs/ticket/tpl/linkedobjectblock.tpl.php | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/htdocs/adherents/tpl/linkedobjectblock.tpl.php b/htdocs/adherents/tpl/linkedobjectblock.tpl.php index 3acb14a4cdb..5928b706a8e 100644 --- a/htdocs/adherents/tpl/linkedobjectblock.tpl.php +++ b/htdocs/adherents/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -echo "\n"; +echo "\n"; global $user; diff --git a/htdocs/asset/tpl/linkedobjectblock.tpl.php b/htdocs/asset/tpl/linkedobjectblock.tpl.php index 59df306c829..aef30995432 100644 --- a/htdocs/asset/tpl/linkedobjectblock.tpl.php +++ b/htdocs/asset/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -print "\n"; +print "\n"; global $user; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/bom/tpl/linkedobjectblock.tpl.php b/htdocs/bom/tpl/linkedobjectblock.tpl.php index 2737b425c9c..8a98c078bc5 100644 --- a/htdocs/bom/tpl/linkedobjectblock.tpl.php +++ b/htdocs/bom/tpl/linkedobjectblock.tpl.php @@ -24,7 +24,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -print "\n"; +print "\n"; global $user, $db; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php index adc9de9339e..613f06a6feb 100644 --- a/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php +++ b/htdocs/comm/propal/tpl/linkedobjectblock.tpl.php @@ -30,7 +30,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/commande/tpl/linkedobjectblock.tpl.php b/htdocs/commande/tpl/linkedobjectblock.tpl.php index 2a6140aaeed..8c1df906ab7 100644 --- a/htdocs/commande/tpl/linkedobjectblock.tpl.php +++ b/htdocs/commande/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -print "\n"; +print "\n"; global $user; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php b/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php index 0b22e31be4b..03b410466f0 100644 --- a/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php +++ b/htdocs/compta/facture/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -print "\n"; +print "\n"; global $user; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/compta/facture/tpl/linkedobjectblockForRec.tpl.php b/htdocs/compta/facture/tpl/linkedobjectblockForRec.tpl.php index d222dfd21dc..d2ef4657586 100644 --- a/htdocs/compta/facture/tpl/linkedobjectblockForRec.tpl.php +++ b/htdocs/compta/facture/tpl/linkedobjectblockForRec.tpl.php @@ -24,7 +24,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/contrat/tpl/linkedobjectblock.tpl.php b/htdocs/contrat/tpl/linkedobjectblock.tpl.php index cdbda7a17b8..5297026d5d3 100644 --- a/htdocs/contrat/tpl/linkedobjectblock.tpl.php +++ b/htdocs/contrat/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/don/tpl/linkedobjectblock.tpl.php b/htdocs/don/tpl/linkedobjectblock.tpl.php index 4097e73d560..5d564d43f7a 100644 --- a/htdocs/don/tpl/linkedobjectblock.tpl.php +++ b/htdocs/don/tpl/linkedobjectblock.tpl.php @@ -19,7 +19,7 @@ * */ -print "\n"; +print "\n"; global $user; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php b/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php index 9f761c24bc6..127ea95a424 100644 --- a/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php +++ b/htdocs/eventorganization/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -echo "\n"; +echo "\n"; global $user; diff --git a/htdocs/expedition/tpl/linkedobjectblock.tpl.php b/htdocs/expedition/tpl/linkedobjectblock.tpl.php index 26e4ebbb47d..2305b0d4fac 100644 --- a/htdocs/expedition/tpl/linkedobjectblock.tpl.php +++ b/htdocs/expedition/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/expensereport/tpl/linkedobjectblock.tpl.php b/htdocs/expensereport/tpl/linkedobjectblock.tpl.php index 6a36b62f924..f97099e57dc 100644 --- a/htdocs/expensereport/tpl/linkedobjectblock.tpl.php +++ b/htdocs/expensereport/tpl/linkedobjectblock.tpl.php @@ -24,7 +24,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/fichinter/tpl/linkedobjectblock.tpl.php b/htdocs/fichinter/tpl/linkedobjectblock.tpl.php index e5903ee5863..8da01bb4f8f 100644 --- a/htdocs/fichinter/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fichinter/tpl/linkedobjectblock.tpl.php @@ -22,7 +22,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php b/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php index 1efd78df372..192a39c9b06 100644 --- a/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fourn/commande/tpl/linkedobjectblock.tpl.php @@ -23,7 +23,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php b/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php index 3f728d99567..e9ec8accf30 100644 --- a/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php +++ b/htdocs/fourn/facture/tpl/linkedobjectblock.tpl.php @@ -25,7 +25,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php b/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php index 2f0ecd06774..21cb16c3644 100644 --- a/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php +++ b/htdocs/modulebuilder/template/core/tpl/linkedobjectblock_myobject.tpl.php @@ -22,7 +22,7 @@ if (empty($conf) || !is_object($conf)) { } -print "\n"; +print "\n"; global $user; diff --git a/htdocs/mrp/tpl/linkedobjectblock.tpl.php b/htdocs/mrp/tpl/linkedobjectblock.tpl.php index 5dbe583fd21..ff9aa269678 100644 --- a/htdocs/mrp/tpl/linkedobjectblock.tpl.php +++ b/htdocs/mrp/tpl/linkedobjectblock.tpl.php @@ -24,7 +24,7 @@ if (empty($conf) || !is_object($conf)) { exit; } -print "\n"; +print "\n"; global $user, $db; global $noMoreLinkedObjectBlockAfter; diff --git a/htdocs/reception/tpl/linkedobjectblock.tpl.php b/htdocs/reception/tpl/linkedobjectblock.tpl.php index c8ff1196c0f..1bfecac3f1d 100644 --- a/htdocs/reception/tpl/linkedobjectblock.tpl.php +++ b/htdocs/reception/tpl/linkedobjectblock.tpl.php @@ -25,7 +25,7 @@ if (empty($conf) || !is_object($conf)) { ?> - + \n"; +print "\n"; global $user; From 883f13b38892c8e98ef6f1cf456129aba7d914a1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Mar 2022 18:14:24 +0100 Subject: [PATCH 14/64] Fix regression verifCond --- htdocs/core/lib/functions.lib.php | 27 ++++++++++++++++++++++----- test/phpunit/SecurityTest.php | 8 ++++++-- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index c6476f98a11..c6ceadf0a71 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8167,7 +8167,7 @@ function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid = * Verify if condition in string is ok or not * * @param string $strToEvaluate String with condition to check - * @return boolean True or False. Note: It returns True if $strToEvaluate is '' + * @return boolean True or False. Note: It returns also True if $strToEvaluate is '' */ function verifCond($strToEvaluate) { @@ -8178,8 +8178,10 @@ function verifCond($strToEvaluate) //print $strToEvaluate."
\n"; $rights = true; if (isset($strToEvaluate) && $strToEvaluate !== '') { - $str = 'if(!('.$strToEvaluate.')) { $rights = false; }'; - dol_eval($str); // The dol_eval must contains all the global $xxx used into a condition + $str = 'if(!('.$strToEvaluate.')) $rights = false;'; + dol_eval($str, 0, 1, '2'); // The dol_eval must contains all the global $xxx used into a condition + //$rep = dol_eval($strToEvaluate, 1, 1 , '1'); // The dol_eval must contains all the global $xxx used into a condition + //$rights = ($rep ? true : false); } return $rights; } @@ -8191,7 +8193,7 @@ function verifCond($strToEvaluate) * @param string $s String to evaluate * @param int $returnvalue 0=No return (used to execute eval($a=something)). 1=Value of eval is returned (used to eval($something)). * @param int $hideerrors 1=Hide errors - * @param string $onlysimplestring Accept only simple string with char 'a-z0-9\s$_->&|='; + * @param string $onlysimplestring 0=Accept all chars, 1=Accept only simple string with char 'a-z0-9\s$_->&|=';, 2=Accept also '!?():";' * @return mixed Nothing or return result of eval */ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1') @@ -8210,7 +8212,22 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' if ($onlysimplestring == '1') { //print preg_quote('$_->&|', '/'); if (preg_match('/[^a-z0-9\s'.preg_quote('$_->&|=', '/').']/i', $s)) { - return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s; + if ($returnvalue) { + return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s; + } else { + dol_syslog('Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s); + return ''; + } + } + } elseif ($onlysimplestring == '2') { + //print preg_quote('$_->&|', '/'); + if (preg_match('/[^a-z0-9\s'.preg_quote('$_->&|=!?():";', '/').']/i', $s)) { + if ($returnvalue) { + return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s; + } else { + dol_syslog('Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s); + return ''; + } } } if (strpos($s, '`') !== false) { diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index a687e6adbd7..7194c1cbfd4 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -876,12 +876,12 @@ class SecurityTest extends PHPUnit\Framework\TestCase include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; include_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; - $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"'; + $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=dol_eval($s, 1, 1, ''); print "result = ".$result."\n"; $this->assertEquals('Parent project not found', $result); - $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\''; + $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=dol_eval($s, 1, 1, ''); print "result = ".$result."\n"; $this->assertEquals('Parent project not found', $result); @@ -910,6 +910,10 @@ class SecurityTest extends PHPUnit\Framework\TestCase print "result = ".$result."\n"; $this->assertContains('Bad string syntax to evaluate', $result); + $result=dol_eval("sprintf(\"%s%s\", \"ex\", \"ec\")('echo abc')", 1, 0, ''); + print "result = ".$result."\n"; + $this->assertContains('Bad string syntax to evaluate', $result); + // Case with param onlysimplestring = 1 $result=dol_eval('1 && $conf->abc->doesnotexist1 && $conf->def->doesnotexist1', 1, 0); // Should return false and not a 'Bad string syntax to evaluate ...' print "result = ".$result."\n"; From e5fd841fe356d35a1121a16161e73ddcaf2e0595 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Mar 2022 18:21:30 +0100 Subject: [PATCH 15/64] Make verifCond more robust against RCE --- htdocs/core/lib/functions.lib.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index de5e3f7201b..75832d42d0a 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8308,10 +8308,10 @@ function verifCond($strToEvaluate) //print $strToEvaluate."
\n"; $rights = true; if (isset($strToEvaluate) && $strToEvaluate !== '') { - $str = 'if(!('.$strToEvaluate.')) $rights = false;'; - dol_eval($str, 0, 1, '2'); // The dol_eval must contains all the global $xxx used into a condition - //$rep = dol_eval($strToEvaluate, 1, 1 , '1'); // The dol_eval must contains all the global $xxx used into a condition - //$rights = ($rep ? true : false); + //$str = 'if(!('.$strToEvaluate.')) $rights = false;'; + //dol_eval($str, 0, 1, '2'); // The dol_eval must contains all the global $xxx used into a condition + $rep = dol_eval($strToEvaluate, 1, 1, '1'); // The dol_eval must contains all the global $xxx used into a condition + $rights = ($rep ? true : false); } return $rights; } @@ -8338,10 +8338,10 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' global $obj; // To get $obj used into list when dol_eval is used for computed fields and $obj is not yet $object global $soc; // For backward compatibility - // Test dangerous char (used for RCE), we allow only PHP variable testing. + // Test on dangerous char (used for RCE), we allow only characters to make PHP variable testing. if ($onlysimplestring == '1') { //print preg_quote('$_->&|', '/'); - if (preg_match('/[^a-z0-9\s'.preg_quote('$_->&|=', '/').']/i', $s)) { + if (preg_match('/[^a-z0-9\s'.preg_quote('$_->&|=!?:', '/').']/i', $s)) { if ($returnvalue) { return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s; } else { @@ -8360,6 +8360,9 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' } } } + if (strpos($s, '::') !== false) { + return 'Bad string syntax to evaluate (double : char is forbidden): '.$s; + } if (strpos($s, '`') !== false) { return 'Bad string syntax to evaluate (backtick char is forbidden): '.$s; } From 2e38caa950aab06339d3e7f4abb5fc4d522cd26b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Mar 2022 18:22:09 +0100 Subject: [PATCH 16/64] phpunit --- test/phpunit/SecurityTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 7194c1cbfd4..636309f2349 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -910,7 +910,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase print "result = ".$result."\n"; $this->assertContains('Bad string syntax to evaluate', $result); - $result=dol_eval("sprintf(\"%s%s\", \"ex\", \"ec\")('echo abc')", 1, 0, ''); + $result=dol_eval("sprintf(\"%s%s\", \"ex\", \"ec\")('echo abc')", 1, 0); print "result = ".$result."\n"; $this->assertContains('Bad string syntax to evaluate', $result); From 762de973ebea283e2746ddcbdd6ad437c44c59ec Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Mar 2022 18:43:16 +0100 Subject: [PATCH 17/64] Fix sql injection --- htdocs/core/lib/security.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index ccdfa261fc8..44d6f5c739b 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -289,7 +289,7 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f } if ($dbt_select != 'rowid' && $dbt_select != 'id') { - $objectid = "'".$objectid."'"; + $objectid = "'".$db->escape($objectid)."'"; } // Features/modules to check From 7c253c7e2882e9679274acad971f1ec51b2daf4e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Mar 2022 18:46:55 +0100 Subject: [PATCH 18/64] Clean code --- htdocs/core/lib/security.lib.php | 33 +++++++++++-------------- htdocs/workstation/workstation_note.php | 5 ---- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 44d6f5c739b..ce94d6128dc 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -216,19 +216,19 @@ function dolGetLdapPasswordHash($password, $type = 'md5') * If GETPOST('action','aZ09') defined, we also check write and delete permission. * This method check permission on module then call checkUserAccessToObject() for permission on object (according to entity and socid of user). * - * @param User $user User to check - * @param string $features Features to check (it must be module $object->element. Can be a 'or' check with 'levela|levelb'. - * Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...) - * This is used to check permission $user->rights->features->... - * @param int $objectid Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional). - * @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany module. Param not used if objectid is null (optional). - * @param string $feature2 Feature to check, second level of permission (optional). Can be a 'or' check with 'sublevela|sublevelb'. - * This is used to check permission $user->rights->features->feature2... - * @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional) - * @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional) - * @param int $isdraft 1=The object with id=$objectid is a draft - * @param int $mode Mode (0=default, 1=return with not die) - * @return int If mode = 0 (default): Always 1, die process if not allowed. If mode = 1: Return 0 if access not allowed. + * @param User $user User to check + * @param string $features Features to check (it must be module $object->element. Can be a 'or' check with 'levela|levelb'. + * Examples: 'societe', 'contact', 'produit&service', 'produit|service', ...) + * This is used to check permission $user->rights->features->... + * @param int $objectid Object ID if we want to check a particular record (optional) is linked to a owned thirdparty (optional). + * @param string $tableandshare 'TableName&SharedElement' with Tablename is table where object is stored. SharedElement is an optional key to define where to check entity for multicompany module. Param not used if objectid is null (optional). + * @param string $feature2 Feature to check, second level of permission (optional). Can be a 'or' check with 'sublevela|sublevelb'. + * This is used to check permission $user->rights->features->feature2... + * @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional) + * @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional) + * @param int $isdraft 1=The object with id=$objectid is a draft + * @param int $mode Mode (0=default, 1=return with not die) + * @return int If mode = 0 (default): Always 1, die process if not allowed. If mode = 1: Return 0 if access not allowed. * @see dol_check_secure_access_document(), checkUserAccessToObject() */ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $feature2 = '', $dbt_keyfield = 'fk_soc', $dbt_select = 'rowid', $isdraft = 0, $mode = 0) @@ -236,6 +236,8 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f global $db, $conf; global $hookmanager; + $objectid = ((int) $objectid); // For the case value is coming from a non sanitized user input + //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename, $feature2, $dbt_socfield, $dbt_select, $isdraft"); //print "user_id=".$user->id.", features=".$features.", feature2=".$feature2.", objectid=".$objectid; //print ", dbtablename=".$dbtablename.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select; @@ -270,7 +272,6 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f $features = 'produit'; } - // Get more permissions checks from hooks $parameters = array('features'=>$features, 'originalfeatures'=>$originalfeatures, 'objectid'=>$objectid, 'dbt_select'=>$dbt_select, 'idtype'=>$dbt_select, 'isdraft'=>$isdraft); $reshook = $hookmanager->executeHooks('restrictedArea', $parameters); @@ -288,10 +289,6 @@ function restrictedArea($user, $features, $objectid = 0, $tableandshare = '', $f return 1; } - if ($dbt_select != 'rowid' && $dbt_select != 'id') { - $objectid = "'".$db->escape($objectid)."'"; - } - // Features/modules to check $featuresarray = array($features); if (preg_match('/&/', $features)) { diff --git a/htdocs/workstation/workstation_note.php b/htdocs/workstation/workstation_note.php index ebe8d99af16..3685b7daf4e 100644 --- a/htdocs/workstation/workstation_note.php +++ b/htdocs/workstation/workstation_note.php @@ -46,11 +46,6 @@ $hookmanager->initHooks(array('workstationnote', 'globalcard')); // Note that co // Fetch optionals attributes and labels $extrafields->fetch_name_optionals_label($object->table_element); -// Security check - Protection if external user -//if ($user->socid > 0) accessforbidden(); -//if ($user->socid > 0) $socid = $user->socid; -//$result = restrictedArea($user, 'workstation', $id); - // Load object include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be include, not include_once // Must be include, not include_once. Include fetch and fetch_thirdparty but not fetch_optionals if ($id > 0 || !empty($ref)) { From 3e1580475c1b0855fe33de7ad657467661ad6f9b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 1 Mar 2022 18:22:09 +0100 Subject: [PATCH 19/64] Fix phpunit --- htdocs/core/lib/functions.lib.php | 2 +- test/phpunit/SecurityTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index c6ceadf0a71..191ad2da21f 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8211,7 +8211,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' // Test dangerous char (used for RCE), we allow only PHP variable testing. if ($onlysimplestring == '1') { //print preg_quote('$_->&|', '/'); - if (preg_match('/[^a-z0-9\s'.preg_quote('$_->&|=', '/').']/i', $s)) { + if (preg_match('/[^a-z0-9\s'.preg_quote('$_->&|=!?():"', '/').']/i', $s)) { if ($returnvalue) { return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s; } else { diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 7194c1cbfd4..b96887b6152 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -910,12 +910,12 @@ class SecurityTest extends PHPUnit\Framework\TestCase print "result = ".$result."\n"; $this->assertContains('Bad string syntax to evaluate', $result); - $result=dol_eval("sprintf(\"%s%s\", \"ex\", \"ec\")('echo abc')", 1, 0, ''); + $result=dol_eval("sprintf(\"%s%s\", \"ex\", \"ec\")('echo abc')", 1, 0); print "result = ".$result."\n"; $this->assertContains('Bad string syntax to evaluate', $result); // Case with param onlysimplestring = 1 - $result=dol_eval('1 && $conf->abc->doesnotexist1 && $conf->def->doesnotexist1', 1, 0); // Should return false and not a 'Bad string syntax to evaluate ...' + $result=dol_eval('1 && getDolGlobalInt("doesnotexist1") && $conf->global->MAIN_FEATURES_LEVEL', 1, 0); // Should return false and not a 'Bad string syntax to evaluate ...' print "result = ".$result."\n"; $this->assertFalse($result); From d78f76447c5f3455bc42e4ab78ac2ccdf1e94151 Mon Sep 17 00:00:00 2001 From: UT from dolibit <45215329+dolibit-ut@users.noreply.github.com> Date: Wed, 2 Mar 2022 00:29:07 +0100 Subject: [PATCH 20/64] Update README.md http://help.luracast.com/restler/examples/ - don't work anymore replaced by https://restler3.luracast.com/examples/index.html --- htdocs/api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/api/README.md b/htdocs/api/README.md index 7ab85cc26bb..1af112920ce 100644 --- a/htdocs/api/README.md +++ b/htdocs/api/README.md @@ -41,7 +41,7 @@ https://**yourdolibarr.tld**/mydolibarr/api/index.php/otherservice?DOLAPIKEY=**a Develop an API -------------- -The API uses Lucarast Restler framework. Please check documentation https://www.luracast.com/products/restler and examples http://help.luracast.com/restler/examples/ +The API uses Lucarast Restler framework. Please check documentation https://www.luracast.com/products/restler and examples https://restler3.luracast.com/examples/index.html Github contains also useful information : https://github.com/Luracast/Restler From 8051128665cfcc8bb14c7ca9b5b6d942b278dc31 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 2 Mar 2022 11:37:19 +0100 Subject: [PATCH 21/64] Split section experimental and stable --- htdocs/admin/system/security.php | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/htdocs/admin/system/security.php b/htdocs/admin/system/security.php index eb3a6d7c884..118fab39f80 100644 --- a/htdocs/admin/system/security.php +++ b/htdocs/admin/system/security.php @@ -405,7 +405,7 @@ print '

'; print '
'; -print load_fiche_titre($langs->trans("OtherSetup").' ('.$langs->trans("Experimental").')', '', 'folder'); +print load_fiche_titre($langs->trans("OtherSetup"), '', 'folder'); //print ''.$langs->trans("PasswordEncryption").': '; @@ -438,19 +438,24 @@ print '
'; print 'MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE = '.(empty($conf->global->MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_ALWAYS_CREATE_LOCK_AFTER_LAST_UPGRADE).'   ('.$langs->trans("Recommended").': 1)
'; print '
'; +print 'MAIN_SECURITY_CSRF_WITH_TOKEN = '.(empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN).'   ('.$langs->trans("Recommended").': 2)'."
"; +print '
'; + +print '
'; +print '
'; + + +print load_fiche_titre($langs->trans("OtherSetup").' ('.$langs->trans("Experimental").')', '', 'folder'); + print 'MAIN_RESTRICTHTML_ONLY_VALID_HTML = '.(empty($conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': 1)' : $conf->global->MAIN_RESTRICTHTML_ONLY_VALID_HTML)."
"; print '
'; print 'MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES = '.(empty($conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': 1)' : $conf->global->MAIN_RESTRICTHTML_REMOVE_ALSO_BAD_ATTRIBUTES)."
"; print '
'; -print 'MAIN_SECURITY_CSRF_WITH_TOKEN = '.(empty($conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN) ? ''.$langs->trans("Undefined").'' : $conf->global->MAIN_SECURITY_CSRF_WITH_TOKEN).'   ('.$langs->trans("Recommended").': 2)'."
"; -print '
'; - print 'MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL = '.(empty($conf->global->MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL) ? ''.$langs->trans("Undefined").'   ('.$langs->trans("Recommended").': '.$langs->trans("Undefined").' '.$langs->trans("or").' 0)' : $conf->global->MAIN_SECURITY_CSRF_TOKEN_RENEWAL_ON_EACH_CALL)."
"; print '
'; - print 'MAIN_EXEC_USE_POPEN = '; if (empty($conf->global->MAIN_EXEC_USE_POPEN)) { print ''.$langs->trans("Undefined").''; From 5ffac5f3ee16abd1764e4345992ba1074bab202f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 2 Mar 2022 11:38:32 +0100 Subject: [PATCH 22/64] Fix typo --- htdocs/core/modules/modAccounting.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/modAccounting.class.php b/htdocs/core/modules/modAccounting.class.php index e0bf3a9bbc5..21b20d063ed 100644 --- a/htdocs/core/modules/modAccounting.class.php +++ b/htdocs/core/modules/modAccounting.class.php @@ -256,7 +256,7 @@ class modAccounting extends DolibarrModules $r++; $this->export_code[$r] = $this->rights_class.'_'.$r; $this->export_label[$r] = 'Chartofaccounts'; - $this->export_icon[$r] = 'accounting'; + $this->export_icon[$r] = $this->picto; $this->export_permission[$r] = array(array("accounting", "chartofaccount")); $this->export_fields_array[$r] = array('ac.rowid'=>'ChartofaccountsId', 'ac.pcg_version'=>'Chartofaccounts', 'aa.rowid'=>'ID', 'aa.account_number'=>"AccountAccounting", 'aa.label'=>"Label", 'aa.account_parent'=>"Accountparent", 'aa.pcg_type'=>"Pcgtype", 'aa.active'=>'Status'); $this->export_TypeFields_array[$r] = array('ac.rowid'=>'List:accounting_system:pcg_version', 'ac.pcg_version'=>'Text', 'aa.rowid'=>'Numeric', 'aa.account_number'=>"Text", 'aa.label'=>"Text", 'aa.account_parent'=>"Text", 'aa.pcg_type'=>'Text', 'aa.active'=>'Status'); From d15c30359004b07d61830dc69eb8ae5d88b55ee2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 2 Mar 2022 11:57:19 +0100 Subject: [PATCH 23/64] Fix missing button --- htdocs/website/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/website/index.php b/htdocs/website/index.php index cdf425e3ae3..8ac4d612264 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2807,7 +2807,7 @@ if (!GETPOST('hide_websitemenu')) { print $langs->trans("PageContainer").': '; print ''; - print ''; + print ''; print 'ref).'" class="button bordertransp"'.$disabled.' title="'.dol_escape_htmltag($langs->trans("AddPage")).'">'; print ''; From 66b0f253b69b2147825ab61b15638ce42e3cd25c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 2 Mar 2022 12:41:21 +0100 Subject: [PATCH 24/64] Clean code --- htdocs/core/class/doleditor.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index 927674942e7..89f6df0cd32 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -316,7 +316,7 @@ class DolEditor jQuery(".buttonforacesave").click(function() { console.log("We click on savefile button for component '.$this->htmlname.'"); var aceEditor = window.ace.edit("'.$this->htmlname.'aceeditorid") - console.log(aceEditor.getSession().getValue()); + //console.log(aceEditor.getSession().getValue()); jQuery("#'.$this->htmlname.'").val(aceEditor.getSession().getValue()); /*if (jQuery("#'.$this->htmlname.'").html().length > 0) return true; else return false;*/ From a7cb3fa492349c5ddf154a7095be253d58aa84a1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 2 Mar 2022 14:44:14 +0100 Subject: [PATCH 25/64] Clean log --- htdocs/core/class/doleditor.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/doleditor.class.php b/htdocs/core/class/doleditor.class.php index 4266fd983c3..93c0a2445dc 100644 --- a/htdocs/core/class/doleditor.class.php +++ b/htdocs/core/class/doleditor.class.php @@ -330,7 +330,7 @@ class DolEditor var aceEditor = window.ace.edit("'.$this->htmlname.'aceeditorid"); if (aceEditor) { var cursorPos = aceEditor.getCursorPosition(); - console.log(cursorPos); + //console.log(cursorPos); if (cursorPos) { jQuery("#'.$this->htmlname.'_x").val(cursorPos.column); jQuery("#'.$this->htmlname.'_y").val(cursorPos.row); @@ -340,6 +340,7 @@ class DolEditor jQuery("#'.$this->htmlname.'").val(aceEditor.getSession().getValue()); /*if (jQuery("#'.$this->htmlname.'").html().length > 0) return true; else return false;*/ + return true; } else { console.log("Failed to retrieve js object ACE from its name"); return false; From 940417efe2869db1613926ce59b219d25afdafca Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 2 Mar 2022 15:13:17 +0100 Subject: [PATCH 26/64] FIX payment not completed when using Paypal. --- htdocs/public/payment/paymentok.php | 72 +++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 5 deletions(-) diff --git a/htdocs/public/payment/paymentok.php b/htdocs/public/payment/paymentok.php index 499ff2c4e31..5bf78e9e17a 100644 --- a/htdocs/public/payment/paymentok.php +++ b/htdocs/public/payment/paymentok.php @@ -245,7 +245,7 @@ if (!empty($conf->paypal->enabled)) { $fulltag = $FULLTAG; $payerID = $PAYPALPAYERID; // Set by newpayment.php - $paymentType = $_SESSION['PaymentType']; + $paymentType = $_SESSION['PaymentType']; // Value can be 'Mark', 'Sole', 'Sale' for example $currencyCodeType = $_SESSION['currencyCodeType']; $FinalPaymentAmt = $_SESSION["FinalPaymentAmt"]; // From env @@ -406,10 +406,19 @@ if ($ispaymentok) { $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; } if (empty($paymentTypeId)) { + dol_syslog("paymentType = ".$paymentType, LOG_DEBUG, 0, '_payment'); + if (empty($paymentType)) { $paymentType = 'CB'; } + // May return nothing when paymentType means nothing + // (for example when paymentType is 'Mark', 'Sole', 'Sale', for paypal) $paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1); + + // If previous line has returned nothing, we force to get the ID of payment of Credit Card (hard coded code 'CB'). + if (empty($paymentTypeId) || $paymentTypeId < 0) { + $paymentTypeId = dol_getIdFromCode($db, 'CB', 'c_paiement', 'code', 'id', 1); + } } dol_syslog("FinalPaymentAmt=".$FinalPaymentAmt." paymentTypeId=".$paymentTypeId." paymentType=".$paymentType." currencyCodeType=".$currencyCodeType, LOG_DEBUG, 0, '_payment'); @@ -783,10 +792,19 @@ if ($ispaymentok) { $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; } if (empty($paymentTypeId)) { + dol_syslog("paymentType = ".$paymentType, LOG_DEBUG, 0, '_payment'); + if (empty($paymentType)) { $paymentType = 'CB'; } + // May return nothing when paymentType means nothing + // (for example when paymentType is 'Mark', 'Sole', 'Sale', for paypal) $paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1); + + // If previous line has returned nothing, we force to get the ID of payment of Credit Card (hard coded code 'CB'). + if (empty($paymentTypeId) || $paymentTypeId < 0) { + $paymentTypeId = dol_getIdFromCode($db, 'CB', 'c_paiement', 'code', 'id', 1); + } } // Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time) @@ -876,12 +894,29 @@ if ($ispaymentok) { $FinalPaymentAmt = $_SESSION["FinalPaymentAmt"]; $paymentTypeId = 0; - if ($paymentmethod == 'paybox') $paymentTypeId = $conf->global->PAYBOX_PAYMENT_MODE_FOR_PAYMENTS; - if ($paymentmethod == 'paypal') $paymentTypeId = $conf->global->PAYPAL_PAYMENT_MODE_FOR_PAYMENTS; - if ($paymentmethod == 'stripe') $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; + if ($paymentmethod == 'paybox') { + $paymentTypeId = $conf->global->PAYBOX_PAYMENT_MODE_FOR_PAYMENTS; + } + if ($paymentmethod == 'paypal') { + $paymentTypeId = $conf->global->PAYPAL_PAYMENT_MODE_FOR_PAYMENTS; + } + if ($paymentmethod == 'stripe') { + $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; + } if (empty($paymentTypeId)) { - if (empty($paymentType)) $paymentType = 'CB'; + dol_syslog("paymentType = ".$paymentType, LOG_DEBUG, 0, '_payment'); + + if (empty($paymentType)) { + $paymentType = 'CB'; + } + // May return nothing when paymentType means nothing + // (for example when paymentType is 'Mark', 'Sole', 'Sale', for paypal) $paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1); + + // If previous line has returned nothing, we force to get the ID of payment of Credit Card (hard coded code 'CB'). + if (empty($paymentTypeId) || $paymentTypeId < 0) { + $paymentTypeId = dol_getIdFromCode($db, 'CB', 'c_paiement', 'code', 'id', 1); + } } // Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time) @@ -986,10 +1021,19 @@ if ($ispaymentok) { $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; } if (empty($paymentTypeId)) { + dol_syslog("paymentType = ".$paymentType, LOG_DEBUG, 0, '_payment'); + if (empty($paymentType)) { $paymentType = 'CB'; } + // May return nothing when paymentType means nothing + // (for example when paymentType is 'Mark', 'Sole', 'Sale', for paypal) $paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1); + + // If previous line has returned nothing, we force to get the ID of payment of Credit Card (hard coded code 'CB'). + if (empty($paymentTypeId) || $paymentTypeId < 0) { + $paymentTypeId = dol_getIdFromCode($db, 'CB', 'c_paiement', 'code', 'id', 1); + } } // Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time) @@ -1091,10 +1135,19 @@ if ($ispaymentok) { $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; } if (empty($paymentTypeId)) { + dol_syslog("paymentType = ".$paymentType, LOG_DEBUG, 0, '_payment'); + if (empty($paymentType)) { $paymentType = 'CB'; } + // May return nothing when paymentType means nothing + // (for example when paymentType is 'Mark', 'Sole', 'Sale', for paypal) $paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1); + + // If previous line has returned nothing, we force to get the ID of payment of Credit Card (hard coded code 'CB'). + if (empty($paymentTypeId) || $paymentTypeId < 0) { + $paymentTypeId = dol_getIdFromCode($db, 'CB', 'c_paiement', 'code', 'id', 1); + } } // Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time) @@ -1272,10 +1325,19 @@ if ($ispaymentok) { $paymentTypeId = $conf->global->STRIPE_PAYMENT_MODE_FOR_PAYMENTS; } if (empty($paymentTypeId)) { + dol_syslog("paymentType = ".$paymentType, LOG_DEBUG, 0, '_payment'); + if (empty($paymentType)) { $paymentType = 'CB'; } + // May return nothing when paymentType means nothing + // (for example when paymentType is 'Mark', 'Sole', 'Sale', for paypal) $paymentTypeId = dol_getIdFromCode($db, $paymentType, 'c_paiement', 'code', 'id', 1); + + // If previous line has returned nothing, we force to get the ID of payment of Credit Card (hard coded code 'CB'). + if (empty($paymentTypeId) || $paymentTypeId < 0) { + $paymentTypeId = dol_getIdFromCode($db, 'CB', 'c_paiement', 'code', 'id', 1); + } } // Do action only if $FinalPaymentAmt is set (session variable is cleaned after this page to avoid duplicate actions when page is POST a second time) From c71bebfd217593b6e35d3d66a10cc30092cff5bf Mon Sep 17 00:00:00 2001 From: kevin Date: Wed, 2 Mar 2022 20:48:46 +0100 Subject: [PATCH 27/64] Add Init Hooks on several project tabs --- htdocs/projet/document.php | 1 + htdocs/projet/info.php | 1 + 2 files changed, 2 insertions(+) diff --git a/htdocs/projet/document.php b/htdocs/projet/document.php index 9e8d3a6ce8e..ef3d455fd82 100644 --- a/htdocs/projet/document.php +++ b/htdocs/projet/document.php @@ -32,6 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Load translation files required by the page $langs->loadLangs(array('projects', 'other')); +$hookmanager->initHooks(array('projetcarddocument')); $action = GETPOST('action', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); diff --git a/htdocs/projet/info.php b/htdocs/projet/info.php index c0afe5d1370..9712e32ffd2 100644 --- a/htdocs/projet/info.php +++ b/htdocs/projet/info.php @@ -67,6 +67,7 @@ $id = GETPOST("id", 'int'); $socid = 0; //if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement. $result = restrictedArea($user, 'projet', $id, 'projet&project'); +$hookmanager->initHooks(array('projetcardinfo')); if (!$user->rights->projet->lire) { accessforbidden(); From 987b32ef196bc63467243aec071b2940de806641 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 2 Mar 2022 22:04:44 +0100 Subject: [PATCH 28/64] Fix a default value is creating a letal blocking situation --- htdocs/accountancy/bookkeeping/list.php | 4 ++-- htdocs/core/class/html.form.class.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index b67b134e3e1..b2d05452416 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -682,13 +682,13 @@ if ($action == 'export_file') { 'name' => 'notifiedexportdate', 'type' => 'checkbox', 'label' => $langs->trans('NotifiedExportDate'), - 'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) ? 'false' : 'true'), + 'value' => (empty($conf->global->ACCOUNTING_DEFAULT_NOTIFIED_EXPORT_DATE) ? '' : 'true'), ); $form_question['notifiedvalidationdate'] = array( 'name' => 'notifiedvalidationdate', 'type' => 'checkbox', 'label' => $langs->trans('NotifiedValidationDate'), - 'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE) ? 'false' : 'true'), + 'value' => (empty($conf->global->ACCOUNTING_DEFAULT_NOTIFIED_VALIDATION_DATE) ? '' : 'true'), ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 300, 600); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 975e6ed86ea..87d3d63cec1 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4807,7 +4807,7 @@ class Form $more .= '
'; $more .= '
'.$input['label'].'
'; $more .= ' Date: Wed, 2 Mar 2022 22:04:44 +0100 Subject: [PATCH 29/64] Fix a default value is creating a letal blocking situation --- htdocs/accountancy/bookkeeping/list.php | 4 ++-- htdocs/core/class/html.form.class.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index b67b134e3e1..d110f74a6a6 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -682,13 +682,13 @@ if ($action == 'export_file') { 'name' => 'notifiedexportdate', 'type' => 'checkbox', 'label' => $langs->trans('NotifiedExportDate'), - 'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) ? 'false' : 'true'), + 'value' => (empty($conf->global->ACCOUNTING_DEFAULT_NOTIFIED_EXPORT_DATE) ? false : true), ); $form_question['notifiedvalidationdate'] = array( 'name' => 'notifiedvalidationdate', 'type' => 'checkbox', 'label' => $langs->trans('NotifiedValidationDate'), - 'value' => (!empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE) ? 'false' : 'true'), + 'value' => (empty($conf->global->ACCOUNTING_DEFAULT_NOTIFIED_VALIDATION_DATE) ? false : true), ); $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 300, 600); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 975e6ed86ea..87d3d63cec1 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4807,7 +4807,7 @@ class Form $more .= '
'; $more .= '
'.$input['label'].'
'; $more .= ' Date: Wed, 2 Mar 2022 22:20:05 +0100 Subject: [PATCH 30/64] Fix label of menu --- htdocs/accountancy/closure/index.php | 1 - htdocs/langs/en_US/accountancy.lang | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/htdocs/accountancy/closure/index.php b/htdocs/accountancy/closure/index.php index 6b578bcab71..f02eda61bf6 100644 --- a/htdocs/accountancy/closure/index.php +++ b/htdocs/accountancy/closure/index.php @@ -13,7 +13,6 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * */ /** diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index a44c819aa78..6f9d74de7c8 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -282,7 +282,7 @@ DescClosure=Consult here the number of movements by month who are not validated OverviewOfMovementsNotValidated=Step 1/ Overview of movements not validated. (Necessary to close a fiscal year) AllMovementsWereRecordedAsValidated=All movements were recorded as validated NotAllMovementsCouldBeRecordedAsValidated=Not all movements could be recorded as validated -ValidateMovements=Validate movements +ValidateMovements=Validate and lock record... DescValidateMovements=Any modification or deletion of writing, lettering and deletes will be prohibited. All entries for an exercise must be validated otherwise closing will not be possible ValidateHistory=Bind Automatically From a9a2928e632bbeda9d2dd91af10222e6da39e766 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Mar 2022 00:13:35 +0100 Subject: [PATCH 31/64] Responsive --- htdocs/bookmarks/card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/bookmarks/card.php b/htdocs/bookmarks/card.php index 8833978e054..bbc92a83ef1 100644 --- a/htdocs/bookmarks/card.php +++ b/htdocs/bookmarks/card.php @@ -160,7 +160,7 @@ if ($action == 'create') { print ''; - print ''; + print ''; dol_set_focus('#titlebookmark'); // Url @@ -230,9 +230,9 @@ if ($id > 0 && !preg_match('/^add/i', $action)) { print ''; From 3c3d6ab0da5ddf470c766ac339b2328f9268d9e4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Mar 2022 01:17:44 +0100 Subject: [PATCH 32/64] Fix regression. Add unit test to detect it. --- htdocs/core/lib/functions.lib.php | 31 ++++++++++++++++++------ htdocs/core/modules/modBarcode.class.php | 3 ++- test/phpunit/SecurityTest.php | 9 +++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 191ad2da21f..9f9435fcdc2 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8167,7 +8167,7 @@ function dol_getIdFromCode($db, $key, $tablename, $fieldkey = 'code', $fieldid = * Verify if condition in string is ok or not * * @param string $strToEvaluate String with condition to check - * @return boolean True or False. Note: It returns also True if $strToEvaluate is '' + * @return boolean True or False. Note: It returns also True if $strToEvaluate is '' or if error */ function verifCond($strToEvaluate) { @@ -8180,8 +8180,10 @@ function verifCond($strToEvaluate) if (isset($strToEvaluate) && $strToEvaluate !== '') { $str = 'if(!('.$strToEvaluate.')) $rights = false;'; dol_eval($str, 0, 1, '2'); // The dol_eval must contains all the global $xxx used into a condition - //$rep = dol_eval($strToEvaluate, 1, 1 , '1'); // The dol_eval must contains all the global $xxx used into a condition + //var_dump($strToEvaluate); + //$rep = dol_eval($strToEvaluate, 1, 1 , '2'); // The dol_eval must contains all the global $xxx used into a condition //$rights = ($rep ? true : false); + //var_dump($rights); } return $rights; } @@ -8193,7 +8195,7 @@ function verifCond($strToEvaluate) * @param string $s String to evaluate * @param int $returnvalue 0=No return (used to execute eval($a=something)). 1=Value of eval is returned (used to eval($something)). * @param int $hideerrors 1=Hide errors - * @param string $onlysimplestring 0=Accept all chars, 1=Accept only simple string with char 'a-z0-9\s$_->&|=';, 2=Accept also '!?():";' + * @param string $onlysimplestring 0=Accept all chars, 1=Accept only simple string with char 'a-z0-9\s$_->&|=';, 2=Accept also '!?():"\';,/' * @return mixed Nothing or return result of eval */ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1') @@ -8221,7 +8223,7 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' } } elseif ($onlysimplestring == '2') { //print preg_quote('$_->&|', '/'); - if (preg_match('/[^a-z0-9\s'.preg_quote('$_->&|=!?():";', '/').']/i', $s)) { + if (preg_match('/[^a-z0-9\s'.preg_quote('^$_->&|=!?():"\';,/', '/').']/i', $s)) { if ($returnvalue) { return 'Bad string syntax to evaluate (found chars that are not chars for simplestring): '.$s; } else { @@ -8231,10 +8233,20 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' } } if (strpos($s, '`') !== false) { - return 'Bad string syntax to evaluate (backtick char is forbidden): '.$s; + if ($returnvalue) { + return 'Bad string syntax to evaluate (backtick char is forbidden): '.$s; + } else { + dol_syslog('Bad string syntax to evaluate (backtick char is forbidden): '.$s); + return ''; + } } if (strpos($s, '.') !== false) { - return 'Bad string syntax to evaluate (dot char is forbidden): '.$s; + if ($returnvalue) { + return 'Bad string syntax to evaluate (dot char is forbidden): '.$s; + } else { + dol_syslog('Bad string syntax to evaluate (dot char is forbidden): '.$s); + return ''; + } } // We block use of php exec or php file functions @@ -8256,7 +8268,12 @@ function dol_eval($s, $returnvalue = 0, $hideerrors = 1, $onlysimplestring = '1' if (strpos($s, '__forbiddenstring__') !== false) { dol_syslog('Bad string syntax to evaluate: '.$s, LOG_WARNING); - return 'Bad string syntax to evaluate: '.$s; + if ($returnvalue) { + return 'Bad string syntax to evaluate: '.$s; + } else { + dol_syslog('Bad string syntax to evaluate: '.$s); + return ''; + } } //print $s."
\n"; diff --git a/htdocs/core/modules/modBarcode.class.php b/htdocs/core/modules/modBarcode.class.php index 877dca880f7..ced58f9b6c4 100644 --- a/htdocs/core/modules/modBarcode.class.php +++ b/htdocs/core/modules/modBarcode.class.php @@ -33,7 +33,6 @@ include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php'; */ class modBarcode extends DolibarrModules { - /** * Constructor. Define names, constants, directories, boxes, permissions * @@ -94,6 +93,7 @@ class modBarcode extends DolibarrModules // Main menu entries $r = 0; + // A menu entry for the Tools top menu $this->menu[$r] = array( 'fk_menu'=>'fk_mainmenu=tools', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'mainmenu'=>'tools', @@ -111,6 +111,7 @@ class modBarcode extends DolibarrModules ); $r++; + // A menu entry for the left menu $this->menu[$r] = array( 'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=admintools', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode 'type'=>'left', // This is a Left menu entry diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index b96887b6152..e9a19dd576a 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -914,7 +914,16 @@ class SecurityTest extends PHPUnit\Framework\TestCase print "result = ".$result."\n"; $this->assertContains('Bad string syntax to evaluate', $result); + global $leftmenu; + $leftmenu = 'admintools'; + $conf->barcode->enabled = 1; + $result=dol_eval('$conf->barcode->enabled && preg_match(\'/^(admintools|all)/\',$leftmenu)', 1, 0, '2'); + print "result = ".$result."\n"; + $this->assertTrue($result); + + // Case with param onlysimplestring = 1 + $result=dol_eval('1 && getDolGlobalInt("doesnotexist1") && $conf->global->MAIN_FEATURES_LEVEL', 1, 0); // Should return false and not a 'Bad string syntax to evaluate ...' print "result = ".$result."\n"; $this->assertFalse($result); From cdf603a7b39c082d32b84900eb0d7e0d986e8c51 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Mar 2022 02:02:04 +0100 Subject: [PATCH 33/64] Prepare v16 --- ChangeLog | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/ChangeLog b/ChangeLog index a9a42c8d878..08d445cdfc7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,32 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 16.0.0 compared to 15.0.0 ***** + +For users: +--------------- + +NEW: ... + + + Modules +NEW: Experimental module Event Organization Management +NEW: Experimental module Workstations Management +NEW: Experimental module Partnership Management + + +For developers: +--------------- + +NEW: + +Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: +* verifCond('stringtoevaluate') now return false when string contains a bad syntax content instead of true. + + + + + ***** ChangeLog for 15.0.0 compared to 14.0.0 ***** For users: From 88944656be2b220a225c8d1170bc76e9abaa6eb7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Mar 2022 02:05:13 +0100 Subject: [PATCH 34/64] Doc --- htdocs/core/lib/functions.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index bc07728080f..d8595c15bbf 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -8311,7 +8311,7 @@ function verifCond($strToEvaluate) //$str = 'if(!('.$strToEvaluate.')) $rights = false;'; //dol_eval($str, 0, 1, '2'); // The dol_eval must contains all the global $xxx used into a condition //var_dump($strToEvaluate); - $rep = dol_eval($strToEvaluate, 1, 1, '1'); // The dol_eval must contains all the global $xxx used into a condition + $rep = dol_eval($strToEvaluate, 1, 1, '1'); // The dol_eval must contains all the global $xxx for all variables $xxx found into the string condition $rights = (($rep && strpos($rep, 'Bad string syntax to evaluate') === false) ? true : false); //var_dump($rights); } From 246474b39b06a306ccdb46d48d40daf399492c51 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Mar 2022 02:15:52 +0100 Subject: [PATCH 35/64] Fix phpunit --- test/phpunit/SecurityTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index e9a19dd576a..ccbb0b38ded 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -916,8 +916,7 @@ class SecurityTest extends PHPUnit\Framework\TestCase global $leftmenu; $leftmenu = 'admintools'; - $conf->barcode->enabled = 1; - $result=dol_eval('$conf->barcode->enabled && preg_match(\'/^(admintools|all)/\',$leftmenu)', 1, 0, '2'); + $result=dol_eval('$conf->currency && preg_match(\'/^(admintools|all)/\',$leftmenu)', 1, 0, '2'); print "result = ".$result."\n"; $this->assertTrue($result); From 2837c938e6c358022782aac90e9c93a17eb251b7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Mar 2022 09:41:15 +0100 Subject: [PATCH 36/64] Fix help easier to understand to avoid lethal situations. Fix reponsive --- htdocs/accountancy/bookkeeping/list.php | 52 +++++++++++++++---------- htdocs/core/class/html.form.class.php | 2 + htdocs/langs/en_US/accountancy.lang | 13 ++++--- htdocs/theme/eldy/global.inc.php | 4 ++ 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index d110f74a6a6..d6236af5d02 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -190,7 +190,7 @@ $arrayfields = array( 't.date_creation'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0), 't.tms'=>array('label'=>$langs->trans("DateModification"), 'checked'=>0), 't.date_export'=>array('label'=>$langs->trans("DateExport"), 'checked'=>1), - 't.date_validated'=>array('label'=>$langs->trans("DateValidation"), 'checked'=>1), + 't.date_validated'=>array('label'=>$langs->trans("DateValidationAndLock"), 'checked'=>1), ); if (empty($conf->global->ACCOUNTING_ENABLE_LETTERING)) { @@ -678,19 +678,28 @@ $formconfirm = ''; if ($action == 'export_file') { $form_question = array(); + // If 1 or not set, we check by default. + $checked = (!isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_EXPORT_DATE)); $form_question['notifiedexportdate'] = array( 'name' => 'notifiedexportdate', 'type' => 'checkbox', 'label' => $langs->trans('NotifiedExportDate'), - 'value' => (empty($conf->global->ACCOUNTING_DEFAULT_NOTIFIED_EXPORT_DATE) ? false : true), + 'value' => $checked, ); + + $form_question['separator'] = array('name'=>'separator', 'type'=>'separator'); + + // If 0 or not set, we NOT check by default. + $checked = (isset($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE) || !empty($conf->global->ACCOUNTING_DEFAULT_NOT_NOTIFIED_VALIDATION_DATE)); $form_question['notifiedvalidationdate'] = array( 'name' => 'notifiedvalidationdate', 'type' => 'checkbox', 'label' => $langs->trans('NotifiedValidationDate'), - 'value' => (empty($conf->global->ACCOUNTING_DEFAULT_NOTIFIED_VALIDATION_DATE) ? false : true), + 'value' => $checked, ); + $form_question['separator2'] = array('name'=>'separator2', 'type'=>'separator'); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?'.$param, $langs->trans("ExportFilteredList").' ('.$listofformat[$formatexportset].')', $langs->trans('ConfirmExportFile'), 'export_fileconfirm', $form_question, '', 1, 300, 600); } @@ -823,7 +832,7 @@ if (!empty($arrayfields['t.piece_num']['checked'])) { // Code journal if (!empty($arrayfields['t.code_journal']['checked'])) { print '
'; } // Date document @@ -845,10 +854,10 @@ if (!empty($arrayfields['t.doc_ref']['checked'])) { if (!empty($arrayfields['t.numero_compte']['checked'])) { print ''; } @@ -1125,24 +1134,25 @@ while ($i < min($num, $limit)) { // Other type } - print '\n"; if (!$i) { $totalarray['nbfield']++; @@ -1167,7 +1177,7 @@ while ($i < min($num, $limit)) { // Label operation if (!empty($arrayfields['t.label_operation']['checked'])) { - print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } @@ -1228,7 +1238,7 @@ while ($i < min($num, $limit)) { // Exported operation date if (!empty($arrayfields['t.date_export']['checked'])) { - print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } @@ -1236,7 +1246,7 @@ while ($i < min($num, $limit)) { // Validated operation date if (!empty($arrayfields['t.date_validated']['checked'])) { - print ''; + print ''; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 87d3d63cec1..ed73218c609 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -4863,6 +4863,8 @@ class Form $moreonecolumn .= ''."\n"; } elseif ($input['type'] == 'hidden') { // Do nothing more, already added by a previous loop + } elseif ($input['type'] == 'separator') { + $more .= '
'; } else { $more .= 'Error type '.$input['type'].' for the confirm box is not a supported type'; } diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 6f9d74de7c8..fd5ff8461fe 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -219,12 +219,12 @@ ByPredefinedAccountGroups=By predefined groups ByPersonalizedAccountGroups=By personalized groups ByYear=By year NotMatch=Not Set -DeleteMvt=Delete some operation lines from accounting +DeleteMvt=Delete some lines from accounting DelMonth=Month to delete DelYear=Year to delete DelJournal=Journal to delete -ConfirmDeleteMvt=This will delete all operation lines of the accounting for the year/month and/or for a specific journal (At least one criterion is required). You will have to reuse the feature '%s' to have the deleted record back in the ledger. -ConfirmDeleteMvtPartial=This will delete the transaction from the accounting (all operation lines related to the same transaction will be deleted) +ConfirmDeleteMvt=This will delete all lines in accountancy for the year/month and/or for a specific journal (At least one criterion is required). You will have to reuse the feature '%s' to have the deleted record back in the ledger. +ConfirmDeleteMvtPartial=This will delete the transaction from the accounting (all lines related to the same transaction will be deleted) FinanceJournal=Finance journal ExpenseReportsJournal=Expense reports journal DescFinanceJournal=Finance journal including all the types of payments by bank account @@ -301,7 +301,7 @@ Accounted=Accounted in ledger NotYetAccounted=Not yet transferred to accounting ShowTutorial=Show Tutorial NotReconciled=Not reconciled -WarningRecordWithoutSubledgerAreExcluded=Warning, all operations without subledger account defined are filtered and excluded from this view +WarningRecordWithoutSubledgerAreExcluded=Warning, all lines without subledger account defined are filtered and excluded from this view ## Admin BindingOptions=Binding options @@ -329,8 +329,9 @@ ACCOUNTING_DISABLE_BINDING_ON_PURCHASES=Disable binding & transfer in accountanc ACCOUNTING_DISABLE_BINDING_ON_EXPENSEREPORTS=Disable binding & transfer in accountancy on expense reports (expense reports will not be taken into account in accounting) ## Export -NotifiedExportDate=Flag exported lines as exported (modification of the lines will not be possible) -NotifiedValidationDate=Validate the exported entries (modification or deletion of the lines will not be possible) +NotifiedExportDate=Flag exported lines as Exported (to modify a line, you will need to delete the whole transaction and re-transfert it into accounting) +NotifiedValidationDate=Validate and Lock the exported entries (same effect than the "Closure" feature, modification and deletion of the lines will DEFINITELY not be possible) +DateValidationAndLock=Date validation and lock ConfirmExportFile=Confirmation of the generation of the accounting export file ? ExportDraftJournal=Export draft journal Modelcsv=Model of export diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index b88cecda187..a4020edccdb 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -6204,6 +6204,10 @@ span#select2-boxbookmark-container { overflow: hidden; } +ul.select2-results__options li { + font-size: 0.95em; +} + /* ============================================================================== */ /* For categories */ From 8655592aea6b21149488ef74205d0a16e9d351d0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 3 Mar 2022 09:51:12 +0100 Subject: [PATCH 37/64] Fix bad merge --- test/phpunit/SecurityTest.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index 3782bf9de85..eabfe389174 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -917,15 +917,13 @@ class SecurityTest extends PHPUnit\Framework\TestCase global $leftmenu; // Used into strings to eval $leftmenu = 'AAA'; - $conf->barcode->enabled = 1; $result=dol_eval('$conf->currency && preg_match(\'/^(AAA|BBB)/\',$leftmenu)', 1, 1, '1'); print "result = ".$result."\n"; $this->assertTrue($result); // Same with syntax error $leftmenu = 'XXX'; - $conf->barcode->enabled = 1; - $result=dol_eval('$conf->barcode->enabled && preg_match(\'/^(AAA|BBB)/\',$leftmenu)', 1, 1, '1'); + $result=dol_eval('$conf->currency && preg_match(\'/^(AAA|BBB)/\',$leftmenu)', 1, 1, '1'); print "result = ".$result."\n"; $this->assertFalse($result); From d884fe65329e98af55bfc054057328852b82e6bb Mon Sep 17 00:00:00 2001 From: Thomas Negre Date: Thu, 3 Mar 2022 09:58:34 +0100 Subject: [PATCH 38/64] Make ticket messages order by date desc by default --- htdocs/ticket/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/ticket/card.php b/htdocs/ticket/card.php index f1d33f4eeb0..de0b621f4bf 100755 --- a/htdocs/ticket/card.php +++ b/htdocs/ticket/card.php @@ -59,8 +59,8 @@ $backtopage = GETPOST('$backtopage', 'alpha'); $notifyTiers = GETPOST("notify_tiers_at_create", 'alpha'); -$sortfield = GETPOST('sortfield', 'aZ09comma'); -$sortorder = GETPOST('sortorder', 'aZ09comma'); +$sortfield = GETPOST('sortfield', 'aZ09comma') ? GETPOST('sortfield', 'aZ09comma') : "a.datep"; +$sortorder = GETPOST('sortorder', 'aZ09comma') ? GETPOST('sortorder', 'aZ09comma') : "desc"; if (GETPOST('actioncode', 'array')) { $actioncode = GETPOST('actioncode', 'array', 3); From 3b06a08aa033c993dc4edf139145778d9cc82bce Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 3 Mar 2022 13:56:10 +0100 Subject: [PATCH 39/64] FIX: User name in ManufacturingOrder --- htdocs/mrp/class/mo.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php index d4abe482a88..97ac9adb6a3 100644 --- a/htdocs/mrp/class/mo.class.php +++ b/htdocs/mrp/class/mo.class.php @@ -112,8 +112,8 @@ class Mo extends CommonObject 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-2, 'position'=>500, 'notnull'=>1,), 'tms' => array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-2, 'position'=>501, 'notnull'=>1,), 'date_valid' => array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-2, 'position'=>502,), - 'fk_user_creat' => array('type'=>'integer', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-2, 'position'=>510, 'notnull'=>1, 'foreignkey'=>'user.rowid', 'csslist'=>'tdoverflowmax100'), - 'fk_user_modif' => array('type'=>'integer', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'position'=>511, 'notnull'=>-1, 'csslist'=>'tdoverflowmax100'), + 'fk_user_creat' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-2, 'position'=>510, 'notnull'=>1, 'foreignkey'=>'user.rowid', 'csslist'=>'tdoverflowmax100'), + 'fk_user_modif' => array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserModif', 'enabled'=>1, 'visible'=>-2, 'position'=>511, 'notnull'=>-1, 'csslist'=>'tdoverflowmax100'), 'date_start_planned' => array('type'=>'datetime', 'label'=>'DateStartPlannedMo', 'enabled'=>1, 'visible'=>1, 'position'=>55, 'notnull'=>-1, 'index'=>1, 'help'=>'KeepEmptyForAsap'), 'date_end_planned' => array('type'=>'datetime', 'label'=>'DateEndPlannedMo', 'enabled'=>1, 'visible'=>1, 'position'=>56, 'notnull'=>-1, 'index'=>1,), 'import_key' => array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>1000, 'notnull'=>-1,), From 13b69bcf938afda42ebb668c6b1d89bc8511d0be Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 4 Mar 2022 07:00:02 +0100 Subject: [PATCH 40/64] NEW Dictionaries - add possibility to manage countries in EEC --- htdocs/admin/dict.php | 64 +++++++++++++++++-- .../install/mysql/migration/15.0.0-16.0.0.sql | 5 +- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index 437d58aeac9..74d26e29da5 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-2021 Alexandre Spangaro + * Copyright (C) 2011-2022 Alexandre Spangaro * Copyright (C) 2015 Ferran Marcet * Copyright (C) 2016 Raphaël Doursenaud * Copyright (C) 2019-2020 Frédéric France @@ -201,7 +201,7 @@ $tabsql = array(); $tabsql[1] = "SELECT f.rowid as rowid, f.code, f.libelle, c.code as country_code, c.label as country, f.active FROM ".MAIN_DB_PREFIX."c_forme_juridique as f, ".MAIN_DB_PREFIX."c_country as c WHERE f.fk_pays=c.rowid"; $tabsql[2] = "SELECT d.rowid as rowid, d.code_departement as code, d.nom as libelle, d.fk_region as region_id, r.nom as region, c.code as country_code, c.label as country, d.active FROM ".MAIN_DB_PREFIX."c_departements as d, ".MAIN_DB_PREFIX."c_regions as r, ".MAIN_DB_PREFIX."c_country as c WHERE d.fk_region=r.code_region and r.fk_pays=c.rowid and r.active=1 and c.active=1"; $tabsql[3] = "SELECT r.rowid as rowid, r.code_region as state_code, r.nom as libelle, r.fk_pays as country_id, c.code as country_code, c.label as country, r.active FROM ".MAIN_DB_PREFIX."c_regions as r, ".MAIN_DB_PREFIX."c_country as c WHERE r.fk_pays=c.rowid and c.active=1"; -$tabsql[4] = "SELECT c.rowid as rowid, c.code, c.label, c.active, c.favorite FROM ".MAIN_DB_PREFIX."c_country AS c"; +$tabsql[4] = "SELECT c.rowid as rowid, c.code, c.label, c.active, c.favorite, c.eec FROM ".MAIN_DB_PREFIX."c_country AS c"; $tabsql[5] = "SELECT c.rowid as rowid, c.code as code, c.label, c.active FROM ".MAIN_DB_PREFIX."c_civility AS c"; $tabsql[6] = "SELECT a.id as rowid, a.code as code, a.libelle AS libelle, a.type, a.active, a.module, a.color, a.position FROM ".MAIN_DB_PREFIX."c_actioncomm AS a"; $tabsql[7] = "SELECT a.id as rowid, a.code as code, a.libelle AS libelle, a.accountancy_code as accountancy_code, c.code as country_code, c.label as country, a.fk_pays as country_id, a.active FROM ".MAIN_DB_PREFIX."c_chargesociales AS a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_pays=c.rowid and c.active=1"; @@ -1093,6 +1093,45 @@ if ($action == 'disable_favorite') { } } +// Is in EEC - Activate +if ($action == 'activate_eec') { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET eec = 1 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET eec = 1 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } +} + +// Is in EEC - Disable +if ($action == 'disable_eec') { + if ($tabrowid[$id]) { + $rowidcol = $tabrowid[$id]; + } else { + $rowidcol = "rowid"; + } + + if ($rowid) { + $sql = "UPDATE ".$tabname[$id]." SET eec = 0 WHERE ".$rowidcol."='".$db->escape($rowid)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } elseif ($code) { + $sql = "UPDATE ".$tabname[$id]." SET eec = 0 WHERE code='".dol_escape_htmltag($code)."'".($entity != '' ? " AND entity = ".(int) $entity : ''); + } + + $result = $db->query($sql); + if (!$result) { + dol_print_error($db); + } +} /* * View @@ -1452,6 +1491,7 @@ if ($id) { if ($id == 4) { $tdsoffields .= ''; + $tdsoffields .= ''; } $tdsoffields .= ''; + print ''; } print ''; + print ''; } print ''; print ''; + print ''; $formconfirm .= ''; $formconfirm .= ''."\n"; diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php index b3a40ba3582..de034f652d3 100644 --- a/htdocs/core/tpl/massactions_pre.tpl.php +++ b/htdocs/core/tpl/massactions_pre.tpl.php @@ -212,14 +212,14 @@ if ($massaction == 'presend') { } if ($massaction == 'preenable') { - print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassEnabling"), $langs->trans("ConfirmMassEnablingQuestion", count($toselect)), "enable", null, '', 0, 200, 500, 1); + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassEnabling"), $langs->trans("ConfirmMassEnablingQuestion", count($toselect)), "enable", null, 'yes', 0, 200, 500, 1); } if ($massaction == 'predisable') { print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassDisabling"), $langs->trans("ConfirmMassDisablingQuestion", count($toselect)), "disable", null, '', 0, 200, 500, 1); } if ($massaction == 'preapproveleave') { - print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassLeaveApproval"), $langs->trans("ConfirmMassLeaveApprovalQuestion", count($toselect)), "approveleave", null, '', 0, 200, 500, 1); + print $form->formconfirm($_SERVER["PHP_SELF"], $langs->trans("ConfirmMassLeaveApproval"), $langs->trans("ConfirmMassLeaveApprovalQuestion", count($toselect)), "approveleave", null, 'yes', 0, 200, 500, 1); } // Allow Pre-Mass-Action hook (eg for confirmation dialog) diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index 44d5fb321e8..091b9ed95a2 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -1083,7 +1083,9 @@ if ((empty($id) && empty($ref)) || $action == 'create' || $action == 'add') { if (empty($include_users)) { print img_warning().' '.$langs->trans("NobodyHasPermissionToValidateHolidays"); } else { - $defaultselectuser = (empty($user->fk_user_holiday_validator) ? $user->fk_user : $user->fk_user_holiday_validator); // Will work only if supervisor has permission to approve so is inside include_users + // Defined default approver (the forced approved of user or the supervisor if no forced value defined) + // Note: This use will be set only if the deinfed approvr has permission to approve so is inside include_users + $defaultselectuser = (empty($user->fk_user_holiday_validator) ? $user->fk_user : $user->fk_user_holiday_validator); if (!empty($conf->global->HOLIDAY_DEFAULT_VALIDATOR)) { $defaultselectuser = $conf->global->HOLIDAY_DEFAULT_VALIDATOR; // Can force default approver } diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 5a955ec0df3..a3a3b7e5d4f 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -274,6 +274,7 @@ ErrorNotInDictionaryPaymentConditions=Not in Payment Terms Dictionary, please mo ErrorIsNotADraft=%s is not a draft ErrorExecIdFailed=Can't execute command "id" ErrorBadCharIntoLoginName=Unauthorized character in the login name +ErrorNotApproverForHoliday=You are not the approver for leave %s # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup. diff --git a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php index 13e34593bba..02eb1c18fb6 100644 --- a/htdocs/modulebuilder/template/core/modules/modMyModule.class.php +++ b/htdocs/modulebuilder/template/core/modules/modMyModule.class.php @@ -432,7 +432,7 @@ class modMyModule extends DolibarrModules $sql = array(); // Document templates - $moduledir = 'mymodule'; + $moduledir = dol_sanitizeFileName('mymodule'); $myTmpObjects = array(); $myTmpObjects['MyObject'] = array('includerefgeneration'=>0, 'includedocgeneration'=>0); @@ -441,8 +441,8 @@ class modMyModule extends DolibarrModules continue; } if ($myTmpObjectArray['includerefgeneration']) { - $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/mymodule/template_myobjects.odt'; - $dirodt = DOL_DATA_ROOT.'/doctemplates/mymodule'; + $src = DOL_DOCUMENT_ROOT.'/install/doctemplates/'.$moduledir.'/template_myobjects.odt'; + $dirodt = DOL_DATA_ROOT.'/doctemplates/'.$moduledir; $dest = $dirodt.'/template_myobjects.odt'; if (file_exists($src) && !file_exists($dest)) { From 378dab69a6753298b5c8ce490f78e843e080d39a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Mar 2022 13:21:32 +0100 Subject: [PATCH 55/64] FIX #19777 #20281 --- htdocs/compta/paiement/cheque/card.php | 50 ++++++++++++------- .../cheque/class/remisecheque.class.php | 1 + htdocs/core/class/html.formfile.class.php | 4 +- .../modules/cheque/modules_chequereceipts.php | 3 +- htdocs/ecm/class/ecmfiles.class.php | 6 ++- 5 files changed, 40 insertions(+), 24 deletions(-) diff --git a/htdocs/compta/paiement/cheque/card.php b/htdocs/compta/paiement/cheque/card.php index 0dd6c57313e..c109acedf7e 100644 --- a/htdocs/compta/paiement/cheque/card.php +++ b/htdocs/compta/paiement/cheque/card.php @@ -41,12 +41,7 @@ $ref = GETPOST('ref', 'alpha'); $action = GETPOST('action', 'aZ09'); $confirm = GETPOST('confirm', 'alpha'); -// Security check -$fieldname = (!empty($ref) ? 'ref' : 'rowid'); -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'cheque', $id, 'bordereau_cheque', '', 'fk_user_author', $fieldname); +$object = new RemiseCheque($db); $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); @@ -63,11 +58,22 @@ if (empty($page) || $page == -1) { $limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; $offset = $limit * $page; -$dir = $conf->bank->dir_output.'/checkdeposits/'; +$upload_dir = $conf->bank->multidir_output[$object->entity ? $object->entity : $conf->entity]."/checkdeposits"; + $filterdate = dol_mktime(0, 0, 0, GETPOST('fdmonth'), GETPOST('fdday'), GETPOST('fdyear')); $filteraccountid = GETPOST('accountid', 'int'); -$object = new RemiseCheque($db); +// Security check +$fieldname = (!empty($ref) ? 'ref' : 'rowid'); +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'cheque', $id, 'bordereau_cheque', '', 'fk_user_author', $fieldname); + +$usercanread = $user->rights->banque->cheque; +$usercancreate = $user->rights->banque->cheque; +$usercandelete = $user->rights->banque->cheque; + /* @@ -242,7 +248,9 @@ if ($action == 'builddoc' && $user->rights->banque->cheque) { $langs->load("other"); - $file = $dir.get_exdir($object->ref, 0, 1, 0, $object, 'cheque').GETPOST('file'); + $filetodelete = GETPOST('file', 'alpha'); + $file = $upload_dir.'/'.$filetodelete; + $ret = dol_delete_file($file, 0, 0, 0, $object); if ($ret) { setEventMessages($langs->trans("FileWasRemoved", GETPOST('file')), null, 'mesgs'); @@ -635,6 +643,12 @@ if ($action == 'new') { $i = 1; if ($num > 0) { while ($objp = $db->fetch_object($resql)) { + $paymentstatic->id = $objp->pid; + $paymentstatic->ref = $objp->pref; + + $accountlinestatic->id = $objp->rowid; + $accountlinestatic->ref = $objp->ref; + print ''; print ''; print ''; // Operation date @@ -644,8 +658,6 @@ if ($action == 'new') { print ''; // Link to payment print ''; // Link to bank transaction print '
'.$langs->trans("BookmarkTitle").''.$langs->trans("SetHereATitleForLink").'
'.$langs->trans("BookmarkTitle").''.$langs->trans("SetHereATitleForLink").'
'; if ($action == 'edit') { - print 'title).'">'; + print 'title).'">'; } else { - print $object->title; + print dol_escape_htmltag($object->title); } print '
'; - print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1, 'maxwidth150'); + print $formaccounting->multi_select_journal($search_ledger_code, 'search_ledger_code', 0, 1, 1, 1, 'small maxwidth150'); print ''; print '
'; - print $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth200', 'account'); + print $formaccounting->select_account($search_accountancy_code_start, 'search_accountancy_code_start', $langs->trans('From'), array(), 1, 1, 'maxwidth150', 'account'); print '
'; print '
'; - print $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth200', 'account'); + print $formaccounting->select_account($search_accountancy_code_end, 'search_accountancy_code_end', $langs->trans('to'), array(), 1, 1, 'maxwidth150', 'account'); print '
'; print '
'; - - print ''; - // Picto + Ref - print '
'; - + $labeltoshow = ''; + $labeltoshowalt = ''; if ($line->doc_type == 'customer_invoice' || $line->doc_type == 'supplier_invoice' || $line->doc_type == 'expense_report') { - print $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1); - print $documentlink; + $labeltoshow .= $objectstatic->getNomUrl(1, '', 0, 0, '', 0, -1, 1); + $labeltoshow .= $documentlink; + $labeltoshowalt .= $objectstatic->ref; } elseif ($line->doc_type == 'bank') { - print $objectstatic->getNomUrl(1); + $labeltoshow .= $objectstatic->getNomUrl(1); + $labeltoshowalt .= $objectstatic->ref; $bank_ref = strstr($line->doc_ref, '-'); - print " " . $bank_ref; + $labeltoshow .= " " . $bank_ref; + $labeltoshowalt .= " " . $bank_ref; } else { - print $line->doc_ref; + $labeltoshow .= $line->doc_ref; + $labeltoshowalt .= $line->doc_ref; } - print '
'; + print '
'; + print $labeltoshow; print "'.$line->label_operation.''.dol_escape_htmltag($line->label_operation).''.dol_print_date($line->date_export, 'dayhour').''.dol_print_date($line->date_export, 'dayhour').''.dol_print_date($line->date_validation, 'dayhour').''.dol_print_date($line->date_validation, 'dayhour').''; $tdsoffields .= ''; @@ -1496,6 +1536,7 @@ if ($id) { if ($id == 4) { print ''; if ($action != 'edit') { @@ -1569,6 +1610,7 @@ if ($id) { } if ($id == 4) { print ''; @@ -1592,10 +1634,10 @@ if ($id) { // Determines the name of the field in relation to the possible names // in data dictionaries - $showfield = 1; // By defaut + $showfield = 1; // By default $cssprefix = ''; $sortable = 1; - $valuetoshow = ucfirst($value); // By defaut + $valuetoshow = ucfirst($value); // By default $valuetoshow = $langs->trans($valuetoshow); // try to translate // Special cases @@ -1794,8 +1836,9 @@ if ($id) { print getTitleFieldOfList($newvaluetoshow, 0, $_SERVER["PHP_SELF"], ($sortable ? $value : ''), ($page ? 'page='.$page.'&' : ''), $param, '', $sortfield, $sortorder, $cssprefix); } } - // Favorite - Only activated on country dictionary + // Favorite & EEC - Only activated on country dictionary if ($id == 4) { + print getTitleFieldOfList($langs->trans("InEEC"), 0, $_SERVER["PHP_SELF"], "eec", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder, '', 0, $langs->trans("CountryIsInEEC")); print getTitleFieldOfList($langs->trans("Favorite"), 0, $_SERVER["PHP_SELF"], "favorite", ($page ? 'page='.$page.'&' : ''), $param, 'align="center"', $sortfield, $sortorder); } @@ -2089,10 +2132,19 @@ if ($id) { } $url .= '&'; - // Favorite + // Favorite & EEC // Only activated on country dictionary if ($id == 4) { print ''; + // Is in EEC + if ($iserasable) { + print ''.$actl[$obj->eec].''; + } else { + print $langs->trans("AlwaysActive"); + } + print ''; + // Favorite if ($iserasable) { print ''.$actl[$obj->favorite].''; } else { diff --git a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql index 5d838fc8bb1..8e1a713ecf7 100644 --- a/htdocs/install/mysql/migration/15.0.0-16.0.0.sql +++ b/htdocs/install/mysql/migration/15.0.0-16.0.0.sql @@ -272,4 +272,7 @@ ALTER TABLE llx_reception MODIFY COLUMN ref_supplier varchar(128); ALTER TABLE llx_bank_account ADD COLUMN pti_in_ctti smallint DEFAULT 0 AFTER domiciliation; -- Set default ticket type to OTHER if no default exists -UPDATE llx_c_ticket_type SET use_default=1 WHERE code='OTHER' AND NOT EXISTS(SELECT * FROM (SELECT * FROM llx_c_ticket_type) AS t WHERE use_default=1); \ No newline at end of file +UPDATE llx_c_ticket_type SET use_default=1 WHERE code='OTHER' AND NOT EXISTS(SELECT * FROM (SELECT * FROM llx_c_ticket_type) AS t WHERE use_default=1); + +UPDATE llx_c_country SET eec=0 WHERE eec IS NULL; +ALTER TABLE llx_c_country MODIFY COLUMN eec tinyint DEFAULT 0 NOT NULL; From 1671b095eb5a64b0dc5f96c745ba85937a323cd4 Mon Sep 17 00:00:00 2001 From: Alexandre SPANGARO Date: Fri, 4 Mar 2022 07:02:40 +0100 Subject: [PATCH 41/64] Fix also table llx_c_country --- htdocs/install/mysql/tables/llx_c_country.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/install/mysql/tables/llx_c_country.sql b/htdocs/install/mysql/tables/llx_c_country.sql index d97c3b90371..7419b68c26d 100644 --- a/htdocs/install/mysql/tables/llx_c_country.sql +++ b/htdocs/install/mysql/tables/llx_c_country.sql @@ -24,8 +24,8 @@ create table llx_c_country rowid integer PRIMARY KEY, code varchar(2) NOT NULL, code_iso varchar(3) , - label varchar(128) NOT NULL, - eec integer , + label varchar(128) NOT NULL, + eec tinyint DEFAULT 0 NOT NULL, active tinyint DEFAULT 1 NOT NULL, favorite tinyint DEFAULT 0 NOT NULL )ENGINE=innodb; From 8c2c3bf3fbd392db4ba5f816223bc7f64fffabe4 Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Fri, 4 Mar 2022 10:06:24 +0100 Subject: [PATCH 42/64] Fix: Can't import thirds. Column Skype doesn't exist --- htdocs/core/modules/modSociete.class.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index e70011a2195..03ca9aa8502 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -5,6 +5,7 @@ * Copyright (C) 2004 Benoit Mortier * Copyright (C) 2005-2013 Regis Houssin * Copyright (C) 2012-2014 Juanjo Menent + * Copyright (C) 2022 Ferran Marcet * * 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 @@ -463,7 +464,6 @@ class modSociete extends DolibarrModules 's.fax' => "Fax", 's.url' => "Url", 's.email' => "Email", - 's.skype' => "Skype", 's.fk_effectif' => "Staff", 's.fk_typent' => "ThirdPartyType", "s.fk_forme_juridique" => "JuridicalStatus", @@ -604,7 +604,6 @@ class modSociete extends DolibarrModules 's.fax' => "eg. +34987654321", 's.url' => "e.g. https://www.mybigcompany.com", 's.email' => "e.g. test@mybigcompany.com", - 's.skype' => "Skype name", 's.fk_effectif' => "1/2/3/5: represents one of the five ranges of employees", 's.fk_typent' => 'matches field "id" (1-9 etc.) OR "code" (TE_SMALL etc.) in table "'.MAIN_DB_PREFIX.'c_typent"', 's.fk_forme_juridique' => '1/2/3 etc...matches field "code" in table "'.MAIN_DB_PREFIX.'c_forme_juridique"', @@ -676,7 +675,6 @@ class modSociete extends DolibarrModules 's.phone_mobile' => "PhoneMobile", 's.fax' => "Fax", 's.email' => "Email", - 's.skype' => "Skype", 's.note_private' => "NotePrivate", 's.note_public' => "NotePublic" ); @@ -742,7 +740,6 @@ class modSociete extends DolibarrModules 's.phone_mobile' => "5551144", 's.fax' => "5551155", 's.email' => "johnsmith@email.com", - 's.skype' => "skype username", 's.note_private' => "My private note", 's.note_public' => "My public note" ); From 82e2f8706a3a30df08bacd684191e6e413c1c7f9 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 4 Mar 2022 11:22:08 +0100 Subject: [PATCH 43/64] Doc --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index a9a42c8d878..a65a8f21329 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ For users: NEW: Online proposal signature NEW: Can define some max limit on expense report (per period, per type or expense, ...) +NEW: Provide a special pages for bookmarks and multicompany for a better use of some mobile applications (like DoliDroid) NEW: Allow the use of __NEWREF__ to get for example the new reference a draft order will get after validation. NEW: Add option to disable globaly some notifications emails. NEW: #18401 Add __NEWREF__ subtitute to get new object reference. From 7701ae2d194b404502407849f374974c9e81dd6e Mon Sep 17 00:00:00 2001 From: Gauthier PC portable 024 Date: Fri, 4 Mar 2022 13:55:52 +0100 Subject: [PATCH 44/64] FIX : in case of TVA refund, negative amount must be allowed --- htdocs/compta/paiement_vat.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/paiement_vat.php b/htdocs/compta/paiement_vat.php index 323221f6f2b..d52a8c3941d 100644 --- a/htdocs/compta/paiement_vat.php +++ b/htdocs/compta/paiement_vat.php @@ -83,7 +83,7 @@ if ($action == 'add_payment' || ($action == 'confirm_paiement' && $confirm == 'y } } - if ($amounts[key($amounts)] <= 0) { + if (empty($amounts[key($amounts)])) { $error++; setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Amount")), null, 'errors'); $action = 'create'; From 744b84cb09f53f4856b0e707492b42cb0f983ba5 Mon Sep 17 00:00:00 2001 From: Eric Seigne Date: Fri, 4 Mar 2022 15:20:50 +0100 Subject: [PATCH 45/64] fix #20270 : use product_id in sql only if product_id is defined --- htdocs/product/class/product.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index e4724eb051c..dc9a08a24c7 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1803,7 +1803,9 @@ class Product extends CommonObject $sql .= " ,pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code"; if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", pfp.packaging"; $sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; - $sql .= " WHERE pfp.fk_product = ".$product_id; + $sql .= " WHERE 1=1"; + if ($product_id != 0) { $sql .= " AND pfp.fk_product = '".$product_id."'"; + } if ($fourn_ref != 'none') { $sql .= " AND pfp.ref_fourn = '".$fourn_ref."'"; } if ($fk_soc > 0) { $sql .= " AND pfp.fk_soc = ".$fk_soc; From 444abbbc0e85cc5b318f57578f0715aa656a07e1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 4 Mar 2022 16:44:33 +0100 Subject: [PATCH 46/64] Fix regression --- htdocs/fourn/class/fournisseur.commande.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 614130097c5..528bda30442 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -470,15 +470,15 @@ class CommandeFournisseur extends CommonOrder $sql .= " FROM ".MAIN_DB_PREFIX."commande_fournisseurdet as l"; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON l.fk_product = p.rowid'; if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON pfp.entity IN (".getEntity('product_fournisseur_price').") AND l.fk_product = pfp.fk_product and l.ref = pfp.ref_fourn AND pfp.fk_soc = ".((int) $this->socid); + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON pfp.entity IN (".getEntity('product_fournisseur_price').") AND l.fk_product = pfp.fk_product and l.ref = pfp.ref_fourn AND l.qty >= pfp.quantity AND pfp.fk_soc = ".((int) $this->socid); } $sql .= " WHERE l.fk_commande = ".$this->id; if ($only_product) { $sql .= ' AND p.fk_product_type = 0'; } if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql.= " AND l.qty >= pfp.quantity "; - $sql.= " GROUP BY l.rowid HAVING max_qty = MAX(pfp.quantity) "; + $sql.= " GROUP BY l.rowid"; + $sql.= " HAVING (max_qty = MAX(pfp.quantity) OR max_qty IS NULL)"; } $sql .= " ORDER BY l.rang, l.rowid"; //print $sql; @@ -3528,11 +3528,11 @@ class CommandeFournisseurLigne extends CommonOrderLine $sql .= ' FROM '.MAIN_DB_PREFIX.'commande_fournisseurdet as cd'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'product as p ON cd.fk_product = p.rowid'; if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON pfp.entity IN (".getEntity('product_fournisseur_price').") AND cd.fk_product = pfp.fk_product and cd.ref = pfp.ref_fourn"; + $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product_fournisseur_price as pfp ON pfp.entity IN (".getEntity('product_fournisseur_price').") AND cd.fk_product = pfp.fk_product and cd.ref = pfp.ref_fourn AND cd.qty >= pfp.quantity"; } $sql .= ' WHERE cd.rowid = '.((int) $rowid); if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) { - $sql .= " AND cd.qty >= pfp.quantity GROUP BY cd.rowid HAVING max_qty = MAX(pfp.quantity)"; + $sql .= " GROUP BY cd.rowid HAVING (max_qty = MAX(pfp.quantity) OR max_qty IS NULL)"; } $result = $this->db->query($sql); if ($result) { From 9d1bcbe55a6c2d83be0c36802ed14eaaefa0fd2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 4 Mar 2022 18:17:23 +0100 Subject: [PATCH 47/64] Fix wrong upload dir introduced here https://github.com/Dolibarr/dolibarr/pull/19165 --- htdocs/commande/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 990ec43c8ae..b6e16a22a9e 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -1371,7 +1371,7 @@ if (empty($reshook)) { include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; // Actions to build doc - $upload_dir = !empty($conf->propal->multidir_output[$object->entity])?$conf->propal->multidir_output[$object->entity]:$conf->propal->dir_output; + $upload_dir = !empty($conf->commande->multidir_output[$object->entity])?$conf->commande->multidir_output[$object->entity]:$conf->commande->dir_output; $permissiontoadd = $usercancreate; include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php'; From 792dcc63349c88761a71590f490990e65c779235 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 4 Mar 2022 19:14:57 +0100 Subject: [PATCH 48/64] FIX creation of the shipment if order contains services - 2/2 --- htdocs/expedition/card.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 743930767dd..4bec4220c6c 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -1194,6 +1194,7 @@ if ($action == 'create') { print ''; } else { if (! empty($conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS)) { + print ''; print ''; } From d326fe02cf1057a66ba8089786d4e6bb08e4fe89 Mon Sep 17 00:00:00 2001 From: Khang Date: Sat, 5 Mar 2022 07:02:36 +0700 Subject: [PATCH 49/64] Feature: unit price for {DOL_PRINT_OBJECT_LINES} Module "Receipt printers": add unit price for {DOL_PRINT_OBJECT_LINES} in tabs "template setup" --- htdocs/core/class/dolreceiptprinter.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index 7653fd24437..66be0356180 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -642,9 +642,9 @@ class dolReceiptPrinter extends Printer case 'DOL_PRINT_OBJECT_LINES': foreach ($object->lines as $line) { if ($line->fk_product) { - $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - 10 - 1; + $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - strlen($line->subprice) - 10 - 1; $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0); - $this->printer->text($line->ref.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n"); + $this->printer->text($line->ref . $spaces . $line->qty . str_pad(price($line->subprice), 10, ' ', STR_PAD_LEFT) . ' ' . str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT) . "\n"); $this->printer->text(strip_tags(htmlspecialchars_decode($line->product_label))."\n"); } else { $spacestoadd = $nbcharactbyline - strlen($line->description) - strlen($line->qty) - 10 - 1; From 9cada0426115df8b63c54854c7c6503b39397e18 Mon Sep 17 00:00:00 2001 From: Khang Date: Sat, 5 Mar 2022 16:58:37 +0700 Subject: [PATCH 50/64] Add unit price for "free-text product" receipt --- htdocs/core/class/dolreceiptprinter.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index 66be0356180..c308a13e865 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -645,11 +645,11 @@ class dolReceiptPrinter extends Printer $spacestoadd = $nbcharactbyline - strlen($line->ref) - strlen($line->qty) - strlen($line->subprice) - 10 - 1; $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0); $this->printer->text($line->ref . $spaces . $line->qty . str_pad(price($line->subprice), 10, ' ', STR_PAD_LEFT) . ' ' . str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT) . "\n"); - $this->printer->text(strip_tags(htmlspecialchars_decode($line->product_label))."\n"); + $this->printer->text(strip_tags(htmlspecialchars_decode($line->product_label))."\n \n"); } else { - $spacestoadd = $nbcharactbyline - strlen($line->description) - strlen($line->qty) - 10 - 1; + $spacestoadd = $nbcharactbyline - strlen($line->description) - strlen($line->qty) - strlen($line->subprice) - 10 - 1; $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0); - $this->printer->text($line->description.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n"); + $this->printer->text($line->description.$spaces.$line->qty.' '.str_pad(price($line->subprice), 10, ' ', STR_PAD_LEFT).' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n \n"); } } break; From 543c475a71d601d51d46707fcd9a149ead1df3ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 6 Mar 2022 10:56:17 +0100 Subject: [PATCH 51/64] clean comment --- htdocs/fourn/class/fournisseur.facture.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index e9db81e298f..2a1a54e70d3 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -12,7 +12,7 @@ * Copyright (C) 2015-2019 Ferran Marcet * Copyright (C) 2016-2021 Alexandre Spangaro * Copyright (C) 2018 Nicolas ZABOURI - * Copyright (C) 2018-2020 Frédéric France + * Copyright (C) 2018-2022 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 @@ -245,7 +245,7 @@ class FactureFournisseur extends CommonInvoice public $multicurrency_total_ht; public $multicurrency_total_tva; public $multicurrency_total_ttc; - //! id of source var_dump($$this);invoice if replacement invoice or credit note + //! id of source invoice if replacement invoice or credit note /** * @var int ID */ From 371565988051e639a912f96234aa50af8da4bf9e Mon Sep 17 00:00:00 2001 From: andreubisquerra Date: Sun, 6 Mar 2022 12:27:59 +0100 Subject: [PATCH 52/64] Set to default place after close sale in TakePOS Set to default place after close sale in TakePOS when Bar Restaurant mode is enabled --- htdocs/takepos/invoice.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 66a75ef7050..3453d0e0579 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -912,6 +912,7 @@ $form = new Form($db); '."\n"; // Local calendar - $s .= '
'.$langs->trans("LocalAgenda").'  
'; + $s .= '
'.$langs->trans("LocalAgenda").'  
'; // Holiday calendar - $s .= '
 
'; + $s .= '
 
'; // External calendars if (is_array($showextcals) && count($showextcals) > 0) { @@ -607,13 +608,13 @@ if (!empty($conf->use_javascript_ajax)) { // If javascript on foreach ($showextcals as $val) { $htmlname = md5($val['name']); - if (!empty($val['default'])) { + if (!empty($val['default']) || GETPOST('check_ext'.$htmlname, 'int')) { $default = "checked"; } else { $default = ''; } - $s .= '
 
'; + $s .= '
 
'; } } @@ -847,6 +848,7 @@ if ($resql) { $event->fk_project = $obj->fk_project; + $event->socid = $obj->fk_soc; $event->thirdparty_id = $obj->fk_soc; $event->contact_id = $obj->fk_contact; @@ -894,13 +896,13 @@ if ($resql) { $daykey = dol_mktime(0, 0, 0, $mois, $jour, $annee, 'gmt'); // $mois, $jour, $annee has been set for user tz $daykeyend = dol_mktime(0, 0, 0, $moisend, $jourend, $anneeend, 'gmt'); // $moisend, $jourend, $anneeend has been set for user tz /* - print 'GMT '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'gmt').'
'; - print 'TZSERVER '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzserver').'
'; - print 'TZUSERREL '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel').'
'; - print 'GMT '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'gmt').'
'; - print 'TZSERVER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzserver').'
'; - print 'TZUSER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel').'
'; - */ + print 'GMT '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'gmt').'
'; + print 'TZSERVER '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzserver').'
'; + print 'TZUSERREL '.$event->date_start_in_calendar.' '.dol_print_date($event->date_start_in_calendar, 'dayhour', 'tzuserrel').'
'; + print 'GMT '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'gmt').'
'; + print 'TZSERVER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzserver').'
'; + print 'TZUSER '.$event->date_end_in_calendar.' '.dol_print_date($event->date_end_in_calendar, 'dayhour', 'tzuserrel').'
'; + */ do { //if ($event->id==408) //print 'daykey='.$daykey.' daykeyend='.$daykeyend.' '.dol_print_date($daykey, 'dayhour', 'gmt').' - '.dol_print_date($event->datep, 'dayhour', 'gmt').' '.dol_print_date($event->datef, 'dayhour', 'gmt').'
'; @@ -1996,7 +1998,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa if ($event->type_code != 'ICALEVENT') { $savlabel = $event->label ? $event->label : $event->libelle; $event->label = $titletoshow; - $event->libelle = $titletoshow; + $event->libelle = $titletoshow; // deprecatd // Note: List of users are inside $event->userassigned. Link may be clickable depending on permissions of user. $titletoshow = (($event->type_picto || $event->type_code) ? $event->getTypePicto() : ''); $titletoshow .= $event->getNomUrl(0, $maxnbofchar, 'cal_event cal_event_title', '', 0, 0); diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 602897d34f9..194ccf40d4d 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -1579,17 +1579,20 @@ if (!$error && ($massaction == 'approveleave' || ($action == 'approveleave' && $ $nbok = 0; foreach ($toselect as $toselectid) { $result = $objecttmp->fetch($toselectid); - if ($result>0) { - if ($objecttmp->statut == Holiday::STATUS_VALIDATED && $user->id == $objecttmp->fk_validator) { + if ($result > 0) { + if ($objecttmp->statut != Holiday::STATUS_VALIDATED) { + setEventMessages($langs->trans('StatusOfRefMustBe', $objecttmp->ref, $langs->transnoentitiesnoconv('Validated')), null, 'warnings'); + continue; + } + if ($user->id == $objecttmp->fk_validator) { $objecttmp->oldcopy = dol_clone($objecttmp); $objecttmp->date_valid = dol_now(); $objecttmp->fk_user_valid = $user->id; $objecttmp->statut = Holiday::STATUS_APPROVED; - $db->begin(); - $verif = $objecttmp->approve($user); + if ($verif <= 0) { setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); $error++; @@ -1664,14 +1667,9 @@ if (!$error && ($massaction == 'approveleave' || ($action == 'approveleave' && $ } } } - - if (!$error) { - $db->commit(); - $nbok++; - } else { - $db->rollback(); - $action = ''; - } + } else { + $langs->load("errors"); + setEventMessages($langs->trans('ErrorNotApproverForHoliday', $objecttmp->ref), null, 'errors'); } } else { setEventMessages($objecttmp->error, $objecttmp->errors, 'errors'); @@ -1683,7 +1681,7 @@ if (!$error && ($massaction == 'approveleave' || ($action == 'approveleave' && $ if (!$error) { if ($nbok > 1) { setEventMessages($langs->trans("RecordsApproved", $nbok), null, 'mesgs'); - } else { + } elseif ($nbok == 1) { setEventMessages($langs->trans("RecordAproved"), null, 'mesgs'); } $db->commit(); diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index ed73218c609..821d87dcd82 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -5037,7 +5037,7 @@ class Form $formconfirm .= '
'.$question.''; $formconfirm .= $this->selectyesno("confirm", $newselectedchoice, 0, false, 0, 0, 'marginleftonly marginrightonly'); - $formconfirm .= ''; + $formconfirm .= ''; $formconfirm .= '
'.$i.''.dol_print_date($db->jdate($objp->date), 'day').''.price($objp->amount).''; - $paymentstatic->id = $objp->pid; - $paymentstatic->ref = $objp->pref; if ($paymentstatic->id) { print $paymentstatic->getNomUrl(1); } else { @@ -654,8 +666,6 @@ if ($action == 'new') { print ''; - $accountlinestatic->id = $objp->rowid; - $accountlinestatic->ref = $objp->ref; if ($accountlinestatic->id > 0) { print $accountlinestatic->getNomUrl(1); } else { @@ -665,10 +675,10 @@ if ($action == 'new') { // Action button print ''; if ($object->statut == 0) { - print 'rowid.'">'.img_delete().''; + print 'rowid.'">'.img_delete().''; } if ($object->statut == 1 && $objp->statut != 2) { - print 'rowid.'">'.img_picto($langs->trans("RejectCheck"), 'disable').''; + print 'rowid.'">'.img_picto($langs->trans("RejectCheck"), 'disable').''; } if ($objp->statut == 2) { print '   '.img_picto($langs->trans('CheckRejected'), 'statut8').''; @@ -724,11 +734,13 @@ print ''; if ($action != 'new') { if ($object->statut == 1) { - $filename = dol_sanitizeFileName($object->ref); - $filedir = $dir.get_exdir($object->ref, 0, 1, 0, $object, 'checkdeposits'); + // Documents + $objref = dol_sanitizeFileName($object->ref); + $filedir = $upload_dir.'/'.$objref; $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; - - print $formfile->showdocuments('remisecheque', $filename, $filedir, $urlsource, 1, 1); + $genallowed = $usercancreate; + $delallowed = $usercandelete; + print $formfile->showdocuments('remisecheque', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $langs->defaultlang); print '
'; } diff --git a/htdocs/compta/paiement/cheque/class/remisecheque.class.php b/htdocs/compta/paiement/cheque/class/remisecheque.class.php index c66edfc8fe1..6b1053240c8 100644 --- a/htdocs/compta/paiement/cheque/class/remisecheque.class.php +++ b/htdocs/compta/paiement/cheque/class/remisecheque.class.php @@ -615,6 +615,7 @@ class RemiseCheque extends CommonObject // We save charset_output to restore it because write_file can change it if needed for // output format that does not support UTF8. $sav_charseSupprimert_output = $outputlangs->charset_output; + $result = $docmodel->write_file($this, $conf->bank->dir_output.'/checkdeposits', $this->ref, $outputlangs); if ($result > 0) { //$outputlangs->charset_output=$sav_charset_output; diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index c64fa50fc56..26d39674e08 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -360,8 +360,8 @@ class FormFile * This also set the property $this->numoffiles * * @param string $modulepart Module the files are related to ('propal', 'facture', 'facture_fourn', 'mymodule', 'mymodule:MyObject', 'mymodule_temp', ...) - * @param string $modulesubdir Existing (so sanitized) sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into subdir of module. - * @param string $filedir Directory to scan + * @param string $modulesubdir Existing (so sanitized) sub-directory to scan (Example: '0/1/10', 'FA/DD/MM/YY/9999'). Use '' if file is not into a subdir of module. + * @param string $filedir Directory to scan (must not end with a /). Example: '/mydolibarrdocuments/facture/FAYYMM-1234' * @param string $urlsource Url of origin page (for return) * @param int|string[] $genallowed Generation is allowed (1/0 or array list of templates) * @param int $delallowed Remove is allowed (1/0) diff --git a/htdocs/core/modules/cheque/modules_chequereceipts.php b/htdocs/core/modules/cheque/modules_chequereceipts.php index dfdf0fbe363..e50a6877848 100644 --- a/htdocs/core/modules/cheque/modules_chequereceipts.php +++ b/htdocs/core/modules/cheque/modules_chequereceipts.php @@ -126,8 +126,7 @@ abstract class ModeleNumRefChequeReceipts } /** - * \class ModeleChequeReceipts - * \brief Classe mere des modeles de + * Class parent for templates of document generation */ abstract class ModeleChequeReceipts extends CommonDocGenerator { diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index 6c2b8fc4023..1ffe39f26ce 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -327,7 +327,11 @@ class EcmFiles extends CommonObject $resql = $this->db->query($sql); if (!$resql) { $error++; - $this->errors[] = 'Error '.$this->db->lasterror(); + if ($this->db->lasterrno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $this->errors[] = 'Error DB_ERROR_RECORD_ALREADY_EXISTS : '.$this->db->lasterror(); + } else { + $this->errors[] = 'Error '.$this->db->lasterror(); + } dol_syslog(__METHOD__.' '.implode(',', $this->errors), LOG_ERR); } From edaf740e783e1ebc06121cb0206e6804edcfd331 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Mar 2022 13:43:16 +0100 Subject: [PATCH 56/64] Update dolreceiptprinter.class.php --- htdocs/core/class/dolreceiptprinter.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index c308a13e865..37b8d580d1c 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -649,7 +649,7 @@ class dolReceiptPrinter extends Printer } else { $spacestoadd = $nbcharactbyline - strlen($line->description) - strlen($line->qty) - strlen($line->subprice) - 10 - 1; $spaces = str_repeat(' ', $spacestoadd > 0 ? $spacestoadd : 0); - $this->printer->text($line->description.$spaces.$line->qty.' '.str_pad(price($line->subprice), 10, ' ', STR_PAD_LEFT).' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n \n"); + $this->printer->text($line->description.$spaces.$line->qty.' '.str_pad(price($line->subprice), 10, ' ', STR_PAD_LEFT).' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n"); } } break; From e13038dc3058b2a4b00c8938cbf5eee18096a95c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Mar 2022 14:06:54 +0100 Subject: [PATCH 57/64] Update product.class.php --- htdocs/product/class/product.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index dc9a08a24c7..b08ccb139ba 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1803,8 +1803,9 @@ class Product extends CommonObject $sql .= " ,pfp.multicurrency_price, pfp.multicurrency_unitprice, pfp.multicurrency_tx, pfp.fk_multicurrency, pfp.multicurrency_code"; if (!empty($conf->global->PRODUCT_USE_SUPPLIER_PACKAGING)) $sql .= ", pfp.packaging"; $sql .= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; - $sql .= " WHERE 1=1"; - if ($product_id != 0) { $sql .= " AND pfp.fk_product = '".$product_id."'"; + $sql .= " WHERE 1 = 1"; + if ($product_id > 0) { + $sql .= " AND pfp.fk_product = ".((int) $product_id); } if ($fourn_ref != 'none') { $sql .= " AND pfp.ref_fourn = '".$fourn_ref."'"; } From acb47a4cc74eb8a04dac23cf4766ce6d2ddff7af Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Mar 2022 14:29:39 +0100 Subject: [PATCH 58/64] Update document.php --- htdocs/projet/document.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/document.php b/htdocs/projet/document.php index ef3d455fd82..2301017edd9 100644 --- a/htdocs/projet/document.php +++ b/htdocs/projet/document.php @@ -32,7 +32,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; // Load translation files required by the page $langs->loadLangs(array('projects', 'other')); -$hookmanager->initHooks(array('projetcarddocument')); +$hookmanager->initHooks(array('projectcarddocument')); $action = GETPOST('action', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); From 2ef42c178b96b7746e2d21c6b579a6c12b9568e0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Mar 2022 14:30:38 +0100 Subject: [PATCH 59/64] Update info.php --- htdocs/projet/info.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/projet/info.php b/htdocs/projet/info.php index 9712e32ffd2..a7382c94d1a 100644 --- a/htdocs/projet/info.php +++ b/htdocs/projet/info.php @@ -67,7 +67,7 @@ $id = GETPOST("id", 'int'); $socid = 0; //if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement. $result = restrictedArea($user, 'projet', $id, 'projet&project'); -$hookmanager->initHooks(array('projetcardinfo')); +$hookmanager->initHooks(array('projectcardinfo')); if (!$user->rights->projet->lire) { accessforbidden(); From feafbaded21f2f5575af4416d04a79a6d1464f37 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Mar 2022 14:31:19 +0100 Subject: [PATCH 60/64] Update info.php --- htdocs/projet/info.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/projet/info.php b/htdocs/projet/info.php index a7382c94d1a..9b0544bccf6 100644 --- a/htdocs/projet/info.php +++ b/htdocs/projet/info.php @@ -62,12 +62,13 @@ if (GETPOST('actioncode', 'array')) { } $search_agenda_label = GETPOST('search_agenda_label'); +$hookmanager->initHooks(array('projectcardinfo')); + // Security check $id = GETPOST("id", 'int'); $socid = 0; //if ($user->socid > 0) $socid = $user->socid; // For external user, no check is done on company because readability is managed by public status of project and assignement. $result = restrictedArea($user, 'projet', $id, 'projet&project'); -$hookmanager->initHooks(array('projectcardinfo')); if (!$user->rights->projet->lire) { accessforbidden(); From e085c3989acc74597e9844d30952b207b3a23990 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Mar 2022 14:59:55 +0100 Subject: [PATCH 61/64] Update product.php --- htdocs/product/admin/product.php | 9 --------- 1 file changed, 9 deletions(-) diff --git a/htdocs/product/admin/product.php b/htdocs/product/admin/product.php index 222e9ffc41f..7a2c2c6102e 100644 --- a/htdocs/product/admin/product.php +++ b/htdocs/product/admin/product.php @@ -159,15 +159,6 @@ if ($action == 'other') $value = GETPOST('activate_useProdSupplierPackaging', 'alpha'); $res = dolibarr_set_const($db, "PRODUCT_USE_SUPPLIER_PACKAGING", $value, 'chaine', 0, '', $conf->entity); - if ($value) { - $sql_test = "SELECT count(packaging) as cpt FROM ".MAIN_DB_PREFIX."product_fournisseur_price WHERE 1"; - $resql = $db->query($sql_test); - - if ($resql < 0) - { - dol_syslog($db->lasterrno(), LOG_ERR); - } - } } if ($action == 'specimen') // For products From 028fc4f0041c67cc76e3a3d8957d36e09f166fc7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Mar 2022 15:05:45 +0100 Subject: [PATCH 62/64] Fix field --- htdocs/install/mysql/migration/12.0.0-13.0.0.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql index cf4b5747684..f76136790c1 100644 --- a/htdocs/install/mysql/migration/12.0.0-13.0.0.sql +++ b/htdocs/install/mysql/migration/12.0.0-13.0.0.sql @@ -562,7 +562,8 @@ INSERT INTO llx_c_socialnetworks (entity, code, label, url, icon, active) VALUES -- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_customers_outstanding_bill_reached.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_customers_outstanding_bill_reached.php' AND entity = 1); -- VMYSQL4.1 INSERT INTO llx_boxes_def (file, entity) SELECT 'box_scheduled_jobs.php', 1 FROM DUAL WHERE NOT EXISTS (SELECT * FROM llx_boxes_def WHERE file = 'box_scheduled_jobs.php' AND entity = 1); -ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging varchar(64); +ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging varchar(64) DEFAULT NULL; +ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging varchar(64) DEFAULT NULL; ALTER TABLE llx_projet ADD COLUMN fk_opp_status_end integer DEFAULT NULL; From c4061e578deedc08e2205ad4a5354c4d41628305 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Mar 2022 15:06:24 +0100 Subject: [PATCH 63/64] Fix field --- htdocs/install/mysql/migration/13.0.0-14.0.0.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql index d03d6b1f75c..e8a3880ff40 100644 --- a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql +++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql @@ -84,6 +84,9 @@ UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'a UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'cameleo'; DELETE FROM llx_user_param where param = 'MAIN_THEME' and value in ('auguria', 'amarok', 'cameleo'); +ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging varchar(64) DEFAULT NULL; +ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging varchar(64) DEFAULT NULL; + -- For v14 From fa707c601517642dd37711be3ba4ccb8604c5641 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 7 Mar 2022 15:20:55 +0100 Subject: [PATCH 64/64] Fix error from v12 --- htdocs/install/mysql/migration/14.0.0-15.0.0.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql index df86c80e72e..5987c4be652 100644 --- a/htdocs/install/mysql/migration/14.0.0-15.0.0.sql +++ b/htdocs/install/mysql/migration/14.0.0-15.0.0.sql @@ -35,6 +35,9 @@ -- VMYSQL4.3 ALTER TABLE llx_partnership MODIFY COLUMN date_partnership_end date NULL; -- VPGSQL8.2 ALTER TABLE llx_partnership ALTER COLUMN date_partnership_end DROP NOT NULL; +ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging varchar(64) DEFAULT NULL; +ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging varchar(64) DEFAULT NULL; + ALTER TABLE llx_accounting_bookkeeping ADD COLUMN date_export datetime DEFAULT NULL; ALTER TABLE llx_eventorganization_conferenceorboothattendee ADD COLUMN fk_project integer NOT NULL;