From 146bd33e90540254ccf451a6aa2c59f9268a288c Mon Sep 17 00:00:00 2001 From: EchoLoGeek <73399671+EchoLoGeek@users.noreply.github.com> Date: Tue, 4 Mar 2025 11:00:24 +0100 Subject: [PATCH 1/8] Fix updateline method for INVOICE_USE_SITUATION = 2 If there is no progress on a line, percent must not be 100% --- htdocs/compta/facture/class/facture.class.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 9772c590d85..d364265c5b2 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -4140,7 +4140,12 @@ class Facture extends CommonInvoice $special_code = 0; } if (!isset($situation_percent) || $situation_percent > 100 || (string) $situation_percent == '' || $situation_percent == null) { - $situation_percent = 100; + // INVOICE_USE_SITUATION = 2 - If there is no progress on a line, percent must not be 100% (No cumulative) + if ($this->type == Facture::TYPE_SITUATION && getDolGlobalInt('INVOICE_USE_SITUATION') == 2 && (int) $situation_percent < 100) { + $situation_percent = 0; + } else { + $situation_percent = 100; + } } if (empty($ref_ext)) { $ref_ext = ''; From 04b0b3d8552412de5e3bb68afdf2d838e076f584 Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Tue, 4 Mar 2025 20:50:54 +0100 Subject: [PATCH 2/8] FIX in dev for #33324 --- htdocs/core/lib/functions.lib.php | 14 ++++++++++---- test/phpunit/FunctionsLibTest.php | 18 +++++++++++++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index d6fd9f751ff..fee55e6481a 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -11959,15 +11959,20 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0) $value = preg_replace('/\s*\|\s*/', '|', $value); - // Split criteria on ' ' but not if we are inside quotes - $crits = dolExplodeKeepIfQuotes($value); + // Split criteria on ' ' but not if we are inside quotes. + // For mode 3, the split is done later on the , only and not on the ' '. + if ($mode != -3 && $mode != 3) { + $crits = dolExplodeKeepIfQuotes($value); + } else { + $crits = array($value); + } $res = ''; if (!is_array($fields)) { $fields = array($fields); } - $i1 = 0; // count the nb of and criteria added (all fields / criteria) + $i1 = 0; // count the nb of "and" criteria added (all fields / criteria) foreach ($crits as $crit) { // Loop on each AND criteria $crit = trim($crit); $i2 = 0; // count the nb of valid criteria added for this this first criteria @@ -12022,7 +12027,8 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0) $listofcodes .= "'".$db->escape($val)."'"; } } - $newres .= ($i2 > 0 ? ' OR ' : '').$db->sanitize($field)." ".($mode == -3 ? 'NOT ' : '')."IN (".$db->sanitize($listofcodes, 1).")"; + + $newres .= ($i2 > 0 ? ' OR ' : '').$db->sanitize($field)." ".($mode == -3 ? 'NOT ' : '')."IN (".$db->sanitize($listofcodes, 1, 0, 1).")"; $i2++; // a criteria for 1 more field was added to string } if ($mode == -3) { diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 135a83de392..30fb513b859 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -1894,7 +1894,6 @@ class FunctionsLibTest extends CommonClassTest return true; } - /** * testRoundUpToNextMultiple * @@ -1918,4 +1917,21 @@ class FunctionsLibTest extends CommonClassTest $this->assertEquals(roundUpToNextMultiple(40.5, 6), 42); $this->assertEquals(roundUpToNextMultiple(44.5, 6), 48); } + + /** + * testNaturalSearch + * + * @return void; + */ + public function testNaturalSearch() + { + $s = natural_search("t.field", "abc def"); + $this->assertEquals($s, " AND (t.field LIKE '%abc%' AND t.field LIKE '%def%')"); + + $s = natural_search("t.field", "'abc def' ghi"); + $this->assertEquals($s, " AND (t.field LIKE '%abc def%' AND t.field LIKE '%ghi%')"); + + $s = natural_search("t.field", "abc def,ghi", 3); + $this->assertEquals($s, " AND (t.field IN ('abc def','ghi'))"); + } } From bcd1f49bc467cfb61ee2e140354b7c93ce864816 Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Tue, 4 Mar 2025 21:17:35 +0100 Subject: [PATCH 3/8] Fix var in log --- htdocs/website/samples/wrapper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/website/samples/wrapper.php b/htdocs/website/samples/wrapper.php index a61c29f5b1b..59fdfde41d0 100644 --- a/htdocs/website/samples/wrapper.php +++ b/htdocs/website/samples/wrapper.php @@ -175,7 +175,7 @@ if ($rss) { require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"; require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"; - dol_syslog("build_exportfile Build export file format=".$format.", type=".$type.", cachedelay=".$cachedelay.", filename=".$filename.", filters size=".count($filters), LOG_DEBUG); + dol_syslog("build_exportfile Build export file format=".$format.", type=".$type.", cachestring=".$cachestring.", filename=".$filename.", filters size=".count($filters), LOG_DEBUG); // Clean parameters if (!$filename) { From 7d8fd29f63f0563886c919b3239aec79f9d5505f Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Tue, 4 Mar 2025 21:17:35 +0100 Subject: [PATCH 4/8] Fix var in log --- htdocs/website/samples/wrapper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/website/samples/wrapper.php b/htdocs/website/samples/wrapper.php index 2aaa9d67ba5..ff6ed2ba0a3 100644 --- a/htdocs/website/samples/wrapper.php +++ b/htdocs/website/samples/wrapper.php @@ -174,7 +174,7 @@ if ($rss) { require_once DOL_DOCUMENT_ROOT."/core/lib/date.lib.php"; require_once DOL_DOCUMENT_ROOT."/core/lib/files.lib.php"; - dol_syslog("build_exportfile Build export file format=".$format.", type=".$type.", cachedelay=".$cachedelay.", filename=".$filename.", filters size=".count($filters), LOG_DEBUG); + dol_syslog("build_exportfile Build export file format=".$format.", type=".$type.", cachestring=".$cachestring.", filename=".$filename.", filters size=".count($filters), LOG_DEBUG); // Clean parameters if (!$filename) { From c35550d89c2c96dcc8507ebfaf9cd159d88bd0cd Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Tue, 4 Mar 2025 21:23:23 +0100 Subject: [PATCH 5/8] Fix var for cachedelay --- htdocs/website/samples/wrapper.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/website/samples/wrapper.php b/htdocs/website/samples/wrapper.php index 59fdfde41d0..2449960f001 100644 --- a/htdocs/website/samples/wrapper.php +++ b/htdocs/website/samples/wrapper.php @@ -132,10 +132,10 @@ $original_file = str_replace("../", "/", $original_file); $cachestring = GETPOST("cache", 'aZ09'); // May be 1, or an int (delay in second of the cache if < 999999, or a timestamp), or a hash if ($cachestring || image_format_supported($original_file) >= 0) { // Important: Following code is to avoid page request by browser and PHP CPU at each Dolibarr page access. - $delaycache = GETPOSTINT('cachedelay') ? GETPOSTINT('cachedelay') : ((is_numeric($cachestring) && (int) $cachestring > 1 && (int) $cachestring < 999999) ? $cachestring : '3600'); - header('Cache-Control: max-age='.$delaycache.', public, must-revalidate'); + $cachedelay = GETPOSTINT('cachedelay') ? GETPOSTINT('cachedelay') : ((is_numeric($cachestring) && (int) $cachestring > 1 && (int) $cachestring < 999999) ? $cachestring : '3600'); + header('Cache-Control: max-age='.$cachedelay.', public, must-revalidate'); header('Pragma: cache'); // This is to avoid having Pragma: no-cache - header('Expires: '.gmdate('D, d M Y H:i:s', time() + (int) $delaycache).' GMT'); // This is to avoid to have Expires set by proxy or web server + header('Expires: '.gmdate('D, d M Y H:i:s', time() + (int) $cachedelay).' GMT'); // This is to avoid to have Expires set by proxy or web server } $refname = basename(dirname($original_file)."/"); From 86f836b652b385729e2a4a41ee4bf047fd28c3b4 Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Tue, 4 Mar 2025 20:50:54 +0100 Subject: [PATCH 6/8] Merge backport --- htdocs/core/lib/functions.lib.php | 13 ++++++++++--- test/phpunit/FunctionsLibTest.php | 18 +++++++++++++++++- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 2921519e6c3..49d30addd20 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -11710,13 +11710,20 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0) $value = preg_replace('/\s*\|\s*/', '|', $value); - $crits = explode(' ', $value); + // Split criteria on ' '. + // For mode 3, the split is done later on the , only and not on the ' '. + if ($mode != -3 && $mode != 3) { + $crits = explode(' ', $value); + } else { + $crits = array($value); + } + $res = ''; if (!is_array($fields)) { $fields = array($fields); } - $i1 = 0; // count the nb of and criteria added (all fields / criteria) + $i1 = 0; // count the nb of "and" criteria added (all fields / criteria) foreach ($crits as $crit) { // Loop on each AND criteria $crit = trim($crit); $i2 = 0; // count the nb of valid criteria added for this this first criteria @@ -11771,7 +11778,7 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0) $listofcodes .= "'".$db->escape($val)."'"; } } - $newres .= ($i2 > 0 ? ' OR ' : '').$field." ".($mode == -3 ? 'NOT ' : '')."IN (".$db->sanitize($listofcodes, 1).")"; + $newres .= ($i2 > 0 ? ' OR ' : '').$field." ".($mode == -3 ? 'NOT ' : '')."IN (".$db->sanitize($listofcodes, 1, 0, 1).")"; $i2++; // a criteria for 1 more field was added to string } if ($mode == -3) { diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 135a83de392..30fb513b859 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -1894,7 +1894,6 @@ class FunctionsLibTest extends CommonClassTest return true; } - /** * testRoundUpToNextMultiple * @@ -1918,4 +1917,21 @@ class FunctionsLibTest extends CommonClassTest $this->assertEquals(roundUpToNextMultiple(40.5, 6), 42); $this->assertEquals(roundUpToNextMultiple(44.5, 6), 48); } + + /** + * testNaturalSearch + * + * @return void; + */ + public function testNaturalSearch() + { + $s = natural_search("t.field", "abc def"); + $this->assertEquals($s, " AND (t.field LIKE '%abc%' AND t.field LIKE '%def%')"); + + $s = natural_search("t.field", "'abc def' ghi"); + $this->assertEquals($s, " AND (t.field LIKE '%abc def%' AND t.field LIKE '%ghi%')"); + + $s = natural_search("t.field", "abc def,ghi", 3); + $this->assertEquals($s, " AND (t.field IN ('abc def','ghi'))"); + } } From c2a044628801b74b3ebc2122d3eebc5bdcec9b0b Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Tue, 4 Mar 2025 21:23:23 +0100 Subject: [PATCH 7/8] Fix var for cachedelay --- htdocs/website/samples/wrapper.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/website/samples/wrapper.php b/htdocs/website/samples/wrapper.php index ff6ed2ba0a3..dd669a379a7 100644 --- a/htdocs/website/samples/wrapper.php +++ b/htdocs/website/samples/wrapper.php @@ -131,10 +131,10 @@ $original_file = str_replace("../", "/", $original_file); $cachestring = GETPOST("cache", 'aZ09'); // May be 1, or an int (delay in second of the cache if < 999999, or a timestamp), or a hash if ($cachestring || image_format_supported($original_file) >= 0) { // Important: Following code is to avoid page request by browser and PHP CPU at each Dolibarr page access. - $delaycache = GETPOSTINT('cachedelay') ? GETPOSTINT('cachedelay') : ((is_numeric($cachestring) && (int) $cachestring > 1 && (int) $cachestring < 999999) ? $cachestring : '3600'); - header('Cache-Control: max-age='.$delaycache.', public, must-revalidate'); + $cachedelay = GETPOSTINT('cachedelay') ? GETPOSTINT('cachedelay') : ((is_numeric($cachestring) && (int) $cachestring > 1 && (int) $cachestring < 999999) ? $cachestring : '3600'); + header('Cache-Control: max-age='.$cachedelay.', public, must-revalidate'); header('Pragma: cache'); // This is to avoid having Pragma: no-cache - header('Expires: '.gmdate('D, d M Y H:i:s', time() + (int) $delaycache).' GMT'); // This is to avoid to have Expires set by proxy or web server + header('Expires: '.gmdate('D, d M Y H:i:s', time() + (int) $cachedelay).' GMT'); // This is to avoid to have Expires set by proxy or web server } $refname = basename(dirname($original_file)."/"); From 14ce4060a8122b88b07ca1cb2a24035200841078 Mon Sep 17 00:00:00 2001 From: ldestailleur Date: Tue, 4 Mar 2025 21:31:08 +0100 Subject: [PATCH 8/8] Fix CI --- htdocs/core/class/html.formsetup.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index b4eae28beb0..0def5ee7882 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -700,7 +700,7 @@ class FormSetupItem { global $conf; if (isset($conf->global->{$this->confKey})) { - $this->fieldValue = getDolGlobalString($this->confKey, null); + $this->fieldValue = getDolGlobalString($this->confKey); return true; } else { $this->fieldValue = null;