From 43f4c5ac962d3a99b33f9cab2410c6d323a8a411 Mon Sep 17 00:00:00 2001 From: gauthier Date: Wed, 22 Apr 2020 15:29:54 +0200 Subject: [PATCH 01/70] FIX : model export list must be sorted by label --- htdocs/core/class/html.formother.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 9556fd6c423..cf3cd58355c 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -75,7 +75,7 @@ class FormOther $sql.= " FROM ".MAIN_DB_PREFIX."export_model"; $sql.= " WHERE type = '".$type."'"; if (!empty($fk_user)) $sql.=" AND fk_user IN (0, ".$fk_user.")"; // An export model - $sql.= " ORDER BY rowid"; + $sql.= " ORDER BY label"; $result = $this->db->query($sql); if ($result) { From 7bc8a70b0a593a39d0acb72e29b445e39ccd3812 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 22 Apr 2020 18:23:48 +0200 Subject: [PATCH 02/70] FIX #13670 --- 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 6e71125cbd5..37dbcbf5ded 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4548,7 +4548,7 @@ function price($amount, $form = 0, $outlangs = '', $trunc = 1, $rounding = -1, $ { if ($currency_code == 'auto') $currency_code = $conf->currency; - $listofcurrenciesbefore = array('USD', 'GBP', 'AUD', 'HKD', 'MXN', 'PEN', 'CNY', 'CAD'); + $listofcurrenciesbefore = array('AUD', 'CAD', 'CNY', 'COP', 'CLP', 'GBP', 'HKD', 'MXN', 'PEN', 'USD'); $listoflanguagesbefore = array('nl_NL'); if (in_array($currency_code, $listofcurrenciesbefore) || in_array($outlangs->defaultlang, $listoflanguagesbefore)) { From de90f24bd47ef33892f21a0c6fb86185f8bd7c0c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 22 Apr 2020 21:29:15 +0200 Subject: [PATCH 03/70] Fix phpcs --- htdocs/core/class/html.formother.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 3a709e295f7..daf8b3db617 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -262,7 +262,7 @@ class FormOther { // phpcs:enable global $langs; - + $out = ''; $sql = "SELECT r.taux, r.revenuestamp_type"; From 0999f5e6f26bc39e67b80b2ac9a0ce0cdcfa8d89 Mon Sep 17 00:00:00 2001 From: Juanjo Menent Date: Thu, 23 Apr 2020 12:12:50 +0200 Subject: [PATCH 04/70] FIX: Error update SQL into stock reception --- htdocs/product/stock/class/mouvementstock.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index e0266172463..2799cbaaf50 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -515,10 +515,11 @@ class MouvementStock extends CommonObject // Update PMP and denormalized value of stock qty at product level if (! $error) { + $newpmp = price2num($newpmp,'MU'); // $sql = "UPDATE ".MAIN_DB_PREFIX."product SET pmp = ".$newpmp.", stock = ".$this->db->ifsql("stock IS NULL", 0, "stock") . " + ".$qty; // $sql.= " WHERE rowid = ".$fk_product; // Update pmp + denormalized fields because we change content of produt_stock. Warning: Do not use "SET p.stock", does not works with pgsql - $sql = "UPDATE ".MAIN_DB_PREFIX."product as p SET pmp = ".$newpmp.", "; + $sql = "UPDATE ".MAIN_DB_PREFIX."product as p SET pmp = '".$newpmp."', "; $sql.= " stock=(SELECT SUM(ps.reel) FROM ".MAIN_DB_PREFIX."product_stock as ps WHERE ps.fk_product = p.rowid)"; $sql.= " WHERE rowid = ".$fk_product; From 93278b2dca15a5c3cf299d9648ef7ccbcfb51772 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Apr 2020 12:42:03 +0200 Subject: [PATCH 05/70] FIX #13713 --- htdocs/fourn/commande/info.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/info.php b/htdocs/fourn/commande/info.php index efabf409cdc..6764c00f003 100644 --- a/htdocs/fourn/commande/info.php +++ b/htdocs/fourn/commande/info.php @@ -40,6 +40,17 @@ $id=GETPOST('id', 'int'); $ref=GETPOST('ref', 'alpha'); $action = GETPOST('action', 'alpha'); +$limit = GETPOST('limit', 'int') ?GETPOST('limit', 'int') : $conf->liste_limit; +$sortfield = GETPOST("sortfield", 'alpha'); +$sortorder = GETPOST("sortorder", 'alpha'); +$page = GETPOST("page", 'int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; +if (!$sortfield) $sortfield = 'a.datep,a.id'; +if (!$sortorder) $sortorder = 'DESC,DESC'; + if (GETPOST('actioncode', 'array')) { $actioncode=GETPOST('actioncode', 'array', 3); @@ -217,7 +228,7 @@ if (!empty($object->id)) // List of all actions $filters = array(); $filters['search_agenda_label'] = $search_agenda_label; - show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters); + show_actions_done($conf, $langs, $db, $object, null, 0, $actioncode, '', $filters, $sortfield, $sortorder); } // End of page From e1129babbcbe1eab280d22d0fc5c5cb0a973e2e6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Apr 2020 12:44:30 +0200 Subject: [PATCH 06/70] Code comment --- htdocs/fourn/commande/info.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/info.php b/htdocs/fourn/commande/info.php index 6764c00f003..3da0211d3f1 100644 --- a/htdocs/fourn/commande/info.php +++ b/htdocs/fourn/commande/info.php @@ -223,7 +223,7 @@ if (!empty($object->id)) //show_actions_todo($conf,$langs,$db,$object,null,0,$actioncode); // List of done actions - //show_actions_done($conf,$langs,$db,$object,null,0,$actioncode); + //show_actions_done($conf,$langs,$db,$object,null,0,$actioncode, '', $filters, $sortfield, $sortorder); // List of all actions $filters = array(); From 3a9add0e7078508ffd79369a659449bfa918edb2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Apr 2020 13:37:43 +0200 Subject: [PATCH 07/70] FIX #13663 --- htdocs/compta/facture/class/facture.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index c2c82424b77..f9285eb2d9c 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1434,9 +1434,10 @@ class Facture extends CommonInvoice $txttoshow = ($user->socid > 0 ? $this->note_public : $this->note_private); if ($txttoshow) { - $notetoshow = $langs->trans("ViewPrivateNote").':
'.dol_string_nohtmltag($txttoshow, 1); + //$notetoshow = $langs->trans("ViewPrivateNote").':
'.dol_string_nohtmltag($txttoshow, 1); + $notetoshow = $langs->trans("ViewPrivateNote").':
'.$txttoshow; $result .= ' '; - $result .= ''; + $result .= ''; $result .= img_picto('', 'note'); $result .= ''; //$result.=img_picto($langs->trans("ViewNote"),'object_generic'); From 436362502c3be8740d03ffe561e8a2954fdcd818 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Apr 2020 13:41:51 +0200 Subject: [PATCH 08/70] CSS --- htdocs/loan/card.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 9e7b8f2565a..3e96a33c931 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -475,7 +475,7 @@ if ($id > 0) print '
'; print '
'; - print ''; + print '
'; // Capital if ($action == 'edit') From 7972174787ef17a98f86403ce1b517ad4ac638ba Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Thu, 23 Apr 2020 13:44:23 +0200 Subject: [PATCH 09/70] remove debug pring --- .../modules/project/task/doc/doc_generic_task_odt.modules.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php index 386de7bfdd7..cae24a1ce7e 100644 --- a/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php +++ b/htdocs/core/modules/project/task/doc/doc_generic_task_odt.modules.php @@ -474,7 +474,6 @@ class doc_generic_task_odt extends ModelePDFTask if (!file_exists($dir)) { - print '$dir'.$dir; if (dol_mkdir($dir) < 0) { $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir); From 6819255b764a2a004ee10770dde354893c9b9f37 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Apr 2020 13:49:18 +0200 Subject: [PATCH 10/70] FIX #13650 --- htdocs/core/modules/modFournisseur.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php index 4b7c8ff3ed2..b8539ad41c1 100644 --- a/htdocs/core/modules/modFournisseur.class.php +++ b/htdocs/core/modules/modFournisseur.class.php @@ -346,7 +346,10 @@ class modFournisseur extends DolibarrModules case 'sellist': $tmp=''; $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null - if ($tmpparam['options'] && is_array($tmpparam['options'])) $tmp=array_shift(array_keys($tmpparam['options'])); + if ($tmpparam['options'] && is_array($tmpparam['options'])) { + $var=array_keys($tmpparam['options']); + $tmp=array_shift($var); + } if (preg_match('/[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/', $tmp)) $typeFilter="List:".$tmp; break; } From b68e85703ff2530021e870675794ed33c11c30c4 Mon Sep 17 00:00:00 2001 From: simicar29 Date: Thu, 23 Apr 2020 16:29:22 +0200 Subject: [PATCH 11/70] Clean line extrafields when deleting invoice Delete extrafields invoice lines when deleting parent object (sql syntax ok for mariadb & pgsql) Delete extrafields when deleting an invoice line --- htdocs/compta/facture/class/facture.class.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index f9285eb2d9c..66cb1aed37d 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2166,13 +2166,16 @@ class Facture extends CommonInvoice } } - + // Invoice line extrafileds + $main = MAIN_DB_PREFIX . 'facturedet'; + $ef = $main . "_extrafields"; + $sqlef = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_facture = $rowid)"; // Delete invoice line $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facturedet WHERE fk_facture = '.$rowid; dol_syslog(get_class($this)."::delete", LOG_DEBUG); - if ($this->db->query($sql) && $this->delete_linked_contact()) + if ($this->db->query($sqlef) && $this->db->query($sql) && $this->delete_linked_contact()) { $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture WHERE rowid = '.$rowid; @@ -5312,7 +5315,14 @@ class FactureLigne extends CommonInvoiceLine } // End call triggers - + // extrafields + $result = $this->deleteExtraFields(); + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + $sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet WHERE rowid = ".$this->rowid; dol_syslog(get_class($this)."::delete", LOG_DEBUG); if ($this->db->query($sql)) From aebc04d30a15eb8e2a46bdd44a1875aacc1db3d7 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 23 Apr 2020 14:33:11 +0000 Subject: [PATCH 12/70] Fixing style errors. --- htdocs/compta/facture/class/facture.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 66cb1aed37d..9b327aadb45 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -5322,7 +5322,7 @@ class FactureLigne extends CommonInvoiceLine $this->db->rollback(); return -1; } - + $sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet WHERE rowid = ".$this->rowid; dol_syslog(get_class($this)."::delete", LOG_DEBUG); if ($this->db->query($sql)) From ce94788dd906cce4f925fc260180359175c88d5a Mon Sep 17 00:00:00 2001 From: simicar29 Date: Thu, 23 Apr 2020 17:01:40 +0200 Subject: [PATCH 13/70] Clean line extrafields when deleting recurring invoice Delete extrafields recurring invoice lines when deleting parent object Delete extrafields when deleting a recurring invoice line --- .../compta/facture/class/facture-rec.class.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index 110f5a9cbb8..f3437308f39 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -664,9 +664,13 @@ class FactureRec extends CommonInvoice $error = 0; $this->db->begin(); + $main = MAIN_DB_PREFIX . 'facturedet_rec'; + $ef = $main . "_extrafields"; + $sqlef = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_facture = $rowid)"; + dol_syslog($sqlef); $sql = "DELETE FROM ".MAIN_DB_PREFIX."facturedet_rec WHERE fk_facture = ".$rowid; dol_syslog($sql); - if ($this->db->query($sql)) + if ($this->db->query($sqlef) && $this->db->query($sql)) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."facture_rec WHERE rowid = ".$rowid; dol_syslog($sql); @@ -675,6 +679,9 @@ class FactureRec extends CommonInvoice // Delete linked object $res = $this->deleteObjectLinked(); if ($res < 0) $error = -3; + // Delete extrafields + $res = $this->deleteExtraFields(); + if ($res < 0) $error = -4; } else { @@ -1881,6 +1888,14 @@ class FactureLigneRec extends CommonInvoiceLine // End call triggers } } + + if (!$error) + { + $result = $this->deleteExtraFields(); + if ($result < 0) { + $error++; + } + } if (!$error) { From 2633e908902d3e20e2cfe35f28447f9842c98582 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 23 Apr 2020 15:03:14 +0000 Subject: [PATCH 14/70] Fixing style errors. --- htdocs/compta/facture/class/facture-rec.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index f3437308f39..5b72b6d465d 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -1888,7 +1888,7 @@ class FactureLigneRec extends CommonInvoiceLine // End call triggers } } - + if (!$error) { $result = $this->deleteExtraFields(); From cd1368cb71202231393aeb207ddd9fcd3cdfdf72 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Apr 2020 17:10:40 +0200 Subject: [PATCH 15/70] Fix dispatch in ledger for various payment done in same account when there is 2 different transaction in 2 different account (backport v12) --- htdocs/accountancy/journal/bankjournal.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index e9be75990dc..06f5a56f943 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -666,7 +666,7 @@ if (! $error && $action == 'writebookkeeping') { } elseif ($tabtype[$key] == 'payment_various') { $bookkeeping->subledger_account = $k; $bookkeeping->subledger_label = $tabcompany[$key]['name']; - $bookkeeping->numero_compte = $tabpay[$obj->rowid]["account_various"]; + $bookkeeping->numero_compte = $tabpay[$key]["account_various"]; $accountingaccount->fetch(null, $bookkeeping->numero_compte, true); $bookkeeping->label_compte = $accountingaccount->label; @@ -1174,7 +1174,11 @@ if (empty($action) || $action == 'view') { //print ''.$langs->trans("ThirdpartyAccountNotDefined").''; if (! empty($tabcompany[$key]['code_compta'])) { - print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknown", $tabcompany[$key]['code_compta']).''; + if (in_array($tabtype[$key], array('payment_various'))) { + // For such case, if subledger is not defined, we won't use subledger accounts. + print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownSubledgerIgnored").''; + } else { + print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknown", $tabcompany[$key]['code_compta']).''; } else { From be46b2062ee29fe57181170b21a5241080f895ab Mon Sep 17 00:00:00 2001 From: Marc Guenneugues Date: Thu, 23 Apr 2020 17:51:06 +0200 Subject: [PATCH 16/70] Clean line extrafields when deleting order --- htdocs/commande/class/commande.class.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 52dfde785a4..54506a4a816 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3396,6 +3396,19 @@ class Commande extends CommonOrder $error++; } + if (!$error) + { + // Delete extrafields of order details + $main = MAIN_DB_PREFIX . 'commandedet'; + $ef = $main . "_extrafields"; + $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_commande = " . $this->id . ")"; + if (!$this->db->query($sql)) + { + $error++; + $this->errors[] = $this->db->lasterror(); + } + } + if (!$error) { // Delete order details From f7d4d78008b132574dc81f6e358bd498b4863f7b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Apr 2020 17:55:55 +0200 Subject: [PATCH 17/70] Fix error 500 --- htdocs/accountancy/journal/bankjournal.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index 06f5a56f943..d2ad7a0503e 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -1179,6 +1179,7 @@ if (empty($action) || $action == 'view') { print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknownSubledgerIgnored").''; } else { print ''.$langs->trans("ThirdpartyAccountNotDefinedOrThirdPartyUnknown", $tabcompany[$key]['code_compta']).''; + } } else { From 1101c4e587232905e2caa9c61545c47a8503e888 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Apr 2020 18:01:04 +0200 Subject: [PATCH 18/70] Fix trans --- htdocs/langs/en_US/accountancy.lang | 1 + htdocs/langs/fr_FR/accountancy.lang | 1 + 2 files changed, 2 insertions(+) diff --git a/htdocs/langs/en_US/accountancy.lang b/htdocs/langs/en_US/accountancy.lang index 4b22f512826..9b80eae930c 100644 --- a/htdocs/langs/en_US/accountancy.lang +++ b/htdocs/langs/en_US/accountancy.lang @@ -218,6 +218,7 @@ ListAccounts=List of the accounting accounts UnknownAccountForThirdparty=Unknown third-party account. We will use %s UnknownAccountForThirdpartyBlocking=Unknown third-party account. Blocking error ThirdpartyAccountNotDefinedOrThirdPartyUnknown=Third-party account not defined or third party unknown. We will use %s +ThirdpartyAccountNotDefinedOrThirdPartyUnknownSubledgerIgnored=Third-party unknown and subledger not defined on the payment. We will keep the subledger account value empty. ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking=Third-party account not defined or third party unknown. Blocking error. UnknownAccountForThirdpartyAndWaitingAccountNotDefinedBlocking=Unknown third-party account and waiting account not defined. Blocking error PaymentsNotLinkedToProduct=Payment not linked to any product / service diff --git a/htdocs/langs/fr_FR/accountancy.lang b/htdocs/langs/fr_FR/accountancy.lang index 0150ff7d017..7c0602332f3 100644 --- a/htdocs/langs/fr_FR/accountancy.lang +++ b/htdocs/langs/fr_FR/accountancy.lang @@ -218,6 +218,7 @@ ListAccounts=Liste des comptes comptables UnknownAccountForThirdparty=Compte de tiers inconnu. %s sera utilisé UnknownAccountForThirdpartyBlocking=Compte de tiers inconnu. Erreur bloquante. ThirdpartyAccountNotDefinedOrThirdPartyUnknown=Code comptable du tiers non défini ou tiers inconnu. On utilisera %s. +ThirdpartyAccountNotDefinedOrThirdPartyUnknownSubledgerIgnored=Tiers inconnu et code comptable auxiliaire non défini sur le paiement. Nous conserverons la valeur du compte auxiliaire vide. ThirdpartyAccountNotDefinedOrThirdPartyUnknownBlocking=Compte tiers non défini ou inconnu. Erreur bloquante. UnknownAccountForThirdpartyAndWaitingAccountNotDefinedBlocking=Compte tiers inconnu et compte d'attente non défini. Erreur blocante. PaymentsNotLinkedToProduct=Paiement non lié à un produit / service From 94be1870ec2faeffcdf9b9b10cd4ac88e89d916f Mon Sep 17 00:00:00 2001 From: Marc Guenneugues Date: Thu, 23 Apr 2020 18:02:53 +0200 Subject: [PATCH 19/70] Clean line extrafields when deleting proposal --- htdocs/comm/propal/class/propal.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 409a1924b70..0962fcd63b6 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -2992,8 +2992,11 @@ class Propal extends CommonObject if (!$error) { + $main = MAIN_DB_PREFIX . 'propaldet'; + $ef = $main . "_extrafields"; + $sqlef = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_propal = " . $this->id . ")"; $sql = "DELETE FROM ".MAIN_DB_PREFIX."propaldet WHERE fk_propal = ".$this->id; - if ($this->db->query($sql)) + if ($this->db->query($sqlef) && $this->db->query($sql)) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."propal WHERE rowid = ".$this->id; if ($this->db->query($sql)) From 039fe922090d4f1812159999927c585c5341269d Mon Sep 17 00:00:00 2001 From: Marc Guenneugues Date: Thu, 23 Apr 2020 18:14:56 +0200 Subject: [PATCH 20/70] Clean line extrafields when deleting supplier invoice --- htdocs/fourn/class/fournisseur.facture.class.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 48ca9ca81f2..8cec13609a0 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1180,10 +1180,14 @@ class FactureFournisseur extends CommonInvoice if (!$error) { + $main = MAIN_DB_PREFIX . 'facture_fourn_det'; + $ef = $main . "_extrafields"; + $sqlef = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_facture_fourn = $rowid)"; + $resqlef = $this->db->query($sqlef); $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det WHERE fk_facture_fourn = '.$rowid.';'; dol_syslog(get_class($this)."::delete", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) + if ($resqlef && $resql) { $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn WHERE rowid = '.$rowid; dol_syslog(get_class($this)."::delete", LOG_DEBUG); @@ -3141,6 +3145,11 @@ class SupplierInvoiceLine extends CommonObjectLine $this->deleteObjectLinked(); + $result = $this->deleteExtraFields(); + if ($result < 0) { + $error++; + } + if (!$error) { // Supprime ligne $sql = 'DELETE FROM '.MAIN_DB_PREFIX.'facture_fourn_det '; From b5f48fb815a80e8343b87bf989b882b412ebe22c Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 23 Apr 2020 16:17:37 +0000 Subject: [PATCH 21/70] Fixing style errors. --- htdocs/fourn/class/fournisseur.facture.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 8cec13609a0..117a99ee2cc 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -3146,9 +3146,9 @@ class SupplierInvoiceLine extends CommonObjectLine $this->deleteObjectLinked(); $result = $this->deleteExtraFields(); - if ($result < 0) { - $error++; - } + if ($result < 0) { + $error++; + } if (!$error) { // Supprime ligne From 64d877bc7bc8968d3443bb03dcd3f196650ba6d3 Mon Sep 17 00:00:00 2001 From: Marc Guenneugues Date: Thu, 23 Apr 2020 18:27:06 +0200 Subject: [PATCH 22/70] Clean line extrafields when deleting supplier order --- .../class/fournisseur.commande.class.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 0ed924ffb64..76b3cdabc6a 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1994,6 +1994,17 @@ class CommandeFournisseur extends CommonOrder // End call triggers } + $main = MAIN_DB_PREFIX . 'commande_fournisseurdet'; + $ef = $main . "_extrafields"; + $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_commande = " . $this->id . ")"; + dol_syslog(get_class($this)."::delete extrafields lines", LOG_DEBUG); + if (!$this->db->query($sql)) + { + $this->error = $this->db->lasterror(); + $this->errors[] = $this->db->lasterror(); + $error++; + } + $sql = "DELETE FROM ".MAIN_DB_PREFIX."commande_fournisseurdet WHERE fk_commande =".$this->id; dol_syslog(get_class($this)."::delete", LOG_DEBUG); if (!$this->db->query($sql)) @@ -3700,6 +3711,14 @@ class CommandeFournisseurLigne extends CommonOrderLine $this->db->begin(); + // extrafields + $result = $this->deleteExtraFields(); + if ($result < 0) + { + $this->db->rollback(); + return -1; + } + $sql = 'DELETE FROM '.MAIN_DB_PREFIX."commande_fournisseurdet WHERE rowid=".$this->id; dol_syslog(__METHOD__, LOG_DEBUG); From 4b58213e5b9ee14609c63f5c0ea27eccd3134d42 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 23 Apr 2020 16:29:36 +0000 Subject: [PATCH 23/70] Fixing style errors. --- htdocs/fourn/class/fournisseur.commande.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 76b3cdabc6a..7de6f6a770e 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -3711,7 +3711,7 @@ class CommandeFournisseurLigne extends CommonOrderLine $this->db->begin(); - // extrafields + // extrafields $result = $this->deleteExtraFields(); if ($result < 0) { From 02c5530e1f94ac7292b763c571e949011d4620f0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 23 Apr 2020 18:31:01 +0200 Subject: [PATCH 24/70] Update mouvementstock.class.php --- htdocs/product/stock/class/mouvementstock.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index 2799cbaaf50..1702c4beecc 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -515,11 +515,12 @@ class MouvementStock extends CommonObject // Update PMP and denormalized value of stock qty at product level if (! $error) { - $newpmp = price2num($newpmp,'MU'); + $newpmp = price2num($newpmp, 'MU'); + // $sql = "UPDATE ".MAIN_DB_PREFIX."product SET pmp = ".$newpmp.", stock = ".$this->db->ifsql("stock IS NULL", 0, "stock") . " + ".$qty; // $sql.= " WHERE rowid = ".$fk_product; // Update pmp + denormalized fields because we change content of produt_stock. Warning: Do not use "SET p.stock", does not works with pgsql - $sql = "UPDATE ".MAIN_DB_PREFIX."product as p SET pmp = '".$newpmp."', "; + $sql = "UPDATE ".MAIN_DB_PREFIX."product as p SET pmp = ".$newpmp.", "; $sql.= " stock=(SELECT SUM(ps.reel) FROM ".MAIN_DB_PREFIX."product_stock as ps WHERE ps.fk_product = p.rowid)"; $sql.= " WHERE rowid = ".$fk_product; From ab5c2b1fd56ba640e0d6ab483f52d2a5b225371c Mon Sep 17 00:00:00 2001 From: Marc Guenneugues Date: Thu, 23 Apr 2020 18:33:58 +0200 Subject: [PATCH 25/70] Clean line extrafields when deleting supplier proposal --- htdocs/supplier_proposal/class/supplier_proposal.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/htdocs/supplier_proposal/class/supplier_proposal.class.php b/htdocs/supplier_proposal/class/supplier_proposal.class.php index 7fdd5466cd5..d292ebe13bf 100644 --- a/htdocs/supplier_proposal/class/supplier_proposal.class.php +++ b/htdocs/supplier_proposal/class/supplier_proposal.class.php @@ -2061,11 +2061,14 @@ class SupplierProposal extends CommonObject if (! $error) { + $main = MAIN_DB_PREFIX . 'supplier_proposaldet'; + $ef = $main . "_extrafields"; + $sqlef = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_supplier_proposal = " . $this->id . ")"; $sql = "DELETE FROM ".MAIN_DB_PREFIX."supplier_proposaldet WHERE fk_supplier_proposal = ".$this->id; if ($this->db->query($sql)) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."supplier_proposal WHERE rowid = ".$this->id; - if ($this->db->query($sql)) + if ($this->db->query($sqlef) && $this->db->query($sql)) { // Delete linked object $res = $this->deleteObjectLinked(); From 285f215acfd51ac595a3c44a38a695729d33e95f Mon Sep 17 00:00:00 2001 From: Marc Guenneugues Date: Thu, 23 Apr 2020 18:52:45 +0200 Subject: [PATCH 26/70] Clean line extrafields when deleting fichinter --- htdocs/fichinter/class/fichinter.class.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 9f180fc24b0..1a4a6817892 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -961,6 +961,16 @@ class Fichinter extends CommonObject } } + if (!$error) + { + $main = MAIN_DB_PREFIX . 'fichinterdet'; + $ef = $main . "_extrafields"; + $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_fichinter = " . $this->id . ")"; + + $resql = $this->db->query($sql); + if (!$resql) $error++; + } + if (!$error) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet"; @@ -1704,6 +1714,13 @@ class FichinterLigne extends CommonObjectLine dol_syslog(get_class($this)."::deleteline lineid=".$this->id); $this->db->begin(); + $result = $this->deleteExtraFields(); + if ($result < 0) { + $error++; + $this->db->rollback(); + return -1; + } + $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet WHERE rowid = ".$this->id; $resql = $this->db->query($sql); From 93735bf9cd5c96388736074b53b8e07e375c77e4 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 23 Apr 2020 16:55:36 +0000 Subject: [PATCH 27/70] Fixing style errors. --- htdocs/fichinter/class/fichinter.class.php | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 1a4a6817892..025a2e13a88 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -961,15 +961,15 @@ class Fichinter extends CommonObject } } - if (!$error) + if (!$error) { - $main = MAIN_DB_PREFIX . 'fichinterdet'; - $ef = $main . "_extrafields"; - $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_fichinter = " . $this->id . ")"; + $main = MAIN_DB_PREFIX . 'fichinterdet'; + $ef = $main . "_extrafields"; + $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_fichinter = " . $this->id . ")"; - $resql = $this->db->query($sql); - if (!$resql) $error++; - } + $resql = $this->db->query($sql); + if (!$resql) $error++; + } if (!$error) { @@ -1715,11 +1715,11 @@ class FichinterLigne extends CommonObjectLine $this->db->begin(); $result = $this->deleteExtraFields(); - if ($result < 0) { - $error++; - $this->db->rollback(); - return -1; - } + if ($result < 0) { + $error++; + $this->db->rollback(); + return -1; + } $sql = "DELETE FROM ".MAIN_DB_PREFIX."fichinterdet WHERE rowid = ".$this->id; $resql = $this->db->query($sql); From a70be95760a3389161cbd2d49b6c82a13c05b1a0 Mon Sep 17 00:00:00 2001 From: Marc Guenneugues Date: Thu, 23 Apr 2020 19:00:47 +0200 Subject: [PATCH 28/70] Clean line extrafields when deleting contrat --- htdocs/contrat/class/contrat.class.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index e40eba40ee2..b265ab59cde 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -1234,6 +1234,22 @@ class Contrat extends CommonObject } } + if (!$error) + { + // Delete contratdet extrafields + $main = MAIN_DB_PREFIX . 'contratdet'; + $ef = $main . "_extrafields"; + $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_contrat = " . $this->id . ")"; + + dol_syslog(get_class($this)."::delete contratdet_extrafields", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) + { + $this->error = $this->db->error(); + $error++; + } + } + if (!$error) { // Delete contratdet From b8a4c0d83b945214548aa578dfdbd1396624d868 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 23 Apr 2020 17:02:57 +0000 Subject: [PATCH 29/70] Fixing style errors. --- htdocs/contrat/class/contrat.class.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index b265ab59cde..9d90520e1d7 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -1234,21 +1234,21 @@ class Contrat extends CommonObject } } - if (!$error) + if (!$error) { - // Delete contratdet extrafields - $main = MAIN_DB_PREFIX . 'contratdet'; - $ef = $main . "_extrafields"; - $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_contrat = " . $this->id . ")"; + // Delete contratdet extrafields + $main = MAIN_DB_PREFIX . 'contratdet'; + $ef = $main . "_extrafields"; + $sql = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_contrat = " . $this->id . ")"; - dol_syslog(get_class($this)."::delete contratdet_extrafields", LOG_DEBUG); - $resql = $this->db->query($sql); - if (!$resql) - { - $this->error = $this->db->error(); - $error++; - } - } + dol_syslog(get_class($this)."::delete contratdet_extrafields", LOG_DEBUG); + $resql = $this->db->query($sql); + if (!$resql) + { + $this->error = $this->db->error(); + $error++; + } + } if (!$error) { From 3ea8d1895bef4256e8053bc41d5d8118ef44c3e2 Mon Sep 17 00:00:00 2001 From: Marc Guenneugues Date: Thu, 23 Apr 2020 19:09:05 +0200 Subject: [PATCH 30/70] Clean line extrafields when deleting expedition --- htdocs/expedition/class/expedition.class.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index bf20ac42611..006db734a0a 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -1280,15 +1280,23 @@ class Expedition extends CommonObject if (!$error) { + $main = MAIN_DB_PREFIX . 'expeditiondet'; + $ef = $main . "_extrafields"; + $sqlef = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_expedition = " . $this->id . ")"; + $sql = "DELETE FROM ".MAIN_DB_PREFIX."expeditiondet"; $sql .= " WHERE fk_expedition = ".$this->id; - if ($this->db->query($sql)) + if ($this->db->query($sqlef) && $this->db->query($sql)) { // Delete linked object $res = $this->deleteObjectLinked(); if ($res < 0) $error++; + // delete extrafields + $res = $this->deleteExtraFields(); + if ($res < 0) $error++; + if (!$error) { $sql = "DELETE FROM ".MAIN_DB_PREFIX."expedition"; From b4fbb8654824da0c3c50c22233f43b269c22c313 Mon Sep 17 00:00:00 2001 From: Marc Guenneugues Date: Thu, 23 Apr 2020 19:22:25 +0200 Subject: [PATCH 31/70] Clean line extrafields when deleting reception --- .../class/fournisseur.commande.dispatch.class.php | 12 ++++++++++++ htdocs/reception/class/reception.class.php | 13 +++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php index b453653c681..bd71918d92d 100644 --- a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php +++ b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php @@ -303,6 +303,7 @@ class CommandeFournisseurDispatch extends CommonObject $this->batch = $obj->batch; $this->eatby = $this->db->jdate($obj->eatby); $this->sellby = $this->db->jdate($obj->sellby); + $this->fetch_optionals(); } $this->db->free($resql); @@ -439,6 +440,16 @@ class CommandeFournisseurDispatch extends CommonObject } } + // Remove extrafields + if (!$error) { + $result = $this->deleteExtraFields(); + if ($result < 0) + { + $error++; + dol_syslog(get_class($this)."::delete error deleteExtraFields ".$this->error, LOG_ERR); + } + } + if (! $error) { $sql = "DELETE FROM ".MAIN_DB_PREFIX.$this->table_element; @@ -689,6 +700,7 @@ class CommandeFournisseurDispatch extends CommonObject $line->batch = $obj->batch; $line->eatby = $this->db->jdate($obj->eatby); $line->sellby = $this->db->jdate($obj->sellby); + $line->fetch_optionals(); $this->lines[$line->id] = $line; } diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 5552d45380e..17e9ea9c1ec 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -763,8 +763,13 @@ class Reception extends CommonObject } // extrafields + $line->array_options = $supplierorderline->array_options; if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($array_options) && count($array_options) > 0) // For avoid conflicts if trigger used - $line->array_options = $array_options; + { + foreach ($array_options as $key => $value) { + $line->array_options[$key] = $value; + } + } $line->fk_product = $fk_product; $line->fk_commande = $supplierorderline->fk_commande; @@ -938,10 +943,14 @@ class Reception extends CommonObject if (!$error) { + $main = MAIN_DB_PREFIX . 'commande_fournisseur_dispatch'; + $ef = $main . "_extrafields"; + $sqlef = "DELETE FROM $ef WHERE fk_object IN (SELECT rowid FROM $main WHERE fk_reception = " . $this->id . ")"; + $sql = "DELETE FROM ".MAIN_DB_PREFIX."commande_fournisseur_dispatch"; $sql .= " WHERE fk_reception = ".$this->id; - if ($this->db->query($sql)) + if ($this->db->query($sqlef) && $this->db->query($sql)) { // Delete linked object $res = $this->deleteObjectLinked(); From ababad540a311339e1b5266b586097cdad9b22c1 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 23 Apr 2020 17:29:52 +0000 Subject: [PATCH 32/70] Fixing style errors. --- .../fournisseur.commande.dispatch.class.php | 16 ++++++++-------- htdocs/reception/class/reception.class.php | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php index bd71918d92d..cec23c590b2 100644 --- a/htdocs/fourn/class/fournisseur.commande.dispatch.class.php +++ b/htdocs/fourn/class/fournisseur.commande.dispatch.class.php @@ -441,14 +441,14 @@ class CommandeFournisseurDispatch extends CommonObject } // Remove extrafields - if (!$error) { - $result = $this->deleteExtraFields(); - if ($result < 0) - { - $error++; - dol_syslog(get_class($this)."::delete error deleteExtraFields ".$this->error, LOG_ERR); - } - } + if (!$error) { + $result = $this->deleteExtraFields(); + if ($result < 0) + { + $error++; + dol_syslog(get_class($this)."::delete error deleteExtraFields ".$this->error, LOG_ERR); + } + } if (! $error) { diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 17e9ea9c1ec..ce718fda964 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -766,10 +766,10 @@ class Reception extends CommonObject $line->array_options = $supplierorderline->array_options; if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($array_options) && count($array_options) > 0) // For avoid conflicts if trigger used { - foreach ($array_options as $key => $value) { - $line->array_options[$key] = $value; - } - } + foreach ($array_options as $key => $value) { + $line->array_options[$key] = $value; + } + } $line->fk_product = $fk_product; $line->fk_commande = $supplierorderline->fk_commande; From 1aafd4667b70148265d79ef44731e659c9b1cc3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 24 Apr 2020 11:57:23 +0200 Subject: [PATCH 33/70] fix countable php7 warning --- htdocs/core/lib/sendings.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/lib/sendings.lib.php b/htdocs/core/lib/sendings.lib.php index 6dc78611c26..96a51815b09 100644 --- a/htdocs/core/lib/sendings.lib.php +++ b/htdocs/core/lib/sendings.lib.php @@ -388,7 +388,7 @@ function show_list_sending_receive($origin,$origin_id,$filter='') //var_dump($expedition->linkedObjects); $receiving=''; - if (count($expedition->linkedObjects['delivery']) > 0) $receiving=reset($expedition->linkedObjects['delivery']); // Take first link + if (!empty($expedition->linkedObjects['delivery'])) $receiving=reset($expedition->linkedObjects['delivery']); // Take first link if (! empty($receiving)) { From 42ee9845ad33dfa9a7a623102357c4e13e3ee0cc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 24 Apr 2020 15:21:02 +0200 Subject: [PATCH 34/70] Report error --- htdocs/compta/facture/class/facture.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 05661fb01cc..1558b6cbfab 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -5013,8 +5013,7 @@ class FactureLigne extends CommonInvoiceLine $returnPercent = floatval($res['situation_percent']); - if($include_credit_note) { - + if ($include_credit_note) { $sql = 'SELECT fd.situation_percent FROM ' . MAIN_DB_PREFIX . 'facturedet fd'; $sql.= ' JOIN ' . MAIN_DB_PREFIX . 'facture f ON (f.rowid = fd.fk_facture) '; $sql.= ' WHERE fd.fk_prev_id =' . $this->fk_prev_id; @@ -5026,6 +5025,8 @@ class FactureLigne extends CommonInvoiceLine while($obj = $this->db->fetch_object($res)) { $returnPercent = $returnPercent + floatval($obj->situation_percent); } + } else { + dol_print_error($this->db); } } From e98671e40489da84d3b9f3728e54dd41f5f6713f Mon Sep 17 00:00:00 2001 From: gauthier Date: Fri, 24 Apr 2020 15:22:38 +0200 Subject: [PATCH 35/70] FIX : Access to undeclared static property: Contact::$table_element --- htdocs/core/tpl/advtarget.tpl.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/tpl/advtarget.tpl.php b/htdocs/core/tpl/advtarget.tpl.php index 07b7744e2f8..a40f1214af1 100644 --- a/htdocs/core/tpl/advtarget.tpl.php +++ b/htdocs/core/tpl/advtarget.tpl.php @@ -459,7 +459,8 @@ if (!empty($conf->categorie->enabled) && $user->rights->categorie->lire) { // Standard Extrafield feature if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) { - $elementype = Contact::$table_element; + $contactstatic = new Contact($db); + $elementype = $contactstatic->table_element; // fetch optionals attributes and labels dol_include_once('/core/class/extrafields.class.php'); $extrafields = new ExtraFields($db); From df917805525cbd22453c9b05c68d4b2785f2290a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 24 Apr 2020 15:57:08 +0200 Subject: [PATCH 36/70] FIX Situation invoice take into account the credit notes. --- htdocs/compta/facture/card.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index d83e13da433..934916fa31e 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -1590,6 +1590,8 @@ if (empty($reshook)) if (!empty($origin) && !empty($originid)) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; + $object->origin = $origin; $object->origin_id = $originid; @@ -1601,6 +1603,17 @@ if (empty($reshook)) $line->fetch_optionals($line->id); $line->situation_percent = $line->get_prev_progress($object->id); // get good progress including credit note + // The $line->situation_percent has been modified, so we must recalculate all amounts + $tabprice = calcul_price_total($line->qty, $line->subprice, $line->remise_percent, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 0, 'HT', 0, $line->product_type, $mysoc, '', $line->situation_percent); + $line->total_ht = $tabprice[0]; + $line->total_tva = $tabprice[1]; + $line->total_ttc = $tabprice[2]; + $line->total_localtax1 = $tabprice[9]; + $line->total_localtax2 = $tabprice[10]; + $line->multicurrency_total_ht = $tabprice[16]; + $line->multicurrency_total_tva = $tabprice[17]; + $line->multicurrency_total_ttc = $tabprice[18]; + // Si fk_remise_except defini on vérifie si la réduction à déjà été appliquée if ($line->fk_remise_except) { @@ -1644,6 +1657,7 @@ if (empty($reshook)) { $nextSituationInvoice = new Facture($db); $nextSituationInvoice->fetch($id); + // create extrafields with data from create form $extralabels = $extrafields->fetch_name_optionals_label($nextSituationInvoice->table_element); $ret = $extrafields->setOptionalsFromPost($extralabels, $nextSituationInvoice); From a685026756fc1046bfb5426947006de9cb4fff5f Mon Sep 17 00:00:00 2001 From: florian HENRY Date: Fri, 24 Apr 2020 17:22:35 +0200 Subject: [PATCH 37/70] fix: remove php warning --- htdocs/compta/accounting-files.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index b8e10e7d0e3..665ab6ce485 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -23,7 +23,7 @@ * \brief Page to show portoflio and files of a thirdparty and download it */ -if ($_GET['action'] == 'dl' || $_POST['action'] == 'dl') { // To not replace token when downloading file +if (array_key_exists('action', $_GET) && $_GET['action'] == 'dl' || array_key_exists('action', $_POST) && $_POST['action'] == 'dl') { // To not replace token when downloading file if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); } From 4564a5cffd7e6c2f1f8ab81db902f8036622d693 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 24 Apr 2020 19:01:08 +0200 Subject: [PATCH 38/70] Update accounting-files.php --- htdocs/compta/accounting-files.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/accounting-files.php b/htdocs/compta/accounting-files.php index 665ab6ce485..83f735c1eeb 100644 --- a/htdocs/compta/accounting-files.php +++ b/htdocs/compta/accounting-files.php @@ -23,7 +23,7 @@ * \brief Page to show portoflio and files of a thirdparty and download it */ -if (array_key_exists('action', $_GET) && $_GET['action'] == 'dl' || array_key_exists('action', $_POST) && $_POST['action'] == 'dl') { // To not replace token when downloading file +if ((array_key_exists('action', $_GET) && $_GET['action'] == 'dl') || (array_key_exists('action', $_POST) && $_POST['action'] == 'dl')) { // To not replace token when downloading file if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); } From df10b86d1fbe6a613160ea8922d617cde6d62faf Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 24 Apr 2020 19:52:34 +0200 Subject: [PATCH 39/70] FIX consistency of price w/wo vat wrong when price entered with tax --- htdocs/core/class/commonobject.class.php | 25 ++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index d4735e4ba8d..157fc718700 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -2807,8 +2807,8 @@ abstract class CommonObject $sql = 'SELECT rowid, qty, '.$fieldup.' as up, remise_percent, total_ht, '.$fieldtva.' as total_tva, total_ttc, '.$fieldlocaltax1.' as total_localtax1, '.$fieldlocaltax2.' as total_localtax2,'; $sql.= ' tva_tx as vatrate, localtax1_tx, localtax2_tx, localtax1_type, localtax2_type, info_bits, product_type'; - if ($this->table_element_line == 'facturedet') $sql.= ', situation_percent'; - $sql.= ', multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc'; + if ($this->table_element_line == 'facturedet') $sql.= ', situation_percent'; + $sql.= ', multicurrency_total_ht, multicurrency_total_tva, multicurrency_total_ttc'; $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line; $sql.= ' WHERE '.$this->fk_element.' = '.$this->id; if ($exclspec) @@ -2847,18 +2847,23 @@ abstract class CommonObject if (empty($reshook) && $forcedroundingmode == '0') // Check if data on line are consistent. This may solve lines that were not consistent because set with $forcedroundingmode='auto' { + // This part of code is to fix data. We should not call it too often. $localtax_array=array($obj->localtax1_type,$obj->localtax1_tx,$obj->localtax2_type,$obj->localtax2_tx); $tmpcal=calcul_price_total($obj->qty, $obj->up, $obj->remise_percent, $obj->vatrate, $obj->localtax1_tx, $obj->localtax2_tx, 0, 'HT', $obj->info_bits, $obj->product_type, $seller, $localtax_array, (isset($obj->situation_percent) ? $obj->situation_percent : 100), $multicurrency_tx); - $diff=price2num($tmpcal[1] - $obj->total_tva, 'MT', 1); - if ($diff) + + $diff_when_using_price_ht=price2num($tmpcal[1] - $obj->total_tva, 'MT', 1); // If price was set with tax price adn unit price HT has a low number of digits, then we may have a diff on recalculation from unit price HT. + $diff_on_current_total=price2num($obj->total_ttc - $obj->total_ht - $obj->total_tva - $obj->total_localtax1 - $obj->total_localtax2, 'MT', 1); + //var_dump($obj->total_ht.' '.$obj->total_tva.' '.$obj->total_localtax1.' '.$obj->total_localtax2.' =? '.$obj->total_ttc); + //var_dump($diff_when_using_price_ht.' '.$diff_on_current_total); + + if ($diff_when_using_price_ht && $diff_on_current_total) { $sqlfix="UPDATE ".MAIN_DB_PREFIX.$this->table_element_line." SET ".$fieldtva." = ".$tmpcal[1].", total_ttc = ".$tmpcal[2]." WHERE rowid = ".$obj->rowid; - dol_syslog('We found unconsistent data into detailed line (difference of '.$diff.') for line rowid = '.$obj->rowid." (total vat of line calculated=".$tmpcal[1].", database=".$obj->total_tva."). We fix the total_vat and total_ttc of line by running sqlfix = ".$sqlfix); - $resqlfix=$this->db->query($sqlfix); - if (! $resqlfix) dol_print_error($this->db, 'Failed to update line'); - $obj->total_tva = $tmpcal[1]; - $obj->total_ttc = $tmpcal[2]; - // + dol_syslog('We found unconsistent data into detailed line (diff_when_using_price_ht = '.$diff_when_using_price_ht.' and diff_on_current_total = '.$diff_on_current_total.') for line rowid = '.$obj->rowid." (total vat of line calculated=".$tmpcal[1].", database=".$obj->total_tva."). We fix the total_vat and total_ttc of line by running sqlfix = ".$sqlfix, LOG_WARNING); + $resqlfix=$this->db->query($sqlfix); + if (! $resqlfix) dol_print_error($this->db, 'Failed to update line'); + $obj->total_tva = $tmpcal[1]; + $obj->total_ttc = $tmpcal[2]; } } From 6798e9e6f5ab8862450ee9745b0017e8f08a5c68 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 24 Apr 2020 19:52:54 +0200 Subject: [PATCH 40/70] Fix remove warning missing the seller in update_price --- htdocs/fourn/class/fournisseur.facture.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index b62190686b3..e20a3f9e7de 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -1967,7 +1967,7 @@ class FactureFournisseur extends CommonInvoice $this->errors[] = $line->error; } else { // Update total price into invoice record - $res = $this->update_price('', 'auto'); + $res = $this->update_price('', 'auto', 0, $this->thirdparty); } return $res; From a040cd030569f06a84ea57aaeef31350dd5cbf44 Mon Sep 17 00:00:00 2001 From: Marc Guenneugues Date: Sat, 25 Apr 2020 15:19:47 +0200 Subject: [PATCH 41/70] Properly assign ->id in expensereport fetch_lines --- htdocs/expensereport/class/expensereport.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index ab54a4f3915..048bdb5d493 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -1049,7 +1049,7 @@ class ExpenseReport extends CommonObject $deplig = new ExpenseReportLine($this->db); $deplig->rowid = $objp->rowid; - $deplig->id = $objp->id; + $deplig->id = $objp->rowid; $deplig->comments = $objp->comments; $deplig->qty = $objp->qty; $deplig->value_unit = $objp->value_unit; From b90a6024f57097830be749a5eee755cc45b603af Mon Sep 17 00:00:00 2001 From: Ferran Marcet Date: Mon, 27 Apr 2020 10:15:47 +0200 Subject: [PATCH 42/70] FIX: Wrong Sql on getListOfTowns api method --- htdocs/api/class/api_setup.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index 5174aae7221..1e1ab2f8307 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -603,7 +603,7 @@ class Setup extends DolibarrApi $sql = "SELECT rowid AS id, zip, town, fk_county, fk_pays AS fk_country"; $sql.= " FROM ".MAIN_DB_PREFIX."c_ziptown as t"; - $sql.= " AND t.active = ".$active; + $sql.= " WHERE t.active = ".$active; if ($zipcode) $sql.=" AND t.zip LIKE '%" . $this->db->escape($zipcode) . "%'"; if ($town) $sql.=" AND t.town LIKE '%" . $this->db->escape($town) . "%'"; // Add sql filters From 7f56c4a785b93f460f43a049257617faa0102d36 Mon Sep 17 00:00:00 2001 From: gauthier Date: Mon, 27 Apr 2020 11:18:53 +0200 Subject: [PATCH 43/70] FIX : Another "Access to undeclared static property: Contact::$table_element" && "Societe::$table_element" --- htdocs/comm/mailing/class/advtargetemailing.class.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/htdocs/comm/mailing/class/advtargetemailing.class.php b/htdocs/comm/mailing/class/advtargetemailing.class.php index da1775955b7..6987a27dacd 100644 --- a/htdocs/comm/mailing/class/advtargetemailing.class.php +++ b/htdocs/comm/mailing/class/advtargetemailing.class.php @@ -615,7 +615,8 @@ class AdvanceTargetingMailing extends CommonObject //Standard Extrafield feature if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) { - $elementtype = Societe::$table_element; + $socstatic = new Societe($this->db); + $elementtype = $socstatic->table_element; $extrafields->fetch_name_optionals_label($elementtype); @@ -752,7 +753,8 @@ class AdvanceTargetingMailing extends CommonObject //Standard Extrafield feature if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) { - $elementtype = Contact::$table_element; + $contactstatic = new Contact($this->db); + $elementtype = $contactstatic->table_element; // fetch optionals attributes and labels dol_include_once('/core/class/extrafields.class.php'); @@ -854,7 +856,8 @@ class AdvanceTargetingMailing extends CommonObject //Standard Extrafield feature if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED)) { - $elementtype = Societe::$table_element; + $socstatic = new Societe($this->db); + $elementtype = $socstatic->table_element; // fetch optionals attributes and labels dol_include_once('/core/class/extrafields.class.php'); From ed632877971d1de2d5f1b8790d17b4a2b9e34d6f Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Apr 2020 14:02:18 +0200 Subject: [PATCH 44/70] Fix font --- htdocs/langs/es_AR/main.lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/langs/es_AR/main.lang b/htdocs/langs/es_AR/main.lang index 1451ea1c508..a48f7399746 100644 --- a/htdocs/langs/es_AR/main.lang +++ b/htdocs/langs/es_AR/main.lang @@ -1,6 +1,6 @@ # Dolibarr language file - Source file is en_US - main DIRECTION=ltr -FONTFORPDF=helvética +FONTFORPDF=helvetica FONTSIZEFORPDF=10 SeparatorDecimal=. SeparatorThousand=, From ed045b26736523cbbf82fc1f8c13081f671192f7 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Apr 2020 14:38:45 +0200 Subject: [PATCH 45/70] FIX #13749 --- htdocs/api/class/api.class.php | 9 +++++++++ htdocs/product/class/api_products.class.php | 18 +++++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index 26f83f36fd6..46431cdb510 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -137,6 +137,15 @@ class DolibarrApi unset($object->labelStatus); unset($object->labelStatusShort); + unset($object->stats_propale); + unset($object->stats_commande); + unset($object->stats_contrat); + unset($object->stats_facture); + unset($object->stats_commande_fournisseur); + unset($object->stats_reception); + unset($object->stats_mrptoconsume); + unset($object->stats_mrptoproduce); + unset($object->element); unset($object->fk_element); unset($object->table_element); diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 0cf6b344abf..b1fee0177d6 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -669,8 +669,6 @@ class Products extends DolibarrApi } /** - * List purchase prices - * * Get a list of all purchase prices of products * * @param string $sortfield Sort field @@ -702,11 +700,11 @@ class Products extends DolibarrApi if ($supplier > 0) { $sql .= " AND s.fk_soc = ".$db->escape($supplier); } - $sql .= " AND s.fk_product = t.rowid "; + $sql .= " AND s.fk_product = t.rowid"; // Select products of given category if ($category > 0) { $sql .= " AND c.fk_categorie = ".$db->escape($category); - $sql .= " AND c.fk_product = t.rowid "; + $sql .= " AND c.fk_product = t.rowid"; } if ($mode == 1) { // Show only products @@ -739,10 +737,15 @@ class Products extends DolibarrApi while ($i < $min) { $obj = $db->fetch_object($result); - $product_static = new Product($db); - if ($product_static->fetch($obj->rowid)) { - $obj_ret[] = $this->_cleanObjectDatas($product_static); + + $product_fourn = new ProductFournisseur($this->db); + $product_fourn_list = $product_fourn->list_product_fournisseur_price($obj->rowid, '', '', 0, 0); + foreach($product_fourn_list as $tmpobj) { + $this->_cleanObjectDatas($tmpobj); } + //var_dump($product_fourn_list->db);exit; + $obj_ret[$obj->rowid] = $product_fourn_list; + $i++; } } @@ -1527,6 +1530,7 @@ class Products extends DolibarrApi unset($object->prices_by_qty_id); unset($object->libelle); unset($object->product_id_already_linked); + unset($object->reputations); unset($object->name); unset($object->firstname); From 635b9bb0fee53252f5cd5442045032614a8086ab Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Apr 2020 15:27:03 +0200 Subject: [PATCH 46/70] FIX #13641 --- htdocs/core/tpl/extrafields_list_search_sql.tpl.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php index 3a0bcf6375c..6b08baddb72 100644 --- a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php +++ b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php @@ -33,12 +33,12 @@ if (! empty($extrafieldsobjectkey) && ! empty($search_array_options) && is_array $sql.= ")"; } } - elseif ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) + elseif ($crit != '' && (! in_array($typ, array('select', 'sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) { $mode_search=0; - if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric - if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int - if (in_array($typ, array('chkbxlst','checkbox'))) $mode_search=4; // Search on a multiselect field with sql type = text + if (in_array($typ, array('int', 'double', 'real', 'price'))) $mode_search=1; // Search on a numeric + if (in_array($typ, array('sellist', 'link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int + if (in_array($typ, array('chkbxlst', 'checkbox'))) $mode_search=4; // Search on a multiselect field with sql type = text if (is_array($crit)) $crit = implode(' ', $crit); // natural_search() expects a string elseif ($typ === 'select' and is_string($crit) and strpos($crit, ' ') === false) { $sql .= ' AND (' . $extrafieldsobjectprefix.$tmpkey . ' = "' . $db->escape($crit) . '")'; From fe6fb12d189825fdec451cb9dfe4ca69be0f7d13 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Apr 2020 17:13:23 +0200 Subject: [PATCH 47/70] Fix missing link --- htdocs/core/class/notify.class.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index 7a3508c7d2f..c0258bdec90 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -314,6 +314,7 @@ class Notify global $user, $conf, $langs, $mysoc; global $hookmanager; global $dolibarr_main_url_root; + global $action; if (!in_array($notifcode, $this->arrayofnotifsupported)) return 0; @@ -526,6 +527,8 @@ class Notify if ($link) $message .= "\n".$urlwithroot.$link; $parameters = array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list); + if (!isset($action)) $action = ''; + $reshook = $hookmanager->executeHooks('formatNotificationMessage', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if (empty($reshook)) { @@ -700,21 +703,25 @@ class Notify $mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated", $newref); break; case 'EXPENSE_REPORT_VALIDATE': + $link = ''.$newref.''; $dir_output = $conf->expensereport->dir_output; $object_type = 'expensereport'; $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportValidated", $newref); break; case 'EXPENSE_REPORT_APPROVE': + $link = ''.$newref.''; $dir_output = $conf->expensereport->dir_output; $object_type = 'expensereport'; $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportApproved", $newref); break; case 'HOLIDAY_VALIDATE': + $link = ''.$newref.''; $dir_output = $conf->holiday->dir_output; $object_type = 'holiday'; $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayValidated", $newref); break; case 'HOLIDAY_APPROVE': + $link = ''.$newref.''; $dir_output = $conf->holiday->dir_output; $object_type = 'holiday'; $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayApproved", $newref); From 91523b4b6425b201f2c8c4e1580b49d9364e8334 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Apr 2020 14:22:13 +0200 Subject: [PATCH 48/70] FIX Can switch from double to price type for extrafields Conflicts: htdocs/core/tpl/admin_extrafields_edit.tpl.php --- htdocs/core/tpl/admin_extrafields_edit.tpl.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/htdocs/core/tpl/admin_extrafields_edit.tpl.php b/htdocs/core/tpl/admin_extrafields_edit.tpl.php index 4063111a6fb..b9035f546dd 100644 --- a/htdocs/core/tpl/admin_extrafields_edit.tpl.php +++ b/htdocs/core/tpl/admin_extrafields_edit.tpl.php @@ -193,14 +193,17 @@ elseif (($type== 'sellist') || ($type == 'chkbxlst') || ($type == 'link') || ($t // Define list of possible type transition $typewecanchangeinto=array( 'varchar'=>array('varchar', 'phone', 'mail', 'url', 'select', 'password', 'text', 'html'), - 'text'=>array('text','html'), - 'html'=>array('text','html'), + 'double'=>array('double', 'price'), + 'price'=>array('double', 'price'), + 'text'=>array('text', 'html'), + 'html'=>array('text', 'html'), 'password'=>array('password', 'varchar'), 'mail'=>array('varchar', 'phone', 'mail', 'url', 'select'), 'url'=>array('varchar', 'phone', 'mail', 'url', 'select'), 'phone'=>array('varchar', 'phone', 'mail', 'url', 'select'), 'select'=>array('varchar', 'phone', 'mail', 'url', 'select') ); + if (in_array($type, array_keys($typewecanchangeinto))) { $newarray=array(); From a8740352af918429cdd766aaf8ca106a0daeec72 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Apr 2020 14:22:52 +0200 Subject: [PATCH 49/70] FIX Extrafields of type price must be '' and not '0' if not defined --- htdocs/core/class/extrafields.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 0938da39dcd..ac388b1ef83 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1681,7 +1681,8 @@ class ExtraFields } elseif ($type == 'price') { - $value = price($value, 0, $langs, 0, 0, -1, $conf->currency); + //$value = price($value, 0, $langs, 0, 0, -1, $conf->currency); + if ($value || $value == '0') $value = price($value, 0, $langs, 0, 0, -1); } elseif ($type == 'select') { From c22e13b138d28bbb902881c6cdd061ca555b8b60 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 28 Apr 2020 14:25:07 +0200 Subject: [PATCH 50/70] FIX Avoid infinite loop when a fetch is inside a compute field. --- htdocs/core/class/commonobject.class.php | 26 ++++++++++++++++++++++-- htdocs/core/class/conf.class.php | 2 ++ htdocs/langs/en_US/admin.lang | 2 +- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index f7202040fe5..10e04896314 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -5012,6 +5012,25 @@ abstract class CommonObject /* Functions for extrafields */ + /** + * Function to make a fetch but set environment to avoid to load computed values before. + * + * @param int $id ID of object + * @return int >0 if OK, 0 if not found, <0 if KO + */ + public function fetchNoCompute($id) + { + global $conf; + + $savDisableCompute = $conf->disable_compute; + $conf->disable_compute = 1; + + $ret = $this->fetch($id); + + $conf->disable_compute = $savDisableCompute; + + return $ret; + } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** @@ -5025,7 +5044,7 @@ abstract class CommonObject public function fetch_optionals($rowid = null, $optionsArray = null) { // phpcs:enable - global $extrafields; + global $conf, $extrafields; if (empty($rowid)) $rowid = $this->id; @@ -5109,7 +5128,10 @@ abstract class CommonObject foreach ($tab as $key => $value) { if (!empty($extrafields) && !empty($extrafields->attributes[$this->table_element]['computed'][$key])) { - $this->array_options["options_".$key] = dol_eval($extrafields->attributes[$this->table_element]['computed'][$key], 1, 0); + //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); + } } } } diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 4136cef1be5..00556f40480 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -48,6 +48,8 @@ class Conf //! To store if javascript/ajax is enabked public $use_javascript_ajax; + //! To store if javascript/ajax is enabked + public $disable_compute; //! Used to store current currency (ISO code like 'USD', 'EUR', ...) public $currency; //! Used to store current css (from theme) diff --git a/htdocs/langs/en_US/admin.lang b/htdocs/langs/en_US/admin.lang index e2c03545124..00e6279349b 100644 --- a/htdocs/langs/en_US/admin.lang +++ b/htdocs/langs/en_US/admin.lang @@ -427,7 +427,7 @@ ExtrafieldCheckBox=Checkboxes ExtrafieldCheckBoxFromList=Checkboxes from table ExtrafieldLink=Link to an object ComputedFormula=Computed field -ComputedFormulaDesc=You can enter here a formula using other properties of object or any PHP coding to get a dynamic computed value. You can use any PHP compatible formulas including the "?" condition operator, and following global object: $db, $conf, $langs, $mysoc, $user, $object.
WARNING: Only some properties of $object may be available. If you need a properties not loaded, just fetch yourself the object into your formula like in the second example.
Using a computed field means you can't enter yourself any value from interface. Also, if there is a syntax error, the formula may return nothing.

Example of formula:
$object->id < 10 ? round($object->id / 2, 2): ($object->id + 2 * $user->id) * (int) substr($mysoc->zip, 1, 2)

Example to reload object
(($reloadedobj = new Societe($db)) && ($reloadedobj->fetch($obj->id ? $obj->id: ($obj->rowid ? $obj->rowid: $object->id)) > 0)) ? $reloadedobj->array_options['options_extrafieldkey'] * $reloadedobj->capital / 5: '-1'

Other example of formula to force load of object and its parent object:
(($reloadedobj = new Task($db)) && ($reloadedobj->fetch($object->id) > 0) && ($secondloadedobj = new Project($db)) && ($secondloadedobj->fetch($reloadedobj->fk_project) > 0)) ? $secondloadedobj->ref: 'Parent project not found' +ComputedFormulaDesc=You can enter here a formula using other properties of object or any PHP coding to get a dynamic computed value. You can use any PHP compatible formulas including the "?" condition operator, and following global object: $db, $conf, $langs, $mysoc, $user, $object.
WARNING: Only some properties of $object may be available. If you need a properties not loaded, just fetch yourself the object into your formula like in the second example.
Using a computed field means you can't enter yourself any value from interface. Also, if there is a syntax error, the formula may return nothing.

Example of formula:
$object->id < 10 ? round($object->id / 2, 2): ($object->id + 2 * $user->id) * (int) substr($mysoc->zip, 1, 2)

Example to reload object
(($reloadedobj = new Societe($db)) && ($reloadedobj->fetchNoCompute($obj->id ? $obj->id: ($obj->rowid ? $obj->rowid: $object->id)) > 0)) ? $reloadedobj->array_options['options_extrafieldkey'] * $reloadedobj->capital / 5: '-1'

Other example of formula to force load of object and its parent object:
(($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' Computedpersistent=Store computed field ComputedpersistentDesc=Computed extra fields will be stored in the database, however, the value will only be recalculated when the object of this field is changed. If the computed field depends on other objects or global data this value might be wrong!! ExtrafieldParamHelpPassword=Leaving this field blank means this value will be stored without encryption (field must be only hidden with star on screen).
Set 'auto' to use the default encryption rule to save password into database (then value read will be the hash only, no way to retrieve original value) From a0c013d87bfc61db04b84ae33990d6b14112724e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 27 Apr 2020 17:13:23 +0200 Subject: [PATCH 51/70] Fix missing link Conflicts: htdocs/core/class/notify.class.php --- htdocs/core/class/notify.class.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index 59d523b6b44..99910e82ecc 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -314,6 +314,7 @@ class Notify global $user,$conf,$langs,$mysoc; global $hookmanager; global $dolibarr_main_url_root; + global $action; if (! in_array($notifcode, $this->arrayofnotifsupported)) return 0; @@ -524,8 +525,10 @@ class Notify $message.= $mesg; if ($link) $message.= "\n" . $urlwithroot . $link; - $parameters=array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list); - $reshook=$hookmanager->executeHooks('formatNotificationMessage', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks + $parameters = array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list); + if (!isset($action)) $action = ''; + + $reshook = $hookmanager->executeHooks('formatNotificationMessage', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if (empty($reshook)) { if (! empty($hookmanager->resArray['subject'])) $subject.=$hookmanager->resArray['subject']; @@ -694,21 +697,25 @@ class Notify $mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated", $newref); break; case 'EXPENSE_REPORT_VALIDATE': + $link = ''.$newref.''; $dir_output = $conf->expensereport->dir_output; $object_type = 'expensereport'; $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportValidated", $newref); break; case 'EXPENSE_REPORT_APPROVE': + $link = ''.$newref.''; $dir_output = $conf->expensereport->dir_output; $object_type = 'expensereport'; $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportApproved", $newref); break; case 'HOLIDAY_VALIDATE': + $link = ''.$newref.''; $dir_output = $conf->holiday->dir_output; $object_type = 'holiday'; $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayValidated", $newref); break; case 'HOLIDAY_APPROVE': + $link = ''.$newref.''; $dir_output = $conf->holiday->dir_output; $object_type = 'holiday'; $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayApproved", $newref); From 84bca036c9eb20c073b1a6549d090deed4a808a6 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 29 Apr 2020 18:03:28 +0200 Subject: [PATCH 52/70] FIX Link missing into email of some notification --- htdocs/core/class/notify.class.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index 99910e82ecc..db0e490a6c6 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -482,26 +482,31 @@ class Notify $mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n"; break; case 'SHIPPING_VALIDATE': + $link = ''.$newref.''; $dir_output = $conf->expedition->dir_output.'/sending/'; - $object_type = 'order_supplier'; + $object_type = 'expedition'; $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpeditionValidated", $newref); break; case 'EXPENSE_REPORT_VALIDATE': + $link = ''.$newref.''; $dir_output = $conf->expensereport->dir_output; $object_type = 'expensereport'; $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportValidated", $newref); break; case 'EXPENSE_REPORT_APPROVE': + $link = ''.$newref.''; $dir_output = $conf->expensereport->dir_output; $object_type = 'expensereport'; $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportApproved", $newref); break; case 'HOLIDAY_VALIDATE': + $link = ''.$newref.''; $dir_output = $conf->holiday->dir_output; $object_type = 'holiday'; $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayValidated", $newref); break; case 'HOLIDAY_APPROVE': + $link = ''.$newref.''; $dir_output = $conf->holiday->dir_output; $object_type = 'holiday'; $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayApproved", $newref); @@ -692,6 +697,7 @@ class Notify $mesg.= "\n\n".$langs->transnoentitiesnoconv("Sincerely").".\n\n"; break; case 'SHIPPING_VALIDATE': + $link = ''.$newref.''; $dir_output = $conf->expedition->dir_output.'/sending/'; $object_type = 'order_supplier'; $mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated", $newref); From 82ace4b4ef6f8fd63ec4f6d73df641fb7362c129 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 3 Sep 2019 22:39:24 +0200 Subject: [PATCH 53/70] FIX Several pb in export of documents FIX Must escape shell FIX Must exclude logs and some dirs for compressed backup FIX gzip and bzip2 must use option -f --- htdocs/admin/tools/dolibarr_export.php | 74 ++-- htdocs/admin/tools/export_files.php | 49 +- htdocs/core/class/utils.class.php | 178 +++++--- htdocs/core/lib/files.lib.php | 591 +++++++++++++++---------- 4 files changed, 520 insertions(+), 372 deletions(-) diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index d04840e2d71..0bef19dde56 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -29,15 +29,15 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; $langs->load("admin"); -$action=GETPOST('action','alpha'); +$action=GETPOST('action', 'alpha'); -$sortfield = GETPOST('sortfield','alpha'); -$sortorder = GETPOST('sortorder','alpha'); -$page = GETPOST('page','int'); +$sortfield = GETPOST('sortfield', 'alpha'); +$sortorder = GETPOST('sortorder', 'alpha'); +$page = GETPOST('page', 'int'); if (! $sortorder) $sortorder="DESC"; if (! $sortfield) $sortfield="date"; if (empty($page) || $page == -1) { $page = 0; } -$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; $offset = $limit * $page; if (! $user->admin) @@ -50,10 +50,20 @@ if (! $user->admin) if ($action == 'delete') { - $file=$conf->admin->dir_output.'/backup/'.basename(GETPOST('urlfile', 'alpha')); - $ret=dol_delete_file($file, 1); - if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); - else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors'); + if (preg_match('/^backup\//', GETPOST('urlfile', 'alpha'))) + { + $file=$conf->admin->dir_output.'/backup/'.basename(GETPOST('urlfile', 'alpha')); + $ret=dol_delete_file($file, 1); + if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); + else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors'); + } + else + { + $file=$conf->admin->dir_output.'/documents/'.basename(GETPOST('urlfile', 'alpha')); + $ret=dol_delete_file($file, 1); + if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); + else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors'); + } $action=''; } @@ -70,7 +80,7 @@ $type=$db->type; //var_dump($db); $help_url='EN:Backups|FR:Sauvegardes|ES:Copias_de_seguridad'; -llxHeader('','',$help_url); +llxHeader('', '', $help_url); ?> trans("Backup"),'','title_setup'); +print load_fiche_titre($langs->trans("Backup"), '', 'title_setup'); //print_barre_liste($langs->trans("Backup"), '', '', '', '', '', $langs->trans("BackupDesc",DOL_DATA_ROOT), 0, 0, 'title_setup'); -print '
'; -print $langs->trans("BackupDesc",DOL_DATA_ROOT); +print '
'; +print $langs->trans("BackupDesc", DOL_DATA_ROOT); print '
'; print '
'; @@ -128,7 +138,7 @@ print '
';
1 trans("BackupDesc3",$dolibarr_main_db_name).'
'; +print $langs->trans("BackupDesc3", $dolibarr_main_db_name).'
'; //print $langs->trans("BackupDescY").'
'; print '
'; ?> @@ -166,7 +176,7 @@ print '
';
@@ -211,6 +221,7 @@ print '
';
+
global->MYSQL_OLD_OPTION_DISABLE_FK)) { ?> @@ -233,14 +244,6 @@ print '
';
- - -
@@ -453,8 +456,10 @@ print "\n";
-
" id="buttonGo" />
+
+ " id="buttonGo"> + +

'.$langs->trans("BackupResult").': '; print $_SESSION["commandbackupresult"]; @@ -476,7 +481,7 @@ if (! empty($_SESSION["commandbackuplastdone"])) } if (! empty($_SESSION["commandbackuptorun"])) { - print '
'.$langs->trans("YouMustRunCommandFromCommandLineAfterLoginToUser",$dolibarr_main_db_user,$dolibarr_main_db_user).':
'."\n"; + print '
'.$langs->trans("YouMustRunCommandFromCommandLineAfterLoginToUser", $dolibarr_main_db_user, $dolibarr_main_db_user).':
'."\n"; print '
'."\n"; print ajax_autoselect("commandbackuptoruntext", 0); print '
'; @@ -505,8 +510,8 @@ print '
';
admin->dir_output.'/backup','files',0,'','',$sortfield,(strtolower($sortorder)=='asc'?SORT_ASC:SORT_DESC),1); -$result=$formfile->list_of_documents($filearray,null,'systemtools','',1,'backup/',1,0,$langs->trans("NoBackupFileAvailable"),0,$langs->trans("PreviousDumpFiles")); +$filearray=dol_dir_list($conf->admin->dir_output.'/backup', 'files', 0, '', '', $sortfield, (strtolower($sortorder)=='asc'?SORT_ASC:SORT_DESC), 1); +$result=$formfile->list_of_documents($filearray, null, 'systemtools', '', 1, 'backup/', 1, 0, $langs->trans("NoBackupFileAvailable"), 0, $langs->trans("PreviousDumpFiles")); print '
'; ?> @@ -526,7 +531,7 @@ print '
';
2 trans("BackupDesc2",DOL_DATA_ROOT).'
'; +print $langs->trans("BackupDesc2", DOL_DATA_ROOT).'
'; print $langs->trans("BackupDescX").'

