From 232f20100706b9d93c5e081f670d7daf44b892fd Mon Sep 17 00:00:00 2001 From: Francis Appels Date: Sun, 23 Feb 2020 17:02:08 +0100 Subject: [PATCH 001/196] Merge remote-tracking branch 'Dolibarr/11.0' into 11 --- htdocs/compta/facture/class/facture.class.php | 9 +++++++++ htdocs/core/lib/pdf.lib.php | 2 +- htdocs/cron/class/cronjob.class.php | 4 ++-- .../framework/Luracast/Restler/AutoLoader.php | 8 +------- .../framework/Luracast/Restler/CommentParser.php | 12 ++++++------ .../framework/Luracast/Restler/Format/XmlFormat.php | 2 +- .../restler/framework/Luracast/Restler/Resources.php | 6 +++--- .../restler/framework/Luracast/Restler/Restler.php | 4 ++-- .../restler/framework/Luracast/Restler/Routes.php | 6 +++--- .../restler/framework/Luracast/Restler/Scope.php | 2 +- .../restler/framework/Luracast/Restler/UI/Emmet.php | 4 ++-- htdocs/projet/element.php | 2 +- htdocs/theme/eldy/global.inc.php | 2 +- 13 files changed, 33 insertions(+), 30 deletions(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index d4a7efd3cf4..99cc638c36f 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -1156,6 +1156,14 @@ class Facture extends CommonInvoice $line->date_start = $object->lines[$i]->date_start; $line->date_end = $object->lines[$i]->date_end; + // Multicurrency + $line->fk_multicurrency = $object->lines[$i]->fk_multicurrency; + $line->multicurrency_code = $object->lines[$i]->multicurrency_code; + $line->multicurrency_subprice = $object->lines[$i]->multicurrency_subprice; + $line->multicurrency_total_ht = $object->lines[$i]->multicurrency_total_ht; + $line->multicurrency_total_tva = $object->lines[$i]->multicurrency_total_tva; + $line->multicurrency_total_ttc = $object->lines[$i]->multicurrency_total_ttc; + $line->fk_fournprice = $object->lines[$i]->fk_fournprice; $marginInfos = getMarginInfos($object->lines[$i]->subprice, $object->lines[$i]->remise_percent, $object->lines[$i]->tva_tx, $object->lines[$i]->localtax1_tx, $object->lines[$i]->localtax2_tx, $object->lines[$i]->fk_fournprice, $object->lines[$i]->pa_ht); $line->pa_ht = $marginInfos[0]; @@ -1170,6 +1178,7 @@ class Facture extends CommonInvoice $this->socid = $object->socid; $this->fk_project = $object->fk_project; + $this->fk_account = $object->fk_account; $this->cond_reglement_id = $object->cond_reglement_id; $this->mode_reglement_id = $object->mode_reglement_id; $this->availability_id = $object->availability_id; diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index a5ba08bb139..59035258c74 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -1401,7 +1401,7 @@ function pdf_getlinedesc($object, $i, $outputlangs, $hideref = 0, $hidedesc = 0, foreach ($tblcateg as $cate) { // Adding the descriptions if they are filled - $desccateg = $cate->add_description; + $desccateg = $cate->description; if ($desccateg) $libelleproduitservice .= '__N__'.$desccateg; } diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 5cde792bbb5..6139f157f8a 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1320,9 +1320,9 @@ class Cronjob extends CommonObject if ($processing) $moretext = ' ('.$langs->trans("Running").')'; elseif ($lastresult) $moretext .= ' ('.$langs->trans("Error").')'; - $this->labelStatus[self::STATUS_DISABLED] = $langs->trans('Draft').$moretext; + $this->labelStatus[self::STATUS_DISABLED] = $langs->trans('Disabled').$moretext; $this->labelStatus[self::STATUS_ENABLED] = $langs->trans('Enabled').$moretext; - $this->labelStatusShort[self::STATUS_DISABLED] = $langs->trans('Draft'); + $this->labelStatusShort[self::STATUS_DISABLED] = $langs->trans('Disabled'); $this->labelStatusShort[self::STATUS_ENABLED] = $langs->trans('Enabled'); } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php index eff8bb61f29..d8445fdc70c 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php @@ -263,13 +263,7 @@ class AutoLoader * @return bool false unless className now exists */ private function loadLastResort($className, $loader = null) { - // @CHANGE LDR Add protection to avoid conflict with other autoloader - /*print 'Try to load '.$className."\n"; - if (in_array($className, array('Google_Client'))) - { - return false; - }*/ - $loaders = array_unique(static::$rogueLoaders); + $loaders = array_unique(static::$rogueLoaders); if (isset($loader)) { if (false === array_search($loader, $loaders)) static::$rogueLoaders[] = $loader; diff --git a/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php b/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php index e8248a385fa..2815f1f6c70 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php @@ -159,7 +159,7 @@ class CommentParser $addNewline = true; } continue; - } elseif ($line{0} == '@') { + } elseif ($line[0] == '@') { $mode = 2; $newParam = true; } @@ -353,7 +353,7 @@ class CommentParser $data = $format->decode($str); } } else { // auto detect - if ($str{0} == '{') { + if ($str[0] == '{') { $d = json_decode($str, true); if (json_last_error() != JSON_ERROR_NONE) { throw new Exception('Error parsing embedded JSON data' @@ -445,7 +445,7 @@ class CommentParser { $r = array(); $email = end($value); - if ($email{0} == '<') { + if ($email[0] == '<') { $email = substr($email, 1, -1); array_pop($value); $r['email'] = $email; @@ -470,7 +470,7 @@ class CommentParser $data = array_shift($value); if (empty($data)) { $r['type'] = 'mixed'; - } elseif ($data{0} == '$') { + } elseif ($data[0] == '$') { $r['name'] = substr($data, 1); $r['type'] = 'mixed'; } else { @@ -478,7 +478,7 @@ class CommentParser $r['type'] = count($data) == 1 ? $data[0] : $data; $data = array_shift($value); - if (!empty($data) && $data{0} == '$') { + if (!empty($data) && $data[0] == '$') { $r['name'] = substr($data, 1); } } @@ -498,7 +498,7 @@ class CommentParser $data = array_shift($value); if (empty($data)) { $r['type'] = 'mixed'; - } elseif ($data{0} == '$') { + } elseif ($data[0] == '$') { $r['name'] = substr($data, 1); $r['type'] = 'mixed'; } else { diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php index b51fa707a53..ceec32e4cb5 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php @@ -221,7 +221,7 @@ class XmlFormat extends Format $namespaces = $xml->getNamespaces(); if (count($namespaces)) { $p = strpos($data, $xml->getName()); - if ($p && $data{$p - 1} == ':') { + if ($p && $data[$p - 1] == ':') { $s = strpos($data, '<') + 1; $prefix = substr($data, $s, $p - $s - 1); static::$namespacedProperties[static::$rootName] = $prefix; diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Resources.php b/htdocs/includes/restler/framework/Luracast/Restler/Resources.php index 43e95fa02be..2986968a990 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Resources.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Resources.php @@ -198,7 +198,7 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi } elseif (false !== ($pos = strpos($id, '-v'))) { //$version = intval(substr($id, $pos + 2)); $id = substr($id, 0, $pos); - } elseif ($id{0} == 'v' && is_numeric($v = substr($id, 1))) { + } elseif ($id[0] == 'v' && is_numeric($v = substr($id, 1))) { $id = ''; //$version = $v; } elseif ($id == 'root' || $id == 'index') { @@ -233,7 +233,7 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi if ($tSlash) { if ($fLen != $tLen && !Text::beginsWith($fullPath, $target . '/')) continue; - } elseif ($fLen > $tLen + 1 && $fullPath{$tLen + 1} != '{' && !Text::beginsWith($fullPath, '{')) { + } elseif ($fLen > $tLen + 1 && $fullPath[$tLen + 1] != '{' && !Text::beginsWith($fullPath, '{')) { //when mapped to root exclude paths that have static parts //they are listed else where under that static part name continue; @@ -275,7 +275,7 @@ class Resources implements iUseAuthentication, iProvideMultiVersionApi if (count($parts) == 1 && $httpMethod == 'GET') { } else { for ($i = 0; $i < count($parts); $i++) { - if (strlen($parts[$i]) && $parts[$i]{0} == '{') { + if (strlen($parts[$i]) && $parts[$i][0] == '{') { $pos = $i - 1; break; } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Restler.php b/htdocs/includes/restler/framework/Luracast/Restler/Restler.php index c2e9b1acb73..fcb5388726c 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Restler.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Restler.php @@ -533,7 +533,7 @@ class Restler extends EventDispatcher rtrim($path, '/') //remove trailing slash if found ); - if (Defaults::$useUrlBasedVersioning && strlen($path) && $path{0} == 'v') { + if (Defaults::$useUrlBasedVersioning && strlen($path) && $path[0] == 'v') { $version = intval(substr($path, 1)); if ($version && $version <= $this->apiVersion) { $this->requestedApiVersion = $version; @@ -1599,7 +1599,7 @@ class Restler extends EventDispatcher */ public function __get($name) { - if ($name{0} == '_') { + if ($name[0] == '_') { $hiddenProperty = substr($name, 1); if (isset($this->$hiddenProperty)) { return $this->$hiddenProperty; diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Routes.php b/htdocs/includes/restler/framework/Luracast/Restler/Routes.php index 73e78dc0039..999094dec4c 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Routes.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Routes.php @@ -87,7 +87,7 @@ class Routes foreach ($methods as $method) { $methodUrl = strtolower($method->getName()); //method name should not begin with _ - if ($methodUrl{0} == '_') { + if ($methodUrl[0] == '_') { continue; } $doc = $method->getDocComment(); @@ -330,7 +330,7 @@ class Routes if (!$type) { return 's'; } - switch ($type{0}) { + switch ($type[0]) { case 'i': case 'f': return 'n'; @@ -428,7 +428,7 @@ class Routes } $index = intval(substr($k, 1)); $details = $value[$httpMethod]['metadata']['param'][$index]; - if ($k{0} == 's' || strpos($k, static::pathVarTypeOf($v)) === 0) { + if ($k[0] == 's' || strpos($k, static::pathVarTypeOf($v)) === 0) { //remove the newlines $data[$details['name']] = trim($v, PHP_EOL); } else { diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Scope.php b/htdocs/includes/restler/framework/Luracast/Restler/Scope.php index 251262017c3..16ccdd33561 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Scope.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Scope.php @@ -203,7 +203,7 @@ class Scope $divider = '\\'; $qualified = false; - if ($className{0} == $divider) { + if ($className[0] == $divider) { $qualified = trim($className, $divider); } elseif (array_key_exists($className, $scope)) { $qualified = $scope[$className]; diff --git a/htdocs/includes/restler/framework/Luracast/Restler/UI/Emmet.php b/htdocs/includes/restler/framework/Luracast/Restler/UI/Emmet.php index abd4a3a73ba..435804b4469 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/UI/Emmet.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/UI/Emmet.php @@ -356,7 +356,7 @@ class Emmet $pos = strpos($string, $f, $start); $tokens = array(); for ($i = $start; $i < $pos; $i++) { - $token = $string{$i}; + $token = $string[$i]; if (('#' == $token || '.' == $token) && (!empty($tokens) || $i == 0) ) { @@ -368,7 +368,7 @@ class Emmet $r[] = $f; } while (false != ($f = strtok(static::DELIMITERS))); for ($i = $pos; $i < strlen($string); $i++) { - $token = $string{$i}; + $token = $string[$i]; $r[] = $tokens[] = $token; } return $r; diff --git a/htdocs/projet/element.php b/htdocs/projet/element.php index 46cf12356c5..ffd083d2359 100644 --- a/htdocs/projet/element.php +++ b/htdocs/projet/element.php @@ -606,7 +606,7 @@ foreach ($listofreferent as $key => $value) $elementarray = $object->get_element_list($key, $tablename, $datefieldname, $dates, $datee, !empty($project_field)?$project_field:'fk_projet'); - if (count($elementarray)>0 && is_array($elementarray)) + if (is_array($elementarray) && count($elementarray) > 0) { $total_ht = 0; $total_ttc = 0; diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index fa4f751d6a6..2eebcb19a6b 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -1297,7 +1297,7 @@ div.fichetwothirdright { browser->layout == 'phone') { print "padding-bottom: 6px\n"; } ?> } div.fichetwothirdright div.ficheaddleft { - padding-left: 20px; + padding-: 20px; } div.fichehalfleft { browser->layout != 'phone') { print "float: ".$left.";\n"; } ?> From c7d886c918eb6b454017281396952800f76792db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 23 Nov 2020 23:25:09 +0100 Subject: [PATCH 002/196] fix status on tooltip in box last product --- htdocs/core/boxes/box_produits.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/core/boxes/box_produits.php b/htdocs/core/boxes/box_produits.php index 38f9a73f57f..7f4b66f5f58 100644 --- a/htdocs/core/boxes/box_produits.php +++ b/htdocs/core/boxes/box_produits.php @@ -133,6 +133,8 @@ class box_produits extends ModeleBoxes $productstatic->type = $objp->fk_product_type; $productstatic->label = $objp->label; $productstatic->entity = $objp->entity; + $productstatic->status = $objp->tosell; + $productstatic->status_buy = $objp->tobuy; $this->info_box_contents[$line][] = array( 'td' => 'class="tdoverflowmax100 maxwidth100onsmartphone"', From 69ea0ea791a4daa0e030aed894eae5b39eb37d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Mon, 23 Nov 2020 23:44:15 +0100 Subject: [PATCH 003/196] Update box_produits.php --- htdocs/core/boxes/box_produits.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/htdocs/core/boxes/box_produits.php b/htdocs/core/boxes/box_produits.php index 7f4b66f5f58..5b490ac32f4 100644 --- a/htdocs/core/boxes/box_produits.php +++ b/htdocs/core/boxes/box_produits.php @@ -87,6 +87,11 @@ class box_produits extends ModeleBoxes if ($user->rights->produit->lire || $user->rights->service->lire) { $sql = "SELECT p.rowid, p.label, p.ref, p.price, p.price_base_type, p.price_ttc, p.fk_product_type, p.tms, p.tosell, p.tobuy, p.fk_price_expression, p.entity"; + $sql .= ", p.accountancy_code_sell"; + $sql .= ", p.accountancy_code_sell_intra"; + $sql .= ", p.accountancy_code_sell_export"; + $sql .= ", p.accountancy_code_buy"; + $sql .= ', p.barcode'; $sql.= " FROM ".MAIN_DB_PREFIX."product as p"; $sql.= ' WHERE p.entity IN ('.getEntity($productstatic->element).')'; if (empty($user->rights->produit->lire)) $sql.=' AND p.fk_product_type != 0'; @@ -135,6 +140,11 @@ class box_produits extends ModeleBoxes $productstatic->entity = $objp->entity; $productstatic->status = $objp->tosell; $productstatic->status_buy = $objp->tobuy; + $productstatic->barcode = $objp->barcode; + $productstatic->accountancy_code_sell = $objp->accountancy_code_sell; + $productstatic->accountancy_code_sell_intra = $objp->accountancy_code_sell_intra; + $productstatic->accountancy_code_sell_export = $objp->accountancy_code_sell_export; + $productstatic->accountancy_code_buy = $objp->accountancy_code_buy; $this->info_box_contents[$line][] = array( 'td' => 'class="tdoverflowmax100 maxwidth100onsmartphone"', From be7714be1c1fa9371428072c375e0cc459fc4dff Mon Sep 17 00:00:00 2001 From: Bernard Saulme Date: Wed, 25 Nov 2020 18:11:36 +0100 Subject: [PATCH 004/196] Use email model option to joint file for subscription Allow the adherent subscription to use the email model option to join or no joint file. --- htdocs/adherents/subscription.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index 611542b8ebc..d1dfd836696 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -333,7 +333,7 @@ if ($user->rights->adherent->cotisation->creer && $action == 'subscription' && ! $listofpaths = array(); $listofnames = array(); $listofmimes = array(); - if (is_object($object->invoice)) { + if (is_object($object->invoice) && is_object($arraydefaultmessage) && intval($arraydefaultmessage->joinfiles)) { $invoicediroutput = $conf->facture->dir_output; $fileparams = dol_most_recent_file($invoicediroutput.'/'.$object->invoice->ref, preg_quote($object->invoice->ref, '/').'[^\-]+'); $file = $fileparams['fullname']; From 6de24e0c2e8b7ba734e288a0d8f4d8e1314cc657 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 00:19:45 +0100 Subject: [PATCH 005/196] Reduce travis load for v12 --- .travis.yml | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3a89572148b..edd7582b1e4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ # We use dist: xenial to have php 5.6+ available os: linux dist: xenial -sudo: required +#dist: bionic language: php @@ -115,6 +115,9 @@ install: - | echo "Adding path of binaries tools installed by composer to the PATH" export PATH="$TRAVIS_BUILD_DIR/htdocs/includes/bin:$PATH" + echo $PATH + ls $TRAVIS_BUILD_DIR/vendor + ls $TRAVIS_BUILD_DIR/htdocs/includes/bin echo @@ -141,15 +144,20 @@ before_script: - | echo "Versions information" + echo # Check PHP echo "PHP version" php -i | head - - # Check PHP CodeSniffer installation + # Check Parallel-lint version + echo "Parallel-lint version" + which parallel-lint + parallel-lint -V + # Check PHP CodeSniffer version echo "PHPCS version" which phpcs phpcs --version | head - phpcs -i | head - - # Check PHPUnit installation + # Check PHPUnit version echo "PHPUnit version" which phpunit phpunit --version | head - @@ -254,17 +262,18 @@ script: # Ensure we catch errors set -e #parallel-lint --exclude htdocs/includes --blame . - parallel-lint --exclude dev/namespacemig --exclude htdocs/includes/myclabs --exclude htdocs/includes/webmozart --exclude htdocs/includes/phpspec --exclude dev/initdata/dbf/includes --exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian --exclude htdocs/includes/squizlabs/php_codesniffer --exclude htdocs/includes/jakub-onderka --exclude htdocs/includes/mike42/escpos-php/example --exclude htdocs/includes/phpunit/ --exclude htdocs/includes/composer/autoload_static.php --blame . + parallel-lint --exclude dev/namespacemig --exclude htdocs/includes/composer --exclude htdocs/includes/myclabs --exclude htdocs/includes/webmozart --exclude htdocs/includes/phpspec --exclude dev/initdata/dbf/includes --exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian --exclude htdocs/includes/squizlabs/php_codesniffer --exclude htdocs/includes/jakub-onderka --exclude htdocs/includes/mike42/escpos-php/example --exclude htdocs/includes/phpunit/ --exclude htdocs/includes/composer/autoload_static.php --blame . set +e echo - | - echo "Checking coding style (excluding Pull Requests builds)" + echo "Checking coding style (excluding Pull Requests builds to not overload travis, excluding also some jobs to avoid duplicate tests)" # Ensure we catch errors set -e # Exclusions are defined in the ruleset.xml file - #phpcs -s -n -p -d memory_limit=-1 --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 . - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .; fi + if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_PHP_VERSION" = "7.4" ] && [ "$DB" = "mysql" ]; then + phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .; + fi set +e echo @@ -376,6 +385,7 @@ script: php upgrade.php 11.0.0 12.0.0 ignoredbversion > $TRAVIS_BUILD_DIR/upgrade11001200.log php upgrade2.php 11.0.0 12.0.0 > $TRAVIS_BUILD_DIR/upgrade11001200-2.log php step5.php 11.0.0 12.0.0 > $TRAVIS_BUILD_DIR/upgrade11001200-3.log + # Enable modules not enabled into original dump php upgrade2.php 0.0.0 0.0.0 MAIN_MODULE_API,MAIN_MODULE_SUPPLIERPROPOSAL,MAIN_MODULE_WEBSITE,MAIN_MODULE_TICKETSUP,MAIN_MODULE_ACCOUNTING > $TRAVIS_BUILD_DIR/enablemodule.log echo $? @@ -396,7 +406,7 @@ script: after_script: - | - echo "After script - Output lines of dolibarr.log" + echo "After script - Output last lines of dolibarr.log" ls $TRAVIS_BUILD_DIR/documents #cat $TRAVIS_BUILD_DIR/documents/dolibarr.log sudo tail -n 50 $TRAVIS_BUILD_DIR/documents/dolibarr.log From 26f07992a96694d66cb47c794a825874d8b2e243 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 00:27:52 +0100 Subject: [PATCH 006/196] Reduce travis load for v11 --- .travis.yml | 86 +++++++++++++++++------------------------------------ 1 file changed, 28 insertions(+), 58 deletions(-) diff --git a/.travis.yml b/.travis.yml index bd0fd6f1fb8..1002216b7cb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,13 +5,15 @@ # We use dist: trusty to have php 5.4+ available os: linux dist: trusty -sudo: required +#sudo: required language: php # Start on every boot services: - memcached +- mysql +- postgresql addons: mariadb: '10.0' @@ -29,60 +31,25 @@ addons: # We need pgloader for import mysql database into pgsql - pgloader -php: -- '5.5' -- '5.6' -- '7.0' -- '7.1' -- '7.2' -- '7.3' -- '7.4' -- nightly - env: global: # Set to true for very verbose output - DEBUG=false - jobs: - # MariaDB overrides MySQL installation so it's not possible to test both yet - #- DB=mysql - - DB=mariadb - - DB=postgresql - # TODO - #- DB=sqlite - # See https://docs.travis-ci.com/user/languages/php/#Apache-%2B-PHP - #- WS=apache - # See https://github.com/DracoBlue/travis-ci-nginx-php-fpm-test - #- WS=nginx jobs: fast_finish: true allow_failures: - php: nightly - # We exclude some combinations not usefull to save Travis CPU - exclude: - - php: '5.6' - env: DB=mariadb - - php: '7.0' - env: DB=mariadb - - php: '7.1' - env: DB=mariadb - - php: '7.2' - env: DB=mariadb - - php: '7.3' - env: DB=mariadb - - php: '5.6' - env: DB=postgresql - - php: '7.0' - env: DB=postgresql - - php: '7.1' - env: DB=postgresql - - php: '7.2' - env: DB=postgresql - - php: '7.3' - env: DB=postgresql - - php: nightly - env: DB=postgresql + include: + - if: type = push + php: '5.5' + env: DB=postgresql + - if: type = pull_request OR type = push + php: '7.4' + env: DB=mysql + - if: type = push AND branch = develop + php: nightly + env: DB=mysql notifications: email: @@ -115,6 +82,7 @@ install: echo "Updating Composer" rm $TRAVIS_BUILD_DIR/composer.json rm $TRAVIS_BUILD_DIR/composer.lock + composer -V composer self-update # To have composer making parallel downloads composer global require hirak/prestissimo @@ -149,6 +117,9 @@ install: - | echo "Adding path of binaries tools installed by composer to the PATH" export PATH="$TRAVIS_BUILD_DIR/htdocs/includes/bin:$PATH" + echo $PATH + ls $TRAVIS_BUILD_DIR/vendor + ls $TRAVIS_BUILD_DIR/htdocs/includes/bin echo @@ -175,15 +146,16 @@ before_script: - | echo "Versions information" + echo # Check PHP echo "PHP version" php -i | head - - # Check PHP CodeSniffer installation + # Check PHP CodeSniffer version echo "PHPCS version" which phpcs phpcs --version | head - phpcs -i | head - - # Check PHPUnit installation + # Check PHPUnit version echo "PHPUnit version" which phpunit phpunit --version | head - @@ -264,10 +236,7 @@ before_script: - sudo sed -i -e "s,www-data,travis,g" /etc/apache2/envvars - sudo chown -R travis:travis /var/lib/apache2/fastcgi - ~/.phpenv/versions/$(phpenv version-name)/sbin/php-fpm - # configure apache virtual hosts for precise - #- sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/default - #- sudo cat /etc/apache2/sites-available/default - # configure apache virtual hosts for trusty + # configure apache virtual hosts - sudo cp -f build/travis-ci/apache.conf /etc/apache2/sites-available/000-default.conf - sudo sed -e "s?%TRAVIS_BUILD_DIR%?$(pwd)?g" --in-place /etc/apache2/sites-available/000-default.conf - sudo cat /etc/apache2/sites-available/000-default.conf @@ -292,17 +261,18 @@ script: # Ensure we catch errors set -e #parallel-lint --exclude htdocs/includes --blame . - parallel-lint --exclude dev/namespacemig --exclude htdocs/includes/myclabs --exclude htdocs/includes/webmozart --exclude htdocs/includes/phpspec --exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian --exclude htdocs/includes/squizlabs/php_codesniffer/tests --exclude htdocs/includes/jakub-onderka/php-parallel-lint/tests --exclude htdocs/includes/mike42/escpos-php/example --exclude htdocs/includes/phpunit/php-token-stream/tests --exclude htdocs/includes/composer/autoload_static.php --blame . + parallel-lint --exclude dev/namespacemig --exclude htdocs/includes/composer --exclude htdocs/includes/myclabs --exclude htdocs/includes/webmozart --exclude htdocs/includes/phpspec --exclude htdocs/includes/sabre --exclude htdocs/includes/phpoffice/phpexcel/Classes/PHPExcel/Shared --exclude htdocs/includes/phpoffice/PhpSpreadsheet --exclude htdocs/includes/sebastian --exclude htdocs/includes/squizlabs/php_codesniffer/tests --exclude htdocs/includes/jakub-onderka/php-parallel-lint/tests --exclude htdocs/includes/mike42/escpos-php/example --exclude htdocs/includes/phpunit/php-token-stream/tests --exclude htdocs/includes/composer/autoload_static.php --blame . set +e echo - | - echo "Checking coding style (excluding Pull Requests builds)" + echo "Checking coding style (excluding Pull Requests builds to not overload travis, excluding also some jobs to avoid duplicate tests)" # Ensure we catch errors set -e # Exclusions are defined in the ruleset.xml file - #phpcs -s -n -p -d memory_limit=-1 --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 . - if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .; fi + if [ "$TRAVIS_PULL_REQUEST" = "false" ] && [ "$TRAVIS_PHP_VERSION" = "7.4" ]; then + phpcs -s -p -d memory_limit=-1 --extensions=php --colors --tab-width=4 --standard=dev/setup/codesniffer/ruleset.xml --encoding=utf-8 --runtime-set ignore_warnings_on_exit true .; + fi set +e echo @@ -431,7 +401,7 @@ script: after_script: - | - echo "After script - Output lines of dolibarr.log" + echo "After script - Output last lines of dolibarr.log" ls $TRAVIS_BUILD_DIR/documents #cat $TRAVIS_BUILD_DIR/documents/dolibarr.log sudo tail -n 50 $TRAVIS_BUILD_DIR/documents/dolibarr.log @@ -457,7 +427,7 @@ after_failure: # Dolibarr log file echo "Debugging informations for file dolibarr.log (latest 50 lines)" tail -n 50 $TRAVIS_BUILD_DIR/documents/dolibarr.log - # MariaDB log file + # Database log file echo "Debugging informations for file mysql error.log" sudo tail -n 50 /var/log/mysql/error.log # TODO: PostgreSQL log file From b9bac939e69cd27fe2ea8948bfbe55b78cd48599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Fri, 27 Nov 2020 09:11:30 +0100 Subject: [PATCH 007/196] doxygen --- htdocs/ecm/class/ecmdirectory.class.php | 213 +++++++++++++----------- htdocs/ecm/class/ecmfiles.class.php | 70 +++++--- htdocs/ecm/dir_add_card.php | 121 +++++++------- 3 files changed, 215 insertions(+), 189 deletions(-) diff --git a/htdocs/ecm/class/ecmdirectory.class.php b/htdocs/ecm/class/ecmdirectory.class.php index f2b87382c76..ca2b9fec473 100644 --- a/htdocs/ecm/class/ecmdirectory.class.php +++ b/htdocs/ecm/class/ecmdirectory.class.php @@ -62,8 +62,19 @@ class EcmDirectory extends CommonObject */ public $description; + /** + * @var int cache nb of doc + */ public $cachenbofdoc = -1; // By default cache initialized with value 'not calculated' + + /** + * @var int date_c + */ public $date_c; + + /** + * @var int date_m + */ public $date_m; /** @@ -81,25 +92,31 @@ class EcmDirectory extends CommonObject */ public $ref; + /** + * @var array array of categories + */ public $cats = array(); + + /** + * @var array array of children categories + */ public $motherof = array(); + /** + * @var array array of forbidden chars + */ public $forbiddenchars = array('<', '>', ':', '/', '\\', '?', '*', '|', '"'); + + /** + * @var array array of forbidden chars for dir + */ public $forbiddencharsdir = array('<', '>', ':', '?', '*', '|', '"'); + /** + * @var int 1 if full arbo loaded + */ public $full_arbo_loaded; - /** - * @var string Error code (or message) - */ - public $error; - - /** - * @var string[] Error codes (or messages) - */ - public $errors = array(); - - /** * Constructor * @@ -131,13 +148,14 @@ class EcmDirectory extends CommonObject $this->description = trim($this->description); $this->date_c = $now; $this->fk_user_c = $user->id; - if ($this->fk_parent <= 0) $this->fk_parent = 0; + if ($this->fk_parent <= 0) { + $this->fk_parent = 0; + } // Check if same directory does not exists with this name $relativepath = $this->label; - if ($this->fk_parent) - { + if ($this->fk_parent) { $parent = new EcmDirectory($this->db); $parent->fetch($this->fk_parent); $relativepath = $parent->getRelativePath().$relativepath; @@ -148,19 +166,16 @@ class EcmDirectory extends CommonObject $cat = new EcmDirectory($this->db); $cate_arbo = $cat->get_full_arbo(1); $pathfound = 0; - foreach ($cate_arbo as $key => $categ) - { + foreach ($cate_arbo as $key => $categ) { $path = str_replace($this->forbiddencharsdir, '_', $categ['fullrelativename']); //print $relativepath.' - '.$path.'
'; - if ($path == $relativepath) - { + if ($path == $relativepath) { $pathfound = 1; break; } } - if ($pathfound) - { + if ($pathfound) { $this->error = "ErrorDirAlreadyExists"; dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING); return -1; @@ -188,21 +203,23 @@ class EcmDirectory extends CommonObject dol_syslog(get_class($this)."::create", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."ecm_directories"); $dir = $conf->ecm->dir_output.'/'.$this->getRelativePath(); $result = dol_mkdir($dir); - if ($result < 0) { $error++; $this->error = "ErrorFailedToCreateDir"; } + if ($result < 0) { + $error++; $this->error = "ErrorFailedToCreateDir"; + } // Call trigger $result = $this->call_trigger('MYECMDIR_CREATE', $user); - if ($result < 0) { $error++; } + if ($result < 0) { + $error++; + } // End call triggers - if (!$error) - { + if (!$error) { $this->db->commit(); return $this->id; } else { @@ -249,22 +266,21 @@ class EcmDirectory extends CommonObject dol_syslog(get_class($this)."::update", LOG_DEBUG); $resql = $this->db->query($sql); - if (!$resql) - { + if (!$resql) { $error++; $this->error = "Error ".$this->db->lasterror(); } - if (!$error && !$notrigger) - { + if (!$error && !$notrigger) { // Call trigger $result = $this->call_trigger('MYECMDIR_MODIFY', $user); - if ($result < 0) { $error++; } + if ($result < 0) { + $error++; + } // End call triggers } - if (!$error) - { + if (!$error) { $this->db->commit(); return 1; } else { @@ -284,20 +300,26 @@ class EcmDirectory extends CommonObject { // Update request $sql = "UPDATE ".MAIN_DB_PREFIX."ecm_directories SET"; - if (preg_match('/[0-9]+/', $value)) $sql .= " cachenbofdoc = ".(int) $value; - else $sql .= " cachenbofdoc = cachenbofdoc ".$value." 1"; + if (preg_match('/[0-9]+/', $value)) { + $sql .= " cachenbofdoc = ".(int) $value; + } else { + $sql .= " cachenbofdoc = cachenbofdoc ".$value." 1"; + } $sql .= " WHERE rowid = ".$this->id; dol_syslog(get_class($this)."::changeNbOfFiles", LOG_DEBUG); $resql = $this->db->query($sql); - if (!$resql) - { + if (!$resql) { $this->error = "Error ".$this->db->lasterror(); return -1; } else { - if (preg_match('/[0-9]+/', $value)) $this->cachenbofdoc = (int) $value; - elseif ($value == '+') $this->cachenbofdoc++; - elseif ($value == '-') $this->cachenbofdoc--; + if (preg_match('/[0-9]+/', $value)) { + $this->cachenbofdoc = (int) $value; + } elseif ($value == '+') { + $this->cachenbofdoc++; + } elseif ($value == '-') { + $this->cachenbofdoc--; + } } return 1; @@ -327,11 +349,9 @@ class EcmDirectory extends CommonObject dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $obj = $this->db->fetch_object($resql); - if ($obj) - { + if ($obj) { $this->id = $obj->rowid; $this->ref = $obj->rowid; @@ -374,7 +394,9 @@ class EcmDirectory extends CommonObject $error = 0; - if ($mode != 'databaseonly') $relativepath = $this->getRelativePath(1); // Ex: dir1/dir2/dir3 + if ($mode != 'databaseonly') { + $relativepath = $this->getRelativePath(1); // Ex: dir1/dir2/dir3 + } dol_syslog(get_class($this)."::delete remove directory id=".$this->id." mode=".$mode.(($mode == 'databaseonly') ? '' : ' relativepath='.$relativepath)); @@ -385,35 +407,30 @@ class EcmDirectory extends CommonObject dol_syslog(get_class($this)."::delete", LOG_DEBUG); $resql = $this->db->query($sql); - if (!$resql) - { + if (!$resql) { $this->db->rollback(); $this->error = "Error ".$this->db->lasterror(); return -2; } else { // Call trigger $result = $this->call_trigger('MYECMDIR_DELETE', $user); - if ($result < 0) - { + if ($result < 0) { $this->db->rollback(); return -2; } // End call triggers } - if ($mode != 'databaseonly') - { + if ($mode != 'databaseonly') { $file = $conf->ecm->dir_output."/".$relativepath; - if ($deletedirrecursive) - { + if ($deletedirrecursive) { $result = @dol_delete_dir_recursive($file, 0, 0); } else { $result = @dol_delete_dir($file, 0); } } - if ($result || !@is_dir(dol_osencode($file))) - { + if ($result || !@is_dir(dol_osencode($file))) { $this->db->commit(); } else { $this->error = 'ErrorFailToDeleteDir'; @@ -422,8 +439,11 @@ class EcmDirectory extends CommonObject $error++; } - if (!$error) return 1; - else return -1; + if (!$error) { + return 1; + } else { + return -1; + } } @@ -465,17 +485,27 @@ class EcmDirectory extends CommonObject $linkclose = '"'.($more ? ' '.$more : '').' title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; $linkstart = 'picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); - if ($withpicto != 2) $result .= ($max ?dol_trunc($newref, $max, 'middle') : $newref); + if ($withpicto) { + $result .= img_object(($notooltip ? '' : $label), $this->picto, ($notooltip ? (($withpicto != 2) ? 'class="paddingright"' : '') : 'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip ? 0 : 1); + } + if ($withpicto != 2) { + $result .= ($max ?dol_trunc($newref, $max, 'middle') : $newref); + } $result .= $linkend; return $result; @@ -497,18 +527,15 @@ class EcmDirectory extends CommonObject do { // Get index cursor in this->cats for id_mere $cursorindex = -1; - foreach ($this->cats as $key => $val) - { - if ($this->cats[$key]['id'] == $idtosearch) - { + foreach ($this->cats as $key => $val) { + if ($this->cats[$key]['id'] == $idtosearch) { $cursorindex = $key; break; } } //print "c=".$idtosearch."-".$cursorindex; - if ($cursorindex >= 0) - { + if ($cursorindex >= 0) { // Path is label sanitized (no space and no special char) and concatenated $ret = dol_sanitizeFileName($this->cats[$cursorindex]['label']).'/'.$ret; @@ -541,11 +568,9 @@ class EcmDirectory extends CommonObject dol_syslog(get_class($this)."::load_motherof", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { // This assignment in condition is not a bug. It allows walking the results. - while ($obj = $this->db->fetch_object($resql)) - { + while ($obj = $this->db->fetch_object($resql)) { $this->motherof[$obj->id_son] = $obj->id_parent; } return 1; @@ -608,8 +633,7 @@ class EcmDirectory extends CommonObject // phpcs:enable global $conf; - if (empty($force) && !empty($this->full_arbo_loaded)) - { + if (empty($force) && !empty($this->full_arbo_loaded)) { return $this->cats; } @@ -632,13 +656,11 @@ class EcmDirectory extends CommonObject dol_syslog(get_class($this)."::get_full_arbo", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $this->cats = array(); $i = 0; // This assignment in condition is not a bug. It allows walking the results. - while ($obj = $this->db->fetch_object($resql)) - { + while ($obj = $this->db->fetch_object($resql)) { $this->cats[$obj->rowid]['id'] = $obj->rowid; $this->cats[$obj->rowid]['id_mere'] = (isset($this->motherof[$obj->rowid]) ? $this->motherof[$obj->rowid] : ''); $this->cats[$obj->rowid]['label'] = $obj->label; @@ -648,10 +670,8 @@ class EcmDirectory extends CommonObject $this->cats[$obj->rowid]['fk_user_c'] = $obj->fk_user_c; $this->cats[$obj->rowid]['login_c'] = $obj->login_c; - if (!empty($obj->rowid_fille)) - { - if (isset($this->cats[$obj->rowid]['id_children']) && is_array($this->cats[$obj->rowid]['id_children'])) - { + if (!empty($obj->rowid_fille)) { + if (isset($this->cats[$obj->rowid]['id_children']) && is_array($this->cats[$obj->rowid]['id_children'])) { $newelempos = count($this->cats[$obj->rowid]['id_children']); //print "this->cats[$i]['id_children'] est deja un tableau de $newelem elements
"; $this->cats[$obj->rowid]['id_children'][$newelempos] = $obj->rowid_fille; @@ -668,9 +688,10 @@ class EcmDirectory extends CommonObject } // We add properties fullxxx to all elements - foreach ($this->cats as $key => $val) - { - if (isset($motherof[$key])) continue; + foreach ($this->cats as $key => $val) { + if (isset($motherof[$key])) { + continue; + } $this->build_path_from_id_categ($key, 0); } @@ -693,8 +714,7 @@ class EcmDirectory extends CommonObject { // phpcs:enable // Define fullpath - if (!empty($this->cats[$id_categ]['id_mere'])) - { + if (!empty($this->cats[$id_categ]['id_mere'])) { $this->cats[$id_categ]['fullpath'] = $this->cats[$this->cats[$id_categ]['id_mere']]['fullpath']; $this->cats[$id_categ]['fullpath'] .= '_'.$id_categ; $this->cats[$id_categ]['fullrelativename'] = $this->cats[$this->cats[$id_categ]['id_mere']]['fullrelativename']; @@ -711,11 +731,11 @@ class EcmDirectory extends CommonObject // Traite ces enfants $protection++; - if ($protection > 20) return; // On ne traite pas plus de 20 niveaux - if (isset($this->cats[$id_categ]['id_children']) && is_array($this->cats[$id_categ]['id_children'])) - { - foreach ($this->cats[$id_categ]['id_children'] as $key => $val) - { + if ($protection > 20) { + return; // On ne traite pas plus de 20 niveaux + } + if (isset($this->cats[$id_categ]['id_children']) && is_array($this->cats[$id_categ]['id_children'])) { + foreach ($this->cats[$id_categ]['id_children'] as $key => $val) { $this->build_path_from_id_categ($val, $protection); } } @@ -741,8 +761,7 @@ class EcmDirectory extends CommonObject // Update request $sql = "UPDATE ".MAIN_DB_PREFIX."ecm_directories SET"; $sql .= " cachenbofdoc = '".count($filelist)."'"; - if (empty($all)) // By default - { + if (empty($all)) { // By default $sql .= " WHERE rowid = ".$this->id; } else { $sql .= " WHERE entity = ".$conf->entity; @@ -750,8 +769,7 @@ class EcmDirectory extends CommonObject dol_syslog(get_class($this)."::refreshcachenboffile", LOG_DEBUG); $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $this->cachenbofdoc = count($filelist); return $this->cachenbofdoc; } else { @@ -782,8 +800,7 @@ class EcmDirectory extends CommonObject $interface = new Interfaces($this->db); $result = $interface->run_triggers($triggerName, $this, $user, $langs, $conf); if ($result < 0) { - if (!empty($this->errors)) - { + if (!empty($this->errors)) { $this->errors = array_merge($this->errors, $interface->errors); } else { $this->errors = $interface->errors; diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index 978b6e46d9e..4b0033cf5ec 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -94,7 +94,15 @@ class EcmFiles extends CommonObject * @var string keywords */ public $keywords; + + /** + * @var string cover + */ public $cover; + + /** + * @var int position + */ public $position; /** @@ -131,7 +139,15 @@ class EcmFiles extends CommonObject * @var string acl */ public $acl; + + /** + * @var string src object type + */ public $src_object_type; + + /** + * @var int src object id + */ public $src_object_id; @@ -233,8 +249,7 @@ class EcmFiles extends CommonObject $sql .= " WHERE filepath ='".$this->db->escape($this->filepath)."'"; $resql = $this->db->query($sql); - if ($resql) - { + if ($resql) { $obj = $this->db->fetch_object($resql); $maxposition = (int) $obj->maxposition; } else { @@ -247,13 +262,11 @@ class EcmFiles extends CommonObject } // Check parameters - if (empty($this->filename) || empty($this->filepath)) - { + if (empty($this->filename) || empty($this->filepath)) { $this->errors[] = 'Bad property filename or filepath'; return --$error; } - if (!isset($this->entity)) - { + if (!isset($this->entity)) { $this->entity = $conf->entity; } // Put here code to add control on parameters values @@ -317,11 +330,12 @@ class EcmFiles extends CommonObject $this->position = $maxposition; // Triggers - if (!$notrigger) - { + if (!$notrigger) { // Call triggers $result = $this->call_trigger(strtoupper(get_class($this)).'_CREATE', $user); - if ($result < 0) { $error++; } + if ($result < 0) { + $error++; + } // End call triggers } } @@ -401,8 +415,7 @@ class EcmFiles extends CommonObject } elseif (!empty($hashforshare)) { $sql .= " AND t.share = '".$this->db->escape($hashforshare)."'"; //$sql .= " AND t.entity = ".$conf->entity; // hashforshare already unique - } elseif ($src_object_type && $src_object_id) - { + } elseif ($src_object_type && $src_object_id) { // Warning: May return several record, and only first one is returned ! $sql .= " AND t.src_object_type ='".$this->db->escape($src_object_type)."' AND t.src_object_id = ".$this->db->escape($src_object_id); $sql .= " AND t.entity = ".$conf->entity; @@ -668,11 +681,12 @@ class EcmFiles extends CommonObject } // Triggers - if (!$error && !$notrigger) - { + if (!$error && !$notrigger) { // Call triggers $result = $this->call_trigger(strtoupper(get_class($this)).'_MODIFY', $user); - if ($result < 0) { $error++; } //Do also here what you must do to rollback action if trigger fail + if ($result < 0) { + $error++; + } //Do also here what you must do to rollback action if trigger fail // End call triggers } @@ -705,11 +719,12 @@ class EcmFiles extends CommonObject $this->db->begin(); // Triggers - if (!$notrigger) - { + if (!$notrigger) { // Call triggers $result = $this->call_trigger(strtoupper(get_class($this)).'_DELETE', $user); - if ($result < 0) { $error++; } //Do also here what you must do to rollback action if trigger fail + if ($result < 0) { + $error++; + } //Do also here what you must do to rollback action if trigger fail // End call triggers } @@ -804,7 +819,9 @@ class EcmFiles extends CommonObject global $dolibarr_main_authentication, $dolibarr_main_demo; global $menumanager; - if (!empty($conf->dol_no_mouse_hover)) $notooltip = 1; // Force disable tooltips + if (!empty($conf->dol_no_mouse_hover)) { + $notooltip = 1; // Force disable tooltips + } $result = ''; @@ -815,25 +832,26 @@ class EcmFiles extends CommonObject $url = DOL_URL_ROOT.'/ecm/'.$this->table_name.'_card.php?id='.$this->id; $linkclose = ''; - if (empty($notooltip)) - { - if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) - { + if (empty($notooltip)) { + if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) { $label = $langs->trans("ShowProject"); $linkclose .= ' alt="'.dol_escape_htmltag($label, 1).'"'; } $linkclose .= ' title="'.dol_escape_htmltag($label, 1).'"'; $linkclose .= ' class="classfortooltip'.($morecss ? ' '.$morecss : '').'"'; - } else $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + } else { + $linkclose = ($morecss ? ' class="'.$morecss.'"' : ''); + } $linkstart = '
'; $linkend = ''; - if ($withpicto) - { + if ($withpicto) { $result .= ($linkstart.img_object(($notooltip ? '' : $label), 'label', ($notooltip ? '' : 'class="classfortooltip"')).$linkend); - if ($withpicto != 2) $result .= ' '; + if ($withpicto != 2) { + $result .= ' '; + } } $result .= $linkstart.$this->ref.$linkend; return $result; diff --git a/htdocs/ecm/dir_add_card.php b/htdocs/ecm/dir_add_card.php index a2726a1ba75..8c13c377bd6 100644 --- a/htdocs/ecm/dir_add_card.php +++ b/htdocs/ecm/dir_add_card.php @@ -41,20 +41,22 @@ $confirm = GETPOST('confirm', 'alpha'); $module = GETPOST('module', 'alpha'); $website = GETPOST('website', 'alpha'); $pageid = GETPOST('pageid', 'int'); -if (empty($module)) $module = 'ecm'; +if (empty($module)) { + $module = 'ecm'; +} // Security check -if ($user->socid > 0) -{ +if ($user->socid > 0) { $action = ''; $socid = $user->socid; } $section = $urlsection = GETPOST('section', 'alpha'); -if (empty($urlsection)) $urlsection = 'misc'; +if (empty($urlsection)) { + $urlsection = 'misc'; +} -if ($module == 'ecm') -{ +if ($module == 'ecm') { $upload_dir = $conf->ecm->dir_output.'/'.$urlsection; } else // For example $module == 'medias' { @@ -65,19 +67,23 @@ $limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; $sortfield = GETPOST("sortfield", 'alpha'); $sortorder = GETPOST("sortorder", 'alpha'); $page = GETPOSTISSET('pageplusone') ? (GETPOST('pageplusone') - 1) : GETPOST("page", 'int'); -if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +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 (!$sortorder) $sortorder = "ASC"; -if (!$sortfield) $sortfield = "label"; +if (!$sortorder) { + $sortorder = "ASC"; +} +if (!$sortfield) { + $sortfield = "label"; +} $ecmdir = new EcmDirectory($db); -if (!empty($section)) -{ +if (!empty($section)) { $result = $ecmdir->fetch($section); - if (!$result > 0) - { + if (!$result > 0) { dol_print_error($db, $ecmdir->error); exit; } @@ -86,18 +92,18 @@ if (!empty($section)) // Permissions $permtoadd = 0; $permtoupload = 0; -if ($module == 'ecm') -{ +if ($module == 'ecm') { $permtoadd = $user->rights->ecm->setup; $permtoupload = $user->rights->ecm->upload; } -if ($module == 'medias') -{ +if ($module == 'medias') { $permtoadd = ($user->rights->mailing->creer || $user->rights->website->write); $permtoupload = ($user->rights->mailing->creer || $user->rights->website->write); } -if (!$permtoadd) accessforbidden(); +if (!$permtoadd) { + accessforbidden(); +} @@ -106,12 +112,9 @@ if (!$permtoadd) accessforbidden(); */ // Action ajout d'un produit ou service -if ($action == 'add' && $permtoadd) -{ - if ($cancel) - { - if (!empty($backtopage)) - { +if ($action == 'add' && $permtoadd) { + if ($cancel) { + if (!empty($backtopage)) { header("Location: ".$backtopage); exit; } else { @@ -120,33 +123,31 @@ if ($action == 'add' && $permtoadd) } } - $ref = GETPOST("ref", 'alpha'); - $label = GETPOST("label", 'alpha'); - $desc = GETPOST("desc", 'alpha'); + $ref = (string) GETPOST("ref", 'alpha'); + $label = (string) GETPOST("label", 'alpha'); + $desc = (string) GETPOST("desc", 'alpha'); $catParent = GETPOST("catParent", 'alpha'); // Can be an int (with ECM) or a string (with generic filemanager) - if ($catParent == '-1') $catParent = 0; + if ($catParent == '-1') { + $catParent = 0; + } $error = 0; - if (empty($label)) - { + if (empty($label)) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors'); $action = 'create'; $error++; } - if (!$error) - { - if ($module == 'ecm') - { + if (!$error) { + if ($module == 'ecm') { $ecmdir->ref = $ref; $ecmdir->label = $label; $ecmdir->description = $desc; $ecmdir->fk_parent = (int) $catParent; $id = $ecmdir->create($user); - if ($id <= 0) - { + if ($id <= 0) { $error++; $langs->load("errors"); setEventMessages($ecmdir->error, $ecmdir->errors, 'errors'); @@ -155,22 +156,18 @@ if ($action == 'add' && $permtoadd) } else // For example $module == 'medias' { $dirfornewdir = ''; - if ($module == 'medias') - { + if ($module == 'medias') { $dirfornewdir = $conf->medias->multidir_output[$conf->entity]; } - if (empty($dirfornewdir)) - { + if (empty($dirfornewdir)) { $error++; dol_print_error('', 'Bad value for module. Not supported.'); } - if (!$error) - { + if (!$error) { $fullpathofdir = $dirfornewdir.'/'.($catParent ? $catParent.'/' : '').$label; $result = dol_mkdir($fullpathofdir, DOL_DATA_ROOT); - if ($result < 0) - { + if ($result < 0) { setEventMessages($langs->trans('ErrorFailToCreateDir', $label), null, 'errors'); $error++; } else { @@ -180,10 +177,8 @@ if ($action == 'add' && $permtoadd) } } - if (!$error) - { - if (!empty($backtopage)) - { + if (!$error) { + if (!empty($backtopage)) { header("Location: ".$backtopage); exit; } else { @@ -194,8 +189,7 @@ if ($action == 'add' && $permtoadd) } // Deleting file -elseif ($action == 'confirm_deletesection' && $confirm == 'yes') -{ +elseif ($action == 'confirm_deletesection' && $confirm == 'yes') { $result = $ecmdir->delete($user); setEventMessages($langs->trans("ECMSectionWasRemoved", $ecmdir->label), null, 'mesgs'); } @@ -212,8 +206,7 @@ llxHeader('', $langs->trans("ECMNewSection")); $form = new Form($db); $formecm = new FormEcm($db); -if ($action == 'create') -{ +if ($action == 'create') { //*********************** // Create //*********************** @@ -222,8 +215,12 @@ if ($action == 'create') print ''; print ''; print ''; - if ($website) print ''; - if ($pageid) print ''; + if ($website) { + print ''; + } + if ($pageid) { + print ''; + } $title = $langs->trans("ECMNewSection"); print load_fiche_titre($title); @@ -240,8 +237,7 @@ if ($action == 'create') print ''."\n"; // Description - if ($module == 'ecm') - { + if ($module == 'ecm') { print ''.$langs->trans("Description").''; print ''; + print ''; } else { diff --git a/htdocs/societe/class/societe.class.php b/htdocs/societe/class/societe.class.php index 30a90a884bd..ee91363dba1 100644 --- a/htdocs/societe/class/societe.class.php +++ b/htdocs/societe/class/societe.class.php @@ -2077,7 +2077,7 @@ class Societe extends CommonObject $discount->amount_tva = $discount->multicurrency_amount_tva = price2num($remise * $vatrate / 100, 'MT'); $discount->amount_ttc = $discount->multicurrency_amount_ttc = price2num($discount->amount_ht + $discount->amount_tva, 'MT'); - $discount->tva_tx = price2num($vatrate, 'MT'); + $discount->tva_tx = price2num($vatrate); $discount->vat_src_code = $vat_src_code; $discount->description = $desc; diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 85937147cff..a987f28c7ed 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -1262,16 +1262,24 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase // Test with 3 chars after . or , // If a . is used and there is 3 digits after, it is a thousand separator - $this->assertEquals(1234, price2num('1.234'), 'Test 1.234 give 1234 with spanish language'); + $this->assertEquals(1234, price2num('1.234', '', 2), 'Test 1.234 give 1234 with spanish language if user input'); + $this->assertEquals(1.234, price2num('1,234', '', 2), 'Test 1,234 give 1234 with spanish language if user input'); + $this->assertEquals(1234, price2num('1 234', '', 2), 'Test 1 234 give 1234 with spanish language if user input'); + $this->assertEquals(1.234, price2num('1.234'), 'Test 1.234 give 1.234 with spanish language'); + $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1234 with spanish language'); $this->assertEquals(1234, price2num('1 234'), 'Test 1 234 give 1234 with spanish language'); - $this->assertEquals(1234, price2num('1.234'), 'Test 1.234 give 1234 with spanish language'); - $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1.234 with spanish language'); $this->assertEquals(21500123, price2num('21.500.123'), 'Test 21.500.123 give 21500123 with spanish language'); - $this->assertEquals(21500123, price2num('21500.123'), 'Test 21500.123 give 21500123 with spanish language'); + $this->assertEquals(21500123, price2num('21500.123', 0, 2), 'Test 21500.123 give 21500123 with spanish language if user input'); + $this->assertEquals(21500.123, price2num('21500.123'), 'Test 21500.123 give 21500123 with spanish language'); $this->assertEquals(21500.123, price2num('21500,123'), 'Test 21500,123 give 21500.123 with spanish language'); // Test with 2 digits $this->assertEquals(21500.12, price2num('21500.12'), 'Test 21500.12 give 21500.12 with spanish language'); $this->assertEquals(21500.12, price2num('21500,12'), 'Test 21500,12 give 21500.12 with spanish language'); + // Test with 3 digits + $this->assertEquals(12123, price2num('12.123', '', 2), 'Test 12.123 give 12123 with spanish language if user input'); + $this->assertEquals(12.123, price2num('12,123', '', 2), 'Test 12,123 give 12.123 with spanish language if user input'); + $this->assertEquals(12.123, price2num('12.123'), 'Test 12.123 give 12.123 with spanish language'); + $this->assertEquals(12.123, price2num('12,123'), 'Test 12,123 give 12.123 with spanish language'); // For french language $newlangs3 = new Translate('', $conf); @@ -1279,9 +1287,12 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase $newlangs3->load("main"); $langs = $newlangs3; + $this->assertEquals(1, price2num('1.000', '', 2), 'Test 1.000 give 1 with french language if user input'); $this->assertEquals(1, price2num('1.000'), 'Test 1.000 give 1 with french language'); $this->assertEquals(1000, price2num('1 000'), 'Test 1.000 give 1 with french language'); + $this->assertEquals(1.234, price2num('1.234', '', 2), 'Test 1.234 give 1.234 with french language if user input'); $this->assertEquals(1.234, price2num('1.234'), 'Test 1.234 give 1.234 with french language'); + $this->assertEquals(1.234, price2num('1,234', '', 2), 'Test 1,234 give 1.234 with french language if user input'); $this->assertEquals(1.234, price2num('1,234'), 'Test 1,234 give 1.234 with french language'); $this->assertEquals(21500000, price2num('21500 000'), 'Test 21500 000 give 21500000 with french language'); $this->assertEquals(21500000, price2num('21 500 000'), 'Test 21 500 000 give 21500000 with french language'); From 59c40227ffb476ffc7d939188fe786ce732e01c2 Mon Sep 17 00:00:00 2001 From: iouston <4319513+iouston@users.noreply.github.com> Date: Fri, 27 Nov 2020 14:31:14 +0100 Subject: [PATCH 009/196] Add PROPAL_ENABLE_NEGATIVE in the case of a call for tenders it is possible to have to figure in less value with quotations whose total is negative --- htdocs/comm/propal/card.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index b2f728ac5f5..85182f1b4bd 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -2411,7 +2411,9 @@ if ($action == 'create') if ($action != 'editline') { // Validate - if ($object->statut == Propal::STATUS_DRAFT && $object->total_ttc >= 0 && count($object->lines) > 0) + + + if (($object->statut == Propal::STATUS_DRAFT && $object->total_ttc >= 0 && count($object->lines) 0) || ($object->statut == Propal::STATUS_DRAFT && !empty($conf->global->PROPAL_ENABLE_NEGATIVE) && count($object->lines) > 0)) { if ($usercanvalidate) { From aaf8d437803a7078b6eb63a39c0e74980fe9acfc Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Fri, 27 Nov 2020 13:33:37 +0000 Subject: [PATCH 010/196] Fixing style errors. --- htdocs/comm/propal/card.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 85182f1b4bd..69a2a4b9f82 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -2411,9 +2411,9 @@ if ($action == 'create') if ($action != 'editline') { // Validate - - if (($object->statut == Propal::STATUS_DRAFT && $object->total_ttc >= 0 && count($object->lines) 0) || ($object->statut == Propal::STATUS_DRAFT && !empty($conf->global->PROPAL_ENABLE_NEGATIVE) && count($object->lines) > 0)) + + if (($object->statut == Propal::STATUS_DRAFT && $object->total_ttc >= 0 && count($object->lines) 0) || ($object->statut == Propal::STATUS_DRAFT && !empty($conf->global->PROPAL_ENABLE_NEGATIVE) && count($object->lines) > 0)) { if ($usercanvalidate) { From 9ce6d87b83c48b00803c6c85fddbab8a55580ee3 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 15:04:58 +0100 Subject: [PATCH 011/196] Clean code --- htdocs/core/boxes/intracommreport_box.php | 88 ----------------------- htdocs/core/boxes/modules_boxes.php | 2 +- 2 files changed, 1 insertion(+), 89 deletions(-) delete mode 100644 htdocs/core/boxes/intracommreport_box.php diff --git a/htdocs/core/boxes/intracommreport_box.php b/htdocs/core/boxes/intracommreport_box.php deleted file mode 100644 index d7c383138b6..00000000000 --- a/htdocs/core/boxes/intracommreport_box.php +++ /dev/null @@ -1,88 +0,0 @@ - - * Copyright (C) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file core/boxes/mybox.php - * \ingroup intracommreport - * \brief This file is a sample box definition file - * Put some comments here - */ -include_once DOL_DOCUMENT_ROOT."/core/boxes/modules_boxes.php"; - -/** - * Class to manage the box - */ -class intracommreportbox extends ModeleBoxes -{ - - public $boxcode = "mybox"; - public $boximg = "intracommreport"; - public $boxlabel; - public $depends = array("intracommreport"); - public $db; - public $param; - public $info_box_head = array(); - public $info_box_contents = array(); - - /** - * Constructor - */ - public function __construct() - { - global $langs; - $langs->load("boxes"); - - $this->boxlabel = $langs->transnoentitiesnoconv("MyBox"); - } - - /** - * Load data into info_box_contents array to show array later. - * - * @param int $max Maximum number of records to load - * @return void - */ - public function loadBox($max = 5) - { - global $conf, $user, $langs, $db; - - $this->max = $max; - - //include_once DOL_DOCUMENT_ROOT . "/intracommreport/class/intracommreport.class.php"; - - $text = $langs->trans("MyBoxDescription", $max); - $this->info_box_head = array( - 'text' => $text, - 'limit' => dol_strlen($text) - ); - - $this->info_box_contents[0][0] = array('td' => 'align="left"', - 'text' => $langs->trans("MyBoxContent")); - } - - /** - * Method to show box - * - * @param array $head Array with properties of box title - * @param array $contents Array with properties of box lines - * @return void - */ - public function showBox($head = null, $contents = null) - { - parent::showBox($this->info_box_head, $this->info_box_contents); - } -} diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php index 2ac7ee05c6b..1e32a28f25c 100644 --- a/htdocs/core/boxes/modules_boxes.php +++ b/htdocs/core/boxes/modules_boxes.php @@ -277,7 +277,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty" box for ($j = 0; $j < $nbcolthisline; $j++) { // Define tdparam $tdparam = ''; - if (isset($contents[$i][$j]['td'])) $tdparam .= ' '.$contents[$i][$j]['td']; + if (!empty($contents[$i][$j]['td'])) $tdparam .= ' '.$contents[$i][$j]['td']; $text = isset($contents[$i][$j]['text']) ? $contents[$i][$j]['text'] : ''; $textwithnotags = preg_replace('/<([^>]+)>/i', '', $text); From 4a5cdd00921b19b32945332aede507c31d479c01 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 15:27:35 +0100 Subject: [PATCH 012/196] Several fixes in export and repair tool --- htdocs/core/class/interfaces.class.php | 2 +- htdocs/core/modules/modBom.class.php | 1 + htdocs/core/modules/modCategorie.class.php | 50 +++------------------- htdocs/exports/class/export.class.php | 1 + htdocs/install/repair.php | 3 +- 5 files changed, 12 insertions(+), 45 deletions(-) diff --git a/htdocs/core/class/interfaces.class.php b/htdocs/core/class/interfaces.class.php index 4199e51cb68..3f542f845b9 100644 --- a/htdocs/core/class/interfaces.class.php +++ b/htdocs/core/class/interfaces.class.php @@ -212,7 +212,7 @@ class Interfaces if ($result < 0) { // Action KO - //dol_syslog("Error in trigger ".$action." - Nb of error string returned = ".count($objMod->errors), LOG_ERR); + //dol_syslog("Error in trigger ".$action." - result = ".$result." - Nb of error strings returned = ".count($objMod->errors), LOG_ERR); $nbtotal++; $nbko++; if (!empty($objMod->errors)) $this->errors = array_merge($this->errors, $objMod->errors); diff --git a/htdocs/core/modules/modBom.class.php b/htdocs/core/modules/modBom.class.php index 7258541a7da..062b89d218d 100644 --- a/htdocs/core/modules/modBom.class.php +++ b/htdocs/core/modules/modBom.class.php @@ -300,6 +300,7 @@ class modBom extends DolibarrModules $this->export_dependencies_array[$r] = array('bomline'=>'tl.rowid'); // To force to activate one or several fields if we select some fields that need same (like to select a unique key if we ask a field of a child to avoid the DISTINCT to discard them, or for computed field than need several other fields) $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'bom_bom as t'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bom_bom_extrafields as extra on (t.rowid = extra.fk_object)'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'bom_bomline as tl ON tl.fk_bom = t.rowid'; $this->export_sql_end[$r] .= ' WHERE 1 = 1'; $this->export_sql_end[$r] .= ' AND t.entity IN ('.getEntity('bom').')'; diff --git a/htdocs/core/modules/modCategorie.class.php b/htdocs/core/modules/modCategorie.class.php index 4f0c1e04307..0ea473ed95b 100644 --- a/htdocs/core/modules/modCategorie.class.php +++ b/htdocs/core/modules/modCategorie.class.php @@ -176,56 +176,20 @@ class modCategorie extends DolibarrModules 's.idprof4'=>"company", 's.tva_intra'=>"company", 's.capital'=>"company", 's.note_public'=>"company", 's.fk_prospectlevel'=>'company', 's.fk_stcomm'=>'company' ); // We define here only fields that use another picto + + $keyforselect = 'societe'; $keyforelement = 'company'; $keyforaliasextra = 'extrasoc'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; + $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'categorie as u, '; $this->export_sql_end[$r] .= MAIN_DB_PREFIX.'categorie_societe as cf, '; - $this->export_sql_end[$r] .= MAIN_DB_PREFIX.'societe as s LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extra ON s.rowid = extra.fk_object '; + $this->export_sql_end[$r] .= MAIN_DB_PREFIX.'societe as s'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_typent as t ON s.fk_typent = t.id LEFT JOIN '.MAIN_DB_PREFIX.'c_country as c ON s.fk_pays = c.rowid LEFT JOIN '.MAIN_DB_PREFIX.'c_effectif as ce ON s.fk_effectif = ce.id LEFT JOIN '.MAIN_DB_PREFIX.'c_forme_juridique as cfj ON s.fk_forme_juridique = cfj.code'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe_extrafields as extrasoc ON s.rowid = extrasoc.fk_object '; $this->export_sql_end[$r] .= ' WHERE u.rowid = cf.fk_categorie AND cf.fk_soc = s.rowid'; $this->export_sql_end[$r] .= ' AND u.entity IN ('.getEntity('category').')'; $this->export_sql_end[$r] .= ' AND u.type = 2'; // Customer/Prospect categories - // Add extra fields - $sql = "SELECT name, label, type, param FROM ".MAIN_DB_PREFIX."extrafields WHERE elementtype = 'societe' AND entity IN (0, ".$conf->entity.")"; - $resql = $this->db->query($sql); - if ($resql) // This can fail when class is used on old database (during migration for example) - { - while ($obj = $this->db->fetch_object($resql)) - { - $fieldname = 'extra.'.$obj->name; - $fieldlabel = ucfirst($obj->label); - $typeFilter = "Text"; - switch ($obj->type) - { - case 'int': - case 'double': - case 'price': - $typeFilter = "Numeric"; - break; - case 'date': - case 'datetime': - $typeFilter = "Date"; - break; - case 'boolean': - $typeFilter = "Boolean"; - break; - case 'sellist': - $typeFilter = "List:".$obj->param; - break; - case 'select': - $typeFilter = "Select:".$obj->param; - break; - } - $this->export_fields_array[$r][$fieldname] = $fieldlabel; - $this->export_TypeFields_array[$r][$fieldname] = $typeFilter; - $this->export_entities_array[$r][$fieldname] = 'company'; - } - } - // End add axtra fields - - - - - $r++; $this->export_code[$r] = 'category_'.$r; $this->export_label[$r] = 'CatProdList'; diff --git a/htdocs/exports/class/export.class.php b/htdocs/exports/class/export.class.php index 978a3059ace..6b939dca247 100644 --- a/htdocs/exports/class/export.class.php +++ b/htdocs/exports/class/export.class.php @@ -102,6 +102,7 @@ class Export // Search module files while (($file = readdir($handle)) !== false) { + $reg = array(); if (is_readable($dir.$file) && preg_match("/^(mod.*)\.class\.php$/i", $file, $reg)) { $modulename = $reg[1]; diff --git a/htdocs/install/repair.php b/htdocs/install/repair.php index 034741c7c7e..e0402bb88a1 100644 --- a/htdocs/install/repair.php +++ b/htdocs/install/repair.php @@ -231,7 +231,7 @@ if ($ok && GETPOST('standard', 'alpha')) $listofmodulesextra = array('societe'=>'societe', 'adherent'=>'adherent', 'product'=>'product', 'socpeople'=>'socpeople', 'commande'=>'commande', 'facture'=>'facture', 'supplier_proposal'=>'supplier_proposal', 'commande_fournisseur'=>'commande_fournisseur', 'facture_fourn'=>'facture_fourn', - 'actioncomm'=>'actioncomm', + 'actioncomm'=>'actioncomm', 'bom_bom'=>'bom_bom', 'mrp_mo'=>'mrp_mo', 'adherent_type'=>'adherent_type', 'user'=>'user', 'projet'=>'projet', 'projet_task'=>'projet_task'); print '
*** Check fields into extra table structure match table of definition. If not add column into table'; foreach ($listofmodulesextra as $tablename => $elementtype) @@ -268,6 +268,7 @@ if ($ok && GETPOST('standard', 'alpha')) $arrayoffieldsfound[$fieldname] = array('type'=>$fieldtype); } + // If it does not match, we create fields foreach ($arrayoffieldsdesc as $code => $label) { From 5ed2bbb2047b9d921c3e2430be3f41c71e6d71dc Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 16:13:27 +0100 Subject: [PATCH 013/196] Fix error message --- htdocs/expedition/card.php | 13 ++++--------- htdocs/product/stock/class/mouvementstock.class.php | 1 + 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 12a5e5747b3..289d317abb7 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -435,16 +435,11 @@ if (empty($reshook)) $result = $object->valid($user); - if ($result < 0) - { - $langs->load("errors"); - setEventMessages($langs->trans($object->error), $object->errors, 'errors'); - } - else - { + if ($result < 0) { + setEventMessages($object->error, $object->errors, 'errors'); + } else { // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) { $outputlangs = $langs; $newlang = ''; if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09'); diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index ffc84f41e92..5c44019b1fc 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -204,6 +204,7 @@ class MouvementStock extends CommonObject { if (empty($batch)) { + $langs->load("errors"); $this->errors[] = $langs->transnoentitiesnoconv("ErrorTryToMakeMoveOnProductRequiringBatchData", $product->ref); dol_syslog("Try to make a movement of a product with status_batch on without any batch data"); From 657749375fe9a5fa4e112403be9bdbe23a7d7ac2 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 16:47:13 +0100 Subject: [PATCH 014/196] Avoid error --- test/phpunit/CoreTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/phpunit/CoreTest.php b/test/phpunit/CoreTest.php index 3169c4063c0..3cfad799181 100644 --- a/test/phpunit/CoreTest.php +++ b/test/phpunit/CoreTest.php @@ -133,6 +133,7 @@ class CoreTest extends PHPUnit\Framework\TestCase * * @return void */ + /* public function testDetectURLROOT() { global $dolibarr_main_prod; @@ -236,7 +237,7 @@ class CoreTest extends PHPUnit\Framework\TestCase return true; } - + */ /** * testSqlAndScriptInjectWithPHPUnit From 4119174ef1c6c21c21fd520755702999edb7eb2d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 27 Nov 2020 16:52:52 +0100 Subject: [PATCH 015/196] Include sql injection tests into PHPUnit --- test/phpunit/AllTests.php | 4 +- test/phpunit/CoreTest.php | 195 ---------------------------------- test/phpunit/SecurityTest.php | 117 ++++++++++++++++++-- 3 files changed, 113 insertions(+), 203 deletions(-) diff --git a/test/phpunit/AllTests.php b/test/phpunit/AllTests.php index d07cc34a544..09c075c1083 100644 --- a/test/phpunit/AllTests.php +++ b/test/phpunit/AllTests.php @@ -77,8 +77,8 @@ class AllTests $suite = new PHPUnit\Framework\TestSuite('PHPUnit Framework'); - require_once dirname(__FILE__).'/CoreTest.php'; - $suite->addTestSuite('CoreTest'); + //require_once dirname(__FILE__).'/CoreTest.php'; + //$suite->addTestSuite('CoreTest'); require_once dirname(__FILE__).'/AdminLibTest.php'; $suite->addTestSuite('AdminLibTest'); require_once dirname(__FILE__).'/CompanyLibTest.php'; diff --git a/test/phpunit/CoreTest.php b/test/phpunit/CoreTest.php index 3cfad799181..22649a80724 100644 --- a/test/phpunit/CoreTest.php +++ b/test/phpunit/CoreTest.php @@ -133,7 +133,6 @@ class CoreTest extends PHPUnit\Framework\TestCase * * @return void */ - /* public function testDetectURLROOT() { global $dolibarr_main_prod; @@ -237,198 +236,4 @@ class CoreTest extends PHPUnit\Framework\TestCase return true; } - */ - - /** - * testSqlAndScriptInjectWithPHPUnit - * - * @return void - */ - public function testSqlAndScriptInjectWithPHPUnit() - { - // This is code copied from main.inc.php !!!!!!!!!!!!!!! - - /** - * Security: WAF layer for SQL Injection and XSS Injection (scripts) protection (Filters on GET, POST, PHP_SELF). - * - * @param string $val Value brut found int $_GET, $_POST or PHP_SELF - * @param string $type 1=GET, 0=POST, 2=PHP_SELF, 3=GET without sql reserved keywords (the less tolerant test) - * @return int >0 if there is an injection, 0 if none - */ - function testSqlAndScriptInject($val, $type) - { - // Decode string first - // So error=alert(1) - $val = preg_replace('//', '', $val); - - $inj = 0; - // For SQL Injection (only GET are used to be included into bad escaped SQL requests) - if ($type == 1 || $type == 3) - { - $inj += preg_match('/delete\s+from/i', $val); - $inj += preg_match('/create\s+table/i', $val); - $inj += preg_match('/insert\s+into/i', $val); - $inj += preg_match('/select\s+from/i', $val); - $inj += preg_match('/into\s+(outfile|dumpfile)/i', $val); - $inj += preg_match('/user\s*\(/i', $val); // avoid to use function user() that return current database login - $inj += preg_match('/information_schema/i', $val); // avoid to use request that read information_schema database - $inj += preg_match('/ - $inj += preg_match('/ondrag([a-z]*)\s*=/i', $val); // - $inj += preg_match('/ontouch([a-z]*)\s*=/i', $val); // - $inj += preg_match('/on(abort|afterprint|beforeprint|beforeunload|blur|canplay|canplaythrough|change|click|contextmenu|copy|cut)\s*=/i', $val); - $inj += preg_match('/on(dblclick|drop|durationchange|ended|error|focus|focusin|focusout|hashchange|input|invalid)\s*=/i', $val); - $inj += preg_match('/on(keydown|keypress|keyup|load|loadeddata|loadedmetadata|loadstart|offline|online|pagehide|pageshow)\s*=/i', $val); - $inj += preg_match('/on(paste|pause|play|playing|progress|ratechange|resize|reset|scroll|search|seeking|select|show|stalled|start|submit|suspend)\s*=/i', $val); - $inj += preg_match('/on(timeupdate|toggle|unload|volumechange|waiting)\s*=/i', $val); - //$inj += preg_match('/on[A-Z][a-z]+\*=/', $val); // To lock event handlers onAbort(), ... - $inj += preg_match('/:|:|:/i', $val); // refused string ':' encoded (no reason to have it encoded) to lock 'javascript:...' - $inj += preg_match('/javascript\s*:/i', $val); - $inj += preg_match('/vbscript\s*:/i', $val); - // For XSS Injection done by adding javascript closing html tags like with onmousemove, etc... (closing a src or href tag with not cleaned param) - if ($type == 1) { - $val = str_replace('enclosure="', 'enclosure=X', $val); // We accept enclosure=" - $inj += preg_match('/"/i', $val); // We refused " in GET parameters value. - } - if ($type == 2) $inj += preg_match('/[;"]/', $val); // PHP_SELF is a file system path. It can contains spaces. - return $inj; - } - - - // Run tests - // More on https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet - - // Should be OK - $expectedresult=0; - - $_SERVER["PHP_SELF"]='/DIR WITH SPACE/htdocs/admin/index.php?mainmenu=home&leftmenu=setup&username=weservices'; - $result=testSqlAndScriptInject($_SERVER["PHP_SELF"], 2); - $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject 1a'); - - // Should detect XSS - $expectedresult=1; - - $_SERVER["PHP_SELF"]='/DIR WITH SPACE/htdocs/admin/index.php?mainmenu=home&leftmenu=setup&username=weservices;badaction'; - $result=testSqlAndScriptInject($_SERVER["PHP_SELF"], 2); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject 1b'); - - $test=""; - $result=testSqlAndScriptInject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa'); - - $test=""; - $result=testSqlAndScriptInject($test, 2); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa2'); - - $test=''; - $result=testSqlAndScriptInject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa3'); - $test=''; - $result=testSqlAndScriptInject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa4'); - $test=''; - $result=testSqlAndScriptInject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa5'); - $test=''; - $result=testSqlAndScriptInject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa6'); - $test=''; - $result=testSqlAndScriptInject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject aaa7'); - - $test=''; - $result=testSqlAndScriptInject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject bbb'); - - $test=''; - $result=testSqlAndScriptInject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject ccc'); - - $test=''; - $result=testSqlAndScriptInject($test, 1); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject ddd'); - - $test='">'; - $result=testSqlAndScriptInject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject eee'); - - $test=' - '; - $result=testSqlAndScriptInject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject eee'); - - $test=""; // Is locked by some browser like chrome because the default directive no-referrer-when-downgrade is sent when requesting the SRC and then refused because of browser protection on img src load without referrer. - $test=""; // Same - - $test=''; - $result=testSqlAndScriptInject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject fff1'); - $test=''; - $result=testSqlAndScriptInject($test, 0); - $this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject fff2'); - - // This case seems to be filtered by browsers now. - $test=''; - //$result=testSqlAndScriptInject($test, 0); - //$this->assertGreaterThanOrEqual($expectedresult, $result, 'Error on testSqlAndScriptInject ggg'); - - $test='