From 272e8f79c9a73157eebde3d19c6a06ec08e4491c Mon Sep 17 00:00:00 2001 From: MDW Date: Tue, 20 Feb 2024 01:26:25 +0100 Subject: [PATCH 01/11] Fix: Improve test configuration (#28294) # Fix: Improve test configuration ## Do not fail early when running tests (stopOnFailure->false) Finishing the phpunits tests does not require a lot of extra time so rather than quiting early, run them all. Also, when needed this option can be enabled on the CLI, but it can not be disabled. So when desired, it can still be added in a ci-flow or local script. ## Improve reporting We want to report Notices and Warnings and with enough detail to help during debug. These options are explicitly activated. --- test/phpunit/phpunittest.xml | 90 ++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 41 deletions(-) diff --git a/test/phpunit/phpunittest.xml b/test/phpunit/phpunittest.xml index 8157d3f3e7a..ce189fe6326 100644 --- a/test/phpunit/phpunittest.xml +++ b/test/phpunit/phpunittest.xml @@ -1,45 +1,53 @@ - - - - - - - - - ../../htdocs/ - ../../htdocs/ - ../../htdocs/ - ../../htdocs/ - ../../htdocs/core/modules/facture/modules_facture.php - ../../htdocs/core/modules/commande/modules_commande.php - ../../htdocs/core/modules/propale/modules_propale.php - ../../htdocs/core/modules/project/modules_project.php - ../../htdocs/core/modules/fichinter/modules_fichinter.php - - ../../build/ - ../../dev/ - ../../doc/ - ../../test/ - ../../documents/ - ../../htdocs/custom/ - ../../htdocs/documents/custom/ - ../../htdocs/nltechno/ - ../../htdocs/products/canvas/ - ../../htdocs/contact/canvas/ - ../../htdocs/societe/canvas/ - ../../htdocs/includes/ - - - + backupGlobals="false" + backupStaticAttributes="true" + convertErrorsToExceptions="true" + convertNoticesToExceptions="true" + convertWarningsToExceptions="true" + colors="true" + processIsolation="false" + stopOnFailure="false"> + + + + + + + + + + + + + + + + + ../../htdocs/ + ../../htdocs/ + ../../htdocs/ + ../../htdocs/ + ../../htdocs/core/modules/facture/modules_facture.php + ../../htdocs/core/modules/commande/modules_commande.php + ../../htdocs/core/modules/propale/modules_propale.php + ../../htdocs/core/modules/project/modules_project.php + ../../htdocs/core/modules/fichinter/modules_fichinter.php + + + ../../build/ + ../../dev/ + ../../doc/ + ../../test/ + ../../documents/ + ../../htdocs/custom/ + ../../htdocs/documents/custom/ + ../../htdocs/nltechno/ + ../../htdocs/products/canvas/ + ../../htdocs/contact/canvas/ + ../../htdocs/societe/canvas/ + ../../htdocs/includes/ + + From b2d90629e7fd7a7d11a5ff2fbc687f055771fb35 Mon Sep 17 00:00:00 2001 From: MDW Date: Tue, 20 Feb 2024 01:27:46 +0100 Subject: [PATCH 02/11] Qual: Apply php-cs-fixer to make only manual changes stand-out (#28300) * Qual: Apply php-cs-fixer to make only manual changes stand-out # Qual: Apply php-cs-fixer to make only manual changes stand-out A few changes will be proposed in the future to these files. This already commits the esthetic changes using php-cs-fixes. * Qual: Apply php-cs-fixer to make only manual changes stand-out # Qual: Apply php-cs-fixer to make only manual changes stand-out A few changes will be proposed in the future to these files. This already commits the esthetic changes using php-cs-fixes. * Qual: Apply php-cs-fixer to make only manual changes stand-out # Qual: Apply php-cs-fixer to make only manual changes stand-out A few changes will be proposed in the future to these files. This already commits the esthetic changes using php-cs-fixes. --- htdocs/core/class/commonobject.class.php | 88 ++++++++++++------------ htdocs/core/class/commonpeople.class.php | 1 + htdocs/core/lib/functions.lib.php | 2 +- 3 files changed, 46 insertions(+), 45 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 93e4fd1074b..38a1ff9ad44 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -911,10 +911,10 @@ abstract class CommonObject } $labelextra = $langs->trans((string) $extrafields->attributes[$this->table_element]['label'][$key]); if ($extrafields->attributes[$this->table_element]['type'][$key] == 'separate') { - $data[$key]= '
'. $labelextra . ''; + $data[$key] = '
'. $labelextra . ''; } else { $value = (empty($this->array_options['options_' . $key]) ? '' : $this->array_options['options_' . $key]); - $data[$key]= '
'. $labelextra . ': ' . $extrafields->showOutputField($key, $value, '', $this->table_element); + $data[$key] = '
'. $labelextra . ': ' . $extrafields->showOutputField($key, $value, '', $this->table_element); $count++; } } @@ -957,7 +957,7 @@ abstract class CommonObject { global $hookmanager; - $parameters = array('objref'=>$objref); + $parameters = array('objref' => $objref); $action = ''; $reshook = $hookmanager->executeHooks('getFormatedCustomerRef', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { @@ -976,7 +976,7 @@ abstract class CommonObject { global $hookmanager; - $parameters = array('objref'=>$objref); + $parameters = array('objref' => $objref); $action = ''; $reshook = $hookmanager->executeHooks('getFormatedSupplierRef', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { @@ -1441,8 +1441,8 @@ abstract class CommonObject 'civility' => $obj->civility, 'lastname' => $obj->lastname, 'firstname' => $obj->firstname, - 'email'=>$obj->email, - 'login'=> (empty($obj->login) ? '' : $obj->login), + 'email' => $obj->email, + 'login' => (empty($obj->login) ? '' : $obj->login), 'photo' => (empty($obj->photo) ? '' : $obj->photo), 'statuscontact' => $obj->statuscontact, 'rowid' => $obj->rowid, @@ -1769,8 +1769,8 @@ abstract class CommonObject if ($idtofetch) { $thirdparty = new Societe($this->db); $result = $thirdparty->fetch($idtofetch); - if ($result<0) { - $this->errors=array_merge($this->errors, $thirdparty->errors); + if ($result < 0) { + $this->errors = array_merge($this->errors, $thirdparty->errors); } $this->thirdparty = $thirdparty; @@ -2980,7 +2980,7 @@ abstract class CommonObject } else { if (!$notrigger) { // Call trigger - $this->context = array('shippingmethodupdate'=>1); + $this->context = array('shippingmethodupdate' => 1); $result = $this->call_trigger(strtoupper(get_class($this)).'_MODIFY', $userused); if ($result < 0) { $error++; @@ -3320,8 +3320,8 @@ abstract class CommonObject dol_print_error($this->db); return -1; } else { - $parameters=array('rowid'=>$rowid, 'rang'=>$rang, 'fieldposition' => $fieldposition); - $action=''; + $parameters = array('rowid' => $rowid, 'rang' => $rang, 'fieldposition' => $fieldposition); + $action = ''; $reshook = $hookmanager->executeHooks('afterRankOfLineUpdate', $parameters, $this, $action); return 1; } @@ -3965,7 +3965,7 @@ abstract class CommonObject // Add module part to target type if object has $module property and isn't in core modules. $targettype = ((!empty($this->module) && ! in_array($this->module, $coremodule)) ? $this->module.'_' : '').$this->element; - $parameters = array('targettype'=>$targettype); + $parameters = array('targettype' => $targettype); // Hook for explicitly set the targettype if it must be differtent than $this->element $reshook = $hookmanager->executeHooks('setLinkedObjectSourceTargetType', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { @@ -4056,7 +4056,7 @@ abstract class CommonObject $withtargettype = false; $withsourcetype = false; - $parameters = array('sourcetype'=>$sourcetype, 'sourceid'=>$sourceid, 'targettype'=>$targettype, 'targetid'=>$targetid); + $parameters = array('sourcetype' => $sourcetype, 'sourceid' => $sourceid, 'targettype' => $targettype, 'targetid' => $targetid); // Hook for explicitly set the targettype if it must be differtent than $this->element $reshook = $hookmanager->executeHooks('setLinkedObjectSourceTargetType', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if ($reshook > 0) { @@ -4750,26 +4750,26 @@ abstract class CommonObject //print $id.'-'.$table.'-'.$elementname.'
'; // Check if element can be deleted $sql = "SELECT COUNT(*) as nb"; - $sql.= " FROM ".$this->db->prefix().$table." as c"; + $sql .= " FROM ".$this->db->prefix().$table." as c"; if (!empty($element['parent']) && !empty($element['parentkey'])) { - $sql.= ", ".$this->db->prefix().$element['parent']." as p"; + $sql .= ", ".$this->db->prefix().$element['parent']." as p"; } if (!empty($element['fk_element'])) { - $sql.= " WHERE c.".$element['fk_element']." = ".((int) $id); + $sql .= " WHERE c.".$element['fk_element']." = ".((int) $id); } else { - $sql.= " WHERE c.".$this->fk_element." = ".((int) $id); + $sql .= " WHERE c.".$this->fk_element." = ".((int) $id); } if (!empty($element['parent']) && !empty($element['parentkey'])) { - $sql.= " AND c.".$element['parentkey']." = p.rowid"; + $sql .= " AND c.".$element['parentkey']." = p.rowid"; } if (!empty($element['parent']) && !empty($element['parenttypefield']) && !empty($element['parenttypevalue'])) { - $sql.= " AND c.".$element['parenttypefield']." = '".$this->db->escape($element['parenttypevalue'])."'"; + $sql .= " AND c.".$element['parenttypefield']." = '".$this->db->escape($element['parenttypevalue'])."'"; } if (!empty($entity)) { if (!empty($element['parent']) && !empty($element['parentkey'])) { - $sql.= " AND p.entity = ".((int) $entity); + $sql .= " AND p.entity = ".((int) $entity); } else { - $sql.= " AND c.entity = ".((int) $entity); + $sql .= " AND c.entity = ".((int) $entity); } } @@ -4973,7 +4973,7 @@ abstract class CommonObject } } - return array('weight'=>$totalWeight, 'volume'=>$totalVolume, 'ordered'=>$totalOrdered, 'toship'=>$totalToShip); + return array('weight' => $totalWeight, 'volume' => $totalVolume, 'ordered' => $totalOrdered, 'toship' => $totalToShip); } @@ -5093,7 +5093,7 @@ abstract class CommonObject } $extrafields->fetch_name_optionals_label($this->table_element_line); - $parameters = array('num'=>$num, 'dateSelector'=>$dateSelector, 'seller'=>$seller, 'buyer'=>$buyer, 'selected'=>$selected, 'table_element_line'=>$this->table_element_line); + $parameters = array('num' => $num, 'dateSelector' => $dateSelector, 'seller' => $seller, 'buyer' => $buyer, 'selected' => $selected, 'table_element_line' => $this->table_element_line); $reshook = $hookmanager->executeHooks('printObjectLineTitle', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if (empty($reshook)) { // Output template part (modules that overwrite templates must declare this into descriptor) @@ -5130,10 +5130,10 @@ abstract class CommonObject //if (is_object($hookmanager) && (($line->product_type == 9 && !empty($line->special_code)) || !empty($line->fk_parent_line))) if (is_object($hookmanager)) { // Old code is commented on preceding line. if (empty($line->fk_parent_line)) { - $parameters = array('line'=>$line, 'num'=>$num, 'i'=>$i, 'dateSelector'=>$dateSelector, 'seller'=>$seller, 'buyer'=>$buyer, 'selected'=>$selected, 'table_element_line'=>$line->table_element, 'defaulttpldir'=>$defaulttpldir); + $parameters = array('line' => $line, 'num' => $num, 'i' => $i, 'dateSelector' => $dateSelector, 'seller' => $seller, 'buyer' => $buyer, 'selected' => $selected, 'table_element_line' => $line->table_element, 'defaulttpldir' => $defaulttpldir); $reshook = $hookmanager->executeHooks('printObjectLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks } else { - $parameters = array('line'=>$line, 'num'=>$num, 'i'=>$i, 'dateSelector'=>$dateSelector, 'seller'=>$seller, 'buyer'=>$buyer, 'selected'=>$selected, 'table_element_line'=>$line->table_element, 'fk_parent_line'=>$line->fk_parent_line, 'defaulttpldir'=>$defaulttpldir); + $parameters = array('line' => $line, 'num' => $num, 'i' => $i, 'dateSelector' => $dateSelector, 'seller' => $seller, 'buyer' => $buyer, 'selected' => $selected, 'table_element_line' => $line->table_element, 'fk_parent_line' => $line->fk_parent_line, 'defaulttpldir' => $defaulttpldir); $reshook = $hookmanager->executeHooks('printObjectSubLine', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks } } @@ -5316,7 +5316,7 @@ abstract class CommonObject $reshook = 0; //if (is_object($hookmanager) && (($line->product_type == 9 && !empty($line->special_code)) || !empty($line->fk_parent_line))) { if (is_object($hookmanager)) { // Old code is commented on preceding line. - $parameters = array('line'=>$line, 'i'=>$i, 'restrictlist'=>$restrictlist, 'selectedLines'=> $selectedLines); + $parameters = array('line' => $line, 'i' => $i, 'restrictlist' => $restrictlist, 'selectedLines' => $selectedLines); if (!empty($line->fk_parent_line)) { $parameters['fk_parent_line'] = $line->fk_parent_line; } @@ -5597,7 +5597,7 @@ abstract class CommonObject $srctemplatepath = ''; - $parameters = array('modelspath'=>$modelspath, 'modele'=>$modele, 'outputlangs'=>$outputlangs, 'hidedetails'=>$hidedetails, 'hidedesc'=>$hidedesc, 'hideref'=>$hideref, 'moreparams'=>$moreparams); + $parameters = array('modelspath' => $modelspath, 'modele' => $modele, 'outputlangs' => $outputlangs, 'hidedetails' => $hidedetails, 'hidedesc' => $hidedesc, 'hideref' => $hideref, 'moreparams' => $moreparams); $reshook = $hookmanager->executeHooks('commonGenerateDocument', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks if (!empty($reshook)) { @@ -6332,7 +6332,7 @@ abstract class CommonObject return 0; } } else { - $this->errors[]=$this->db->lasterror; + $this->errors[] = $this->db->lasterror; return -1; } } @@ -6653,7 +6653,7 @@ abstract class CommonObject if (!$error && $trigger) { // Call trigger - $this->context = array('extrafieldaddupdate'=>1); + $this->context = array('extrafieldaddupdate' => 1); $result = $this->call_trigger($trigger, $userused); if ($result < 0) { $error++; @@ -6771,7 +6771,7 @@ abstract class CommonObject if (!$error && $trigger) { // Call trigger - $this->context = array('extralanguagesaddupdate'=>1); + $this->context = array('extralanguagesaddupdate' => 1); $result = $this->call_trigger($trigger, $userused); if ($result < 0) { $error++; @@ -7066,7 +7066,7 @@ abstract class CommonObject if (!$error && $trigger) { // Call trigger - $this->context = array('extrafieldupdate'=>1); + $this->context = array('extrafieldupdate' => 1); $result = $this->call_trigger($trigger, $userused); if ($result < 0) { $error++; @@ -7197,7 +7197,7 @@ abstract class CommonObject // Special case that force options and type ($type can be integer, varchar, ...) if (!empty($this->fields[$key]['arrayofkeyval']) && is_array($this->fields[$key]['arrayofkeyval'])) { $param['options'] = $this->fields[$key]['arrayofkeyval']; - $type = (($this->fields[$key]['type']=='checkbox') ? $this->fields[$key]['type'] : 'select'); + $type = (($this->fields[$key]['type'] == 'checkbox') ? $this->fields[$key]['type'] : 'select'); } $label = $this->fields[$key]['label']; @@ -7249,7 +7249,7 @@ abstract class CommonObject // Add validation state class if (!empty($validationClass)) { - $morecss.= $validationClass; + $morecss .= $validationClass; } if (in_array($type, array('date'))) { @@ -7375,7 +7375,7 @@ abstract class CommonObject $pos++; } $tmpbefore = substr($InfoFieldList[4], 0, $pos); - $tmpafter = substr($InfoFieldList[4], $pos+1); + $tmpafter = substr($InfoFieldList[4], $pos + 1); //var_dump($InfoFieldList[4].' -> '.$pos); var_dump($tmpafter); $InfoFieldList[4] = $tmpbefore; if ($tmpafter !== '') { @@ -7796,7 +7796,7 @@ abstract class CommonObject $out = ''; } - if ($isDependList==1) { + if ($isDependList == 1) { $out .= $this->getJSListDependancies('_common'); } /* Add comments @@ -7847,7 +7847,7 @@ abstract class CommonObject $type = 'varchar'; // convert varchar(xx) int varchar } if (!empty($val['arrayofkeyval']) && is_array($val['arrayofkeyval'])) { - $type = (($this->fields[$key]['type']=='checkbox') ? $this->fields[$key]['type'] : 'select'); + $type = (($this->fields[$key]['type'] == 'checkbox') ? $this->fields[$key]['type'] : 'select'); } if (preg_match('/^integer:(.*):(.*)/i', $val['type'], $reg)) { $type = 'link'; @@ -8359,7 +8359,7 @@ abstract class CommonObject if (preg_match('/^integer:(.*):(.*)/i', $val['type'], $reg)) { $type = 'link'; - $param['options'] = array($reg[1].':'.$reg[2]=>$reg[1].':'.$reg[2]); + $param['options'] = array($reg[1].':'.$reg[2] => $reg[1].':'.$reg[2]); } elseif (preg_match('/^sellist:(.*):(.*):(.*):(.*)/i', $val['type'], $reg)) { $param['options'] = array($reg[1].':'.$reg[2].':'.$reg[3].':'.$reg[4] => 'N'); $type = 'sellist'; @@ -8529,7 +8529,7 @@ abstract class CommonObject $out = ''; - $parameters = array('mode'=>$mode, 'params'=>$params, 'keysuffix'=>$keysuffix, 'keyprefix'=>$keyprefix, 'display_type'=>$display_type); + $parameters = array('mode' => $mode, 'params' => $params, 'keysuffix' => $keysuffix, 'keyprefix' => $keyprefix, 'display_type' => $display_type); $reshook = $hookmanager->executeHooks('showOptionals', $parameters, $this, $action); // Note that $action and $object may have been modified by hook if (empty($reshook)) { @@ -8590,7 +8590,7 @@ abstract class CommonObject } $colspan = 0; - if (is_array($params) && count($params) > 0 && $display_type=='card') { + if (is_array($params) && count($params) > 0 && $display_type == 'card') { if (array_key_exists('cols', $params)) { $colspan = $params['cols']; } elseif (array_key_exists('colspan', $params)) { // For backward compatibility. Use cols instead now. @@ -8677,7 +8677,7 @@ abstract class CommonObject $domData .= ' data-targetid="'.$this->id.'"'; $html_id = (empty($this->id) ? '' : 'extrarow-'.$this->element.'_'.$key.'_'.$this->id); - if ($display_type=='card') { + if ($display_type == 'card') { if (getDolGlobalString('MAIN_EXTRAFIELDS_USE_TWO_COLUMS') && ($e % 2) == 0) { $colspan = 0; } @@ -8788,12 +8788,12 @@ abstract class CommonObject break; } - $out .= ($display_type=='card' ? '' : ''); + $out .= ($display_type == 'card' ? '' : ''); if (getDolGlobalString('MAIN_EXTRAFIELDS_USE_TWO_COLUMS') && (($e % 2) == 1)) { - $out .= ($display_type=='card' ? '' : ''); + $out .= ($display_type == 'card' ? '' : ''); } else { - $out .= ($display_type=='card' ? '' : ''); + $out .= ($display_type == 'card' ? '' : ''); } $e++; @@ -10572,7 +10572,7 @@ abstract class CommonObject // Process foreach ($to_del as $del) { if ($c->fetch($del) > 0) { - $result=$c->del_type($this, $type_categ); + $result = $c->del_type($this, $type_categ); if ($result < 0) { $error++; $this->error = $c->error; diff --git a/htdocs/core/class/commonpeople.class.php b/htdocs/core/class/commonpeople.class.php index 8c7daf0e074..00063ad2685 100644 --- a/htdocs/core/class/commonpeople.class.php +++ b/htdocs/core/class/commonpeople.class.php @@ -1,5 +1,6 @@ + * Copyright (C) 2024 MDW * * 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 diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 48ba1267862..c1fbff4a59e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -4597,7 +4597,7 @@ function img_picto($titlealt, $picto, $moreatt = '', $pictoisfullpath = false, $ 'graph' => 'chart-line', 'grip_title' => 'arrows-alt', 'grip' => 'arrows-alt', 'help' => 'question-circle', 'generic' => 'file', 'holiday' => 'umbrella-beach', 'info' => 'info-circle', 'inventory' => 'boxes', 'intracommreport' => 'globe-europe', 'jobprofile' => 'cogs', - 'knowledgemanagement' => 'ticket-alt', 'label' => 'layer-group', 'layout'=>'columns', 'line' => 'bars', 'loan' => 'money-bill-alt', + 'knowledgemanagement' => 'ticket-alt', 'label' => 'layer-group', 'layout' => 'columns', 'line' => 'bars', 'loan' => 'money-bill-alt', 'member' => 'user-alt', 'meeting' => 'chalkboard-teacher', 'mrp' => 'cubes', 'next' => 'arrow-alt-circle-right', 'trip' => 'wallet', 'expensereport' => 'wallet', 'group' => 'users', 'movement' => 'people-carry', 'sign-out' => 'sign-out-alt', From 7dce4c354d1696f2171373435c673e649d2fb0e6 Mon Sep 17 00:00:00 2001 From: MDW Date: Tue, 20 Feb 2024 01:29:47 +0100 Subject: [PATCH 03/11] Fix: PHPUnit Object Test template (#28299) # Fix PHPUnit Object Test template Fix some typing issues discovered when reusing the template. --- .../template/test/phpunit/MyObjectTest.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/htdocs/modulebuilder/template/test/phpunit/MyObjectTest.php b/htdocs/modulebuilder/template/test/phpunit/MyObjectTest.php index 47e3d8f475e..89b2e3db554 100644 --- a/htdocs/modulebuilder/template/test/phpunit/MyObjectTest.php +++ b/htdocs/modulebuilder/template/test/phpunit/MyObjectTest.php @@ -1,6 +1,7 @@ -/* Copyright (C) 2023 Alexandre Janniaux +/* Copyright (C) 2007-2017 Laurent Destailleur +/* Copyright (C) 2023 Alexandre Janniaux + * Copyright (C) 2024 MDW * Copyright (C) ---Put here your own copyright and developer email--- * * This program is free software: you can redistribute it and/or modify @@ -81,7 +82,7 @@ class MyObjectTest extends PHPUnit\Framework\TestCase * * @return void */ - public static function setUpBeforeClass() + public static function setUpBeforeClass(): void { global $conf, $user, $langs, $db; $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. @@ -94,7 +95,7 @@ class MyObjectTest extends PHPUnit\Framework\TestCase * * @return void */ - protected function setUp() + protected function setUp(): void { global $conf, $user, $langs, $db; $conf = $this->savconf; @@ -110,7 +111,7 @@ class MyObjectTest extends PHPUnit\Framework\TestCase * * @return void */ - protected function tearDown() + protected function tearDown(): void { print __METHOD__."\n"; } @@ -120,7 +121,7 @@ class MyObjectTest extends PHPUnit\Framework\TestCase * * @return void */ - public static function tearDownAfterClass() + public static function tearDownAfterClass(): void { global $conf, $user, $langs, $db; $db->rollback(); From 1263af735fc8d0e1603a81f0df002f0b6db370b5 Mon Sep 17 00:00:00 2001 From: thibdrev Date: Tue, 20 Feb 2024 02:00:11 +0100 Subject: [PATCH 04/11] qual: phpstan for htdocs/product/fournisseurs.php (#28289) htdocs/product/fournisseurs.php 146 Property Product::$cost_price (float) does not accept string. --- htdocs/product/fournisseurs.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index 84437ca0b05..87522b88255 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -48,16 +48,16 @@ if (isModEnabled('barcode')) { // Load translation files required by the page $langs->loadLangs(array('products', 'suppliers', 'bills', 'margins', 'stocks')); -$id = GETPOST('id', 'int'); +$id = GETPOSTINT('id'); $ref = GETPOST('ref', 'alpha'); -$rowid = GETPOST('rowid', 'int'); +$rowid = GETPOSTINT('rowid'); $action = GETPOST('action', 'aZ09'); $cancel = GETPOST('cancel', 'alpha'); $contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'pricesuppliercard'; -$socid = GETPOST('socid', 'int'); -$cost_price = price2num(GETPOST('cost_price', 'alpha'), '', 2); -$pmp = price2num(GETPOST('pmp', 'alpha'), '', 2); +$socid = GETPOSTINT('socid'); +$cost_price = GETPOSTFLOAT('cost_price'); +$pmp = GETPOSTFLOAT('pmp'); $backtopage = GETPOST('backtopage', 'alpha'); $error = 0; @@ -65,9 +65,9 @@ $error = 0; $extrafields = new ExtraFields($db); // If socid provided by ajax company selector -if (GETPOST('search_fourn_id', 'int')) { - $_GET['id_fourn'] = GETPOST('search_fourn_id', 'int'); - $_POST['id_fourn'] = GETPOST('search_fourn_id', 'int'); +if (GETPOSTINT('search_fourn_id')) { + $_GET['id_fourn'] = GETPOSTINT('search_fourn_id'); + $_POST['id_fourn'] = GETPOSTINT('search_fourn_id'); } // Security check @@ -81,10 +81,10 @@ if (!$user->hasRight('fournisseur', 'lire') && (!isModEnabled('margin') && !$use accessforbidden(); } -$limit = GETPOST('limit', 'int') ? GETPOST('limit', 'int') : $conf->liste_limit; +$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit; $sortfield = GETPOST('sortfield', 'aZ09comma'); $sortorder = GETPOST('sortorder', 'aZ09comma'); -$page = (GETPOST("page", 'int') ? GETPOST("page", 'int') : 0); +$page = GETPOSTINT("page") ? GETPOSTINT("page") : 0; if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 @@ -143,7 +143,7 @@ if (empty($reshook)) { $result = $object->fetch($id); //Need dol_clone methode 1 (same object class) because update product use hasbatch method on oldcopy $object->oldcopy = dol_clone($object, 1); - $object->cost_price = price2num($cost_price); + $object->cost_price = $cost_price; $result = $object->update($object->id, $user); if ($result > 0) { setEventMessages($langs->trans("RecordSaved"), null, 'mesgs'); @@ -157,7 +157,7 @@ if (empty($reshook)) { if ($action == 'setpmp') { if ($id) { $result = $object->fetch($id); - $object->pmp = price2num($pmp); + $object->pmp = $pmp; $sql = "UPDATE ".MAIN_DB_PREFIX."product SET pmp = ".((float) $object->pmp)." WHERE rowid = ".((int) $id); $resql = $db->query($sql); //$result = $object->update($object->id, $user); @@ -297,7 +297,7 @@ if (empty($reshook)) { $extralabels = $extrafields->fetch_name_optionals_label("product_fournisseur_price"); $extrafield_values = $extrafields->getOptionalsFromPost("product_fournisseur_price"); - $newprice = price2num(GETPOST("price", "alpha")); + $newprice = GETPOSTFLOAT("price"); if (empty($packaging)) { $packaging = 1; @@ -309,8 +309,8 @@ if (empty($reshook)) { $object->packaging = $packaging; if (isModEnabled("multicurrency")) { - $multicurrency_tx = price2num(GETPOST("multicurrency_tx", 'alpha')); - $multicurrency_price = price2num(GETPOST("multicurrency_price", 'alpha')); + $multicurrency_tx = GETPOSTFLOAT("multicurrency_tx"); + $multicurrency_price = GETPOSTFLOAT("multicurrency_price"); $multicurrency_code = GETPOST("multicurrency_code", 'alpha'); $ret = $object->update_buyprice($quantity, $newprice, $user, GETPOST("price_base_type"), $supplier, GETPOST("oselDispo"), $ref_fourn, $tva_tx, GETPOST("charges"), $remise_percent, 0, $npr, $delivery_time_days, $supplier_reputation, array(), '', $multicurrency_price, GETPOST("multicurrency_price_base_type"), $multicurrency_tx, $multicurrency_code, $supplier_description, $barcode, $fk_barcode_type, $extrafield_values); From 2b9a674a7c1692ed86813ae103b8fa9ede99cb21 Mon Sep 17 00:00:00 2001 From: thibdrev Date: Tue, 20 Feb 2024 02:01:34 +0100 Subject: [PATCH 05/11] qual: phpstan for htdocs/fourn/class/api_supplier_invoices.class.php (#28288) htdocs/fourn/class/api_supplier_invoices.class.php 474 Property Paiement::$datepaye (int) does not accept string. htdocs/fourn/class/api_supplier_invoices.class.php 475 Property Paiement::$amounts (array) does not accept array. htdocs/fourn/class/api_supplier_invoices.class.php 476 Property Paiement::$multicurrency_amounts (array) does not accept arra --- htdocs/fourn/class/api_supplier_invoices.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index d79d9769fd8..c96182ec545 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -400,7 +400,7 @@ class SupplierInvoices extends DolibarrApi * Add payment line to a specific supplier invoice with the remain to pay as amount. * * @param int $id Id of invoice - * @param string $datepaye {@from body} Payment date {@type timestamp} + * @param int $datepaye {@from body} Payment date {@type timestamp} * @param int $payment_mode_id {@from body} Payment mode ID (look it up via REST GET to /setup/dictionary/payment_types) {@min 1} * @param string $closepaidinvoices {@from body} Close paid invoices {@choice yes,no} * @param int $accountid {@from body} Bank account ID (look it up via REST GET to /bankaccounts) {@min 1} @@ -461,12 +461,12 @@ class SupplierInvoices extends DolibarrApi $amounts = array(); $multicurrency_amounts = array(); - $paymentamount = price2num($paymentamount, 'MT'); + $paymentamount = (float) price2num($paymentamount, 'MT'); $amounts[$id] = $paymentamount; // Multicurrency - $newvalue = price2num($this->invoice->multicurrency_total_ttc, 'MT'); + $newvalue = (float) price2num($this->invoice->multicurrency_total_ttc, 'MT'); $multicurrency_amounts[$id] = $newvalue; // Creation of payment line From 269a3e6c105571ad25ccd71ffc84affd0a5bd73f Mon Sep 17 00:00:00 2001 From: thibdrev Date: Tue, 20 Feb 2024 02:01:55 +0100 Subject: [PATCH 06/11] qual: phpstan for htdocs/product/class/propalmergepdfproduct.class.php (#28287) htdocs/product/class/propalmergepdfproduct.class.php 313 Property Propalmergepdfproduct::$fk_product (int) does not accept string. htdocs/product/class/propalmergepdfproduct.class.php 319 Property Propalmergepdfproduct::$fk_user_mod (int) does not accept string. --- htdocs/product/class/propalmergepdfproduct.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/class/propalmergepdfproduct.class.php b/htdocs/product/class/propalmergepdfproduct.class.php index 7253c50511b..a16edd1f53f 100644 --- a/htdocs/product/class/propalmergepdfproduct.class.php +++ b/htdocs/product/class/propalmergepdfproduct.class.php @@ -310,13 +310,13 @@ class Propalmergepdfproduct extends CommonObject // Clean parameters if (isset($this->fk_product)) { - $this->fk_product = trim($this->fk_product); + $this->fk_product = (int) $this->fk_product; } if (isset($this->file_name)) { $this->file_name = trim($this->file_name); } if (isset($this->fk_user_mod)) { - $this->fk_user_mod = trim($this->fk_user_mod); + $this->fk_user_mod = (int) $this->fk_user_mod; } if (isset($this->lang)) { $this->lang = trim($this->lang); From aadea9db4fba0629ed8fe16e63021f288ed35e50 Mon Sep 17 00:00:00 2001 From: thibdrev Date: Tue, 20 Feb 2024 02:02:18 +0100 Subject: [PATCH 07/11] qual: phpstan for htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php (#28286) htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php 182 Property pdf_eagle::$atLeastOneBatch (int) does not accept bool. --- htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php index b1a5df12197..25c440b9413 100644 --- a/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php +++ b/htdocs/core/modules/stocktransfer/doc/pdf_eagle.modules.php @@ -86,7 +86,9 @@ class pdf_eagle extends ModelePDFStockTransfer public $posxwarehousedestination; /** - * @var int at Least One Batch + * @var bool True if at least one line of the StockTransfer object has a batch set. + * Populated by $pdf_eagle->atLeastOneBatch() + * @see atLeastOneBatch() */ public $atLeastOneBatch; @@ -916,7 +918,7 @@ class pdf_eagle extends ModelePDFStockTransfer * * @param StockTransfer $object Stock Transfer object * @return boolean true if at least one line has batch set, false if not - */ + */ public function atLeastOneBatch($object) { global $conf; From 7b1c8c43f648d046c8afe62f40ca89177db19e1c Mon Sep 17 00:00:00 2001 From: thibdrev Date: Tue, 20 Feb 2024 02:04:41 +0100 Subject: [PATCH 08/11] qual : phpstan for htdocs/core/class/dolgraph.class.php (#28284) * qual : phpstan for htdocs/core/class/dolgraph.class.php htdocs/core/class/dolgraph.class.php 703 Method DolGraph::GetCeilMaxValue() should return int but returns float. htdocs/core/class/dolgraph.class.php 1551 Method DolGraph::total() should return string but returns (float|int). htdocs/core/class/dolgraph.class.php 1593 Method DolGraph::getDefaultGraphSizeForStats() should return int but returns string. htdocs/core/class/dolgraph.class.php 1599 Method DolGraph::getDefaultGraphSizeForStats() should return int but returns string. * phpcs --- htdocs/core/class/dolgraph.class.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index 0fb4d9b7a66..d1743b8c733 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -700,7 +700,7 @@ class DolGraph } //print "max=".$max." res=".$res; - return $res; + return (int) $res; } // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps @@ -1540,7 +1540,7 @@ class DolGraph /** * Output HTML string to total value * - * @return string HTML string to total value + * @return float|int HTML string to total value */ public function total() { @@ -1587,16 +1587,16 @@ class DolGraph public static function getDefaultGraphSizeForStats($direction, $defaultsize = '') { global $conf; + $defaultsize = (int) $defaultsize; if ($direction == 'width') { if (empty($conf->dol_optimize_smallscreen)) { - return ($defaultsize ? $defaultsize : '500'); + return ($defaultsize ? $defaultsize : 500); } else { - return (empty($_SESSION['dol_screenwidth']) ? '280' : ($_SESSION['dol_screenwidth'] - 40)); + return (empty($_SESSION['dol_screenwidth']) ? 280 : ($_SESSION['dol_screenwidth'] - 40)); } - } - if ($direction == 'height') { - return (empty($conf->dol_optimize_smallscreen) ? ($defaultsize ? $defaultsize : '220') : '200'); + } elseif ($direction == 'height') { + return (empty($conf->dol_optimize_smallscreen) ? ($defaultsize ? $defaultsize : 220) : 200); } return 0; } From d3679744f94c3a39a4931146adb2616df629d34e Mon Sep 17 00:00:00 2001 From: thibdrev Date: Tue, 20 Feb 2024 02:05:12 +0100 Subject: [PATCH 09/11] qual: phstan - various "$tms (int) does not accept string." (#28283) * Update paymentvat.class.php * Update tva.class.php * Update localtax.class.php --- htdocs/compta/localtax/class/localtax.class.php | 2 +- htdocs/compta/tva/class/paymentvat.class.php | 2 +- htdocs/compta/tva/class/tva.class.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/compta/localtax/class/localtax.class.php b/htdocs/compta/localtax/class/localtax.class.php index 1da6c6d31d4..67d5b5b561d 100644 --- a/htdocs/compta/localtax/class/localtax.class.php +++ b/htdocs/compta/localtax/class/localtax.class.php @@ -328,7 +328,7 @@ class Localtax extends CommonObject $this->id = 0; - $this->tms = ''; + $this->tms = dol_now(); $this->ltt = 0; $this->datep = ''; $this->datev = ''; diff --git a/htdocs/compta/tva/class/paymentvat.class.php b/htdocs/compta/tva/class/paymentvat.class.php index 1f8b01d3c2d..a8f38ccb9d5 100644 --- a/htdocs/compta/tva/class/paymentvat.class.php +++ b/htdocs/compta/tva/class/paymentvat.class.php @@ -536,7 +536,7 @@ class PaymentVAT extends CommonObject { $this->id = 0; $this->fk_tva = 0; - $this->datec = ''; + $this->datec = dol_now(); $this->tms = ''; $this->datep = ''; $this->amount = ''; diff --git a/htdocs/compta/tva/class/tva.class.php b/htdocs/compta/tva/class/tva.class.php index 218d666d518..d84a5c5c588 100644 --- a/htdocs/compta/tva/class/tva.class.php +++ b/htdocs/compta/tva/class/tva.class.php @@ -419,7 +419,7 @@ class Tva extends CommonObject { $this->id = 0; - $this->tms = ''; + $this->tms = dol_now(); $this->datep = ''; $this->datev = ''; $this->amount = ''; From 246ec58531dbd7be8c16ae7f3765356b0c20b678 Mon Sep 17 00:00:00 2001 From: MDW Date: Tue, 20 Feb 2024 02:09:00 +0100 Subject: [PATCH 10/11] Qual: Refactor for distinction between encodings (STEP6) (Was PR #28228 !) (#28281) * Qual: Refactor for distinction between encodings # Qual: Refactor for distinction between encodings Renamed path/file variable to equivalents with prefix os_ and utf8. Also added $utf8_fullpath to optimize. * Fix: Fix mixed os_path/utf8_path # Fix: Fix mixed os_path/utf8_path This fixes the mixing of a os_path encoding en utf8_path encoding by reorganising the statement order. Also avoid a os_encode call by reusing data already available. --- htdocs/core/lib/files.lib.php | 78 ++++++++++++++++++----------------- 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index f981ffe081a..d40af1aadd5 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -44,7 +44,7 @@ function dol_basename($pathfile) * Scan a directory and return a list of files/directories. * Content for string is UTF8 and dir separator is "/". * - * @param string $path Starting path from which to search. This is a full path. + * @param string $utf8_path Starting path from which to search. This is a full path. * @param string $types Can be "directories", "files", or "all" * @param int $recursive Determines whether subdirectories are searched * @param string $filter Regex filter to restrict list. This regex value must be escaped for '/' by doing preg_quote($var,'/'), since this char is used for preg_match function, @@ -60,7 +60,7 @@ function dol_basename($pathfile) * @return array Array of array('name'=>'xxx','fullname'=>'/abc/xxx','date'=>'yyy','size'=>99,'type'=>'dir|file',...) * @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, $nbsecondsold = 0) +function dol_dir_list($utf8_path, $types = "all", $recursive = 0, $filter = "", $excludefilter = null, $sortcriteria = "name", $sortorder = SORT_ASC, $mode = 0, $nohook = 0, $relativename = "", $donotfollowsymlinks = 0, $nbsecondsold = 0) { global $db, $hookmanager; global $object; @@ -79,8 +79,8 @@ function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excl dol_syslog("'$f' has unescaped '/'", LOG_ERR); } } - dol_syslog("files.lib.php::dol_dir_list path=".$path." types=".$types." recursive=".$recursive." filter=".$filter." excludefilter=".json_encode($excludefilter).$error_info); - //print 'xxx'."files.lib.php::dol_dir_list path=".$path." types=".$types." recursive=".$recursive." filter=".$filter." excludefilter=".json_encode($excludefilter); + dol_syslog("files.lib.php::dol_dir_list path=".$utf8_path." types=".$types." recursive=".$recursive." filter=".$filter." excludefilter=".json_encode($excludefilter).$error_info); + //print 'xxx'."files.lib.php::dol_dir_list path=".$utf8_path." types=".$types." recursive=".$recursive." filter=".$filter." excludefilter=".json_encode($excludefilter); if (!$filters_ok) { // Return empty array when filters are invalid return array(); @@ -92,8 +92,8 @@ function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excl $loadperm = ($mode == 1 || $mode == 4); // Clean parameters - $path = preg_replace('/([\\/]+)$/', '', $path); - $newpath = dol_osencode($path); + $utf8_path = preg_replace('/([\\/]+)$/', '', $utf8_path); + $os_path = dol_osencode($utf8_path); $now = dol_now(); $reshook = 0; @@ -105,7 +105,7 @@ function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excl $hookmanager->initHooks(array('fileslib')); $parameters = array( - 'path' => $newpath, + 'path' => $os_path, 'types' => $types, 'recursive' => $recursive, 'filter' => $filter, @@ -121,24 +121,28 @@ function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excl // $hookmanager->resArray may contain array stacked by other modules if (empty($reshook)) { - if (!is_dir($newpath)) { + if (!is_dir($os_path)) { return array(); } - if (($dir = opendir($newpath)) === false) { + if (($dir = opendir($os_path)) === false) { return array(); } else { $filedate = ''; $filesize = ''; $fileperm = ''; - while (false !== ($file = readdir($dir))) { // $file is always a basename (into directory $newpath) - if (!utf8_check($file)) { - $file = mb_convert_encoding($file, 'UTF-8', 'ISO-8859-1'); // To be sure data is stored in utf8 in memory + while (false !== ($os_file = readdir($dir))) { // $utf8_file is always a basename (in directory $os_path) + $os_fullpathfile = ($os_path ? $os_path.'/' : '').$os_file; + + if (!utf8_check($os_file)) { + $utf8_file = mb_convert_encoding($os_file, 'UTF-8', 'ISO-8859-1'); // Make sure data is stored in utf8 in memory + } else { + $utf8_file = $os_file; } - $fullpathfile = ($newpath ? $newpath.'/' : '').$file; $qualified = 1; + $utf8_fullpathfile = "$utf8_path/$utf8_file"; // Temp variable for speed // Define excludefilterarray $excludefilterarray = array('^\.'); if (is_array($excludefilter)) { @@ -148,39 +152,39 @@ function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excl } // Check if file is qualified foreach ($excludefilterarray as $filt) { - if (preg_match('/'.$filt.'/i', $file) || preg_match('/'.$filt.'/i', $fullpathfile)) { + if (preg_match('/'.$filt.'/i', $utf8_file) || preg_match('/'.$filt.'/i', $utf8_fullpathfile)) { $qualified = 0; break; } } - //print $fullpathfile.' '.$file.' '.$qualified.'
'; + //print $utf8_fullpathfile.' '.$utf8_file.' '.$qualified.'
'; if ($qualified) { - $isdir = is_dir(dol_osencode($path."/".$file)); + $isdir = is_dir($os_fullpathfile); // Check whether this is a file or directory and whether we're interested in that type if ($isdir && (($types == "directories") || ($types == "all") || $recursive > 0)) { // Add entry into file_list array if (($types == "directories") || ($types == "all")) { if ($loaddate || $sortcriteria == 'date') { - $filedate = dol_filemtime($path."/".$file); + $filedate = dol_filemtime($utf8_fullpathfile); } if ($loadsize || $sortcriteria == 'size') { - $filesize = dol_filesize($path."/".$file); + $filesize = dol_filesize($utf8_fullpathfile); } if ($loadperm || $sortcriteria == 'perm') { - $fileperm = dol_fileperm($path."/".$file); + $fileperm = dol_fileperm($utf8_fullpathfile); } - 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', $utf8_file)) { // We do not search key $filter into all $path, only into $file part $reg = array(); - preg_match('/([^\/]+)\/[^\/]+$/', $path.'/'.$file, $reg); + preg_match('/([^\/]+)\/[^\/]+$/', $utf8_fullpathfile, $reg); $level1name = (isset($reg[1]) ? $reg[1] : ''); $file_list[] = array( - "name" => $file, - "path" => $path, + "name" => $utf8_file, + "path" => $utf8_path, "level1name" => $level1name, - "relativename" => ($relativename ? $relativename.'/' : '').$file, - "fullname" => $path.'/'.$file, + "relativename" => ($relativename ? $relativename.'/' : '').$utf8_file, + "fullname" => $utf8_fullpathfile, "date" => $filedate, "size" => $filesize, "perm" => $fileperm, @@ -191,30 +195,30 @@ function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excl // if we're in a directory and we want recursive behavior, call this function again if ($recursive > 0) { - if (empty($donotfollowsymlinks) || !is_link($path."/".$file)) { - //var_dump('eee '. $path."/".$file. ' '.is_dir($path."/".$file).' '.is_link($path."/".$file)); - $file_list = array_merge($file_list, dol_dir_list($path."/".$file, $types, $recursive + 1, $filter, $excludefilter, $sortcriteria, $sortorder, $mode, $nohook, ($relativename != '' ? $relativename.'/' : '').$file, $donotfollowsymlinks, $nbsecondsold)); + if (empty($donotfollowsymlinks) || !is_link($utf8_fullpathfile)) { + //var_dump('eee '. $utf8_fullpathfile. ' '.is_dir($utf8_fullpathfile).' '.is_link($utf8_fullpathfile)); + $file_list = array_merge($file_list, dol_dir_list($utf8_fullpathfile, $types, $recursive + 1, $filter, $excludefilter, $sortcriteria, $sortorder, $mode, $nohook, ($relativename != '' ? $relativename.'/' : '').$utf8_file, $donotfollowsymlinks, $nbsecondsold)); } } } elseif (!$isdir && (($types == "files") || ($types == "all"))) { // Add file into file_list array if ($loaddate || $sortcriteria == 'date') { - $filedate = dol_filemtime($path."/".$file); + $filedate = dol_filemtime($utf8_fullpathfile); } if ($loadsize || $sortcriteria == 'size') { - $filesize = dol_filesize($path."/".$file); + $filesize = dol_filesize($utf8_fullpathfile); } - if (!$filter || preg_match('/'.$filter.'/i', $file)) { // We do not search key $filter into $path, only into $file + if (!$filter || preg_match('/'.$filter.'/i', $utf8_file)) { // We do not search key $filter into $utf8_path, only into $utf8_file if (empty($nbsecondsold) || $filedate <= ($now - $nbsecondsold)) { - preg_match('/([^\/]+)\/[^\/]+$/', $path.'/'.$file, $reg); + preg_match('/([^\/]+)\/[^\/]+$/', $utf8_fullpathfile, $reg); $level1name = (isset($reg[1]) ? $reg[1] : ''); $file_list[] = array( - "name" => $file, - "path" => $path, + "name" => $utf8_file, + "path" => $utf8_path, "level1name" => $level1name, - "relativename" => ($relativename ? $relativename.'/' : '').$file, - "fullname" => $path.'/'.$file, + "relativename" => ($relativename ? $relativename.'/' : '').$utf8_file, + "fullname" => $utf8_fullpathfile, "date" => $filedate, "size" => $filesize, "type" => 'file' @@ -233,7 +237,7 @@ function dol_dir_list($path, $types = "all", $recursive = 0, $filter = "", $excl } } - if (is_object($hookmanager) && is_array($hookmanager->resArray)) { + if ($hookmanager instanceof HookManager && is_array($hookmanager->resArray)) { $file_list = array_merge($file_list, $hookmanager->resArray); } From db6b17ad498d1b433c0df5515337601706677c3b Mon Sep 17 00:00:00 2001 From: noec764 <58433943+noec764@users.noreply.github.com> Date: Tue, 20 Feb 2024 02:12:06 +0100 Subject: [PATCH 11/11] NEW: Add Filter on product reffering object status(Order and Order Supplier) (#28275) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * NEW: Add Filter on product reffering object status(Order and Order Supplier) * Update html.formorder.class.php * Update commande.php * Update commande_fournisseur.php --------- Co-authored-by: Noé Co-authored-by: Laurent Destailleur --- htdocs/core/class/html.formorder.class.php | 39 ++++++++++++++++++- htdocs/product/stats/commande.php | 23 ++++++++++- htdocs/product/stats/commande_fournisseur.php | 23 ++++++++++- 3 files changed, 80 insertions(+), 5 deletions(-) diff --git a/htdocs/core/class/html.formorder.class.php b/htdocs/core/class/html.formorder.class.php index 82d80ba3336..f657e1b8caf 100644 --- a/htdocs/core/class/html.formorder.class.php +++ b/htdocs/core/class/html.formorder.class.php @@ -23,6 +23,7 @@ */ require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; +require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; /** * Class to manage HTML output components for orders @@ -68,7 +69,43 @@ class FormOrder extends Form $selectedarray = explode(',', $selected); } - print Form::multiselectarray($hmlname, $options, $selectedarray, 0, 0, $morecss); + print Form::multiselectarray($hmlname, $options, $selectedarray, 0, 0, $morecss, 0, 150); + } + + /** + * Return combo list of different status of orders + * + * @param string $selected Preselected value + * @param int $short Use short labels + * @param string $hmlname Name of HTML select element + * @return void + */ + public function selectOrderStatus($selected = '', $short = 0, $hmlname = 'order_status') + { + $options = array(); + + $statustohow = array( + Commande::STATUS_DRAFT, + Commande::STATUS_VALIDATED, + Commande::STATUS_SHIPMENTONPROCESS, + Commande::STATUS_CLOSED, + Commande::STATUS_CANCELED + ); + + $tmpsupplierorder = new Commande($this->db); + + foreach ($statustohow as $value) { + $tmpsupplierorder->statut = $value; + $options[$value] = $tmpsupplierorder->getLibStatut($short); + } + + if (is_array($selected)) { + $selectedarray = $selected; + } else { + $selectedarray = explode(',', $selected); + } + + print Form::multiselectarray($hmlname, $options, $selectedarray, 0, 0, '', 0, 150); } /** diff --git a/htdocs/product/stats/commande.php b/htdocs/product/stats/commande.php index 199469264e0..3532afb8116 100644 --- a/htdocs/product/stats/commande.php +++ b/htdocs/product/stats/commande.php @@ -30,6 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formorder.class.php'; // Load translation files required by the page $langs->loadLangs(array('orders', 'products', 'companies')); @@ -67,10 +68,16 @@ if (!$sortfield) { } $search_month = GETPOST('search_month', 'int'); $search_year = GETPOST('search_year', 'int'); +if (GETPOSTISARRAY('search_status')) { + $search_status = join(',', GETPOST('search_status', 'array:intcomma')); +} else { + $search_status = (GETPOST('search_status', 'intcomma') != '' ? GETPOST('search_status', 'intcomma') : GETPOST('statut', 'intcomma')); +} if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { $search_month = ''; $search_year = ''; + $search_status = ''; } $result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); @@ -85,6 +92,7 @@ $societestatic = new Societe($db); $form = new Form($db); $formother = new FormOther($db); +$formorder = new FormOrder($db); if ($id > 0 || !empty($ref)) { $product = new Product($db); @@ -155,10 +163,10 @@ if ($id > 0 || !empty($ref)) { $sql .= " AND d.fk_commande = c.rowid"; $sql .= " AND d.fk_product = ".((int) $product->id); if (!empty($search_month)) { - $sql .= ' AND MONTH(c.date_commande) IN ('.$db->sanitize($search_month).')'; + $sql .= " AND MONTH(c.date_commande) IN (".$db->sanitize($search_month).")"; } if (!empty($search_year)) { - $sql .= ' AND YEAR(c.date_commande) IN ('.$db->sanitize($search_year).')'; + $sql .= " AND YEAR(c.date_commande) IN (".$db->sanitize($search_year).")"; } if (!$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); @@ -166,6 +174,11 @@ if ($id > 0 || !empty($ref)) { if ($socid) { $sql .= " AND c.fk_soc = ".((int) $socid); } + + if ($search_status != '') { + $sql .= " AND c.fk_statut IN (".$db->sanitize($search_status).")"; + } + $sql .= $db->order($sortfield, $sortorder); //Calcul total qty and amount for global if full scan list @@ -197,6 +210,10 @@ if ($id > 0 || !empty($ref)) { $option .= '&search_year='.urlencode($search_year); } + if ($search_status != '') { + $option .= '&search_status='.urlencode($search_status); + } + print '
'."\n"; print ''; if (!empty($sortfield)) { @@ -217,6 +234,8 @@ if ($id > 0 || !empty($ref)) { print $langs->trans('Period').' ('.$langs->trans("OrderDate").') - '; print $langs->trans('Month').': '; print $langs->trans('Year').':'.$formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5); + print $langs->trans('Status'); + $formorder->selectOrderStatus($search_status, 1, 'search_status'); print '
'; print ''; print ''; diff --git a/htdocs/product/stats/commande_fournisseur.php b/htdocs/product/stats/commande_fournisseur.php index 6a5500456d5..a76c572af19 100644 --- a/htdocs/product/stats/commande_fournisseur.php +++ b/htdocs/product/stats/commande_fournisseur.php @@ -28,6 +28,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php'; require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formorder.class.php'; // Load translation files required by the page $langs->loadLangs(array('orders', 'products', 'companies')); @@ -67,10 +68,16 @@ if (!$sortfield) { } $search_month = GETPOST('search_month', 'int'); $search_year = GETPOST('search_year', 'int'); +if (GETPOSTISARRAY('search_status')) { + $search_status = join(',', GETPOST('search_status', 'array:intcomma')); +} else { + $search_status = (GETPOST('search_status', 'intcomma') != '' ? GETPOST('search_status', 'intcomma') : GETPOST('statut', 'intcomma')); +} if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { $search_month = ''; $search_year = ''; + $search_status = ''; } $result = restrictedArea($user, 'produit|service', $fieldvalue, 'product&product', '', '', $fieldtype); @@ -85,6 +92,7 @@ $societestatic = new Societe($db); $form = new Form($db); $formother = new FormOther($db); +$formorder = new FormOrder($db); if ($id > 0 || !empty($ref)) { $product = new Product($db); @@ -155,10 +163,10 @@ if ($id > 0 || !empty($ref)) { $sql .= " AND d.fk_commande = c.rowid"; $sql .= " AND d.fk_product = ".((int) $product->id); if (!empty($search_month)) { - $sql .= ' AND MONTH(c.date_commande) IN ('.$db->sanitize($search_month).')'; + $sql .= " AND MONTH(c.date_commande) IN (".$db->sanitize($search_month).")"; } if (!empty($search_year)) { - $sql .= ' AND YEAR(c.date_commande) IN ('.$db->sanitize($search_year).')'; + $sql .= " AND YEAR(c.date_commande) IN (".$db->sanitize($search_year).")"; } if (!$user->hasRight('societe', 'client', 'voir')) { $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id); @@ -166,6 +174,11 @@ if ($id > 0 || !empty($ref)) { if ($socid) { $sql .= " AND c.fk_soc = ".((int) $socid); } + + if ($search_status != '') { + $sql .= " AND c.fk_statut IN (".$db->sanitize($search_status).")"; + } + $sql .= $db->order($sortfield, $sortorder); // Calcul total qty and amount for global if full scan list @@ -197,6 +210,10 @@ if ($id > 0 || !empty($ref)) { $option .= '&search_year='.urlencode($search_year); } + if ($search_status != '') { + $param .= '&search_status='.urlencode($search_status); + } + print ''."\n"; print ''; if (!empty($sortfield)) { @@ -217,6 +234,8 @@ if ($id > 0 || !empty($ref)) { print $langs->trans('Period').' ('.$langs->trans("OrderDate").') - '; print $langs->trans('Month').': '; print $langs->trans('Year').':'.$formother->selectyear($search_year ? $search_year : - 1, 'search_year', 1, 20, 5); + print $langs->trans('Status'); + $formorder->selectSupplierOrderStatus($search_status, 1, 'search_status'); print '
'; print ''; print '';