'; ?> @@ -582,7 +587,7 @@ print "\n"; ?>
-
" id="buttonGo" />

@@ -593,8 +598,8 @@ print "\n";
admin->dir_output.'/documents','files',0,'','',$sortfield,(strtolower($sortorder)=='asc'?SORT_ASC:SORT_DESC),1); -$result=$formfile->list_of_documents($filearray,null,'systemtools','',1,'documents/',1,0,$langs->trans("NoBackupFileAvailable"),0,$langs->trans("PreviousDumpFiles")); +$filearray=dol_dir_list($conf->admin->dir_output.'/documents', 'files', 0, '', '', $sortfield, (strtolower($sortorder)=='asc'?SORT_ASC:SORT_DESC), 1); +$result=$formfile->list_of_documents($filearray, null, 'systemtools', '', 1, 'documents/', 1, 0, $langs->trans("NoBackupFileAvailable"), 0, $langs->trans("PreviousDumpFiles")); print '
'; ?> @@ -605,9 +610,6 @@ print '
';
- - - load("admin"); -$action=GETPOST('action','alpha'); -$what=GETPOST('what','alpha'); -$export_type=GETPOST('export_type','alpha'); -$file=GETPOST('zipfilename_template','alpha'); +$action=GETPOST('action', 'alpha'); +$what=GETPOST('what', 'alpha'); +$export_type=GETPOST('export_type', 'alpha'); +$file=GETPOST('zipfilename_template', 'alpha'); $compression = GETPOST('compression'); $file = dol_sanitizeFileName($file); -$sortfield = GETPOST('sortfield','alpha'); -$sortorder = GETPOST('sortorder','alpha'); -$page = GETPOST("page",'int'); +$sortfield = GETPOST('sortfield', 'alpha'); +$sortorder = GETPOST('sortorder', 'alpha'); +$page = GETPOST("page", 'int'); if (! $sortorder) $sortorder="DESC"; if (! $sortfield) $sortfield="date"; if ($page < 0) { $page = 0; } elseif (empty($page)) $page = 0; -$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$limit = GETPOST('limit', 'int')?GETPOST('limit', 'int'):$conf->liste_limit; $offset = $limit * $page; if (! $user->admin) accessforbidden(); @@ -112,21 +112,27 @@ $utils = new Utils($db); if ($compression == 'zip') { - $ret = dol_compress_dir(DOL_DATA_ROOT, $outputdir."/".$file, $compression); + $ret = dol_compress_dir(DOL_DATA_ROOT, $outputdir."/".$file, $compression, '/(\.log|\/temp\/|documents\/admin\/documents\/)/'); if ($ret < 0) { - $errormsg = $langs->trans("ErrorFailedToWriteInDir",$outputfile); + $errormsg = $langs->trans("ErrorFailedToWriteInDir", $outputdir); } } elseif (in_array($compression, array('gz', 'bz'))) { - $file = substr($file, 0, strrpos($file, '.')); - $file .= '.tar'; - $cmd = 'tar -cf '.$outputdir."/".$file." --exclude=documents/admin/documents -C ".DOL_DATA_ROOT." ".DOL_DATA_ROOT."/../documents/"; - exec($cmd, $out, $retval); - //var_dump($cmd, DOL_DATA_ROOT);exit; + $userlogin = ($user->login ? $user->login : 'unknown'); - if ($retval != 0) + $outputfile = $conf->admin->dir_temp.'/export_files.'.$userlogin.'.out'; // File used with popen method + + $file = substr($file, 0, strrpos($file, '.')); + $file .= '.tar'; + // We also exclude '/temp/' dir and 'documents/admin/documents' + $cmd = "tar -cf ".$outputdir."/".$file." --exclude-vcs --exclude 'temp' --exclude 'dolibarr.log' --exclude='documents/admin/documents' -C ".dirname(DOL_DATA_ROOT)." ".basename(DOL_DATA_ROOT); + + $result = $utils->executeCLI($cmd, $outputfile); + + $retval = $result['error']; + if ($result['result'] || ! empty($retval)) { $langs->load("errors"); dol_syslog("Documents tar retval after exec=".$retval, LOG_ERR); @@ -136,15 +142,17 @@ elseif (in_array($compression, array('gz', 'bz'))) { if ($compression == 'gz') { - $cmd = "gzip " . $outputdir."/".$file; + $cmd = "gzip -f " . $outputdir."/".$file; } if ($compression == 'bz') { - $cmd = "bzip2 " . $outputdir."/".$file; + $cmd = "bzip2 -f " . $outputdir."/".$file; } - exec($cmd, $out, $retval); - if ($retval != 0) + $result = $utils->executeCLI($cmd, $outputfile); + + $retval = $result['error']; + if ($result['result'] || ! empty($retval)) { $errormsg = 'Error '.$compression.' generation return '.$retval; unlink($outputdir."/".$file); @@ -166,4 +174,3 @@ header("Location: dolibarr_export.php"); $time_end = time(); $db->close(); - diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index 5007e642300..86eff6613c1 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -32,15 +32,15 @@ class Utils */ public $db; - var $output; // Used by Cron method to return message - var $result; // Used by Cron method to return data + public $output; // Used by Cron method to return message + public $result; // Used by Cron method to return data /** * Constructor * * @param DoliDB $db Database handler */ - function __construct($db) + public function __construct($db) { $this->db = $db; } @@ -54,7 +54,7 @@ class Utils * @param int $nbsecondsold Nb of seconds old to accept deletion of a directory if $choice is 'tempfilesold' * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) */ - function purgeFiles($choice = 'tempfilesold', $nbsecondsold = 86400) + public function purgeFiles($choice = 'tempfilesold', $nbsecondsold = 86400) { global $conf, $langs, $dolibarr_main_data_root; @@ -106,7 +106,7 @@ class Utils if (! empty($conf->syslog->enabled)) { $filelog=$conf->global->SYSLOG_FILE; - $filelog=preg_replace('/DOL_DATA_ROOT/i',DOL_DATA_ROOT,$filelog); + $filelog=preg_replace('/DOL_DATA_ROOT/i', DOL_DATA_ROOT, $filelog); $alreadyincluded=false; foreach ($filesarray as $tmpcursor) @@ -193,7 +193,7 @@ class Utils * @param int $execmethod 0=Use default method (that is 1 by default), 1=Use the PHP 'exec', 2=Use the 'popen' method * @return int 0 if OK, < 0 if KO (this function is used also by cron so only 0 is OK) */ - function dumpDatabase($compression='none', $type='auto', $usedefault=1, $file='auto', $keeplastnfiles=0, $execmethod=0) + public function dumpDatabase($compression = 'none', $type = 'auto', $usedefault = 1, $file = 'auto', $keeplastnfiles = 0, $execmethod = 0) { global $db, $conf, $langs, $dolibarr_main_data_root; global $dolibarr_main_db_name, $dolibarr_main_db_host, $dolibarr_main_db_user, $dolibarr_main_db_port, $dolibarr_main_db_pass; @@ -251,8 +251,8 @@ class Utils // Parameteres execution $command = $cmddump; - $command = preg_replace('/(\$|%)/', '', $command); // We removed chars that can be used to inject vars that contains space inside path of command without seeing there is a space to bypass the escapeshellarg. - if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // If there is spaces, we add quotes on command to be sure $command is only a program and not a program+parameters + $command = preg_replace('/(\$|%)/', '', $command); // We removed chars that can be used to inject vars that contains space inside path of command without seeing there is a space to bypass the escapeshellarg. + if (preg_match("/\s/", $command)) $command=escapeshellarg($command); // If there is spaces, we add quotes on command to be sure $command is only a program and not a program+parameters //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass); $param=$dolibarr_main_db_name." -h ".$dolibarr_main_db_host; @@ -262,7 +262,6 @@ class Utils if (GETPOST("disable_fk", "alpha") || $usedefault) $param.=" -K"; if (GETPOST("sql_compat", "alpha") && GETPOST("sql_compat", "alpha") != 'NONE') $param.=" --compatible=".escapeshellarg(GETPOST("sql_compat", "alpha")); if (GETPOST("drop_database", "alpha")) $param.=" --add-drop-database"; - if (GETPOST("use_mysql_quick_param", "alpha"))$param.=" --quick"; if (GETPOST("sql_structure", "alpha") || $usedefault) { if (GETPOST("drop", "alpha") || $usedefault) $param.=" --add-drop-table=TRUE"; @@ -292,8 +291,8 @@ class Utils $paramclear=$param; if (! empty($dolibarr_main_db_pass)) { - $paramcrypted.=' -p"'.preg_replace('/./i','*',$dolibarr_main_db_pass).'"'; - $paramclear.=' -p"'.str_replace(array('"','`'),array('\"','\`'),$dolibarr_main_db_pass).'"'; + $paramcrypted.=' -p"'.preg_replace('/./i', '*', $dolibarr_main_db_pass).'"'; + $paramclear.=' -p"'.str_replace(array('"','`'), array('\"','\`'), $dolibarr_main_db_pass).'"'; } $errormsg=''; @@ -317,27 +316,29 @@ class Utils // TODO Replace with executeCLI function if ($execmethod == 1) { - exec($fullcommandclear, $readt, $retval); - $result = $retval; + $output_arr = array(); $retval = null; + exec($fullcommandclear, $output_arr, $retval); if ($retval != 0) { $langs->load("errors"); dol_syslog("Datadump retval after exec=".$retval, LOG_ERR); - $error = 'Error '.$retval; + $errormsg = 'Error '.$retval; $ok=0; } else { $i=0; - if (!empty($readt)) - foreach($readt as $key=>$read) + if (!empty($output_arr)) { - $i++; // output line number - if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) continue; - fwrite($handle, $read.($execmethod == 2 ? '' : "\n")); - if (preg_match('/'.preg_quote('-- Dump completed').'/i',$read)) $ok=1; - elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i',$read)) $ok=1; + foreach($output_arr as $key => $read) + { + $i++; // output line number + if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) continue; + fwrite($handle, $read.($execmethod == 2 ? '' : "\n")); + if (preg_match('/'.preg_quote('-- Dump completed').'/i', $read)) $ok=1; + elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i', $read)) $ok=1; + } } } } @@ -351,9 +352,9 @@ class Utils $read = fgets($handlein); // Exclude warning line we don't want if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) continue; - fwrite($handle,$read); - if (preg_match('/'.preg_quote('-- Dump completed').'/i',$read)) $ok=1; - elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i',$read)) $ok=1; + fwrite($handle, $read); + if (preg_match('/'.preg_quote('-- Dump completed').'/i', $read)) $ok=1; + elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i', $read)) $ok=1; } pclose($handlein); } @@ -369,7 +370,7 @@ class Utils else { $langs->load("errors"); - dol_syslog("Failed to open file ".$outputfile,LOG_ERR); + dol_syslog("Failed to open file ".$outputfile, LOG_ERR); $errormsg=$langs->trans("ErrorFailedToWriteInDir"); } @@ -380,18 +381,18 @@ class Utils if ($handle) { // Get 2048 first chars of error message. - $errormsg = fgets($handle,2048); + $errormsg = fgets($handle, 2048); // Close file if ($compression == 'none') fclose($handle); if ($compression == 'gz') gzclose($handle); if ($compression == 'bz') bzclose($handle); - if ($ok && preg_match('/^-- MySql/i',$errormsg)) $errormsg=''; // Pas erreur + if ($ok && preg_match('/^-- MySql/i', $errormsg)) $errormsg=''; // Pas erreur else { // Renommer fichier sortie en fichier erreur //print "$outputfile -> $outputerror"; @dol_delete_file($outputerror, 1, 0, 0, null, false, 0); - @rename($outputfile,$outputerror); + @rename($outputfile, $outputerror); // Si safe_mode on et command hors du parametre exec, on a un fichier out vide donc errormsg vide if (! $errormsg) { @@ -450,8 +451,8 @@ class Utils // Parameteres execution $command = $cmddump; - $command = preg_replace('/(\$|%)/', '', $command); // We removed chars that can be used to inject vars that contains space inside path of command without seeing there is a space to bypass the escapeshellarg. - if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // If there is spaces, we add quotes on command to be sure $command is only a program and not a program+parameters + $command = preg_replace('/(\$|%)/', '', $command); // We removed chars that can be used to inject vars that contains space inside path of command without seeing there is a space to bypass the escapeshellarg. + if (preg_match("/\s/", $command)) $command=escapeshellarg($command); // If there is spaces, we add quotes on command to be sure $command is only a program and not a program+parameters //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass); //$param="-F c"; @@ -515,7 +516,7 @@ class Utils * @param int $execmethod 0=Use default method (that is 1 by default), 1=Use the PHP 'exec', 2=Use the 'popen' method * @return array array('result'=>...,'output'=>...,'error'=>...). result = 0 means OK. */ - function executeCLI($command, $outputfile, $execmethod=0) + public function executeCLI($command, $outputfile, $execmethod = 0) { global $conf, $langs; @@ -535,6 +536,7 @@ class Utils if ($execmethod == 1) { + $retval = null; exec($command, $output_arr, $retval); $result = $retval; if ($retval != 0) @@ -546,7 +548,6 @@ class Utils } if ($execmethod == 2) // With this method, there is no way to get the return code, only output { - $ok=0; $handle = fopen($outputfile, 'w+b'); if ($handle) { @@ -555,7 +556,7 @@ class Utils while (!feof($handlein)) { $read = fgets($handlein); - fwrite($handle,$read); + fwrite($handle, $read); $output_arr[]=$read; } pclose($handlein); @@ -584,14 +585,15 @@ class Utils * @param string $module Module name * @return int <0 if KO, >0 if OK */ - function generateDoc($module) + public function generateDoc($module) { - global $conf, $langs; + global $conf, $langs, $user, $mysoc; global $dirins; $error = 0; $modulelowercase=strtolower($module); + $now=dol_now(); // Dir for module $dir = $dirins.'/'.$modulelowercase; @@ -621,11 +623,12 @@ class Utils exit; } - $arrayversion=explode('.',$moduleobj->version,3); + $arrayversion=explode('.', $moduleobj->version, 3); if (count($arrayversion)) { $FILENAMEASCII=strtolower($module).'.asciidoc'; - $FILENAMEDOC=strtolower($module).'.html'; // TODO Use/text PDF + $FILENAMEDOC=strtolower($module).'.html'; + $FILENAMEDOCPDF=strtolower($module).'.pdf'; $dirofmodule = dol_buildpath(strtolower($module), 0); $dirofmoduledoc = dol_buildpath(strtolower($module), 0).'/doc'; @@ -641,13 +644,25 @@ class Utils return -1; } - $conf->global->MODULEBUILDER_ASCIIDOCTOR='asciidoctor'; - if (empty($conf->global->MODULEBUILDER_ASCIIDOCTOR)) + if (empty($conf->global->MODULEBUILDER_ASCIIDOCTOR) && empty($conf->global->MODULEBUILDER_ASCIIDOCTORPDF)) { $this->error = 'Setup of module ModuleBuilder not complete'; return -1; } + // Copy some files into temp directory, so instruction include::ChangeLog.md[] will works inside the asciidoc file. + dol_copy($dirofmodule.'/README.md', $dirofmoduletmp.'/README.md', 0, 1); + dol_copy($dirofmodule.'/ChangeLog.md', $dirofmoduletmp.'/ChangeLog.md', 0, 1); + + // Replace into README.md and ChangeLog.md (in case they are included into documentation with tag __README__ or __CHANGELOG__) + $arrayreplacement=array(); + $arrayreplacement['/^#\s.*/m']=''; // Remove first level of title into .md files + $arrayreplacement['/^#/m']='##'; // Add on # to increase level + + dolReplaceInFile($dirofmoduletmp.'/README.md', $arrayreplacement, '', 0, 0, 1); + dolReplaceInFile($dirofmoduletmp.'/ChangeLog.md', $arrayreplacement, '', 0, 0, 1); + + $destfile=$dirofmoduletmp.'/'.$FILENAMEASCII; $fhandle = fopen($destfile, 'w+'); @@ -680,35 +695,48 @@ class Utils $i++; } - fwrite($fhandle, "\n\n\n== DATA SPECIFICATIONS...\n\n"); - - // TODO - fwrite($fhandle, "TODO..."); - - - fwrite($fhandle, "\n\n\n== CHANGELOG...\n\n"); - - // TODO - fwrite($fhandle, "TODO..."); - - - fclose($fhandle); - } - // Copy some files into temp directory - dol_copy($dirofmodule.'/README.md', $dirofmoduletmp.'/README.md', 0, 1); - dol_copy($dirofmodule.'/ChangeLog.md', $dirofmoduletmp.'/ChangeLog.md', 0, 1); + $contentreadme=file_get_contents($dirofmoduletmp.'/README.md'); + $contentchangelog=file_get_contents($dirofmoduletmp.'/ChangeLog.md'); + + include DOL_DOCUMENT_ROOT.'/core/lib/parsemd.lib.php'; + + //var_dump($phpfileval['fullname']); + $arrayreplacement=array( + 'mymodule'=>strtolower($module), + 'MyModule'=>$module, + 'MYMODULE'=>strtoupper($module), + 'My module'=>$module, + 'my module'=>$module, + 'Mon module'=>$module, + 'mon module'=>$module, + 'htdocs/modulebuilder/template'=>strtolower($module), + '__MYCOMPANY_NAME__'=>$mysoc->name, + '__KEYWORDS__'=>$module, + '__USER_FULLNAME__'=>$user->getFullName($langs), + '__USER_EMAIL__'=>$user->email, + '__YYYY-MM-DD__'=>dol_print_date($now, 'dayrfc'), + '---Put here your own copyright and developer email---'=>dol_print_date($now, 'dayrfc').' '.$user->getFullName($langs).($user->email?' <'.$user->email.'>':''), + '__DATA_SPECIFICATION__'=>'Not yet available', + '__README__'=>dolMd2Asciidoc($contentreadme), + '__CHANGELOG__'=>dolMd2Asciidoc($contentchangelog), + ); + + dolReplaceInFile($destfile, $arrayreplacement); + } // Launch doc generation $currentdir = getcwd(); chdir($dirofmodule); + require_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php'; + $utils = new Utils($db); + + // Build HTML doc $command=$conf->global->MODULEBUILDER_ASCIIDOCTOR.' '.$destfile.' -n -o '.$dirofmoduledoc.'/'.$FILENAMEDOC; $outfile=$dirofmoduletmp.'/out.tmp'; - require_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php'; - $utils = new Utils($this->db); $resarray = $utils->executeCLI($command, $outfile); if ($resarray['result'] != '0') { @@ -716,6 +744,16 @@ class Utils } $result = ($resarray['result'] == 0) ? 1 : 0; + // Build PDF doc + $command=$conf->global->MODULEBUILDER_ASCIIDOCTORPDF.' '.$destfile.' -n -o '.$dirofmoduledoc.'/'.$FILENAMEDOCPDF; + $outfile=$dirofmoduletmp.'/outpdf.tmp'; + $resarray = $utils->executeCLI($command, $outfile); + if ($resarray['result'] != '0') + { + $this->error = $resarray['error'].' '.$resarray['output']; + } + $result = ($resarray['result'] == 0) ? 1 : 0; + chdir($currentdir); } else @@ -751,7 +789,7 @@ class Utils * * @return int 0 if OK, < 0 if KO */ - function compressSyslogs() + public function compressSyslogs() { global $conf; @@ -857,7 +895,7 @@ class Utils $this->output = 'Archive log files (keeping last SYSLOG_FILE_SAVES='.$nbSaves.' files) done.'; return 0; - } + } /** Backup the db OR just a table without mysqldump binary, with PHP only (does not require any exec permission) * Author: David Walsh (http://davidwalsh.name/backup-mysql-database-php) @@ -869,7 +907,7 @@ class Utils * @param string $tables Table name or '*' for all * @return int <0 if KO, >0 if OK */ - function backupTables($outputfile, $tables='*') + public function backupTables($outputfile, $tables = '*') { global $db, $langs; global $errormsg; @@ -896,7 +934,7 @@ class Utils } else { - $tables = is_array($tables) ? $tables : explode(',',$tables); + $tables = is_array($tables) ? $tables : explode(',', $tables); } //cycle through @@ -904,7 +942,7 @@ class Utils if (fwrite($handle, '') === false) { $langs->load("errors"); - dol_syslog("Failed to open file ".$outputfile,LOG_ERR); + dol_syslog("Failed to open file ".$outputfile, LOG_ERR); $errormsg=$langs->trans("ErrorFailedToWriteInDir"); return -1; } @@ -947,9 +985,9 @@ class Utils // Saving the table structure fwrite($handle, "\n--\n-- Table structure for table `".$table."`\n--\n"); - if (GETPOST("nobin_drop")) fwrite($handle,"DROP TABLE IF EXISTS `".$table."`;\n"); // Dropping table if exists prior to re create it - fwrite($handle,"/*!40101 SET @saved_cs_client = @@character_set_client */;\n"); - fwrite($handle,"/*!40101 SET character_set_client = utf8 */;\n"); + if (GETPOST("nobin_drop")) fwrite($handle, "DROP TABLE IF EXISTS `".$table."`;\n"); // Dropping table if exists prior to re create it + fwrite($handle, "/*!40101 SET @saved_cs_client = @@character_set_client */;\n"); + fwrite($handle, "/*!40101 SET character_set_client = utf8 */;\n"); $resqldrop=$db->query('SHOW CREATE TABLE '.$table); $row2 = $db->fetch_row($resqldrop); if (empty($row2[1])) @@ -958,7 +996,7 @@ class Utils } else { - fwrite($handle,$row2[1].";\n"); + fwrite($handle, $row2[1].";\n"); //fwrite($handle,"/*!40101 SET character_set_client = @saved_cs_client */;\n\n"); // Dumping the data (locking the table and disabling the keys check while doing the process) @@ -972,7 +1010,7 @@ class Utils while($row = $db->fetch_row($result)) { // For each row of data we print a line of INSERT - fwrite($handle,'INSERT '.$delayed.$ignore.'INTO `'.$table.'` VALUES ('); + fwrite($handle, 'INSERT '.$delayed.$ignore.'INTO `'.$table.'` VALUES ('); $columns = count($row); for($j=0; $j<$columns; $j++) { // Processing each columns of the row to ensure that we correctly save the value (eg: add quotes for string - in fact we add quotes for everything, it's easier) @@ -991,11 +1029,11 @@ class Utils $row[$j] = "'".$row[$j]."'"; } } - fwrite($handle,implode(',', $row).");\n"); + fwrite($handle, implode(',', $row).");\n"); } if (GETPOST("nobin_disable_fk")) fwrite($handle, "ALTER TABLE `".$table."` ENABLE KEYS;\n"); // Enabling back the keys/index checking if (!GETPOST("nobin_nolocks")) fwrite($handle, "UNLOCK TABLES;\n"); // Unlocking the table - fwrite($handle,"\n\n\n"); + fwrite($handle, "\n\n\n"); } } diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 295bda85d53..d2aee3e6a30 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -4,6 +4,7 @@ * Copyright (C) 2012-2016 Juanjo Menent * Copyright (C) 2015 Marcos García * Copyright (C) 2016 Raphaël Doursenaud + * Copyright (C) 2019 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 @@ -34,7 +35,7 @@ */ function dol_basename($pathfile) { - return preg_replace('/^.*\/([^\/]+)$/','$1',rtrim($pathfile,'/')); + return preg_replace('/^.*\/([^\/]+)$/', '$1', rtrim($pathfile, '/')); } /** @@ -54,9 +55,9 @@ function dol_basename($pathfile) * @param string $relativename For recursive purpose only. Must be "" at first call. * @param string $donotfollowsymlinks Do not follow symbolic links * @return array Array of array('name'=>'xxx','fullname'=>'/abc/xxx','date'=>'yyy','size'=>99,'type'=>'dir|file',...) - * @see dol_dir_list_indatabase + * @see dol_dir_list_in_database() */ -function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0) +function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excludefilter = null, $sortcriteria = "name", $sortorder = SORT_ASC, $mode = 0, $nohook = 0, $relativename = "", $donotfollowsymlinks = 0) { global $db, $hookmanager; global $object; @@ -68,7 +69,7 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil $loadsize=($mode==1||$mode==3)?true:false; // Clean parameters - $path=preg_replace('/([\\/]+)$/i','',$path); + $path=preg_replace('/([\\/]+)$/i', '', $path); $newpath=dol_osencode($path); $reshook = 0; @@ -116,9 +117,9 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil $excludefilterarray=array('^\.'); if (is_array($excludefilter)) { - $excludefilterarray=array_merge($excludefilterarray,$excludefilter); + $excludefilterarray=array_merge($excludefilterarray, $excludefilter); } - else if ($excludefilter) $excludefilterarray[]=$excludefilter; + elseif ($excludefilter) $excludefilterarray[]=$excludefilter; // Check if file is qualified foreach($excludefilterarray as $filt) { @@ -140,9 +141,9 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil if ($loaddate || $sortcriteria == 'date') $filedate=dol_filemtime($path."/".$file); if ($loadsize || $sortcriteria == 'size') $filesize=dol_filesize($path."/".$file); - if (! $filter || preg_match('/'.$filter.'/i',$file)) // We do not search key $filter into all $path, only into $file part + if (! $filter || preg_match('/'.$filter.'/i', $file)) // We do not search key $filter into all $path, only into $file part { - preg_match('/([^\/]+)\/[^\/]+$/',$path.'/'.$file,$reg); + preg_match('/([^\/]+)\/[^\/]+$/', $path.'/'.$file, $reg); $level1name=(isset($reg[1])?$reg[1]:''); $file_list[] = array( "name" => $file, @@ -167,15 +168,15 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil } } } - else if (! $isdir && (($types == "files") || ($types == "all"))) + elseif (! $isdir && (($types == "files") || ($types == "all"))) { // Add file into file_list array if ($loaddate || $sortcriteria == 'date') $filedate=dol_filemtime($path."/".$file); if ($loadsize || $sortcriteria == 'size') $filesize=dol_filesize($path."/".$file); - if (! $filter || preg_match('/'.$filter.'/i',$file)) // We do not search key $filter into $path, only into $file + if (! $filter || preg_match('/'.$filter.'/i', $file)) // We do not search key $filter into $path, only into $file { - preg_match('/([^\/]+)\/[^\/]+$/',$path.'/'.$file,$reg); + preg_match('/([^\/]+)\/[^\/]+$/', $path.'/'.$file, $reg); $level1name=(isset($reg[1])?$reg[1]:''); $file_list[] = array( "name" => $file, @@ -194,15 +195,9 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil closedir($dir); // Obtain a list of columns - if (! empty($sortcriteria)) + if (! empty($sortcriteria) && $sortorder) { - $myarray=array(); - foreach ($file_list as $key => $row) - { - $myarray[$key] = (isset($row[$sortcriteria])?$row[$sortcriteria]:''); - } - // Sort the data - if ($sortorder) array_multisort($myarray, $sortorder, $file_list); + $file_list = dol_sort_array($file_list, $sortcriteria, ($sortorder == SORT_ASC ? 'asc' : 'desc')); } } } @@ -224,9 +219,9 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil * @param string $sortorder Sort order (SORT_ASC, SORT_DESC) * @param int $mode 0=Return array minimum keys loaded (faster), 1=Force all keys like description * @return array Array of array('name'=>'xxx','fullname'=>'/abc/xxx','type'=>'dir|file',...) - * @see dol_dir_list + * @see dol_dir_list() */ -function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0) +function dol_dir_list_in_database($path, $filter = "", $excludefilter = null, $sortcriteria = "name", $sortorder = SORT_ASC, $mode = 0) { global $conf, $db; @@ -248,7 +243,7 @@ function dol_dir_list_in_database($path, $filter="", $excludefilter=null, $sortc $obj = $db->fetch_object($resql); if ($obj) { - preg_match('/([^\/]+)\/[^\/]+$/',DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename,$reg); + preg_match('/([^\/]+)\/[^\/]+$/', DOL_DATA_ROOT.'/'.$obj->filepath.'/'.$obj->filename, $reg); $level1name=(isset($reg[1])?$reg[1]:''); $file_list[] = array( "rowid" => $obj->rowid, @@ -313,11 +308,11 @@ function completeFileArrayWithDatabaseInfo(&$filearray, $relativedir) global $object; if (! empty($object->id)) { - if (! empty($conf->product->enabled)) $upload_dirold = $conf->product->multidir_output[$object->entity].'/'.substr(substr("000".$object->id, -2),1,1).'/'.substr(substr("000".$object->id, -2),0,1).'/'.$object->id."/photos"; - else $upload_dirold = $conf->service->multidir_output[$object->entity].'/'.substr(substr("000".$object->id, -2),1,1).'/'.substr(substr("000".$object->id, -2),0,1).'/'.$object->id."/photos"; + if (! empty($conf->product->enabled)) $upload_dirold = $conf->product->multidir_output[$object->entity].'/'.substr(substr("000".$object->id, -2), 1, 1).'/'.substr(substr("000".$object->id, -2), 0, 1).'/'.$object->id."/photos"; + else $upload_dirold = $conf->service->multidir_output[$object->entity].'/'.substr(substr("000".$object->id, -2), 1, 1).'/'.substr(substr("000".$object->id, -2), 0, 1).'/'.$object->id."/photos"; - $relativedirold = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $upload_dirold); - $relativedirold = preg_replace('/^[\\/]/','',$relativedirold); + $relativedirold = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $upload_dirold); + $relativedirold = preg_replace('/^[\\/]/', '', $relativedirold); $filearrayindatabase = array_merge($filearrayindatabase, dol_dir_list_in_database($relativedirold, '', null, 'name', SORT_ASC)); } @@ -353,7 +348,7 @@ function completeFileArrayWithDatabaseInfo(&$filearray, $relativedir) $filearray[$key]['cover']=0; $filearray[$key]['acl']=''; - $rel_filename = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filearray[$key]['fullname']); + $rel_filename = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filearray[$key]['fullname']); if (! preg_match('/([\\/]temp[\\/]|[\\/]thumbs|\.meta$)/', $rel_filetorenameafter)) // If not a tmp file { dol_syslog("list_of_documents We found a file called '".$filearray[$key]['name']."' not indexed into database. We add it"); @@ -442,6 +437,18 @@ function dol_is_dir($folder) else return false; } +/** + * Return if path is empty + * + * @param string $dir Path of Directory + * @return boolean True or false + */ +function dol_is_dir_empty($dir) +{ + if (!is_readable($dir)) return false; + return (count(scandir($dir)) == 2); +} + /** * Return if path is a file * @@ -477,7 +484,7 @@ function dol_is_url($url) $tmpprot=array('file','http','https','ftp','zlib','data','ssh','ssh2','ogg','expect'); foreach($tmpprot as $prot) { - if (preg_match('/^'.$prot.':/i',$url)) return true; + if (preg_match('/^'.$prot.':/i', $url)) return true; } return false; } @@ -515,7 +522,7 @@ function dol_dir_is_emtpy($folder) * * @param string $file Filename * @return int <0 if KO, Number of lines in files if OK - * @see dol_nboflines + * @see dol_nboflines() */ function dol_count_nb_of_line($file) { @@ -523,7 +530,7 @@ function dol_count_nb_of_line($file) $newfile=dol_osencode($file); //print 'x'.$file; - $fp=fopen($newfile,'r'); + $fp=fopen($newfile, 'r'); if ($fp) { while (!feof($fp)) @@ -570,19 +577,20 @@ function dol_filemtime($pathoffile) /** * Make replacement of strings into a file. * - * @param string $srcfile Source file (can't be a directory) - * @param array $arrayreplacement Array with strings to replace. Example: array('valuebefore'=>'valueafter', ...) - * @param string $destfile Destination file (can't be a directory). If empty, will be same than source file. - * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' - * @param int $indexdatabase 1=index new file into database. - * @return int <0 if error, 0 if nothing done (dest file already exists), >0 if OK - * @see dol_copy dolReplaceRegExInFile + * @param string $srcfile Source file (can't be a directory) + * @param array $arrayreplacement Array with strings to replace. Example: array('valuebefore'=>'valueafter', ...) + * @param string $destfile Destination file (can't be a directory). If empty, will be same than source file. + * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' + * @param int $indexdatabase 1=index new file into database. + * @param int $arrayreplacementisregex 1=Array of replacement is regex + * @return int <0 if error, 0 if nothing done (dest file already exists), >0 if OK + * @see dol_copy() */ -function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0) +function dolReplaceInFile($srcfile, $arrayreplacement, $destfile = '', $newmask = 0, $indexdatabase = 0, $arrayreplacementisregex = 0) { global $conf; - dol_syslog("files.lib.php::dolReplaceInFile srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." indexdatabase=".$indexdatabase); + dol_syslog("files.lib.php::dolReplaceInFile srcfile=".$srcfile." destfile=".$destfile." newmask=".$newmask." indexdatabase=".$indexdatabase." arrayreplacementisregex=".$arrayreplacementisregex); if (empty($srcfile)) return -1; if (empty($destfile)) $destfile=$srcfile; @@ -613,7 +621,17 @@ function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, // Create $newpathoftmpdestfile from $newpathofsrcfile $content = file_get_contents($newpathofsrcfile, 'r'); - $content = make_substitutions($content, $arrayreplacement, null); + if (empty($arrayreplacementisregex)) + { + $content = make_substitutions($content, $arrayreplacement, null); + } + else + { + foreach ($arrayreplacement as $key => $value) + { + $content = preg_replace($key, $value, $content); + } + } file_put_contents($newpathoftmpdestfile, $content); @chmod($newpathoftmpdestfile, octdec($newmask)); @@ -637,21 +655,6 @@ function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, return 1; } -/** - * Make replacement of strings into a file. - * - * @param string $srcfile Source file (can't be a directory) - * @param array $arrayreplacement Array with strings to replace. Example: array('valuebefore'=>'valueafter', ...) - * @param string $destfile Destination file (can't be a directory). If empty, will be same than source file. - * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' - * @param int $indexdatabase Index new file into database. - * @return int <0 if error, 0 if nothing done (dest file already exists), >0 if OK - * @see dol_copy dolReplaceInFile - */ -function dolReplaceRegExInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0) -{ - // TODO -} /** * Copy a file to another file. @@ -661,9 +664,9 @@ function dolReplaceRegExInFile($srcfile, $arrayreplacement, $destfile='', $newma * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' * @param int $overwriteifexists Overwrite file if exists (1 by default) * @return int <0 if error, 0 if nothing done (dest file already exists and overwriteifexists=0), >0 if OK - * @see dol_delete_file + * @see dol_delete_file() dolCopyDir() */ -function dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1) +function dol_copy($srcfile, $destfile, $newmask = 0, $overwriteifexists = 1) { global $conf; @@ -717,9 +720,9 @@ function dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1) * @param int $overwriteifexists Overwrite file if exists (1 by default) * @param array $arrayreplacement Array to use to replace filenames with another one during the copy (works only on file names, not on directory names). * @return int <0 if error, 0 if nothing done (all files already exists and overwriteifexists=0), >0 if OK - * @see dol_copy + * @see dol_copy() */ -function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayreplacement=null) +function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayreplacement = null) { global $conf; @@ -809,9 +812,9 @@ function dolCopyDir($srcfile, $destfile, $newmask, $overwriteifexists, $arrayrep * @param int $testvirus Do an antivirus test. Move is canceled if a virus is found. * @param int $indexdatabase Index new file into database. * @return boolean True if OK, false if KO - * @see dol_move_uploaded_file + * @see dol_move_uploaded_file() */ -function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvirus=0, $indexdatabase=1) +function dol_move($srcfile, $destfile, $newmask = 0, $overwriteifexists = 1, $testvirus = 0, $indexdatabase = 1) { global $user, $db, $conf; $result=false; @@ -860,8 +863,8 @@ function dol_move($srcfile, $destfile, $newmask=0, $overwriteifexists=1, $testvi if ($result && $indexdatabase) { // Rename entry into ecm database - $rel_filetorenamebefore = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $srcfile); - $rel_filetorenameafter = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $destfile); + $rel_filetorenamebefore = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $srcfile); + $rel_filetorenameafter = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $destfile); if (! preg_match('/([\\/]temp[\\/]|[\\/]thumbs|\.meta$)/', $rel_filetorenameafter)) // If not a tmp file { $rel_filetorenamebefore = preg_replace('/^[\\/]/', '', $rel_filetorenamebefore); @@ -956,18 +959,18 @@ function dol_unescapefile($filename) */ function dolCheckVirus($src_file) { - global $conf, $db; + global $conf; if (! empty($conf->global->MAIN_ANTIVIRUS_COMMAND)) { if (! class_exists('AntiVir')) { require_once DOL_DOCUMENT_ROOT.'/core/class/antivir.class.php'; } - $antivir = new AntiVir($db); + $antivir=new AntiVir($db); $result = $antivir->dol_avscan_file($src_file); if ($result < 0) // If virus or error, we stop here { - $reterrors = $antivir->errors; + $reterrors=$antivir->errors; return $reterrors; } } @@ -982,6 +985,7 @@ function dolCheckVirus($src_file) * - This function can be used only into a HTML page context. Use dol_move if you are outside. * - Test on antivirus is always done (if antivirus set). * - Database of files is NOT updated (this is done by dol_add_file_process() that calls this function). + * - Extension .noexe may be added if file is executable and MAIN_DOCUMENT_IS_OUTSIDE_WEBROOT_SO_NOEXE_NOT_REQUIRED is not set. * * @param string $src_file Source full path filename ($_FILES['field']['tmp_name']) * @param string $dest_file Target full path filename ($_FILES['field']['name']) @@ -990,10 +994,10 @@ function dolCheckVirus($src_file) * @param integer $uploaderrorcode Value of PHP upload error code ($_FILES['field']['error']) * @param int $nohook Disable all hooks * @param string $varfiles _FILES var name - * @return int|string >0 if OK, <0 or string if KO - * @see dol_move + * @return int >0 if OK, <0 or string if KO + * @see dol_move() */ -function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $varfiles='addedfile') +function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan = 0, $uploaderrorcode = 0, $nohook = 0, $varfiles = 'addedfile') { global $conf, $db, $user, $langs; global $object, $hookmanager; @@ -1045,8 +1049,8 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable $checkvirusarray=dolCheckVirus($src_file); if (count($checkvirusarray)) { - dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$dest_file.'") KO with antivirus: result='.$result.' errors='.join(',',$checkvirusarray), LOG_WARNING); - return 'ErrorFileIsInfectedWithAVirus: '.join(',',$checkvirusarray); + dol_syslog('Files.lib::dol_move_uploaded_file File "'.$src_file.'" (target name "'.$dest_file.'") KO with antivirus: errors='.join(',', $checkvirusarray), LOG_WARNING); + return 'ErrorFileIsInfectedWithAVirus: '.join(',', $checkvirusarray); } } @@ -1060,15 +1064,15 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable // Security: // We refuse cache files/dirs, upload using .. and pipes into filenames. - if (preg_match('/^\./',$src_file) || preg_match('/\.\./',$src_file) || preg_match('/[<>|]/',$src_file)) + if (preg_match('/^\./', basename($src_file)) || preg_match('/\.\./', $src_file) || preg_match('/[<>|]/', $src_file)) { dol_syslog("Refused to deliver file ".$src_file, LOG_WARNING); return -1; } // Security: - // On interdit fichiers caches, remontees de repertoire ainsi que les pipe dans les noms de fichiers. - if (preg_match('/^\./',$dest_file) || preg_match('/\.\./',$dest_file) || preg_match('/[<>|]/',$dest_file)) + // We refuse cache files/dirs, upload using .. and pipes into filenames. + if (preg_match('/^\./', basename($dest_file)) || preg_match('/\.\./', $dest_file) || preg_match('/[<>|]/', $dest_file)) { dol_syslog("Refused to deliver file ".$dest_file, LOG_WARNING); return -2; @@ -1134,9 +1138,9 @@ function dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disable * @param boolean $allowdotdot Allow to delete file path with .. inside. Never use this, it is reserved for migration purpose. * @param int $indexdatabase Try to remove also index entries. * @return boolean True if no error (file is deleted or if glob is used and there's nothing to delete), False if error - * @see dol_delete_dir + * @see dol_delete_dir() */ -function dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1) +function dol_delete_file($file, $disableglob = 0, $nophperrors = 0, $nohook = 0, $object = null, $allowdotdot = false, $indexdatabase = 1) { global $db, $conf, $user, $langs; global $hookmanager; @@ -1148,7 +1152,7 @@ function dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $obje // Security: // We refuse transversal using .. and pipes into filenames. - if ((! $allowdotdot && preg_match('/\.\./',$file)) || preg_match('/[<>|]/',$file)) + if ((! $allowdotdot && preg_match('/\.\./', $file)) || preg_match('/[<>|]/', $file)) { dol_syslog("Refused to delete file ".$file, LOG_WARNING); return false; @@ -1181,8 +1185,8 @@ function dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $obje if (empty($disableglob) && ! empty($file_osencoded)) { $ok=true; - $globencoded=str_replace('[','\[',$file_osencoded); - $globencoded=str_replace(']','\]',$globencoded); + $globencoded=str_replace('[', '\[', $file_osencoded); + $globencoded=str_replace(']', '\]', $globencoded); $listofdir=glob($globencoded); if (! empty($listofdir) && is_array($listofdir)) { @@ -1195,7 +1199,7 @@ function dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $obje dol_syslog("Removed file ".$filename, LOG_DEBUG); // Delete entry into ecm database - $rel_filetodelete = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $filename); + $rel_filetodelete = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $filename); if (! preg_match('/(\/temp\/|\/thumbs\/|\.meta$)/', $rel_filetodelete)) // If not a tmp file { $rel_filetodelete = preg_replace('/^[\\/]/', '', $rel_filetodelete); @@ -1217,9 +1221,12 @@ function dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $obje } } } - else dol_syslog("Failed to remove file ".$filename, LOG_WARNING); - // TODO Failure to remove can be because file was already removed or because of permission - // If error because it does not exists, we should return true, and we should return false if this is a permission problem + else + { + dol_syslog("Failed to remove file ".$filename, LOG_WARNING); + // TODO Failure to remove can be because file was already removed or because of permission + // If error because it does not exists, we should return true, and we should return false if this is a permission problem + } } } else dol_syslog("No files to delete found", LOG_DEBUG); @@ -1244,13 +1251,13 @@ function dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $obje * @param string $dir Directory to delete * @param int $nophperrors Disable all PHP output errors * @return boolean True if success, false if error - * @see dol_delete_file dol_copy + * @see dol_delete_file() dolCopyDir() */ -function dol_delete_dir($dir,$nophperrors=0) +function dol_delete_dir($dir, $nophperrors = 0) { // Security: // We refuse transversal using .. and pipes into filenames. - if (preg_match('/\.\./',$dir) || preg_match('/[<>|]/',$dir)) + if (preg_match('/\.\./', $dir) || preg_match('/[<>|]/', $dir)) { dol_syslog("Refused to delete dir ".$dir, LOG_WARNING); return false; @@ -1270,9 +1277,9 @@ function dol_delete_dir($dir,$nophperrors=0) * @param int $countdeleted Counter to count nb of elements found really deleted * @return int Number of files and directory we try to remove. NB really removed is returned into var by reference $countdeleted. */ -function dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$countdeleted=0) +function dol_delete_dir_recursive($dir, $count = 0, $nophperrors = 0, $onlysub = 0, &$countdeleted = 0) { - dol_syslog("functions.lib:dol_delete_dir_recursive ".$dir,LOG_DEBUG); + dol_syslog("functions.lib:dol_delete_dir_recursive ".$dir, LOG_DEBUG); if (dol_is_dir($dir)) { $dir_osencoded=dol_osencode($dir); @@ -1319,7 +1326,7 @@ function dol_delete_dir_recursive($dir, $count=0, $nophperrors=0, $onlysub=0, &$ * * @param object $object Object to clean * @return int 0 if error, 1 if OK - * @see dol_convert_file + * @see dol_convert_file() */ function dol_delete_preview($object) { @@ -1347,26 +1354,26 @@ function dol_delete_preview($object) // For new preview files if (file_exists($filepreviewnew) && is_writable($filepreviewnew)) { - if (! dol_delete_file($filepreviewnew,1)) + if (! dol_delete_file($filepreviewnew, 1)) { - $object->error=$langs->trans("ErrorFailedToDeleteFile",$filepreviewnew); + $object->error=$langs->trans("ErrorFailedToDeleteFile", $filepreviewnew); return 0; } } if (file_exists($filepreviewnewbis) && is_writable($filepreviewnewbis)) { - if (! dol_delete_file($filepreviewnewbis,1)) + if (! dol_delete_file($filepreviewnewbis, 1)) { - $object->error=$langs->trans("ErrorFailedToDeleteFile",$filepreviewnewbis); + $object->error=$langs->trans("ErrorFailedToDeleteFile", $filepreviewnewbis); return 0; } } // For old preview files if (file_exists($filepreviewold) && is_writable($filepreviewold)) { - if (! dol_delete_file($filepreviewold,1)) + if (! dol_delete_file($filepreviewold, 1)) { - $object->error=$langs->trans("ErrorFailedToDeleteFile",$filepreviewold); + $object->error=$langs->trans("ErrorFailedToDeleteFile", $filepreviewold); return 0; } } @@ -1379,9 +1386,9 @@ function dol_delete_preview($object) if (file_exists($preview) && is_writable($preview)) { - if ( ! dol_delete_file($preview,1) ) + if ( ! dol_delete_file($preview, 1) ) { - $object->error=$langs->trans("ErrorFailedToOpenFile",$preview); + $object->error=$langs->trans("ErrorFailedToOpenFile", $preview); return 0; } } @@ -1435,7 +1442,7 @@ function dol_meta_create($object) $nblignes = count($object->lines); $client = $object->thirdparty->name . " " . $object->thirdparty->address . " " . $object->thirdparty->zip . " " . $object->thirdparty->town; $meta = "REFERENCE=\"" . $object->ref . "\" - DATE=\"" . dol_print_date($object->date,'') . "\" + DATE=\"" . dol_print_date($object->date, '') . "\" NB_ITEMS=\"" . $nblignes . "\" CLIENT=\"" . $client . "\" AMOUNT_EXCL_TAX=\"" . $object->total_ht . "\" @@ -1447,13 +1454,13 @@ function dol_meta_create($object) $meta .= "ITEM_" . $i . "_QUANTITY=\"" . $object->lines[$i]->qty . "\" ITEM_" . $i . "_AMOUNT_WO_TAX=\"" . $object->lines[$i]->total_ht . "\" ITEM_" . $i . "_VAT=\"" .$object->lines[$i]->tva_tx . "\" - ITEM_" . $i . "_DESCRIPTION=\"" . str_replace("\r\n","",nl2br($object->lines[$i]->desc)) . "\" + ITEM_" . $i . "_DESCRIPTION=\"" . str_replace("\r\n", "", nl2br($object->lines[$i]->desc)) . "\" "; } } - $fp = fopen($file,"w"); - fputs($fp,$meta); + $fp = fopen($file, "w"); + fputs($fp, $meta); fclose($fp); if (! empty($conf->global->MAIN_UMASK)) @chmod($file, octdec($conf->global->MAIN_UMASK)); @@ -1478,7 +1485,7 @@ function dol_meta_create($object) * @param string $trackid Track id (used to prefix name of session vars to avoid conflict) * @return void */ -function dol_init_file_process($pathtoscan='', $trackid='') +function dol_init_file_process($pathtoscan = '', $trackid = '') { $listofpaths=array(); $listofnames=array(); @@ -1486,7 +1493,7 @@ function dol_init_file_process($pathtoscan='', $trackid='') if ($pathtoscan) { - $listoffiles=dol_dir_list($pathtoscan,'files'); + $listoffiles=dol_dir_list($pathtoscan, 'files'); foreach($listoffiles as $key => $val) { $listofpaths[]=$val['fullname']; @@ -1495,9 +1502,9 @@ function dol_init_file_process($pathtoscan='', $trackid='') } } $keytoavoidconflict = empty($trackid)?'':'-'.$trackid; - $_SESSION["listofpaths".$keytoavoidconflict]=join(';',$listofpaths); - $_SESSION["listofnames".$keytoavoidconflict]=join(';',$listofnames); - $_SESSION["listofmimes".$keytoavoidconflict]=join(';',$listofmimes); + $_SESSION["listofpaths".$keytoavoidconflict]=join(';', $listofpaths); + $_SESSION["listofnames".$keytoavoidconflict]=join(';', $listofnames); + $_SESSION["listofmimes".$keytoavoidconflict]=join(';', $listofmimes); } @@ -1516,7 +1523,7 @@ function dol_init_file_process($pathtoscan='', $trackid='') * @param int $generatethumbs 1=Generate also thumbs for uploaded image files * @return int <=0 if KO, >0 if OK */ -function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesession=0, $varfiles='addedfile', $savingdocmask='', $link=null, $trackid='', $generatethumbs=1) +function dol_add_file_process($upload_dir, $allowoverwrite = 0, $donotupdatesession = 0, $varfiles = 'addedfile', $savingdocmask = '', $link = null, $trackid = '', $generatethumbs = 1) { global $db,$user,$conf,$langs; @@ -1546,8 +1553,8 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio if ($savingdocmask) { - $destfull=$upload_dir . "/" . preg_replace('/__file__/',$TFile['name'][$i],$savingdocmask); - $destfile=preg_replace('/__file__/',$TFile['name'][$i],$savingdocmask); + $destfull=$upload_dir . "/" . preg_replace('/__file__/', $TFile['name'][$i], $savingdocmask); + $destfile=preg_replace('/__file__/', $TFile['name'][$i], $savingdocmask); } // dol_sanitizeFileName the file name and lowercase extension @@ -1614,7 +1621,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio { setEventMessages($langs->trans("ErrorFileNotUploaded"), null, 'errors'); } - else if (preg_match('/ErrorFileIsInfectedWithAVirus/',$resupload)) // Files infected by a virus + elseif (preg_match('/ErrorFileIsInfectedWithAVirus/', $resupload)) // Files infected by a virus { setEventMessages($langs->trans("ErrorFileIsInfectedWithAVirus"), null, 'errors'); } @@ -1666,7 +1673,7 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio * @param string $trackid Track id (used to prefix name of session vars to avoid conflict) * @return void */ -function dol_remove_file_process($filenb,$donotupdatesession=0,$donotdeletefile=1,$trackid='') +function dol_remove_file_process($filenb, $donotupdatesession = 0, $donotdeletefile = 1, $trackid = '') { global $db,$user,$conf,$langs,$_FILES; @@ -1677,22 +1684,22 @@ function dol_remove_file_process($filenb,$donotupdatesession=0,$donotdeletefile= $listofnames=array(); $listofmimes=array(); $keytoavoidconflict = empty($trackid)?'':'-'.$trackid; - if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';',$_SESSION["listofpaths".$keytoavoidconflict]); - if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';',$_SESSION["listofnames".$keytoavoidconflict]); - if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';',$_SESSION["listofmimes".$keytoavoidconflict]); + if (! empty($_SESSION["listofpaths".$keytoavoidconflict])) $listofpaths=explode(';', $_SESSION["listofpaths".$keytoavoidconflict]); + if (! empty($_SESSION["listofnames".$keytoavoidconflict])) $listofnames=explode(';', $_SESSION["listofnames".$keytoavoidconflict]); + if (! empty($_SESSION["listofmimes".$keytoavoidconflict])) $listofmimes=explode(';', $_SESSION["listofmimes".$keytoavoidconflict]); if ($keytodelete >= 0) { $pathtodelete=$listofpaths[$keytodelete]; $filetodelete=$listofnames[$keytodelete]; - if (empty($donotdeletefile)) $result = dol_delete_file($pathtodelete,1); // The delete of ecm database is inside the function dol_delete_file + if (empty($donotdeletefile)) $result = dol_delete_file($pathtodelete, 1); // The delete of ecm database is inside the function dol_delete_file else $result=0; if ($result >= 0) { if (empty($donotdeletefile)) { $langs->load("other"); - setEventMessages($langs->trans("FileWasRemoved",$filetodelete), null, 'mesgs'); + setEventMessages($langs->trans("FileWasRemoved", $filetodelete), null, 'mesgs'); } if (empty($donotupdatesession)) { @@ -1718,13 +1725,13 @@ function dol_remove_file_process($filenb,$donotupdatesession=0,$donotdeletefile= * @param int $setsharekey Set also the share key * @return int <0 if KO, 0 if nothing done, >0 if OK */ -function addFileIntoDatabaseIndex($dir, $file, $fullpathorig='', $mode='uploaded', $setsharekey=0) +function addFileIntoDatabaseIndex($dir, $file, $fullpathorig = '', $mode = 'uploaded', $setsharekey = 0) { global $db, $user; $result = 0; - $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $dir); + $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $dir); if (! preg_match('/[\\/]temp[\\/]|[\\/]thumbs|\.meta$/', $rel_dir)) // If not a tmp dir { @@ -1766,7 +1773,7 @@ function addFileIntoDatabaseIndex($dir, $file, $fullpathorig='', $mode='uploaded * @param string $mode How file was created ('uploaded', 'generated', ...) * @return int <0 if KO, 0 if nothing done, >0 if OK */ -function deleteFilesIntoDatabaseIndex($dir, $file, $mode='uploaded') +function deleteFilesIntoDatabaseIndex($dir, $file, $mode = 'uploaded') { global $conf, $db, $user; @@ -1780,7 +1787,7 @@ function deleteFilesIntoDatabaseIndex($dir, $file, $mode='uploaded') $db->begin(); - $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT,'/').'/', '', $dir); + $rel_dir = preg_replace('/^'.preg_quote(DOL_DATA_ROOT, '/').'/', '', $dir); $filename = basename($file); $rel_dir = preg_replace('/[\\/]$/', '', $rel_dir); @@ -1820,38 +1827,36 @@ function deleteFilesIntoDatabaseIndex($dir, $file, $mode='uploaded') * @param string $fileinput Input file name * @param string $ext Format of target file (It is also extension added to file if fileoutput is not provided). * @param string $fileoutput Output filename + * @param string $page Page number if we convert a PDF into png * @return int <0 if KO, 0=Nothing done, >0 if OK */ -function dol_convert_file($fileinput, $ext='png', $fileoutput='') +function dol_convert_file($fileinput, $ext = 'png', $fileoutput = '', $page = '') { global $langs; - if (class_exists('Imagick')) { - $image=new Imagick(); + $image=new Imagick(); try { - $ret = $image->readImage($fileinput); + $filetoconvert=$fileinput.(($page != '')?'['.$page.']':''); + //var_dump($filetoconvert); + $ret = $image->readImage($filetoconvert); } catch(Exception $e) { - dol_syslog("Failed to read image using Imagick. Try to install package 'apt-get install ghostscript'.", LOG_WARNING); + $ext = pathinfo($fileinput, PATHINFO_EXTENSION); + dol_syslog("Failed to read image using Imagick (Try to install package 'apt-get install php-imagick ghostscript' and check there is no policy to disable ".$ext." convertion in /etc/ImageMagick*/policy.xml): ".$e->getMessage(), LOG_WARNING); return 0; } if ($ret) { - $ret = $image->setImageFormat($ext); + $ret = $image->setImageFormat($ext); if ($ret) { if (empty($fileoutput)) $fileoutput=$fileinput.".".$ext; $count = $image->getNumberImages(); + if (! dol_is_file($fileoutput) || is_writeable($fileoutput)) { - try { - $ret = $image->writeImages($fileoutput, true); - } - catch(Exception $e) - { - dol_syslog($e->getMessage(), LOG_WARNING); - } + $ret = $image->writeImages($fileoutput, true); } else { @@ -1885,26 +1890,89 @@ function dol_convert_file($fileinput, $ext='png', $fileoutput='') * @param string $mode 'gz' or 'bz' or 'zip' * @return int <0 if KO, >0 if OK */ -function dol_compress_file($inputfile, $outputfile, $mode="gz") +function dol_compress_file($inputfile, $outputfile, $mode = "gz") { + global $conf; + $foundhandler=0; try { + dol_syslog("dol_compress_file mode=".$mode." inputfile=".$inputfile." outputfile=".$outputfile); + $data = implode("", file(dol_osencode($inputfile))); if ($mode == 'gz') { $foundhandler=1; $compressdata = gzencode($data, 9); } elseif ($mode == 'bz') { $foundhandler=1; $compressdata = bzcompress($data, 9); } elseif ($mode == 'zip') { + if (class_exists('ZipArchive') && ! empty($conf->global->MAIN_USE_ZIPARCHIVE_FOR_ZIP_COMPRESS)) + { + $foundhandler=1; + + $rootPath = realpath($inputfile); + + dol_syslog("Class ZipArchive is set so we zip using ZipArchive to zip into ".$outputfile.' rootPath='.$rootPath); + $zip = new ZipArchive; + + if ($zip->open($outputfile, ZipArchive::CREATE) !== true) { + $errormsg="Failed to open file ".$outputfile."\n"; + dol_syslog("dol_compress_file failure - ".$errormsg, LOG_ERR); + return -6; + } + + // Create recursive directory iterator + /** @var SplFileInfo[] $files */ + $files = new RecursiveIteratorIterator( + new RecursiveDirectoryIterator($rootPath), + RecursiveIteratorIterator::LEAVES_ONLY + ); + + foreach ($files as $name => $file) + { + // Skip directories (they would be added automatically) + if (!$file->isDir()) + { + // Get real and relative path for current file + $filePath = $file->getRealPath(); + $relativePath = substr($filePath, strlen($rootPath) + 1); + + // Add current file to archive + $zip->addFile($filePath, $relativePath); + } + } + + // Zip archive will be created only after closing object + $zip->close(); + + dol_syslog("dol_compress_file success - ".count($zip->numFiles)." files"); + return 1; + } + if (defined('ODTPHP_PATHTOPCLZIP')) { $foundhandler=1; include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php'; $archive = new PclZip($outputfile); - $archive->add($inputfile, PCLZIP_OPT_REMOVE_PATH, dirname($inputfile)); - //$archive->add($inputfile); - return 1; + $result = $archive->add($inputfile, PCLZIP_OPT_REMOVE_PATH, dirname($inputfile)); + + if ($result === 0) + { + global $errormsg; + $errormsg=$archive->errorInfo(true); + dol_syslog("dol_compress_file failure - ".$errormsg, LOG_ERR); + if ($archive->errorCode() == PCLZIP_ERR_WRITE_OPEN_FAIL) + { + dol_syslog("dol_compress_file error PCLZIP_ERR_WRITE_OPEN_FAIL", LOG_ERR); + return -4; + } + return -3; + } + else + { + dol_syslog("dol_compress_file success - ".count($result)." files"); + return 1; + } } } @@ -1917,7 +1985,7 @@ function dol_compress_file($inputfile, $outputfile, $mode="gz") } else { - dol_syslog("Try to zip with format ".$mode." with no handler for this format",LOG_ERR); + dol_syslog("Try to zip with format ".$mode." with no handler for this format", LOG_ERR); return -2; } } @@ -1925,7 +1993,7 @@ function dol_compress_file($inputfile, $outputfile, $mode="gz") { global $langs, $errormsg; $langs->load("errors"); - dol_syslog("Failed to open file ".$outputfile,LOG_ERR); + dol_syslog("Failed to open file ".$outputfile, LOG_ERR); $errormsg=$langs->trans("ErrorFailedToWriteInDir"); return -1; } @@ -1938,11 +2006,11 @@ function dol_compress_file($inputfile, $outputfile, $mode="gz") * @param string $outputdir Target dir name * @return array array('error'=>'Error code') or array() if no error */ -function dol_uncompress($inputfile,$outputdir) +function dol_uncompress($inputfile, $outputdir) { - global $langs; + global $conf, $langs; - if (defined('ODTPHP_PATHTOPCLZIP')) + if (defined('ODTPHP_PATHTOPCLZIP') && empty($conf->global->MAIN_USE_ZIPARCHIVE_FOR_ZIP_UNCOMPRESS)) { dol_syslog("Constant ODTPHP_PATHTOPCLZIP for pclzip library is set to ".ODTPHP_PATHTOPCLZIP.", so we use Pclzip to unzip into ".$outputdir); include_once ODTPHP_PATHTOPCLZIP.'/pclzip.lib.php'; @@ -1997,9 +2065,10 @@ function dol_uncompress($inputfile,$outputdir) * @param string $inputdir Source dir name * @param string $outputfile Target file name (output directory must exists and be writable) * @param string $mode 'zip' + * @param string $excludefiles A regex pattern. For example: '/\.log$|\/temp\//' * @return int <0 if KO, >0 if OK */ -function dol_compress_dir($inputdir, $outputfile, $mode="zip") +function dol_compress_dir($inputdir, $outputfile, $mode = "zip", $excludefiles = '') { $foundhandler=0; @@ -2009,7 +2078,7 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") { global $langs, $errormsg; $langs->load("errors"); - $errormsg=$langs->trans("ErrorFailedToWriteInDir",$outputfile); + $errormsg=$langs->trans("ErrorFailedToWriteInDir", $outputfile); return -3; } @@ -2030,6 +2099,7 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") return 1; } else*/ + //if (class_exists('ZipArchive') && ! empty($conf->global->MAIN_USE_ZIPARCHIVE_FOR_ZIP_COMPRESS)) if (class_exists('ZipArchive')) { $foundhandler=1; @@ -2037,6 +2107,13 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") // Initialize archive object $zip = new ZipArchive(); $result = $zip->open($outputfile, ZipArchive::CREATE | ZipArchive::OVERWRITE); + if (! $result) + { + global $langs, $errormsg; + $langs->load("errors"); + $errormsg=$langs->trans("ErrorFailedToWriteInFile", $outputfile); + return -4; + } // Create recursive directory iterator /** @var SplFileInfo[] $files */ @@ -2053,9 +2130,11 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") // Get real and relative path for current file $filePath = $file->getRealPath(); $relativePath = substr($filePath, strlen($inputdir) + 1); - - // Add current file to archive - $zip->addFile($filePath, $relativePath); + if (empty($excludefiles) || ! preg_match($excludefiles, $filePath)) + { + // Add current file to archive + $zip->addFile($filePath, $relativePath); + } } } @@ -2068,7 +2147,7 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") if (! $foundhandler) { - dol_syslog("Try to zip with format ".$mode." with no handler for this format",LOG_ERR); + dol_syslog("Try to zip with format ".$mode." with no handler for this format", LOG_ERR); return -2; } else @@ -2082,7 +2161,7 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") $langs->load("errors"); dol_syslog("Failed to open file ".$outputfile, LOG_ERR); dol_syslog($e->getMessage(), LOG_ERR); - $errormsg=$langs->trans("ErrorFailedToWriteInDir",$outputfile); + $errormsg=$langs->trans("ErrorFailedToWriteInDir", $outputfile); return -1; } } @@ -2099,9 +2178,9 @@ function dol_compress_dir($inputdir, $outputfile, $mode="zip") * @param int $mode 0=Return array minimum keys loaded (faster), 1=Force all keys like date and size to be loaded (slower), 2=Force load of date only, 3=Force load of size only * @return string Full path to most recent file */ -function dol_most_recent_file($dir,$regexfilter='',$excludefilter=array('(\.meta|_preview.*\.png)$','^\.'),$nohook=false,$mode='') +function dol_most_recent_file($dir, $regexfilter = '', $excludefilter = array('(\.meta|_preview.*\.png)$','^\.'), $nohook = false, $mode = '') { - $tmparray=dol_dir_list($dir,'files',0,$regexfilter,$excludefilter,'date',SORT_DESC,$mode,$nohook); + $tmparray=dol_dir_list($dir, 'files', 0, $regexfilter, $excludefilter, 'date', SORT_DESC, $mode, $nohook); return $tmparray[0]; } @@ -2115,9 +2194,9 @@ function dol_most_recent_file($dir,$regexfilter='',$excludefilter=array('(\.meta * @param string $refname Ref of object to check permission for external users (autodetect if not provided) * @param string $mode Check permission for 'read' or 'write' * @return mixed Array with access information : 'accessallowed' & 'sqlprotectagainstexternals' & 'original_file' (as a full path name) - * @see restrictedArea + * @see restrictedArea() */ -function dol_check_secure_access_document($modulepart, $original_file, $entity, $fuser='', $refname='', $mode='read') +function dol_check_secure_access_document($modulepart, $original_file, $entity, $fuser = '', $refname = '', $mode = 'read') { global $conf, $db, $user; global $dolibarr_main_data_root, $dolibarr_main_document_root_alt; @@ -2134,6 +2213,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, if ($modulepart == 'users') $modulepart='user'; dol_syslog('modulepart='.$modulepart.' original_file='.$original_file.' entity='.$entity); + // We define $accessallowed and $sqlprotectagainstexternals $accessallowed=0; $sqlprotectagainstexternals=''; @@ -2142,8 +2222,6 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // Find the subdirectory name as the reference. For exemple original_file='10/myfile.pdf' -> refname='10' if (empty($refname)) $refname=basename(dirname($original_file)."/"); - $relative_original_file = $original_file; - // Define possible keys to use for permission check $lire='lire'; $read='read'; $download='download'; if ($mode == 'write') @@ -2293,7 +2371,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, $original_file=$conf->adherent->dir_temp.'/'.$original_file; } // Wrapping pour les images des stats produits - elseif (preg_match('/^productstats_/i',$modulepart) && !empty($conf->product->dir_temp)) + elseif (preg_match('/^productstats_/i', $modulepart) && !empty($conf->product->dir_temp)) { if ($fuser->rights->produit->{$lire} || $fuser->rights->service->{$lire}) $accessallowed=1; $original_file=(!empty($conf->product->multidir_temp[$entity])?$conf->product->multidir_temp[$entity]:$conf->service->multidir_temp[$entity]).'/'.$original_file; @@ -2320,7 +2398,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // Wrapping pour les prelevements elseif ($modulepart == 'prelevement' && !empty($conf->prelevement->dir_output)) { - if ($fuser->rights->prelevement->bons->{$lire} || preg_match('/^specimen/i',$original_file)) $accessallowed=1; + if ($fuser->rights->prelevement->bons->{$lire} || preg_match('/^specimen/i', $original_file)) $accessallowed=1; $original_file=$conf->prelevement->dir_output.'/'.$original_file; } // Wrapping pour les graph energie @@ -2369,11 +2447,11 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for users - else if ($modulepart == 'user' && !empty($conf->user->dir_output)) + elseif ($modulepart == 'user' && !empty($conf->user->dir_output)) { $canreaduser=(! empty($fuser->admin) || $fuser->rights->user->user->{$lire}); if ($fuser->id == (int) $refname) { $canreaduser=1; } // A user can always read its own card - if ($canreaduser || preg_match('/^specimen/i',$original_file)) + if ($canreaduser || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2381,10 +2459,10 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for third parties - else if (($modulepart == 'company' || $modulepart == 'societe') && !empty($conf->societe->dir_output)) + elseif (($modulepart == 'company' || $modulepart == 'societe' || $modulepart == 'thirdparty') && !empty($conf->societe->dir_output)) { if (empty($entity) || empty($conf->societe->multidir_output[$entity])) return array('accessallowed'=>0, 'error'=>'Value entity must be provided'); - if ($fuser->rights->societe->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->societe->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2393,7 +2471,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for contact - else if ($modulepart == 'contact' && !empty($conf->societe->dir_output)) + elseif ($modulepart == 'contact' && !empty($conf->societe->dir_output)) { if (empty($entity) || empty($conf->societe->multidir_output[$entity])) return array('accessallowed'=>0, 'error'=>'Value entity must be provided'); if ($fuser->rights->societe->{$lire}) @@ -2404,9 +2482,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for invoices - else if (($modulepart == 'facture' || $modulepart == 'invoice') && !empty($conf->facture->dir_output)) + elseif (($modulepart == 'facture' || $modulepart == 'invoice') && !empty($conf->facture->dir_output)) { - if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2414,73 +2492,73 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."facture WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; } // Wrapping for mass actions - else if ($modulepart == 'massfilesarea_proposals' && !empty($conf->propal->multidir_output[$entity])) + elseif ($modulepart == 'massfilesarea_proposals' && !empty($conf->propal->multidir_output[$entity])) { - if ($fuser->rights->propal->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->propal->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->propal->multidir_output[$entity].'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_orders') + elseif ($modulepart == 'massfilesarea_orders') { - if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->commande->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_invoices') + elseif ($modulepart == 'massfilesarea_invoices') { - if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_expensereport') + elseif ($modulepart == 'massfilesarea_expensereport') { - if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->expensereport->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_interventions') + elseif ($modulepart == 'massfilesarea_interventions') { - if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->ficheinter->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_supplier_proposal' && !empty($conf->supplier_proposal->dir_output)) + elseif ($modulepart == 'massfilesarea_supplier_proposal' && !empty($conf->supplier_proposal->dir_output)) { - if ($fuser->rights->supplier_proposal->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->supplier_proposal->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->supplier_proposal->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_supplier_order') + elseif ($modulepart == 'massfilesarea_supplier_order') { - if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->fournisseur->commande->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_supplier_invoice') + elseif ($modulepart == 'massfilesarea_supplier_invoice') { - if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->fournisseur->facture->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; } - else if ($modulepart == 'massfilesarea_contract' && !empty($conf->contrat->dir_output)) + elseif ($modulepart == 'massfilesarea_contract' && !empty($conf->contrat->dir_output)) { - if ($fuser->rights->contrat->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->contrat->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2488,9 +2566,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for interventions - else if (($modulepart == 'fichinter' || $modulepart == 'ficheinter') && !empty($conf->ficheinter->dir_output)) + elseif (($modulepart == 'fichinter' || $modulepart == 'ficheinter') && !empty($conf->ficheinter->dir_output)) { - if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->ficheinter->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2499,9 +2577,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les deplacements et notes de frais - else if ($modulepart == 'deplacement' && !empty($conf->deplacement->dir_output)) + elseif ($modulepart == 'deplacement' && !empty($conf->deplacement->dir_output)) { - if ($fuser->rights->deplacement->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->deplacement->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2509,9 +2587,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, //$sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."fichinter WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; } // Wrapping pour les propales - else if (($modulepart == 'propal' || $modulepart == 'propale') && !empty($conf->propal->multidir_output[$entity])) + elseif (($modulepart == 'propal' || $modulepart == 'propale') && !empty($conf->propal->multidir_output[$entity])) { - if ($fuser->rights->propale->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->propale->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2520,9 +2598,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les commandes - else if (($modulepart == 'commande' || $modulepart == 'order') && !empty($conf->commande->dir_output)) + elseif (($modulepart == 'commande' || $modulepart == 'order') && !empty($conf->commande->dir_output)) { - if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->commande->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2531,18 +2609,18 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les projets - else if ($modulepart == 'project' && !empty($conf->projet->dir_output)) + elseif ($modulepart == 'project' && !empty($conf->projet->dir_output)) { - if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->projet->dir_output.'/'.$original_file; $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."projet WHERE ref='".$db->escape($refname)."' AND entity IN (".getEntity('project').")"; } - else if ($modulepart == 'project_task' && !empty($conf->projet->dir_output)) + elseif ($modulepart == 'project_task' && !empty($conf->projet->dir_output)) { - if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->projet->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2551,9 +2629,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les commandes fournisseurs - else if (($modulepart == 'commande_fournisseur' || $modulepart == 'order_supplier') && !empty($conf->fournisseur->commande->dir_output)) + elseif (($modulepart == 'commande_fournisseur' || $modulepart == 'order_supplier') && !empty($conf->fournisseur->commande->dir_output)) { - if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->fournisseur->commande->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2562,19 +2640,19 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les factures fournisseurs - else if (($modulepart == 'facture_fournisseur' || $modulepart == 'invoice_supplier') && !empty($conf->fournisseur->facture->dir_output)) + elseif (($modulepart == 'facture_fournisseur' || $modulepart == 'invoice_supplier') && !empty($conf->fournisseur->facture->dir_output)) { - if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->fournisseur->facture->dir_output.'/'.$original_file; - $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."facture_fourn WHERE facnumber='".$db->escape($refname)."' AND entity=".$conf->entity; + $sqlprotectagainstexternals = "SELECT fk_soc as fk_soc FROM ".MAIN_DB_PREFIX."facture_fourn WHERE ref='".$db->escape($refname)."' AND entity=".$conf->entity; } // Wrapping pour les rapport de paiements - else if ($modulepart == 'supplier_payment') + elseif ($modulepart == 'supplier_payment') { - if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->fournisseur->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2583,9 +2661,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les rapport de paiements - else if ($modulepart == 'facture_paiement' && !empty($conf->facture->dir_output)) + elseif ($modulepart == 'facture_paiement' && !empty($conf->facture->dir_output)) { - if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->facture->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2594,9 +2672,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for accounting exports - else if ($modulepart == 'export_compta' && !empty($conf->accounting->dir_output)) + elseif ($modulepart == 'export_compta' && !empty($conf->accounting->dir_output)) { - if ($fuser->rights->accounting->bind->write || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->accounting->bind->write || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2604,18 +2682,18 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les expedition - else if ($modulepart == 'expedition' && !empty($conf->expedition->dir_output)) + elseif ($modulepart == 'expedition' && !empty($conf->expedition->dir_output)) { - if ($fuser->rights->expedition->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->expedition->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } $original_file=$conf->expedition->dir_output."/sending/".$original_file; } // Wrapping pour les bons de livraison - else if ($modulepart == 'livraison' && !empty($conf->expedition->dir_output)) + elseif ($modulepart == 'livraison' && !empty($conf->expedition->dir_output)) { - if ($fuser->rights->expedition->livraison->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->expedition->livraison->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2623,9 +2701,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les actions - else if ($modulepart == 'actions' && !empty($conf->agenda->dir_output)) + elseif ($modulepart == 'actions' && !empty($conf->agenda->dir_output)) { - if ($fuser->rights->agenda->myactions->{$read} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->agenda->myactions->{$read} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2633,9 +2711,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les actions - else if ($modulepart == 'actionsreport' && !empty($conf->agenda->dir_temp)) + elseif ($modulepart == 'actionsreport' && !empty($conf->agenda->dir_temp)) { - if ($fuser->rights->agenda->allactions->{$read} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->agenda->allactions->{$read} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2643,10 +2721,10 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les produits et services - else if ($modulepart == 'product' || $modulepart == 'produit' || $modulepart == 'service' || $modulepart == 'produit|service') + elseif ($modulepart == 'product' || $modulepart == 'produit' || $modulepart == 'service' || $modulepart == 'produit|service') { if (empty($entity) || (empty($conf->product->multidir_output[$entity]) && empty($conf->service->multidir_output[$entity]))) return array('accessallowed'=>0, 'error'=>'Value entity must be provided'); - if (($fuser->rights->produit->{$lire} || $fuser->rights->service->{$lire}) || preg_match('/^specimen/i',$original_file)) + if (($fuser->rights->produit->{$lire} || $fuser->rights->service->{$lire}) || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2655,20 +2733,31 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les lots produits - else if ($modulepart == 'product_batch' || $modulepart == 'produitlot') + elseif ($modulepart == 'product_batch' || $modulepart == 'produitlot') { if (empty($entity) || (empty($conf->productbatch->multidir_output[$entity]))) return array('accessallowed'=>0, 'error'=>'Value entity must be provided'); - if (($fuser->rights->produit->{$lire} ) || preg_match('/^specimen/i',$original_file)) + if (($fuser->rights->produit->{$lire} ) || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } if (! empty($conf->productbatch->enabled)) $original_file=$conf->productbatch->multidir_output[$entity].'/'.$original_file; } - // Wrapping pour les contrats - else if ($modulepart == 'contract' && !empty($conf->contrat->dir_output)) + // Wrapping for stock movements + elseif ($modulepart == 'movement' || $modulepart == 'mouvement') { - if ($fuser->rights->contrat->{$lire} || preg_match('/^specimen/i',$original_file)) + if (empty($entity) || empty($conf->stock->multidir_output[$entity])) return array('accessallowed'=>0, 'error'=>'Value entity must be provided'); + if (($fuser->rights->stock->{$lire} || $fuser->rights->stock->movement->{$lire} || $fuser->rights->stock->mouvement->{$lire}) || preg_match('/^specimen/i', $original_file)) + { + $accessallowed=1; + } + if (! empty($conf->stock->enabled)) $original_file=$conf->stock->multidir_output[$entity].'/movement/'.$original_file; + } + + // Wrapping pour les contrats + elseif ($modulepart == 'contract' && !empty($conf->contrat->dir_output)) + { + if ($fuser->rights->contrat->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2677,9 +2766,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les dons - else if ($modulepart == 'donation' && !empty($conf->don->dir_output)) + elseif ($modulepart == 'donation' && !empty($conf->don->dir_output)) { - if ($fuser->rights->don->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->don->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2687,9 +2776,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les dons - else if ($modulepart == 'dolresource' && !empty($conf->resource->dir_output)) + elseif ($modulepart == 'dolresource' && !empty($conf->resource->dir_output)) { - if ($fuser->rights->resource->{$read} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->resource->{$read} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2697,9 +2786,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour les remises de cheques - else if ($modulepart == 'remisecheque' && !empty($conf->banque->dir_output)) + elseif ($modulepart == 'remisecheque' && !empty($conf->bank->dir_output)) { - if ($fuser->rights->banque->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->banque->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2708,7 +2797,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for bank - else if ($modulepart == 'bank' && !empty($conf->bank->dir_output)) + elseif (($modulepart == 'banque' || $modulepart == 'bank') && !empty($conf->bank->dir_output)) { if ($fuser->rights->banque->{$lire}) { @@ -2718,7 +2807,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for export module - else if ($modulepart == 'export' && !empty($conf->export->dir_temp)) + elseif ($modulepart == 'export' && !empty($conf->export->dir_temp)) { // Aucun test necessaire car on force le rep de download sur // le rep export qui est propre a l'utilisateur @@ -2727,35 +2816,35 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for import module - else if ($modulepart == 'import' && !empty($conf->import->dir_temp)) + elseif ($modulepart == 'import' && !empty($conf->import->dir_temp)) { $accessallowed=1; $original_file=$conf->import->dir_temp.'/'.$original_file; } // Wrapping pour l'editeur wysiwyg - else if ($modulepart == 'editor' && !empty($conf->fckeditor->dir_output)) + elseif ($modulepart == 'editor' && !empty($conf->fckeditor->dir_output)) { $accessallowed=1; $original_file=$conf->fckeditor->dir_output.'/'.$original_file; } // Wrapping for backups - else if ($modulepart == 'systemtools' && !empty($conf->admin->dir_output)) + elseif ($modulepart == 'systemtools' && !empty($conf->admin->dir_output)) { if ($fuser->admin) $accessallowed=1; $original_file=$conf->admin->dir_output.'/'.$original_file; } // Wrapping for upload file test - else if ($modulepart == 'admin_temp' && !empty($conf->admin->dir_temp)) + elseif ($modulepart == 'admin_temp' && !empty($conf->admin->dir_temp)) { if ($fuser->admin) $accessallowed=1; $original_file=$conf->admin->dir_temp.'/'.$original_file; } // Wrapping pour BitTorrent - else if ($modulepart == 'bittorrent' && !empty($conf->bittorrent->dir_output)) + elseif ($modulepart == 'bittorrent' && !empty($conf->bittorrent->dir_output)) { $accessallowed=1; $dir='files'; @@ -2764,9 +2853,9 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping pour Foundation module - else if ($modulepart == 'member' && !empty($conf->adherent->dir_output)) + elseif ($modulepart == 'member' && !empty($conf->adherent->dir_output)) { - if ($fuser->rights->adherent->{$lire} || preg_match('/^specimen/i',$original_file)) + if ($fuser->rights->adherent->{$lire} || preg_match('/^specimen/i', $original_file)) { $accessallowed=1; } @@ -2774,7 +2863,7 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, } // Wrapping for Scanner - else if ($modulepart == 'scanner_user_temp' && !empty($conf->scanner->dir_temp)) + elseif ($modulepart == 'scanner_user_temp' && !empty($conf->scanner->dir_temp)) { $accessallowed=1; $original_file=$conf->scanner->dir_temp.'/'.$fuser->id.'/'.$original_file; @@ -2787,45 +2876,58 @@ function dol_check_secure_access_document($modulepart, $original_file, $entity, // If modulepart=module Allows any module to open a file if file is in directory called DOL_DATA_ROOT/modulepart else { - if (preg_match('/^specimen/i',$original_file)) $accessallowed=1; // If link to a file called specimen. Test must be done before changing $original_file int full path. + if (preg_match('/^specimen/i', $original_file)) $accessallowed=1; // If link to a file called specimen. Test must be done before changing $original_file int full path. if ($fuser->admin) $accessallowed=1; // If user is admin // Define $accessallowed - if (preg_match('/^([a-z]+)_user_temp$/i',$modulepart,$reg)) + if (preg_match('/^([a-z]+)_user_temp$/i', $modulepart, $reg)) { if (empty($conf->{$reg[1]}->dir_temp)) // modulepart not supported { - dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + dol_print_error('', 'Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); exit; } if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1; $original_file=$conf->{$reg[1]}->dir_temp.'/'.$fuser->id.'/'.$original_file; } - else if (preg_match('/^([a-z]+)_temp$/i',$modulepart,$reg)) + elseif (preg_match('/^([a-z]+)_temp$/i', $modulepart, $reg)) { if (empty($conf->{$reg[1]}->dir_temp)) // modulepart not supported { - dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + dol_print_error('', 'Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); exit; } if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1; $original_file=$conf->{$reg[1]}->dir_temp.'/'.$original_file; } - else if (preg_match('/^([a-z]+)_user$/i',$modulepart,$reg)) + elseif (preg_match('/^([a-z]+)_user$/i', $modulepart, $reg)) { if (empty($conf->{$reg[1]}->dir_output)) // modulepart not supported { - dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + dol_print_error('', 'Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); exit; } if ($fuser->rights->{$reg[1]}->{$lire} || $fuser->rights->{$reg[1]}->{$read} || ($fuser->rights->{$reg[1]}->{$download})) $accessallowed=1; $original_file=$conf->{$reg[1]}->dir_output.'/'.$fuser->id.'/'.$original_file; } + elseif (preg_match('/^massfilesarea_([a-z]+)$/i', $modulepart, $reg)) + { + if (empty($conf->{$reg[1]}->dir_output)) // modulepart not supported + { + dol_print_error('', 'Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + exit; + } + if ($fuser->rights->{$reg[1]}->{$lire} || preg_match('/^specimen/i', $original_file)) + { + $accessallowed=1; + } + $original_file=$conf->{$reg[1]}->dir_output.'/temp/massgeneration/'.$user->id.'/'.$original_file; + } else { if (empty($conf->$modulepart->dir_output)) // modulepart not supported { - dol_print_error('','Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); + dol_print_error('', 'Error call dol_check_secure_access_document with not supported value for modulepart parameter ('.$modulepart.')'); exit; } @@ -2971,4 +3073,3 @@ function getFilesUpdated(&$file_list, SimpleXMLElement $dir, $path = '', $pathre return $file_list; } - From b1495e12ce4cec42eaca686bc30f12b5be70a869 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 30 Apr 2020 18:45:00 +0200 Subject: [PATCH 54/70] FIX A variable was erased by a temporary variable --- htdocs/compta/facture/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 934916fa31e..9fa696c69b3 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -4202,7 +4202,7 @@ elseif ($id > 0 || ! empty($ref)) $current_situation_counter = array(); foreach ($object->tab_previous_situation_invoice as $prev_invoice) { - $totalpaye = $prev_invoice->getSommePaiement(); + $tmptotalpaidforthisinvoice = $prev_invoice->getSommePaiement(); $total_prev_ht += $prev_invoice->total_ht; $total_prev_ttc += $prev_invoice->total_ttc; $current_situation_counter[] = (($prev_invoice->type == Facture::TYPE_CREDIT_NOTE)?-1:1) * $prev_invoice->situation_counter; @@ -4213,7 +4213,7 @@ elseif ($id > 0 || ! empty($ref)) if (! empty($conf->banque->enabled)) print ''; print '' . price($prev_invoice->total_ht) . ''; print '' . price($prev_invoice->total_ttc) . ''; - print '' . $prev_invoice->getLibStatut(3, $totalpaye) . ''; + print '' . $prev_invoice->getLibStatut(3, $tmptotalpaidforthisinvoice) . ''; print ''; } } From 1c7873b4f46f236c7cfed4fb280a897cb582e991 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 1 May 2020 15:53:56 +0200 Subject: [PATCH 55/70] FIX Sanitizing menu parameter --- htdocs/core/get_menudiv.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/get_menudiv.php b/htdocs/core/get_menudiv.php index edebf8a31b4..af64d065931 100644 --- a/htdocs/core/get_menudiv.php +++ b/htdocs/core/get_menudiv.php @@ -184,8 +184,8 @@ else // If external user } // Load the menu manager (only if not already done) -$file_menu=$conf->standard_menu; -if (GETPOST('menu')) $file_menu=GETPOST('menu'); // example: menu=eldy_menu.php +$file_menu = $conf->standard_menu; +if (GETPOST('menu', 'aZ09')) $file_menu = GETPOST('menu', 'aZ09'); // example: menu=eldy_menu.php if (! class_exists('MenuManager')) { $menufound=0; From 385f9982540dddf424c9eb35e4c62de0a435408c Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 1 May 2020 21:01:40 +0200 Subject: [PATCH 56/70] Fix restore param --quick --- htdocs/admin/tools/dolibarr_export.php | 8 ++++++++ htdocs/core/class/utils.class.php | 1 + 2 files changed, 9 insertions(+) diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index 0bef19dde56..ee8594e6bf8 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -244,6 +244,14 @@ print '';
+ + +
diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index 86eff6613c1..61fc845d7dc 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -262,6 +262,7 @@ class Utils if (GETPOST("disable_fk", "alpha") || $usedefault) $param.=" -K"; if (GETPOST("sql_compat", "alpha") && GETPOST("sql_compat", "alpha") != 'NONE') $param.=" --compatible=".escapeshellarg(GETPOST("sql_compat", "alpha")); if (GETPOST("drop_database", "alpha")) $param.=" --add-drop-database"; + if (GETPOST("use_mysql_quick_param", "alpha"))$param.=" --quick"; if (GETPOST("sql_structure", "alpha") || $usedefault) { if (GETPOST("drop", "alpha") || $usedefault) $param.=" --add-drop-table=TRUE"; From e0ebe85c134bebf41e794026af59b9b475648af7 Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Sun, 3 May 2020 09:15:12 +0200 Subject: [PATCH 57/70] Fix addline titles --- htdocs/core/tpl/objectline_create.tpl.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/core/tpl/objectline_create.tpl.php b/htdocs/core/tpl/objectline_create.tpl.php index 160d323a2c2..5e99146bc53 100644 --- a/htdocs/core/tpl/objectline_create.tpl.php +++ b/htdocs/core/tpl/objectline_create.tpl.php @@ -813,7 +813,7 @@ if (!empty($usemargins) && $user->rights->margins->creer) jQuery("#prod_entry_mode_free").prop('checked',true).change(); jQuery("#prod_entry_mode_predef").prop('checked',false).change(); jQuery("#search_idprod, #idprod, #search_idprodfournprice, #buying_price").val(''); - jQuery("#price_ht, #multicurrency_price_ht, #price_ttc, #price_ttc, #fourn_ref, #tva_tx, #buying_price, #title_vat, #title_up_ht, #title_up_ht_currency, #title_up_ttc, #title_up_ttc_currency").show(); + jQuery("#price_ht, #multicurrency_price_ht, #price_ttc, #price_ttc, #fourn_ref, #tva_tx, #buying_price, #title_fourn_ref, #title_vat, #title_up_ht, #title_up_ht_currency, #title_up_ttc, #title_up_ttc_currency").show(); jQuery("#np_marginRate, #np_markRate, .np_marginRate, .np_markRate, #units, #title_units").show(); jQuery("#fournprice_predef").hide(); } @@ -825,11 +825,13 @@ if (!empty($usemargins) && $user->rights->margins->creer) global->MAIN_DISABLE_EDIT_PREDEF_PRICEHT)) { ?> jQuery("#price_ht").val('').show(); jQuery("#multicurrency_price_ht").val('').show(); + jQuery("#title_up_ht, #title_up_ht_currency").show(); jQuery("#price_ht").val('').hide(); jQuery("#multicurrency_price_ht").val('').hide(); + jQuery("#title_up_ht, #title_up_ht_currency").hide(); - jQuery("#price_ttc, #fourn_ref, #tva_tx, #title_vat, #title_up_ht_currency, #title_up_ttc, #title_up_ttc_currency").hide(); + jQuery("#price_ttc, #fourn_ref, #tva_tx, #title_fourn_ref, #title_vat, #title_up_ttc, #title_up_ttc_currency").hide(); jQuery("#np_marginRate, #np_markRate, .np_marginRate, .np_markRate, #units, #title_units").hide(); jQuery("#buying_price").show(); jQuery('#trlinefordates, .divlinefordates').show(); From 6d894b7abd3bd0c7e47a4e98b817b9d954ca0f1b Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 4 May 2020 19:08:31 +0200 Subject: [PATCH 58/70] Fix missing link in message --- htdocs/core/class/notify.class.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index db0e490a6c6..6c0ec1ec62b 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -528,7 +528,7 @@ class Notify $message.= $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification2", $application, $mysoc->name)."\n"; $message.= "\n"; $message.= $mesg; - if ($link) $message.= "\n" . $urlwithroot . $link; + if ($link) $message.= "\n" . $urlwithroot . $link; // if link is already added around the ref into the translation text, then $link must be set to '' $parameters = array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list); if (!isset($action)) $action = ''; @@ -600,6 +600,7 @@ class Notify { foreach($conf->global as $key => $val) { + $reg = array(); if ($val == '' || ! preg_match('/^NOTIFICATION_FIXEDEMAIL_'.$notifcode.'_THRESHOLD_HIGHER_(.*)$/', $key, $reg)) continue; $threshold = (float) $reg[1]; @@ -743,7 +744,7 @@ class Notify $message.= $langs->transnoentities("YouReceiveMailBecauseOfNotification2", $application, $mysoc->name)."\n"; $message.= "\n"; $message.= $mesg; - //if ($link) $message.= "\n" . $urlwithroot . $link; // link already added around the ref into the text + if ($link) $message.= "\n" . $urlwithroot . $link; // if link is already added around the ref into the translation text, then $link must be set to '' $message = nl2br($message); From 2afd38e2f65c555579dd661dd728f15c98e0e3e0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Mon, 4 May 2020 21:59:31 +0200 Subject: [PATCH 59/70] FIX Combo list of available users to filter on the list of leaves. --- htdocs/core/class/html.form.class.php | 54 +++++++++++++-------------- htdocs/holiday/list.php | 8 ++-- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 39a006e0342..93061d200d8 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -1574,16 +1574,16 @@ class Form // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps /** - * Return select list of users + * Return the HTML select list of users * - * @param string $selected Id user preselected - * @param string $htmlname Field name in form - * @param int $show_empty 0=liste sans valeur nulle, 1=ajoute valeur inconnue - * @param array $exclude Array list of users id to exclude - * @param int $disabled If select list must be disabled - * @param array $include Array list of users id to include - * @param int $enableonly Array list of users id to be enabled. All other must be disabled - * @param string $force_entity '0' or Ids of environment to force + * @param string $selected Id user preselected + * @param string $htmlname Field name in form + * @param int $show_empty 0=liste sans valeur nulle, 1=ajoute valeur inconnue + * @param array $exclude Array list of users id to exclude + * @param int $disabled If select list must be disabled + * @param array|string $include Array list of users id to include. User '' for all users or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me + * @param int $enableonly Array list of users id to be enabled. All other must be disabled + * @param string $force_entity '0' or Ids of environment to force * @return void * @deprecated Use select_dolusers instead * @see select_dolusers() @@ -1598,24 +1598,24 @@ class Form /** * Return select list of users * - * @param string $selected User id or user object of user preselected. If 0 or < -2, we use id of current user. If -1, keep unselected (if empty is allowed) - * @param string $htmlname Field name in form - * @param int $show_empty 0=list with no empty value, 1=add also an empty value into list - * @param array $exclude Array list of users id to exclude - * @param int $disabled If select list must be disabled - * @param array|string $include Array list of users id to include or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me - * @param array $enableonly Array list of users id to be enabled. If defined, it means that others will be disabled - * @param string $force_entity '0' or Ids of environment to force - * @param int $maxlength Maximum length of string into list (0=no limit) - * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status - * @param string $morefilter Add more filters into sql request (Example: 'employee = 1') - * @param integer $show_every 0=default list, 1=add also a value "Everybody" at beginning of list - * @param string $enableonlytext If option $enableonlytext is set, we use this text to explain into label why record is disabled. Not used if enableonly is empty. - * @param string $morecss More css - * @param int $noactive Show only active users (this will also happened whatever is this option if USER_HIDE_INACTIVE_IN_COMBOBOX is on). - * @param int $outputmode 0=HTML select string, 1=Array - * @param bool $multiple add [] in the name of element and add 'multiple' attribut - * @return string HTML select string + * @param string $selected User id or user object of user preselected. If 0 or < -2, we use id of current user. If -1, keep unselected (if empty is allowed) + * @param string $htmlname Field name in form + * @param int $show_empty 0=list with no empty value, 1=add also an empty value into list + * @param array $exclude Array list of users id to exclude + * @param int $disabled If select list must be disabled + * @param array|string $include Array list of users id to include. User '' for all users or 'hierarchy' to have only supervised users or 'hierarchyme' to have supervised + me + * @param array $enableonly Array list of users id to be enabled. If defined, it means that others will be disabled + * @param string $force_entity '0' or Ids of environment to force + * @param int $maxlength Maximum length of string into list (0=no limit) + * @param int $showstatus 0=show user status only if status is disabled, 1=always show user status into label, -1=never show user status + * @param string $morefilter Add more filters into sql request (Example: 'employee = 1') + * @param integer $show_every 0=default list, 1=add also a value "Everybody" at beginning of list + * @param string $enableonlytext If option $enableonlytext is set, we use this text to explain into label why record is disabled. Not used if enableonly is empty. + * @param string $morecss More css + * @param int $noactive Show only active users (this will also happened whatever is this option if USER_HIDE_INACTIVE_IN_COMBOBOX is on). + * @param int $outputmode 0=HTML select string, 1=Array + * @param bool $multiple add [] in the name of element and add 'multiple' attribut + * @return string HTML select string * @see select_dolgroups() */ public function select_dolusers($selected = '', $htmlname = 'userid', $show_empty = 0, $exclude = null, $disabled = 0, $include = '', $enableonly = '', $force_entity = '0', $maxlength = 0, $showstatus = 0, $morefilter = '', $show_every = 0, $enableonlytext = '', $morecss = '', $noactive = 0, $outputmode = 0, $multiple = false) diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index 2361edf8a27..2277563aaa0 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -1,9 +1,9 @@ - * Copyright (C) 2013-2018 Laurent Destailleur + * Copyright (C) 2013-2020 Laurent Destailleur * Copyright (C) 2012-2016 Regis Houssin * Copyright (C) 2018 Charlene Benke - * Copyright (C) 2019 Frédéric France + * Copyright (C) 2019 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 @@ -476,7 +476,7 @@ if ($resql) $include = ''; - if (!empty($user->rights->holiday->read_all)) $include = 'hierarchyme'; // Can see all + if (empty($user->rights->holiday->read_all)) $include = 'hierarchyme'; // Can see only its hierarchyl print '
'; print ''."\n"; @@ -488,7 +488,7 @@ if ($resql) if (!empty($arrayfields['cp.ref']['checked'])) { print ''; } From c0b9fef22907d7cc747b28f142a345702e75ae79 Mon Sep 17 00:00:00 2001 From: Pierre Ardoin <32256817+mapiolca@users.noreply.github.com> Date: Tue, 5 May 2020 08:40:30 +0200 Subject: [PATCH 60/70] Fix issue in status name Before : $commandestatic->LibStatut($obj->nb) shows bad value because bad param Now : $commandestatic->LibStatut($obj->fk_statut) shows good value. --- htdocs/fourn/commande/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/commande/index.php b/htdocs/fourn/commande/index.php index 78d6c01679f..dd50efc7591 100644 --- a/htdocs/fourn/commande/index.php +++ b/htdocs/fourn/commande/index.php @@ -189,7 +189,7 @@ if ($resql) $obj = $db->fetch_object($resql); print ''; - print ''; + print ''; print ''; print "\n"; From c14b6884e3f71de24cd27dc4da3d1e0db04bb13d Mon Sep 17 00:00:00 2001 From: gauthier Date: Tue, 5 May 2020 10:02:36 +0200 Subject: [PATCH 61/70] FIX : missing hook init + table class + $page not set --- htdocs/compta/prelevement/bons.php | 1 + htdocs/compta/prelevement/list.php | 1 + htdocs/compta/prelevement/rejets.php | 4 +++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/prelevement/bons.php b/htdocs/compta/prelevement/bons.php index 2b67b73c95b..27654de1ad0 100644 --- a/htdocs/compta/prelevement/bons.php +++ b/htdocs/compta/prelevement/bons.php @@ -53,6 +53,7 @@ $search_ref = GETPOST('search_ref', 'alpha'); $search_amount = GETPOST('search_amount', 'alpha'); $bon=new BonPrelevement($db, ""); +$hookmanager->initHooks(array('withdrawalsreceiptslist')); /* diff --git a/htdocs/compta/prelevement/list.php b/htdocs/compta/prelevement/list.php index 81e58e19cca..eb741b981d9 100644 --- a/htdocs/compta/prelevement/list.php +++ b/htdocs/compta/prelevement/list.php @@ -56,6 +56,7 @@ $search_company = GETPOST('search_company', 'alpha'); $statut = GETPOST('statut', 'int'); $bon=new BonPrelevement($db, ""); +$hookmanager->initHooks(array('withdrawalsreceiptslineslist')); $ligne=new LignePrelevement($db, $user); diff --git a/htdocs/compta/prelevement/rejets.php b/htdocs/compta/prelevement/rejets.php index 333d07a4617..7611945a40d 100644 --- a/htdocs/compta/prelevement/rejets.php +++ b/htdocs/compta/prelevement/rejets.php @@ -40,6 +40,7 @@ $result = restrictedArea($user, 'prelevement', '', '', 'bons'); // Get supervariables $page = GETPOST('page', 'int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 $sortorder = GETPOST('sortorder', 'alpha'); $sortfield = GETPOST('sortfield', 'alpha'); @@ -57,6 +58,7 @@ if ($sortorder == "") $sortorder="DESC"; if ($sortfield == "") $sortfield="p.datec"; $rej = new RejetPrelevement($db, $user); +$hookmanager->initHooks(array('withdrawalsreceiptsrejectedlist')); $ligne = new LignePrelevement($db, $user); /* @@ -85,7 +87,7 @@ if ($result) print_barre_liste($langs->trans("WithdrawsRefused"), $page, $_SERVER["PHP_SELF"], $urladd, $sortfield, $sortorder, '', $num); print"\n\n"; - print '
'; - print ''; + print ''; print '
'.$commandestatic->LibStatut($obj->nb).''.$commandestatic->LibStatut($obj->fk_statut).''.$obj->nb.' '.$commandestatic->LibStatut($obj->fk_statut, 3).'
'; + print '
'; print ''; print_liste_field_titre("Line", $_SERVER["PHP_SELF"], "p.ref", '', $urladd); print_liste_field_titre("ThirdParty", $_SERVER["PHP_SELF"], "s.nom", '', $urladd); From 78a427c9967a398e0fd8d3aaeaa4c1b723a487db Mon Sep 17 00:00:00 2001 From: atm-lena Date: Tue, 5 May 2020 14:35:03 +0200 Subject: [PATCH 62/70] FIX wrong user right's name to top menu "commercial" --- htdocs/core/menus/standard/eldy.lib.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 84555ba23cf..f1859c0fcc5 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -234,7 +234,7 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = ) ? 1 : 0, 'perms'=>(!empty($user->rights->propal->lire) || !empty($user->rights->commande->lire) || - !empty($user->rights->supplier_order->lire) || + !empty($user->rights->fournisseur->lire) || !empty($user->rights->supplier_proposal->lire) || !empty($user->rights->contrat->lire) || !empty($user->rights->ficheinter->lire) From 36a0780f148c684e3172a689e2d8e550d0473b52 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 5 May 2020 15:20:40 +0200 Subject: [PATCH 63/70] More complete fix for #13817 --- htdocs/core/menus/standard/eldy.lib.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index f1859c0fcc5..17edca45676 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -227,19 +227,21 @@ function print_eldy_menu($db, $atarget, $type_user, &$tabMenu, &$menu, $noout = $tmpentry = array( 'enabled'=>(!empty($conf->propal->enabled) || !empty($conf->commande->enabled) || - !empty($conf->supplier_order->enabled) || - !empty($conf->supplier_proposal->enabled) || - !empty($conf->contrat->enabled) || + !empty($conf->fournisseur->enabled) || + !empty($conf->supplier_proposal->enabled) || + !empty($conf->supplier_order->enabled) || + !empty($conf->contrat->enabled) || !empty($conf->ficheinter->enabled) ) ? 1 : 0, 'perms'=>(!empty($user->rights->propal->lire) || !empty($user->rights->commande->lire) || !empty($user->rights->fournisseur->lire) || !empty($user->rights->supplier_proposal->lire) || + !empty($user->rights->supplier_order->lire) || !empty($user->rights->contrat->lire) || !empty($user->rights->ficheinter->lire) ), - 'module'=>'propal|commande|supplier_order|supplier_proposal|contrat|ficheinter' + 'module'=>'propal|commande|supplier_proposal|supplier_order|contrat|ficheinter' ); $onlysupplierorder = ! empty($user->rights->fournisseur->commande->lire) && From fa305fdaca1b7b32e51c8f80233693a2625eec4e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 5 May 2020 21:49:46 +0200 Subject: [PATCH 64/70] Prepare version 11.0.4 --- ChangeLog | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/ChangeLog b/ChangeLog index 3b81e0555d5..a7d0282fba5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,84 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 11.0.4 compared to 11.0.3 ***** +FIX: #13749 +FIX: #7594 +FIX: #7594 Expense report multi pagebreak +FIX: Access to undeclared static property: Contact::$table_element +FIX: actions on supplier proposal not saved (bad trigger name) +FIX: Add function "completeTabsHead" to "addreplace" type hook. +FIX: All forms must use newToken() +FIX: Another "Access to undeclared static property: Contact::$table_element" && "Societe::$table_element" +FIX: author search supplier proposal list +FIX: A variable was erased by a temporary variable +FIX: Avoid infinite loop when a fetch is inside a compute field. +FIX: Backto link +FIX: Bad position of total in column +FIX: bad value in currency into discount created from down payment +FIX: buyprice extrafield langfile and tooltip +FIX: Buyprice was updated only if min price for this qty had same qty +FIX: Can switch from double to price type for extrafields +FIX: Can use decimal value in virtual products +FIX: child categories only with good entity rights +FIX: cloning of emailing when no content selected +FIX: closing tags +FIX: Combo list of available users to filter on the list of leaves. +FIX: Compatibility with multicompany, bad numerotation of task. +FIX: consistency of price w/wo vat wrong when price entered with tax +FIX: default value of selectMasssAction broken +FIX: draftordered replenish virtual stock +FIX: Error update SQL into stock reception +FIX: expensereport status in generated pdf +FIX: extra date field incorrect check +FIX: Extrafields of type price must be '' and not '0' if not defined +FIX: Foreign currency lost when splitting a discount +FIX: get remain to pay with rounding decimals +FIX: gzip and bzip2 must use option -f +FIX: IHM, unexpected quote +FIX: keep viewstatut for doli 3.5 +FIX: Link missing into email of some notification +FIX: Look and feel v11 +FIX: md stylesheet to be included by external modules like eldy +FIX: missing array option +FIX: missing default accountancy product buy code +FIX: missing fk_bank during export of suppliers invoices +FIX: missing member entity +FIX: missing selectedlines on supplier order but checkbox are displayed +FIX: Missing token and take into account max date when it can. +FIX: model export list must be sorted by label +FIX: multicurrency manage on hidden conf SUPPLIER_PROPOSAL_UPDATE_PRICE_ON_SUPPlIER_PROPOSAL +FIX: Must escape shell +FIX: Must exclude logs and some dirs for compressed backup +FIX: ordered stock already in $stock +FIX: picture migration script from doli 9.0 +FIX: print pictures on shipment docs +FIX: product get purchase prices +FIX: product purchase prices +FIX: Protection when database has a corrupted product id +FIX: remove unused var, $usercancreate can be change by Multicompany +FIX: replenish stock to buy +FIX: Sanitizing menu parameter +FIX: Send email from bulk action of list of thirdparties +FIX: setup of suggested payment mode on proposals and orders +FIX: Several pb in export of documents +FIX: Situation invoice take into account the credit notes. +FIX: some others modules (like subtotal) use other product_type than 0 or 1 AND must not be considered in this report +FIX: sort by default role makes no sense +FIX: sort on company on member list +FIX: TakePOS buying price +FIX: text version of html emailing (removed the body style) +FIX: The "test smtp connectivity" failed on page to setup mass emailing +FIX: Error logs an Orderline::delete error, but this is an Orderline::insert error +FIX: Translation of tooltips of extrafields +FIX: Use getNomURL instead of hard coded link. Fix limit. +FIX: Use of image into free text for PDF if DOL_DATA_DIR is outside of +FIX: viewstatut to search status +FIX: we must export company mail address on contact vcard only if contact email address is empty +FIX: when we filter a list on a view status, we want this filter to be on bookmark that we create +FIX: Wrong Sql on getListOfTowns api method +FIX: wrong user right's name to top menu "commercial" +FIX: XSS Vulnerability ***** ChangeLog for 11.0.3 compared to 11.0.2 ***** FIX: unit price for selected supplier products not set. NaN was used. From d9cef1c8d79ac971641fc4304355f5cb44d5b5f3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 6 May 2020 01:49:19 +0200 Subject: [PATCH 65/70] Fix packager to publish on new web site --- build/makepack-dolibarr.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index c6b8cd330c8..933c5b8f994 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -19,7 +19,7 @@ use Term::ANSIColor; # Change this to defined target for option 98 and 99 $PROJECT="dolibarr"; $PUBLISHSTABLE="eldy,dolibarr\@frs.sourceforge.net:/home/frs/project/dolibarr"; -$PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/dolibarr.org/httpdocs/files"; +$PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/asso.dolibarr.org/dolibarr_documents/website/www.dolibarr.org/files"; #@LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","EXEDOLIWAMP","SNAPSHOT"); # Possible packages From b3a064d309e2533c911bbf45f246f98309a1e2b8 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 6 May 2020 16:02:34 +0200 Subject: [PATCH 66/70] Fix dup --- ChangeLog | 1 - 1 file changed, 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index a7d0282fba5..bcbfb1a959c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,6 @@ English Dolibarr ChangeLog ***** ChangeLog for 11.0.4 compared to 11.0.3 ***** FIX: #13749 -FIX: #7594 FIX: #7594 Expense report multi pagebreak FIX: Access to undeclared static property: Contact::$table_element FIX: actions on supplier proposal not saved (bad trigger name) From d4400cf80fce889f4836338ca40a8bff0080ee2e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 May 2020 11:39:32 +0200 Subject: [PATCH 67/70] FIX links into emails of notifications --- htdocs/core/class/notify.class.php | 56 ++++++++++++++---------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/htdocs/core/class/notify.class.php b/htdocs/core/class/notify.class.php index 6c0ec1ec62b..8a03196beef 100644 --- a/htdocs/core/class/notify.class.php +++ b/htdocs/core/class/notify.class.php @@ -416,34 +416,34 @@ class Notify switch ($notifcode) { case 'BILL_VALIDATE': - $link='/compta/facture/card.php?facid='.$object->id; + $link = '' . $newref . ''; $dir_output = $conf->facture->dir_output; $object_type = 'facture'; - $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoiceValidated", $newref); + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoiceValidated", $link); break; case 'BILL_PAYED': - $link='/compta/facture/card.php?facid='.$object->id; + $link ='' . $newref . ''; $dir_output = $conf->facture->dir_output; $object_type = 'facture'; - $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoicePayed", $newref); + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInvoicePayed", $link); break; case 'ORDER_VALIDATE': - $link='/commande/card.php?id='.$object->id; + $link = '' . $newref . ''; $dir_output = $conf->commande->dir_output; $object_type = 'order'; - $mesg = $outputlangs->transnoentitiesnoconv("EMailTextOrderValidated", $newref); + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextOrderValidated", $link); break; case 'PROPAL_VALIDATE': - $link='/comm/propal/card.php?id='.$object->id; + $link = '' . $newref . ''; $dir_output = $conf->propal->multidir_output[$object->entity]; $object_type = 'propal'; - $mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalValidated", $newref); + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalValidated", $link); break; case 'PROPAL_CLOSE_SIGNED': - $link='/comm/propal/card.php?id='.$object->id; + $link = '' . $newref . ''; $dir_output = $conf->propal->multidir_output[$object->entity]; $object_type = 'propal'; - $mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedSigned", $newref); + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextProposalClosedSigned", $link); break; case 'FICHINTER_ADD_CONTACT': $link='/fichinter/card.php?id='.$object->id; @@ -452,17 +452,17 @@ class Notify $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionAddedContact", $newref); break; case 'FICHINTER_VALIDATE': - $link='/fichinter/card.php?id='.$object->id; + $link = '' . $newref . ''; $dir_output = $conf->ficheinter->dir_output; $object_type = 'ficheinter'; - $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionValidated", $newref); + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextInterventionValidated", $link); break; case 'ORDER_SUPPLIER_VALIDATE': $link='/fourn/commande/card.php?id='.$object->id; $dir_output = $conf->fournisseur->commande->dir_output; $object_type = 'order_supplier'; $mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n"; - $mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderValidatedBy", $newref, $user->getFullName($outputlangs)); + $mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderValidatedBy", $link, $user->getFullName($outputlangs)); $mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n"; break; case 'ORDER_SUPPLIER_APPROVE': @@ -470,46 +470,46 @@ class Notify $dir_output = $conf->fournisseur->commande->dir_output; $object_type = 'order_supplier'; $mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n"; - $mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderApprovedBy", $newref, $user->getFullName($outputlangs)); + $mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderApprovedBy", $link, $user->getFullName($outputlangs)); $mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n"; break; case 'ORDER_SUPPLIER_REFUSE': - $link='/fourn/commande/card.php?id='.$object->id; + $link = '' . $newref . ''; $dir_output = $conf->fournisseur->commande->dir_output; $object_type = 'order_supplier'; $mesg = $outputlangs->transnoentitiesnoconv("Hello").",\n\n"; - $mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderRefusedBy", $newref, $user->getFullName($outputlangs)); + $mesg.= $outputlangs->transnoentitiesnoconv("EMailTextOrderRefusedBy", $link, $user->getFullName($outputlangs)); $mesg.= "\n\n".$outputlangs->transnoentitiesnoconv("Sincerely").".\n\n"; break; case 'SHIPPING_VALIDATE': $link = ''.$newref.''; $dir_output = $conf->expedition->dir_output.'/sending/'; $object_type = 'expedition'; - $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpeditionValidated", $newref); + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpeditionValidated", $link); break; case 'EXPENSE_REPORT_VALIDATE': $link = ''.$newref.''; $dir_output = $conf->expensereport->dir_output; $object_type = 'expensereport'; - $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportValidated", $newref); + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportValidated", $link); break; case 'EXPENSE_REPORT_APPROVE': $link = ''.$newref.''; $dir_output = $conf->expensereport->dir_output; $object_type = 'expensereport'; - $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportApproved", $newref); + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextExpenseReportApproved", $link); break; case 'HOLIDAY_VALIDATE': $link = ''.$newref.''; $dir_output = $conf->holiday->dir_output; $object_type = 'holiday'; - $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayValidated", $newref); + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayValidated", $link); break; case 'HOLIDAY_APPROVE': $link = ''.$newref.''; $dir_output = $conf->holiday->dir_output; $object_type = 'holiday'; - $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayApproved", $newref); + $mesg = $outputlangs->transnoentitiesnoconv("EMailTextHolidayApproved", $link); break; } $ref = dol_sanitizeFileName($newref); @@ -528,7 +528,6 @@ class Notify $message.= $outputlangs->transnoentities("YouReceiveMailBecauseOfNotification2", $application, $mysoc->name)."\n"; $message.= "\n"; $message.= $mesg; - if ($link) $message.= "\n" . $urlwithroot . $link; // if link is already added around the ref into the translation text, then $link must be set to '' $parameters = array('notifcode'=>$notifcode, 'sendto'=>$sendto, 'replyto'=>$replyto, 'file'=>$filename_list, 'mimefile'=>$mimetype_list, 'filename'=>$mimefilename_list); if (!isset($action)) $action = ''; @@ -655,7 +654,7 @@ class Notify break; case 'FICHINTER_ADD_CONTACT': $link = '' . $newref . ''; - $dir_output = $conf->facture->dir_output; + $dir_output = $conf->ficheinter->dir_output; $object_type = 'ficheinter'; $mesg = $langs->transnoentitiesnoconv("EMailTextInterventionAddedContact", $link); break; @@ -701,31 +700,31 @@ class Notify $link = ''.$newref.''; $dir_output = $conf->expedition->dir_output.'/sending/'; $object_type = 'order_supplier'; - $mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated", $newref); + $mesg = $langs->transnoentitiesnoconv("EMailTextExpeditionValidated", $link); break; case 'EXPENSE_REPORT_VALIDATE': $link = ''.$newref.''; $dir_output = $conf->expensereport->dir_output; $object_type = 'expensereport'; - $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportValidated", $newref); + $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportValidated", $link); break; case 'EXPENSE_REPORT_APPROVE': $link = ''.$newref.''; $dir_output = $conf->expensereport->dir_output; $object_type = 'expensereport'; - $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportApproved", $newref); + $mesg = $langs->transnoentitiesnoconv("EMailTextExpenseReportApproved", $link); break; case 'HOLIDAY_VALIDATE': $link = ''.$newref.''; $dir_output = $conf->holiday->dir_output; $object_type = 'holiday'; - $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayValidated", $newref); + $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayValidated", $link); break; case 'HOLIDAY_APPROVE': $link = ''.$newref.''; $dir_output = $conf->holiday->dir_output; $object_type = 'holiday'; - $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayApproved", $newref); + $mesg = $langs->transnoentitiesnoconv("EMailTextHolidayApproved", $link); break; } $ref = dol_sanitizeFileName($newref); @@ -744,7 +743,6 @@ class Notify $message.= $langs->transnoentities("YouReceiveMailBecauseOfNotification2", $application, $mysoc->name)."\n"; $message.= "\n"; $message.= $mesg; - if ($link) $message.= "\n" . $urlwithroot . $link; // if link is already added around the ref into the translation text, then $link must be set to '' $message = nl2br($message); From 0cd05887ce95de5496924a941a92f31155a0ed2e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Thu, 7 May 2020 17:21:27 +0200 Subject: [PATCH 68/70] FIX count of open day when date and start are not open should be 0 --- htdocs/core/lib/date.lib.php | 10 +++++++++- htdocs/holiday/card.php | 4 +++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 123e3297f11..56dfee3988c 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -896,15 +896,23 @@ function num_open_day($timestampStart, $timestampEnd, $inhour = 0, $lastday = 0, if ($timestampStart < $timestampEnd) { $numdays = num_between_day($timestampStart, $timestampEnd, $lastday); + $numholidays = num_public_holiday($timestampStart, $timestampEnd, $country_code, $lastday); $nbOpenDay = $numdays - $numholidays; - $nbOpenDay.= " " . $langs->trans("Days"); + $nbOpenDay.= ' '.$langs->trans("Days"); if ($inhour == 1 && $nbOpenDay <= 3) $nbOpenDay = $nbOpenDay*24 . $langs->trans("HourShort"); return $nbOpenDay - (($inhour == 1 ? 12 : 0.5) * abs($halfday)); } elseif ($timestampStart == $timestampEnd) { + $numholidays = 0; + if ($lastday) { + $numholidays = num_public_holiday($timestampStart, $timestampEnd, $country_code, $lastday); + if ($numholidays == 1) return 0; + } + $nbOpenDay=$lastday; + if ($inhour == 1) $nbOpenDay = $nbOpenDay*24 . $langs->trans("HourShort"); return $nbOpenDay - (($inhour == 1 ? 12 : 0.5) * abs($halfday)); } diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index 9cc287cd28a..6dd218255e5 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -1291,7 +1291,9 @@ else if ($includesunday) $htmlhelp.='
'.$langs->trans("DayIsANonWorkingDay", $langs->trans("Sunday")); print $form->textwithpicto($langs->trans('NbUseDaysCP'), $htmlhelp); print ''; - print '
'; + print ''; print ''; if ($object->statut == Holiday::STATUS_REFUSED) From d9a0edcf2b83aa9e9f6e35fefa8e740f1c36ab14 Mon Sep 17 00:00:00 2001 From: Regis Houssin Date: Fri, 8 May 2020 00:01:56 +0200 Subject: [PATCH 69/70] FIX missing file manifest.json.php --- htdocs/theme/md/manifest.json.php | 57 +++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 htdocs/theme/md/manifest.json.php diff --git a/htdocs/theme/md/manifest.json.php b/htdocs/theme/md/manifest.json.php new file mode 100644 index 00000000000..f8d059752a6 --- /dev/null +++ b/htdocs/theme/md/manifest.json.php @@ -0,0 +1,57 @@ + + * Copyright (C) 2006 Rodolphe Quiedeville + * Copyright (C) 2007-2017 Regis Houssin + * Copyright (C) 2011 Philippe Grand + * Copyright (C) 2012 Juanjo Menent + * Copyright (C) 2018 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FI8TNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/theme/md/manifest.json.php + * \brief File for The Web App + */ + +if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); +if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); +if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); +if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1'); +if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1'); +if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); +if (! defined('NOLOGIN')) define('NOLOGIN', '1'); +if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', '1'); +if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', '1'); +if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1'); + +require_once __DIR__.'/../../main.inc.php'; + +$appli=constant('DOL_APPLICATION_TITLE'); +if (!empty($conf->global->MAIN_APPLICATION_TITLE)) $appli=$conf->global->MAIN_APPLICATION_TITLE; + +?> +{ + "name": "", + "icons": [ + { + "src": "", + "sizes": "256x256", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} \ No newline at end of file From 1a9afe6b203b1224ae0e4a641dcefe3c2073eb0a Mon Sep 17 00:00:00 2001 From: Maxime Kohlhaas Date: Fri, 8 May 2020 01:40:25 +0200 Subject: [PATCH 70/70] Fix missing hook params for printFieldListValue --- htdocs/accountancy/bookkeeping/list.php | 2 +- htdocs/adherents/list.php | 2 +- htdocs/adherents/subscription/list.php | 2 +- htdocs/admin/emailcollector_list.php | 2 +- htdocs/asset/list.php | 2 +- htdocs/comm/action/list.php | 2 +- htdocs/comm/propal/list.php | 2 +- htdocs/commande/list.php | 2 +- htdocs/compta/bank/list.php | 2 +- htdocs/compta/cashcontrol/cashcontrol_list.php | 2 +- htdocs/compta/facture/list.php | 2 +- htdocs/contact/list.php | 2 +- htdocs/contrat/list.php | 2 +- htdocs/contrat/services_list.php | 2 +- htdocs/expedition/list.php | 2 +- htdocs/expensereport/list.php | 2 +- htdocs/fichinter/list.php | 2 +- htdocs/fourn/facture/list.php | 2 +- htdocs/holiday/list.php | 2 +- htdocs/product/list.php | 2 +- htdocs/product/stock/list.php | 2 +- htdocs/product/stock/productlot_list.php | 2 +- htdocs/projet/list.php | 2 +- htdocs/projet/tasks/list.php | 2 +- htdocs/projet/tasks/time.php | 2 +- htdocs/reception/list.php | 2 +- htdocs/societe/list.php | 2 +- htdocs/societe/website.php | 2 +- htdocs/supplier_proposal/list.php | 2 +- htdocs/ticket/list.php | 2 +- htdocs/user/list.php | 2 +- htdocs/zapier/hook_list.php | 2 +- 32 files changed, 32 insertions(+), 32 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/list.php b/htdocs/accountancy/bookkeeping/list.php index d8fe9975da5..129fedf3867 100644 --- a/htdocs/accountancy/bookkeeping/list.php +++ b/htdocs/accountancy/bookkeeping/list.php @@ -966,7 +966,7 @@ while ($i < min($num, $limit)) } // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index c9b7ee42fcf..838e7cd9a5c 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -872,7 +872,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index a582584ae7f..fa47d01cd41 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -524,7 +524,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/admin/emailcollector_list.php b/htdocs/admin/emailcollector_list.php index 53d9fd8d1f1..9c76c176414 100644 --- a/htdocs/admin/emailcollector_list.php +++ b/htdocs/admin/emailcollector_list.php @@ -479,7 +479,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column diff --git a/htdocs/asset/list.php b/htdocs/asset/list.php index fb8c4066a10..ae307bf1a42 100644 --- a/htdocs/asset/list.php +++ b/htdocs/asset/list.php @@ -459,7 +459,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column diff --git a/htdocs/comm/action/list.php b/htdocs/comm/action/list.php index 95a3e6dbe09..410d31fb07e 100644 --- a/htdocs/comm/action/list.php +++ b/htdocs/comm/action/list.php @@ -718,7 +718,7 @@ if ($resql) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; diff --git a/htdocs/comm/propal/list.php b/htdocs/comm/propal/list.php index dcc9c7a54c7..eaeea9e3d43 100644 --- a/htdocs/comm/propal/list.php +++ b/htdocs/comm/propal/list.php @@ -1065,7 +1065,7 @@ if ($resql) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index e2b6aa06136..8a023cf7e80 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -1075,7 +1075,7 @@ if ($resql) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/compta/bank/list.php b/htdocs/compta/bank/list.php index e0d7f7d5c29..ac2caaf94eb 100644 --- a/htdocs/compta/bank/list.php +++ b/htdocs/compta/bank/list.php @@ -529,7 +529,7 @@ foreach ($accounts as $key=>$type) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters=array('arrayfields'=>$arrayfields); + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters, $objecttmp); // Note that $action and $objecttmpect may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/compta/cashcontrol/cashcontrol_list.php b/htdocs/compta/cashcontrol/cashcontrol_list.php index 6c59276d600..c13528224c4 100644 --- a/htdocs/compta/cashcontrol/cashcontrol_list.php +++ b/htdocs/compta/cashcontrol/cashcontrol_list.php @@ -496,7 +496,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index f5ab943d831..c3bfe93bf30 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -1313,7 +1313,7 @@ if ($resql) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 9903e37cd5e..d51399d21a9 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -936,7 +936,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/contrat/list.php b/htdocs/contrat/list.php index c32e45c1b42..857f9609d36 100644 --- a/htdocs/contrat/list.php +++ b/htdocs/contrat/list.php @@ -744,7 +744,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/contrat/services_list.php b/htdocs/contrat/services_list.php index 29501ddee88..85579d65980 100644 --- a/htdocs/contrat/services_list.php +++ b/htdocs/contrat/services_list.php @@ -687,7 +687,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index d5cda3e2ebb..c3db317c9de 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -591,7 +591,7 @@ if ($resql) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index 5604ee77dc3..7f5e86d9c98 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -761,7 +761,7 @@ if ($resql) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 03000bdb44d..fd45d2daecb 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -562,7 +562,7 @@ if ($resql) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index b895bf63513..ddb2ce853b1 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -1058,7 +1058,7 @@ if ($resql) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index 2277563aaa0..18df214f4c6 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -744,7 +744,7 @@ if ($resql) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; diff --git a/htdocs/product/list.php b/htdocs/product/list.php index ce3f8f1cd81..cc12bc73349 100644 --- a/htdocs/product/list.php +++ b/htdocs/product/list.php @@ -1148,7 +1148,7 @@ if ($resql) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/product/stock/list.php b/htdocs/product/stock/list.php index e4ad265c793..057735c49cc 100644 --- a/htdocs/product/stock/list.php +++ b/htdocs/product/stock/list.php @@ -571,7 +571,7 @@ if ($num) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; diff --git a/htdocs/product/stock/productlot_list.php b/htdocs/product/stock/productlot_list.php index 527afee2607..154ede71956 100644 --- a/htdocs/product/stock/productlot_list.php +++ b/htdocs/product/stock/productlot_list.php @@ -476,7 +476,7 @@ if ($resql) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/projet/list.php b/htdocs/projet/list.php index 650c14c5ee2..f3a8900a148 100644 --- a/htdocs/projet/list.php +++ b/htdocs/projet/list.php @@ -895,7 +895,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 3fd85f4082e..7d995965294 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -836,7 +836,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/projet/tasks/time.php b/htdocs/projet/tasks/time.php index f9069f7efa7..3a5e3c89ae3 100644 --- a/htdocs/projet/tasks/time.php +++ b/htdocs/projet/tasks/time.php @@ -1332,7 +1332,7 @@ if (($id > 0 || !empty($ref)) || $projectidforalltimes > 0) */ // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$task_time); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$task_time, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; diff --git a/htdocs/reception/list.php b/htdocs/reception/list.php index fea2662b93f..7566edfc610 100644 --- a/htdocs/reception/list.php +++ b/htdocs/reception/list.php @@ -885,7 +885,7 @@ if ($resql) include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/societe/list.php b/htdocs/societe/list.php index e480d68eca4..4e033e5f35e 100644 --- a/htdocs/societe/list.php +++ b/htdocs/societe/list.php @@ -1279,7 +1279,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/societe/website.php b/htdocs/societe/website.php index 5d248ec16fd..d5e89459771 100644 --- a/htdocs/societe/website.php +++ b/htdocs/societe/website.php @@ -481,7 +481,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $objectwebsiteaccount); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column diff --git a/htdocs/supplier_proposal/list.php b/htdocs/supplier_proposal/list.php index a133d781337..91ef70c7b94 100644 --- a/htdocs/supplier_proposal/list.php +++ b/htdocs/supplier_proposal/list.php @@ -779,7 +779,7 @@ if ($resql) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/ticket/list.php b/htdocs/ticket/list.php index 8d76ef5c5eb..08419e5c46d 100644 --- a/htdocs/ticket/list.php +++ b/htdocs/ticket/list.php @@ -669,7 +669,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column diff --git a/htdocs/user/list.php b/htdocs/user/list.php index eb14f61e982..1ceec68a622 100644 --- a/htdocs/user/list.php +++ b/htdocs/user/list.php @@ -655,7 +655,7 @@ while ($i < min($num, $limit)) // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation diff --git a/htdocs/zapier/hook_list.php b/htdocs/zapier/hook_list.php index 56a68ad7300..dbd9239e752 100644 --- a/htdocs/zapier/hook_list.php +++ b/htdocs/zapier/hook_list.php @@ -519,7 +519,7 @@ while ($i < min($num, $limit)) { // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook - $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $parameters = array('arrayfields'=>$arrayfields, 'obj'=>$obj, 'i'=>$i, 'totalarray'=>&$totalarray); $reshook = $hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Action column
'.num_open_day($object->date_debut_gmt, $object->date_fin_gmt, 0, 1, $object->halfday).''; + print num_open_day($object->date_debut_gmt, $object->date_fin_gmt, 0, 1, $object->halfday); + print '