From 9bbd285c3a800111ae793f4791f8c1816a016e18 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Sat, 2 Dec 2023 15:53:22 +0100 Subject: [PATCH 01/31] fix: feature MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS was broken --- htdocs/core/class/CMailFile.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index d05854d3435..166ae74e28f 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -268,7 +268,7 @@ class CMailFile if (!empty($conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_DATA)) { // Search into the body for findHtmlImages($dolibarr_main_data_root.'/medias'); + if ($findimg<0) { + dol_syslog("CMailFile::CMailfile: Error on findHtmlImages"); + $this->error = 'ErrorInAddAttachementsImageBAseOnMedia'; + return; + } } if (!empty($conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_DATA)) { // Search into the body for error = 'ErrorInAddAttachementsImageBAseOnMedia'; + return; + } + $findimg += $resultImageData; } // Set atleastoneimage if there is at least one embedded file (into ->html_images) @@ -1847,7 +1858,7 @@ class CMailFile // We search (into mail body this->html), if we find some strings like "... file=xxx.img" // For example when: - // + // $matches = array(); preg_match_all('/src="data:image\/('.implode('|', $extensions).');base64,([^"]+)"/Ui', $this->html, $matches); // If "xxx.ext" or 'xxx.ext' found diff --git a/test/phpunit/CMailFileTest.php b/test/phpunit/CMailFileTest.php index 729aa4b4c7f..9d270901dc2 100644 --- a/test/phpunit/CMailFileTest.php +++ b/test/phpunit/CMailFileTest.php @@ -23,18 +23,19 @@ * \remarks To run this script as CLI: phpunit filename.php */ -global $conf,$user,$langs,$db; +global $conf, $user, $langs, $db; //define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver //require_once 'PHPUnit/Autoload.php'; require_once dirname(__FILE__).'/../../htdocs/master.inc.php'; require_once dirname(__FILE__).'/../../htdocs/core/class/CMailFile.class.php'; +require_once dirname(__FILE__).'/../../htdocs/core/lib/files.lib.php'; if (empty($user->id)) { print "Load permissions for admin user nb 1\n"; $user->fetch(1); $user->getrights(); } -$conf->global->MAIN_DISABLE_ALL_MAILS=1; +$conf->global->MAIN_DISABLE_ALL_MAILS = 1; /** @@ -42,7 +43,7 @@ $conf->global->MAIN_DISABLE_ALL_MAILS=1; * * @backupGlobals disabled * @backupStaticAttributes enabled - * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. + * @remarks backupGlobals must be disabled to have db,conf,user and lang not erased. */ class CMailFileTest extends PHPUnit\Framework\TestCase { @@ -62,13 +63,13 @@ class CMailFileTest extends PHPUnit\Framework\TestCase parent::__construct(); //$this->sharedFixture - global $conf,$user,$langs,$db; - $this->savconf=$conf; - $this->savuser=$user; - $this->savlangs=$langs; - $this->savdb=$db; + global $conf, $user, $langs, $db; + $this->savconf = $conf; + $this->savuser = $user; + $this->savlangs = $langs; + $this->savdb = $db; - print __METHOD__." db->type=".$db->type." user->id=".$user->id; + print __METHOD__ . " db->type=" . $db->type . " user->id=" . $user->id; //print " - db ".$db->db; print "\n"; } @@ -80,23 +81,23 @@ class CMailFileTest extends PHPUnit\Framework\TestCase */ public static function setUpBeforeClass(): void { - global $conf,$user,$langs,$db; + global $conf, $user, $langs, $db; $db->begin(); // This is to have all actions inside a transaction even if test launched without suite. - print __METHOD__."\n"; + print __METHOD__ . "\n"; } /** * tearDownAfterClass * - * @return void + * @return void */ public static function tearDownAfterClass(): void { - global $conf,$user,$langs,$db; + global $conf, $user, $langs, $db; $db->rollback(); - print __METHOD__."\n"; + print __METHOD__ . "\n"; } /** @@ -106,24 +107,25 @@ class CMailFileTest extends PHPUnit\Framework\TestCase */ protected function setUp(): void { - global $conf,$user,$langs,$db; - $conf=$this->savconf; - $user=$this->savuser; - $langs=$this->savlangs; - $db=$this->savdb; + global $conf, $user, $langs, $db; + $conf = $this->savconf; + $user = $this->savuser; + $langs = $this->savlangs; + $db = $this->savdb; - $conf->global->MAIN_DISABLE_ALL_MAILS=1; // If I comment/remove this lien, unit test still works alone but failed when ran from AllTest. Don't know why. + $conf->global->MAIN_DISABLE_ALL_MAILS = 1; // If I comment/remove this lien, unit test still works alone but failed when ran from AllTest. Don't know why. - print __METHOD__."\n"; + print __METHOD__ . "\n"; } + /** * End phpunit tests * - * @return void + * @return void */ protected function tearDown(): void { - print __METHOD__."\n"; + print __METHOD__ . "\n"; } /** @@ -133,16 +135,16 @@ class CMailFileTest extends PHPUnit\Framework\TestCase */ public function testCMailFileText() { - global $conf,$user,$langs,$db; - $conf=$this->savconf; - $user=$this->savuser; - $langs=$this->savlangs; - $db=$this->savdb; + global $conf, $user, $langs, $db; + $conf = $this->savconf; + $user = $this->savuser; + $langs = $this->savlangs; + $db = $this->savdb; - $localobject=new CMailFile('Test', 'test@test.com', 'from@from.com', 'Message txt', array(), array(), array(), '', '', 1, 0); + $localobject = new CMailFile('Test', 'test@test.com', 'from@from.com', 'Message txt', array(), array(), array(), '', '', 1, 0); - $result=$localobject->sendfile(); - print __METHOD__." result=".$result."\n"; + $result = $localobject->sendfile(); + print __METHOD__ . " result=" . $result . "\n"; $this->assertFalse($result); // False because mail send disabled return $result; @@ -155,54 +157,112 @@ class CMailFileTest extends PHPUnit\Framework\TestCase */ public function testCMailFileStatic() { - global $conf,$user,$langs,$db; - $conf=$this->savconf; - $user=$this->savuser; - $langs=$this->savlangs; - $db=$this->savdb; + global $conf, $user, $langs, $db; + $conf = $this->savconf; + $user = $this->savuser; + $langs = $this->savlangs; + $db = $this->savdb; - $localobject=new CMailFile('', '', '', ''); + $localobject = new CMailFile('', '', '', ''); - $src='John Doe '; - $result=$localobject->getValidAddress($src, 0); - print __METHOD__." result=".$result."\n"; + $src = 'John Doe '; + $result = $localobject->getValidAddress($src, 0); + print __METHOD__ . " result=" . $result . "\n"; $this->assertEquals($result, 'John Doe '); - $src='John Doe '; - $result=$localobject->getValidAddress($src, 1); - print __METHOD__." result=".$result."\n"; + $src = 'John Doe '; + $result = $localobject->getValidAddress($src, 1); + print __METHOD__ . " result=" . $result . "\n"; $this->assertEquals($result, ''); - $src='John Doe '; - $result=$localobject->getValidAddress($src, 2); - print __METHOD__." result=".$result."\n"; + $src = 'John Doe '; + $result = $localobject->getValidAddress($src, 2); + print __METHOD__ . " result=" . $result . "\n"; $this->assertEquals($result, 'john@doe.com'); - $src='John Doe '; - $result=$localobject->getValidAddress($src, 3, 0); - print __METHOD__." result=".$result."\n"; + $src = 'John Doe '; + $result = $localobject->getValidAddress($src, 3, 0); + print __METHOD__ . " result=" . $result . "\n"; $this->assertEquals($result, '"John Doe" '); - $src='John Doe '; - $result=$localobject->getValidAddress($src, 3, 1); - print __METHOD__." result=".$result."\n"; + $src = 'John Doe '; + $result = $localobject->getValidAddress($src, 3, 1); + print __METHOD__ . " result=" . $result . "\n"; $this->assertEquals($result, '"=?UTF-8?B?Sm9obiBEb2U=?=" '); - $src='John Doe '; - $result=$localobject->getValidAddress($src, 4); - print __METHOD__." result=".$result."\n"; + $src = 'John Doe '; + $result = $localobject->getValidAddress($src, 4); + print __METHOD__ . " result=" . $result . "\n"; $this->assertEquals($result, 'John Doe'); - $src='John Doe , John Doe2 , John Doe3 '; - $result=$localobject->getValidAddress($src, 4); - print __METHOD__." result=".$result."\n"; + $src = 'John Doe , John Doe2 , John Doe3 '; + $result = $localobject->getValidAddress($src, 4); + print __METHOD__ . " result=" . $result . "\n"; $this->assertEquals($result, 'John Doe,John Doe2,John Doe3'); - $src='John Doe , John Doe2 , John Doe3 '; - $result=$localobject->getValidAddress($src, 4, 0, 2); - print __METHOD__." result=".$result."\n"; + $src = 'John Doe , John Doe2 , John Doe3 '; + $result = $localobject->getValidAddress($src, 4, 0, 2); + print __METHOD__ . " result=" . $result . "\n"; $this->assertEquals($result, 'John Doe,John Doe2...'); return $result; } + + public function testCMailFileHTMLWithImage() + { + + global $conf, $user, $langs, $db; + $conf = $this->savconf; + $user = $this->savuser; + $langs = $this->savlangs; + $db = $this->savdb; + $conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS = 1; + $conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_DATA = 1; + + dol_delete_dir_recursive(DOL_DATA_ROOT . '/medias/image'); + dol_mkdir(DOL_DATA_ROOT . '/medias/image'); + dol_copy(dirname(__FILE__) . '/img250x20.png', DOL_DATA_ROOT . '/medias/image/img250x20.png'); + + $msg = ''; + $msg .= ''; + $msg .= '

From wikipedia

Red dot'; + $msg .= ''; + + + $localobject = new CMailFile('Test', 'test@test.com', 'from@from.com', $msg, array(), array(), array(), '', '', 0, -1,'','','','','standard','','/tmp'); + + $result = count($localobject->html_images); + print __METHOD__ . " result count image detected in the mail=" . $result . "\n"; + $this->assertEquals($result, 2); + + + foreach ($localobject->html_images as $i => $val) + if ($localobject->html_images[$i]) { + if ($localobject->html_images[$i]['type'] == 'cidfromdata') { + if (preg_match('/img250x20\.png/i',$localobject->html_images[$i]['fullpath'])) { + print __METHOD__ . " content type must be image png =" . $localobject->html_images[$i]['content_type'] . "\n"; + $this->assertEquals($localobject->html_images[$i]['content_type'], 'image/png'); + + print __METHOD__ . " type must be cidfromurl =" . $localobject->html_images[$i]['type'] . "\n"; + $this->assertEquals($localobject->html_images[$i]['type'], 'cidfromurl'); + + $fileSize=9744; + print __METHOD__ . " File size must be =" . $fileSize . "\n"; + $this->assertEquals(dol_filesize($localobject->html_images[$i]['fullpath']), $fileSize); + } elseif (preg_match('/\.png/i',$localobject->html_images[$i]['fullpath'])) { + print __METHOD__ . " content type must be image png =" . $localobject->html_images[$i]['content_type'] . "\n"; + $this->assertEquals($localobject->html_images[$i]['content_type'], 'image/png'); + + print __METHOD__ . " type must be cidfromdata =" . $localobject->html_images[$i]['type'] . "\n"; + $this->assertEquals($localobject->html_images[$i]['type'], 'cidfromdata'); + + $fileSize=85; + print __METHOD__ . " File size must be =" . $fileSize . "\n"; + $this->assertEquals(dol_filesize($localobject->html_images[$i]['fullpath']), $fileSize); + } + } + } + + return $result; + } } From 6bb952bf9a98aa427a8772b3af26a4520e360fd9 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 13 Dec 2023 11:32:48 +0100 Subject: [PATCH 03/31] typo --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index cf4a893fee0..7c0a7c400ad 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -265,7 +265,7 @@ class CMailFile $findimg = $this->findHtmlImages($dolibarr_main_data_root.'/medias'); if ($findimg<0) { dol_syslog("CMailFile::CMailfile: Error on findHtmlImages"); - $this->error = 'ErrorInAddAttachementsImageBAseOnMedia'; + $this->error = 'ErrorInAddAttachementsImageBaseOnMedia'; return; } } From 67ad440381f4fb6996211efefefde65021b7ed2e Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 13 Dec 2023 11:33:18 +0100 Subject: [PATCH 04/31] typo --- htdocs/core/class/CMailFile.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 7c0a7c400ad..7b0af81a62c 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -276,7 +276,7 @@ class CMailFile $resultImageData = $this->findHtmlImagesIsSrcData($upload_dir_tmp); if ($resultImageData<0) { dol_syslog("CMailFile::CMailfile: Error on findHtmlImagesInSrcData"); - $this->error = 'ErrorInAddAttachementsImageBAseOnMedia'; + $this->error = 'ErrorInAddAttachementsImageBaseOnMedia'; return; } $findimg += $resultImageData; From 8be0970a0c04622846643d174f793606e801df14 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Wed, 13 Dec 2023 11:47:25 +0100 Subject: [PATCH 05/31] review test --- test/phpunit/CMailFileTest.php | 42 ++++++++++++++++------------------ 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/test/phpunit/CMailFileTest.php b/test/phpunit/CMailFileTest.php index 9d270901dc2..96d6e195b41 100644 --- a/test/phpunit/CMailFileTest.php +++ b/test/phpunit/CMailFileTest.php @@ -26,9 +26,9 @@ global $conf, $user, $langs, $db; //define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver //require_once 'PHPUnit/Autoload.php'; -require_once dirname(__FILE__).'/../../htdocs/master.inc.php'; -require_once dirname(__FILE__).'/../../htdocs/core/class/CMailFile.class.php'; -require_once dirname(__FILE__).'/../../htdocs/core/lib/files.lib.php'; +require_once dirname(__FILE__) . '/../../htdocs/master.inc.php'; +require_once dirname(__FILE__) . '/../../htdocs/core/class/CMailFile.class.php'; +require_once dirname(__FILE__) . '/../../htdocs/core/lib/files.lib.php'; if (empty($user->id)) { print "Load permissions for admin user nb 1\n"; @@ -229,7 +229,7 @@ class CMailFileTest extends PHPUnit\Framework\TestCase $msg .= ''; - $localobject = new CMailFile('Test', 'test@test.com', 'from@from.com', $msg, array(), array(), array(), '', '', 0, -1,'','','','','standard','','/tmp'); + $localobject = new CMailFile('Test', 'test@test.com', 'from@from.com', $msg, array(), array(), array(), '', '', 0, -1, '', '', '', '', 'standard', '', '/tmp'); $result = count($localobject->html_images); print __METHOD__ . " result count image detected in the mail=" . $result . "\n"; @@ -238,28 +238,26 @@ class CMailFileTest extends PHPUnit\Framework\TestCase foreach ($localobject->html_images as $i => $val) if ($localobject->html_images[$i]) { - if ($localobject->html_images[$i]['type'] == 'cidfromdata') { - if (preg_match('/img250x20\.png/i',$localobject->html_images[$i]['fullpath'])) { - print __METHOD__ . " content type must be image png =" . $localobject->html_images[$i]['content_type'] . "\n"; - $this->assertEquals($localobject->html_images[$i]['content_type'], 'image/png'); + if (preg_match('/img250x20\.png/i', $localobject->html_images[$i]['fullpath'])) { + print __METHOD__ . " content type must be image png =" . $localobject->html_images[$i]['content_type'] . "\n"; + $this->assertEquals($localobject->html_images[$i]['content_type'], 'image/png'); - print __METHOD__ . " type must be cidfromurl =" . $localobject->html_images[$i]['type'] . "\n"; - $this->assertEquals($localobject->html_images[$i]['type'], 'cidfromurl'); + print __METHOD__ . " type must be cidfromurl =" . $localobject->html_images[$i]['type'] . "\n"; + $this->assertEquals($localobject->html_images[$i]['type'], 'cidfromurl'); - $fileSize=9744; - print __METHOD__ . " File size must be =" . $fileSize . "\n"; - $this->assertEquals(dol_filesize($localobject->html_images[$i]['fullpath']), $fileSize); - } elseif (preg_match('/\.png/i',$localobject->html_images[$i]['fullpath'])) { - print __METHOD__ . " content type must be image png =" . $localobject->html_images[$i]['content_type'] . "\n"; - $this->assertEquals($localobject->html_images[$i]['content_type'], 'image/png'); + $fileSize = 9744; + print __METHOD__ . " File size must be =" . $fileSize . "\n"; + $this->assertEquals(dol_filesize($localobject->html_images[$i]['fullpath']), $fileSize); + } elseif (preg_match('/\.png/i', $localobject->html_images[$i]['fullpath'])) { + print __METHOD__ . " content type must be image png =" . $localobject->html_images[$i]['content_type'] . "\n"; + $this->assertEquals($localobject->html_images[$i]['content_type'], 'image/png'); - print __METHOD__ . " type must be cidfromdata =" . $localobject->html_images[$i]['type'] . "\n"; - $this->assertEquals($localobject->html_images[$i]['type'], 'cidfromdata'); + print __METHOD__ . " type must be cidfromdata =" . $localobject->html_images[$i]['type'] . "\n"; + $this->assertEquals($localobject->html_images[$i]['type'], 'cidfromdata'); - $fileSize=85; - print __METHOD__ . " File size must be =" . $fileSize . "\n"; - $this->assertEquals(dol_filesize($localobject->html_images[$i]['fullpath']), $fileSize); - } + $fileSize = 85; + print __METHOD__ . " File size must be =" . $fileSize . "\n"; + $this->assertEquals(dol_filesize($localobject->html_images[$i]['fullpath']), $fileSize); } } From 734de118f071e8c428f1342efd4ce3cb00cccb02 Mon Sep 17 00:00:00 2001 From: atm-florian Date: Wed, 13 Dec 2023 16:38:25 +0100 Subject: [PATCH 06/31] FIX: disable pointer events on jQuery-UI tooltips to prevent a glitch (fast-blinking tooltip) --- htdocs/theme/eldy/global.inc.php | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 4af0c6366f1..290ff4691c9 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -5058,6 +5058,7 @@ div.ui-tooltip.mytooltip { color: var(--tooltipfontcolor); line-height: 1.6em; min-width: 550px; + pointer-events: none; } Date: Tue, 19 Dec 2023 08:51:02 +0100 Subject: [PATCH 07/31] search by thirdparty in don list --- htdocs/don/list.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/htdocs/don/list.php b/htdocs/don/list.php index 891f7e6877b..fa9c1a2547c 100644 --- a/htdocs/don/list.php +++ b/htdocs/don/list.php @@ -57,6 +57,7 @@ $search_status = (GETPOST("search_status", 'intcomma') != '') ? GETPOST("search_ $search_all = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml')); $search_ref = GETPOST('search_ref', 'alpha'); $search_company = GETPOST('search_company', 'alpha'); +$search_thirdparty = GETPOST('search_thirdparty', 'alpha'); $search_name = GETPOST('search_name', 'alpha'); $search_amount = GETPOST('search_amount', 'alpha'); $optioncss = GETPOST('optioncss', 'alpha'); @@ -69,6 +70,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_all = ""; $search_ref = ""; $search_company = ""; + $search_thirdparty = ""; $search_name = ""; $search_amount = ""; $search_status = ''; @@ -106,7 +108,10 @@ $sql = "SELECT d.rowid, d.datedon, d.fk_soc as socid, d.firstname, d.lastname, d $sql .= " d.amount, d.fk_statut as status,"; $sql .= " p.rowid as pid, p.ref, p.title, p.public"; $sql .= " FROM ".MAIN_DB_PREFIX."don as d LEFT JOIN ".MAIN_DB_PREFIX."projet AS p"; -$sql .= " ON p.rowid = d.fk_projet WHERE d.entity IN (".getEntity('donation').")"; +$sql .= " ON p.rowid = d.fk_projet"; +$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe AS s ON s.rowid = d.fk_soc"; +$sql .= " WHERE d.entity IN (". getEntity('donation') . ")"; + if ($search_status != '' && $search_status != '-4') { $sql .= " AND d.fk_statut IN (".$db->sanitize($search_status).")"; } @@ -119,6 +124,9 @@ if (trim($search_all) != '') { if (trim($search_company) != '') { $sql .= natural_search('d.societe', $search_company); } +if (trim($search_thirdparty) != '') { + $sql .= " AND s.nom LIKE '%" . $db->escape($search_thirdparty) . "%'"; +} if (trim($search_name) != '') { $sql .= natural_search(array('d.lastname', 'd.firstname'), $search_name); } From 11780b0f12152ee83e2cb0ee9b4ce3c8d6505a4e Mon Sep 17 00:00:00 2001 From: Thomas905 Date: Tue, 19 Dec 2023 08:58:02 +0100 Subject: [PATCH 08/31] search by ref & rowid in don list --- htdocs/don/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/don/list.php b/htdocs/don/list.php index 891f7e6877b..7cb4e37df5a 100644 --- a/htdocs/don/list.php +++ b/htdocs/don/list.php @@ -111,7 +111,7 @@ if ($search_status != '' && $search_status != '-4') { $sql .= " AND d.fk_statut IN (".$db->sanitize($search_status).")"; } if (trim($search_ref) != '') { - $sql .= natural_search('d.ref', $search_ref); + $sql .= natural_search(['d.ref', "d.rowid"], $search_ref); } if (trim($search_all) != '') { $sql .= natural_search(array_keys($fieldstosearchall), $search_all); From 87695c931e7929dac7f7b24d3c7468fcad08255d Mon Sep 17 00:00:00 2001 From: Thomas905 Date: Tue, 19 Dec 2023 17:14:41 +0100 Subject: [PATCH 09/31] fix --- htdocs/don/list.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/don/list.php b/htdocs/don/list.php index fa9c1a2547c..b50c6710877 100644 --- a/htdocs/don/list.php +++ b/htdocs/don/list.php @@ -125,7 +125,7 @@ if (trim($search_company) != '') { $sql .= natural_search('d.societe', $search_company); } if (trim($search_thirdparty) != '') { - $sql .= " AND s.nom LIKE '%" . $db->escape($search_thirdparty) . "%'"; + $sql .= natural_search("s.nom", $search_thirdparty); } if (trim($search_name) != '') { $sql .= natural_search(array('d.lastname', 'd.firstname'), $search_name); From 2ad52d9fc976af1204e8e586b2c7d892738cfbd2 Mon Sep 17 00:00:00 2001 From: atm-adrien Date: Wed, 20 Dec 2023 14:22:37 +0100 Subject: [PATCH 10/31] FIX : Adding the $encode parrameter to recursive _replaceHtmlWithOdtTag() utilisation --- htdocs/includes/odtphp/odf.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index 2f6f0dbea0b..445bdf46a5a 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -246,23 +246,23 @@ class Odf break; case 'strong': case 'b': - $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; + $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; break; case 'i': case 'em': - $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; + $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; break; case 'u': - $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; + $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; break; case 's': - $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; + $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; break; case 'sub': - $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; + $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; break; case 'sup': - $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; + $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; break; case 'span': if (isset($tag['attributes']['style'])) { @@ -299,12 +299,12 @@ class Odf // Generate a unique id for the style (using microtime and random because some CPUs are really fast...) $key = floatval(str_replace('.', '', microtime(true))) + rand(0, 10); $customStyles[$key] = $odtStyles; - $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; + $odtResult .= '' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . ''; } } break; default: - $odtResult .= $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations); + $odtResult .= $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode); break; } } From 377ec642293e7e615e746c9c2fb13daf19fababe Mon Sep 17 00:00:00 2001 From: atm-florian Date: Thu, 21 Dec 2023 17:02:34 +0100 Subject: [PATCH 11/31] FIX 17.0: deprecated field should only be a fallback --- htdocs/compta/facture/class/facture.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 7232137ae1c..9d96dce5088 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -695,7 +695,7 @@ class Facture extends CommonInvoice $sql .= ", ".(empty($this->date_pointoftax) ? "null" : "'".$this->db->idate($this->date_pointoftax)."'"); $sql .= ", ".($this->note_private ? "'".$this->db->escape($this->note_private)."'" : "null"); $sql .= ", ".($this->note_public ? "'".$this->db->escape($this->note_public)."'" : "null"); - $sql .= ", ".($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null"); + $sql .= ", ".($this->ref_customer ? "'".$this->db->escape($this->ref_customer)."'" : ($this->ref_client ? "'".$this->db->escape($this->ref_client)."'" : "null")); $sql .= ", ".($this->fk_account > 0 ? $this->fk_account : 'NULL'); $sql .= ", ".($this->module_source ? "'".$this->db->escape($this->module_source)."'" : "null"); $sql .= ", ".($this->pos_source != '' ? "'".$this->db->escape($this->pos_source)."'" : "null"); From 40329db2b2eb2cd48b53eaccf450d37bc5317e4e Mon Sep 17 00:00:00 2001 From: Eric Seigne Date: Thu, 21 Dec 2023 18:20:05 +0100 Subject: [PATCH 12/31] next fix for #17665 : autoloader collision --- .../framework/Luracast/Restler/AutoLoader.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php index 5ed160a070a..765927bbf88 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php @@ -290,10 +290,14 @@ class AutoLoader if (is_array($loader) && is_callable($loader)) { $b = new $loader[0]; - if (false !== $file = $b::$loader[1]($className) - && $this->exists($className, $b::$loader[1])) { - return $file; - } + //avoid PHP Fatal error: Uncaught Error: Access to undeclared static property: Composer\\Autoload\\ClassLoader::$loader + //in case of multiple autoloader systems + if(property_exists($b, $loader[1])) { + if (false !== $file = $b::$loader[1]($className) + && $this->exists($className, $b::$loader[1])) { + return $file; + } + } } elseif (is_callable($loader) && false !== $file = $loader($className) && $this->exists($className, $loader)) { From 23e39cb8b3a5f5b1f7b1b5d9633f9ddbd9cdf9fe Mon Sep 17 00:00:00 2001 From: Eric Seigne Date: Fri, 22 Dec 2023 11:05:17 +0100 Subject: [PATCH 13/31] update changes --- dev/dolibarr_changes.txt | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index e4bc7104303..7c31d61cc46 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -102,7 +102,7 @@ with * Replace in tcpdf.php if (!@TCPDF_STATIC::file_exists($file)) { - return false; + return false; } with @@ -110,9 +110,9 @@ with if (!@TCPDF_STATIC::file_exists($file)) { // DOL CHANGE If we keep this, the image is not visible on pages after the first one. //var_dump($file.' '.(!@TCPDF_STATIC::file_exists($file))); - //return false; + //return false; } - + * Replace in tcpdf.php if (($imgsrc[0] === '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) { @@ -133,7 +133,7 @@ with } } elseif (($imgsrc[0] === '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) { - + * In tecnickcom/tcpdf/include/tcpdf_static, in function fopenLocal, replace @@ -158,10 +158,10 @@ define('QR_FIND_FROM_RANDOM', false); * Removed useless directories ("examples", "tools") -* Optionnaly, removed all fonts except - dejavusans* (used by greek, arab, persan, romanian, turkish), - freemono* (russian), - cid*+msungstdlight+stsongstdlight+uni2cid* (chinese), +* Optionnaly, removed all fonts except + dejavusans* (used by greek, arab, persan, romanian, turkish), + freemono* (russian), + cid*+msungstdlight+stsongstdlight+uni2cid* (chinese), helvetica* (all other languages), zapfdingbats.php (for special chars like form checkboxes) @@ -215,11 +215,11 @@ window.location.href=pRef * Replace vTmpDiv=this.newNode(vTmpCell, 'div', null, null, vTaskList[i].getResource()); -with +with var vTmpNode=this.newNode(vTmpCell, 'div', null, ''); vTmpNode=this.newNode(vTmpNode, 'a', null, '', vLangs[vLang]['moreinfo']); vTmpNode.setAttribute('href',vTaskList[i].getLink()); - + * Replace '% Comp.' to have a smaller text column header 'comp':'% Comp.' with @@ -262,6 +262,17 @@ Change content of file htdocs/includes/restler/framework/Luracast/Restler/explor // @CHANGE LDR if (!is_string($haystack)) return false; +* Add a test into AutoLoader.php to complete function loadThisLoader and test if property exists before calling it + + //avoid PHP Fatal error: Uncaught Error: Access to undeclared static property: Composer\\Autoload\\ClassLoader::$loader + //in case of multiple autoloader systems + if(property_exists($b, $loader[1])) { + if (false !== $file = $b::$loader[1]($className) + && $this->exists($className, $b::$loader[1])) { + return $file; + } + } + PARSEDOWN --------- @@ -269,10 +280,10 @@ PARSEDOWN * Add support of css by adding in Parsedown.php: // @CHANGE LDR - 'class' => $Link['element']['attributes']['class'] + 'class' => $Link['element']['attributes']['class'] ... - + // @CHANGE LDR if (preg_match('/{([^}]+)}/', $remainder, $matches2)) { @@ -311,7 +322,7 @@ Add into Class Google of file OAuth2/Service/Google: } $this->approvalPrompt = $prompt; } - + JEDITABLE.JS From 46dc2646541f8eb009c092dae833537272cbdc72 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 27 Dec 2023 14:40:16 +0100 Subject: [PATCH 14/31] Update dolibarr_changes.txt --- dev/dolibarr_changes.txt | 61 ++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 28 deletions(-) diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index 7c31d61cc46..ebfc2890e39 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -152,9 +152,9 @@ with elseif (strpos($filename, '://') === false) * To avoid to have QRcode changed because generated with a random mask, replace -define('QR_FIND_FROM_RANDOM', 2); -with -define('QR_FIND_FROM_RANDOM', false); + define('QR_FIND_FROM_RANDOM', 2); + with: + define('QR_FIND_FROM_RANDOM', false); * Removed useless directories ("examples", "tools") @@ -173,15 +173,15 @@ In htdocs/includes/tecnickcom/tcpdf/tcpdf.php * In tecnickcom/tcpdf/include/tcpdf_static, in function intToRoman, right at the beginning of the function, replace: - $roman = ''; + $roman = ''; -with: + with: - $roman = ''; - if ($number >= 4000) { - // do not represent numbers above 4000 in Roman numerals - return strval($number); - } + $roman = ''; + if ($number >= 4000) { + // do not represent numbers above 4000 in Roman numerals + return strval($number); + } @@ -192,14 +192,14 @@ Add fpdf_tpl.php 1.2 Add tcpdi.php Add tcpdi_parser.php and replace: -require_once(dirname(__FILE__).'/include/tcpdf_filters.php'); -with: -require_once(dirname(__FILE__).'/../tecnickcom/tcpdf/include/tcpdf_filters.php'); + require_once(dirname(__FILE__).'/include/tcpdf_filters.php'); + with: + require_once(dirname(__FILE__).'/../tecnickcom/tcpdf/include/tcpdf_filters.php'); * Fix by replacing } elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1] >= 2))) { -with + with } elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1]) >= 2)) { @@ -262,16 +262,22 @@ Change content of file htdocs/includes/restler/framework/Luracast/Restler/explor // @CHANGE LDR if (!is_string($haystack)) return false; -* Add a test into AutoLoader.php to complete function loadThisLoader and test if property exists before calling it +* Add a test into AutoLoader.php to complete function loadThisLoader and test if property exists before calling it. For this replace code - //avoid PHP Fatal error: Uncaught Error: Access to undeclared static property: Composer\\Autoload\\ClassLoader::$loader - //in case of multiple autoloader systems - if(property_exists($b, $loader[1])) { - if (false !== $file = $b::$loader[1]($className) - && $this->exists($className, $b::$loader[1])) { - return $file; - } - } + if (false !== $file = $b::$loader[1]($className) && $this->exists($className, $b::$loader[1])) { + return $file; + } + + with: + + //avoid PHP Fatal error: Uncaught Error: Access to undeclared static property: Composer\\Autoload\\ClassLoader::$loader + //in case of multiple autoloader systems + if(property_exists($b, $loader[1])) { + if (false !== $file = $b::$loader[1]($className) + && $this->exists($className, $b::$loader[1])) { + return $file; + } + } PARSEDOWN @@ -285,11 +291,10 @@ PARSEDOWN ... // @CHANGE LDR - if (preg_match('/{([^}]+)}/', $remainder, $matches2)) - { - $Element['attributes']['class'] = $matches2[1]; - $remainder = preg_replace('/{'.preg_quote($matches2[1],'/').'}/', '', $remainder); - } + if (preg_match('/{([^}]+)}/', $remainder, $matches2)) { + $Element['attributes']['class'] = $matches2[1]; + $remainder = preg_replace('/{'.preg_quote($matches2[1],'/').'}/', '', $remainder); + } // @CHANGE LDR From 3d23322556a9c3f8bee1d5080e3a7f6e2bf852ff Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 28 Dec 2023 08:59:44 +0100 Subject: [PATCH 15/31] FIX: bad accountancy code autoselection for supplier ventilation --- htdocs/accountancy/class/accountingaccount.class.php | 2 +- htdocs/accountancy/supplier/list.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index 8e5f7690dd1..22713357ff8 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -839,7 +839,7 @@ class AccountingAccount extends CommonObject } $suggestedid = $accountingAccount['dom']; // There is a doubt for this case. Is it an error on vat or we just forgot to fill vat number ? $suggestedaccountingaccountfor = 'eecwithoutvatnumber'; - } elseif ($isSellerInEEC && $isBuyerInEEC && !empty($product->accountancy_code_sell_intra)) { + } elseif ($isSellerInEEC && $isBuyerInEEC) { // European intravat sale if ($type == 'customer' && !empty($product->accountancy_code_sell_intra)) { $code_p = $product->accountancy_code_sell_intra; diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index aae34a51e03..85f64242c64 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -623,6 +623,7 @@ if ($result) { $code_buy_t=$return['code_t']; } //var_dump($return); + //exit; if (!empty($code_buy_p)) { // Value was defined previously From 39d986ae591d64b892ce44c7d3bff2534229271f Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 28 Dec 2023 09:00:39 +0100 Subject: [PATCH 16/31] FIX: bad accountancy code autoselection for supplier ventilation --- htdocs/accountancy/supplier/list.php | 1 - 1 file changed, 1 deletion(-) diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index 85f64242c64..aae34a51e03 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -623,7 +623,6 @@ if ($result) { $code_buy_t=$return['code_t']; } //var_dump($return); - //exit; if (!empty($code_buy_p)) { // Value was defined previously From 14cc6c0332703bc510960cdd7391a44261ca27c0 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 Dec 2023 13:09:41 +0100 Subject: [PATCH 17/31] Fix phpunit --- test/phpunit/CMailFileTest.php | 44 +++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/test/phpunit/CMailFileTest.php b/test/phpunit/CMailFileTest.php index 96d6e195b41..7413c28ae8c 100644 --- a/test/phpunit/CMailFileTest.php +++ b/test/phpunit/CMailFileTest.php @@ -208,14 +208,20 @@ class CMailFileTest extends PHPUnit\Framework\TestCase return $result; } + /** + * testCMailFileHTMLWithImage + * + * @return int + */ public function testCMailFileHTMLWithImage() { - global $conf, $user, $langs, $db; + $conf = $this->savconf; $user = $this->savuser; $langs = $this->savlangs; $db = $this->savdb; + $conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_IN_MEDIAS = 1; $conf->global->MAIN_MAIL_ADD_INLINE_IMAGES_IF_DATA = 1; @@ -237,29 +243,29 @@ class CMailFileTest extends PHPUnit\Framework\TestCase foreach ($localobject->html_images as $i => $val) - if ($localobject->html_images[$i]) { - if (preg_match('/img250x20\.png/i', $localobject->html_images[$i]['fullpath'])) { - print __METHOD__ . " content type must be image png =" . $localobject->html_images[$i]['content_type'] . "\n"; - $this->assertEquals($localobject->html_images[$i]['content_type'], 'image/png'); + if ($localobject->html_images[$i]) { + if (preg_match('/img250x20\.png/i', $localobject->html_images[$i]['fullpath'])) { + print __METHOD__ . " content type must be image png =" . $localobject->html_images[$i]['content_type'] . "\n"; + $this->assertEquals($localobject->html_images[$i]['content_type'], 'image/png'); - print __METHOD__ . " type must be cidfromurl =" . $localobject->html_images[$i]['type'] . "\n"; - $this->assertEquals($localobject->html_images[$i]['type'], 'cidfromurl'); + print __METHOD__ . " type must be cidfromurl =" . $localobject->html_images[$i]['type'] . "\n"; + $this->assertEquals($localobject->html_images[$i]['type'], 'cidfromurl'); - $fileSize = 9744; - print __METHOD__ . " File size must be =" . $fileSize . "\n"; - $this->assertEquals(dol_filesize($localobject->html_images[$i]['fullpath']), $fileSize); - } elseif (preg_match('/\.png/i', $localobject->html_images[$i]['fullpath'])) { - print __METHOD__ . " content type must be image png =" . $localobject->html_images[$i]['content_type'] . "\n"; - $this->assertEquals($localobject->html_images[$i]['content_type'], 'image/png'); + $fileSize = 9744; + print __METHOD__ . " File size must be =" . $fileSize . "\n"; + $this->assertEquals(dol_filesize($localobject->html_images[$i]['fullpath']), $fileSize); + } elseif (preg_match('/\.png/i', $localobject->html_images[$i]['fullpath'])) { + print __METHOD__ . " content type must be image png =" . $localobject->html_images[$i]['content_type'] . "\n"; + $this->assertEquals($localobject->html_images[$i]['content_type'], 'image/png'); - print __METHOD__ . " type must be cidfromdata =" . $localobject->html_images[$i]['type'] . "\n"; - $this->assertEquals($localobject->html_images[$i]['type'], 'cidfromdata'); + print __METHOD__ . " type must be cidfromdata =" . $localobject->html_images[$i]['type'] . "\n"; + $this->assertEquals($localobject->html_images[$i]['type'], 'cidfromdata'); - $fileSize = 85; - print __METHOD__ . " File size must be =" . $fileSize . "\n"; - $this->assertEquals(dol_filesize($localobject->html_images[$i]['fullpath']), $fileSize); - } + $fileSize = 85; + print __METHOD__ . " File size must be =" . $fileSize . "\n"; + $this->assertEquals(dol_filesize($localobject->html_images[$i]['fullpath']), $fileSize); } + } return $result; } From 8da8db215a83385b757b2790b88f636e40ad87f1 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 30 Dec 2023 15:25:15 +0100 Subject: [PATCH 18/31] Fix phpunit --- htdocs/theme/eldy/global.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 290ff4691c9..5a68987162c 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -5058,7 +5058,7 @@ div.ui-tooltip.mytooltip { color: var(--tooltipfontcolor); line-height: 1.6em; min-width: 550px; - pointer-events: none; + pointer-events: none; } Date: Sun, 31 Dec 2023 17:16:53 +0100 Subject: [PATCH 19/31] FIX #27262 Recurrent invoice - user to string conversion --- htdocs/fourn/class/fournisseur.facture-rec.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/fourn/class/fournisseur.facture-rec.class.php b/htdocs/fourn/class/fournisseur.facture-rec.class.php index bad8edf3a66..a44bb305455 100644 --- a/htdocs/fourn/class/fournisseur.facture-rec.class.php +++ b/htdocs/fourn/class/fournisseur.facture-rec.class.php @@ -1323,7 +1323,7 @@ class FactureFournisseurRec extends CommonInvoice } if (!$error && ($facturerec->auto_validate || $forcevalidation)) { $result = $new_fac_fourn->validate($user); - $laststep="Validate by user $user"; + $laststep="Validate by user {$user->login}"; if ($result <= 0) { $this->errors = $new_fac_fourn->errors; $this->error = $new_fac_fourn->error; From 0dffaa53dd7b14abc897df3fcbff22066182e6f5 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 2 Jan 2024 14:45:49 +0100 Subject: [PATCH 20/31] Fix doc --- dev/dolibarr_changes.txt | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index be467e8eadf..3cca5c44724 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -188,17 +188,10 @@ Add file fpdf_tpl.php 1.2 Add file tcpdi.php -<<<<<<< HEAD Add file tcpdi_parser.php and replace: require_once(dirname(__FILE__).'/include/tcpdf_filters.php'); with: require_once(dirname(__FILE__).'/../tecnickcom/tcpdf/include/tcpdf_filters.php'); -======= -Add tcpdi_parser.php and replace: - require_once(dirname(__FILE__).'/include/tcpdf_filters.php'); - with: - require_once(dirname(__FILE__).'/../tecnickcom/tcpdf/include/tcpdf_filters.php'); ->>>>>>> branch '13.0' of git@github.com:Dolibarr/dolibarr.git * Fix syntax error by replacing @@ -218,21 +211,12 @@ with window.location.href=pRef * Replace -<<<<<<< HEAD vTmpDiv=this.newNode(vTmpCell, 'div', null, null, vTaskList[i].getResource()); with var vTmpNode=this.newNode(vTmpCell, 'div', null, ''); vTmpNode=this.newNode(vTmpNode, 'a', null, '', vLangs[vLang]['moreinfo']); vTmpNode.setAttribute('href',vTaskList[i].getLink()); -======= -vTmpDiv=this.newNode(vTmpCell, 'div', null, null, vTaskList[i].getResource()); -with -var vTmpNode=this.newNode(vTmpCell, 'div', null, ''); -vTmpNode=this.newNode(vTmpNode, 'a', null, '', vLangs[vLang]['moreinfo']); -vTmpNode.setAttribute('href',vTaskList[i].getLink()); - ->>>>>>> branch '13.0' of git@github.com:Dolibarr/dolibarr.git * Replace '% Comp.' to have a smaller text column header 'comp':'% Comp.' with @@ -272,7 +256,6 @@ RESTLER: // @CHANGE LDR if (!is_string($haystack)) return false; -<<<<<<< HEAD * Replace $loaders = array_unique(static::$rogueLoaders); @@ -282,12 +265,6 @@ RESTLER: $loaders = array_unique(static::$rogueLoaders, SORT_REGULAR); -+With swagger 2 provided into /explorer: ----------------------------------------- - -Change content of file htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html - -======= * Add a test into AutoLoader.php to complete function loadThisLoader and test if property exists before calling it. For this replace code if (false !== $file = $b::$loader[1]($className) && $this->exists($className, $b::$loader[1])) { @@ -304,7 +281,13 @@ Change content of file htdocs/includes/restler/framework/Luracast/Restler/explor return $file; } } ->>>>>>> branch '13.0' of git@github.com:Dolibarr/dolibarr.git + + ++With swagger 2 provided into /explorer: +---------------------------------------- + +Change content of file htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html + PARSEDOWN From 3fae1cc0992596df493217e4846eac904a6c7fc4 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Tue, 2 Jan 2024 14:47:18 +0100 Subject: [PATCH 21/31] Fix doc --- dev/dolibarr_changes.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index cd64efe58e7..bd826f56938 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -110,15 +110,11 @@ with if (!@TCPDF_STATIC::file_exists($file)) { // DOL CHANGE If we keep this, the image is not visible on pages after the first one. //var_dump($file.' '.(!@TCPDF_STATIC::file_exists($file))); -<<<<<<< HEAD //return false; $tfile = str_replace(' ', '%20', $file); if (@TCPDF_STATIC::file_exists($tfile)) { $file = $tfile; } -======= - //return false; ->>>>>>> branch '15.0' of git@github.com:Dolibarr/dolibarr.git } * Replace in tcpdf.php From 43fceaf468f19e9714bbf296da4c611c68357301 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 4 Jan 2024 11:47:43 +0100 Subject: [PATCH 22/31] fix: pregmatch all always return empty array, muxt be tested like in findHtmlImages --- htdocs/core/class/CMailFile.class.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 7b0af81a62c..c801af3ad10 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -1752,14 +1752,13 @@ class CMailFile { // Build the array of image extensions $extensions = array_keys($this->image_types); - // We search (into mail body this->html), if we find some strings like "... file=xxx.img" // For example when: // $matches = array(); preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $matches); // If "xxx.ext" or 'xxx.ext' found - if (!empty($matches)) { + if (!empty($matches) && !empty($matches[1])) { $i = 0; // We are interested in $matches[1] only (the second set of parenthesis into regex) foreach ($matches[1] as $full) { @@ -1790,7 +1789,6 @@ class CMailFile $i++; } } - if (!empty($this->html_images)) { $inline = array(); From 053e0981adde798960c93bfebd48d225a681d964 Mon Sep 17 00:00:00 2001 From: Florian HENRY Date: Thu, 4 Jan 2024 11:49:10 +0100 Subject: [PATCH 23/31] fix: pregmatch all always return empty array, muxt be tested like in findHtmlImages --- htdocs/core/class/CMailFile.class.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index c801af3ad10..da861fbfb0d 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -1752,6 +1752,7 @@ class CMailFile { // Build the array of image extensions $extensions = array_keys($this->image_types); + // We search (into mail body this->html), if we find some strings like "... file=xxx.img" // For example when: // @@ -1789,6 +1790,7 @@ class CMailFile $i++; } } + if (!empty($this->html_images)) { $inline = array(); From bd77c11d416c26de407d133897741d484be6a493 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 6 Jan 2024 13:31:28 +0100 Subject: [PATCH 24/31] Fix class not loaded on mobile. --- htdocs/accountancy/bookkeeping/card.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/accountancy/bookkeeping/card.php b/htdocs/accountancy/bookkeeping/card.php index 651afe93562..2609ffb29bf 100644 --- a/htdocs/accountancy/bookkeeping/card.php +++ b/htdocs/accountancy/bookkeeping/card.php @@ -330,7 +330,7 @@ if ($action == 'valid') { * View */ -$html = new Form($db); +$form = new Form($db); $formaccounting = new FormAccounting($db); $title = $langs->trans("CreateMvts"); @@ -339,7 +339,7 @@ llxHeader('', $title); // Confirmation to delete the command if ($action == 'delete') { - $formconfirm = $html->formconfirm($_SERVER["PHP_SELF"].'?id='.$id.'&mode='.$mode, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'confirm_delete', '', 0, 1); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$id.'&mode='.$mode, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'confirm_delete', '', 0, 1); print $formconfirm; } @@ -374,7 +374,7 @@ if ($action == 'create') { print ''; print ''.$langs->trans("Docdate").''; print ''; - print $html->selectDate('', 'doc_date', '', '', '', "create_mvt", 1, 1); + print $form->selectDate('', 'doc_date', '', '', '', "create_mvt", 1, 1); print ''; print ''; From 834a7a078a85d7ca5acb529f64768f3efbe391b5 Mon Sep 17 00:00:00 2001 From: MDW Date: Mon, 8 Jan 2024 18:21:37 +0100 Subject: [PATCH 25/31] Fix: vcard - add missing db argument in call to dol_print_error # Fix: vcard - add missing db argument in call to dol_print_error The first argument is the DoliDB object --- htdocs/contact/vcard.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/contact/vcard.php b/htdocs/contact/vcard.php index d366d1c2b17..33818122a4f 100644 --- a/htdocs/contact/vcard.php +++ b/htdocs/contact/vcard.php @@ -41,7 +41,7 @@ $result = restrictedArea($user, 'contact', $id, 'socpeople&societe'); $result = $contact->fetch($id); if ($result <= 0) { - dol_print_error($contact->error); + dol_print_error($db, $contact->error); exit; } From efce6c5aab47d65d23491d60230095c99b3f1acc Mon Sep 17 00:00:00 2001 From: MDW Date: Mon, 8 Jan 2024 23:45:26 +0100 Subject: [PATCH 26/31] Fix: fournisseur.commande - add missing argument addline call The call to addline had several missing arguments. Added. --- .../class/fournisseur.commande.class.php | 58 ++++++++++--------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index fa70a9e0b25..800ef87b319 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1457,8 +1457,12 @@ class CommandeFournisseur extends CommonOrder $line->date_end, $line->array_options, $line->fk_unit, + $line->multicurrency_subprice, // pu_ht_devise + $line->origin, // origin + $line->origin_id, // origin_id + $line->rang, // rang $line->special_code - ); + ); if ($result < 0) { dol_syslog(get_class($this)."::create ".$this->error, LOG_WARNING); // do not use dol_print_error here as it may be a functionnal error $this->db->rollback(); @@ -1727,31 +1731,31 @@ class CommandeFournisseur extends CommonOrder /** * Add order line * - * @param string $desc Description - * @param float $pu_ht Unit price (used if $price_base_type is 'HT') - * @param float $qty Quantity - * @param float $txtva Taux tva - * @param float $txlocaltax1 Localtax1 tax - * @param float $txlocaltax2 Localtax2 tax - * @param int $fk_product Id product - * @param int $fk_prod_fourn_price Id supplier price - * @param string $ref_supplier Supplier reference price - * @param float $remise_percent Remise - * @param string $price_base_type HT or TTC - * @param float $pu_ttc Unit price TTC (used if $price_base_type is 'TTC') - * @param int $type Type of line (0=product, 1=service) - * @param int $info_bits More information - * @param bool $notrigger Disable triggers - * @param int $date_start Date start of service - * @param int $date_end Date end of service - * @param array $array_options extrafields array - * @param string $fk_unit Code of the unit to use. Null to use the default one - * @param string $pu_ht_devise Amount in currency - * @param string $origin 'order', ... - * @param int $origin_id Id of origin object - * @param int $rang Rank - * @param int $special_code Special code - * @return int <=0 if KO, >0 if OK + * @param string $desc Description + * @param float $pu_ht Unit price (used if $price_base_type is 'HT') + * @param float $qty Quantity + * @param float $txtva VAT Rate + * @param float $txlocaltax1 Localtax1 tax + * @param float $txlocaltax2 Localtax2 tax + * @param int $fk_product Id product + * @param int $fk_prod_fourn_price Id supplier price + * @param string $ref_supplier Supplier reference price + * @param float $remise_percent Remise + * @param string $price_base_type HT or TTC + * @param float $pu_ttc Unit price TTC (used if $price_base_type is 'TTC') + * @param int $type Type of line (0=product, 1=service) + * @param int $info_bits More information + * @param bool $notrigger Disable triggers + * @param int $date_start Date start of service + * @param int $date_end Date end of service + * @param array $array_options extrafields array + * @param string $fk_unit Code of the unit to use. Null to use the default one + * @param string $pu_ht_devise Amount in currency + * @param string $origin 'order', ... + * @param int $origin_id Id of origin object + * @param int $rang Rank + * @param int $special_code Special code + * @return int Return integer <=0 if KO, >0 if OK */ public function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1 = 0.0, $txlocaltax2 = 0.0, $fk_product = 0, $fk_prod_fourn_price = 0, $ref_supplier = '', $remise_percent = 0.0, $price_base_type = 'HT', $pu_ttc = 0.0, $type = 0, $info_bits = 0, $notrigger = false, $date_start = null, $date_end = null, $array_options = 0, $fk_unit = null, $pu_ht_devise = 0, $origin = '', $origin_id = 0, $rang = -1, $special_code = 0) { @@ -1975,7 +1979,7 @@ class CommandeFournisseur extends CommonOrder // Multicurrency $this->line->fk_multicurrency = $this->fk_multicurrency; $this->line->multicurrency_code = $this->multicurrency_code; - $this->line->multicurrency_subprice = $pu_ht_devise; + $this->line->multicurrency_subprice = $pu_ht_devise; $this->line->multicurrency_total_ht = $multicurrency_total_ht; $this->line->multicurrency_total_tva = $multicurrency_total_tva; $this->line->multicurrency_total_ttc = $multicurrency_total_ttc; From 6d88670eeebdf4d51649ac746115dd17078c80b9 Mon Sep 17 00:00:00 2001 From: MDW Date: Tue, 9 Jan 2024 00:03:24 +0100 Subject: [PATCH 27/31] Fix: Sitemap generation - fix invalid replacement regex # Fix: Sitemap generation - fix invalid replacement regex The regex is invalid because the delimiters are slashes which are also present in the text to match. Fixed by changing the delimiters. --- htdocs/website/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/website/index.php b/htdocs/website/index.php index 84d408b4f0b..c799e2ce898 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2673,7 +2673,7 @@ if ($action == 'generatesitemaps' && $usercanedit) { // Add the entry Sitemap: into the robot file. $robotcontent = @file_get_contents($filerobot); - $result = preg_replace('/\n/ims', '', $robotcontent); + $result = preg_replace('@\n@ims', '', $robotcontent); if ($result) { $robotcontent = $result; } From 8f7a4800ee7bf05051305647071e7dcc5fc0a066 Mon Sep 17 00:00:00 2001 From: William Mead Date: Tue, 9 Jan 2024 14:49:20 +0100 Subject: [PATCH 28/31] Added notification information on intervention validated confirmation message --- htdocs/fichinter/card.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index 349139e69ff..de838f401bf 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -1105,6 +1105,12 @@ if ($action == 'create') { $numref = $object->ref; } $text = $langs->trans('ConfirmValidateIntervention', $numref); + if (isModEnabled('notification')) { + require_once DOL_DOCUMENT_ROOT.'/core/class/notify.class.php'; + $notify = new Notify($db); + $text .= '
'; + $text .= $notify->confirmMessage('FICHINTER_VALIDATE', $object->socid, $object); + } $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ValidateIntervention'), $text, 'confirm_validate', '', 1, 1); } From c2f3ce14911ad8e42421d39b4f62ba6b95edf4c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?No=C3=A9?= Date: Tue, 9 Jan 2024 15:38:35 +0100 Subject: [PATCH 29/31] FIX: BarCode Header not well displayed --- htdocs/core/modules/printsheet/doc/pdf_tcpdflabel.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/core/modules/printsheet/doc/pdf_tcpdflabel.class.php b/htdocs/core/modules/printsheet/doc/pdf_tcpdflabel.class.php index 0d380ce1537..a274baa5823 100644 --- a/htdocs/core/modules/printsheet/doc/pdf_tcpdflabel.class.php +++ b/htdocs/core/modules/printsheet/doc/pdf_tcpdflabel.class.php @@ -135,7 +135,7 @@ class pdf_tcpdflabel extends CommonStickerGenerator // Top if ($header != '') { $pdf->SetXY($_PosX + $xleft, $_PosY + 1); // Only 1 mm and not ytop for top text - $pdf->Cell($this->_Width - 2 * $xleft, $this->_Line_Height, $outputlangs->convToOutputCharset($header), 0, 1, 'C'); + $pdf->Cell(2 * strlen($header), $this->_Line_Height, $outputlangs->convToOutputCharset($header), 0, 1, 'C'); } $ytop += (empty($header) ? 0 : (1 + $this->_Line_Height)); From 5c434e273ea053dc4c302b86ea74fe3c14960040 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Wed, 10 Jan 2024 15:25:16 +0100 Subject: [PATCH 30/31] Update index.php --- htdocs/website/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/website/index.php b/htdocs/website/index.php index c799e2ce898..fad19c82a61 100644 --- a/htdocs/website/index.php +++ b/htdocs/website/index.php @@ -2673,7 +2673,7 @@ if ($action == 'generatesitemaps' && $usercanedit) { // Add the entry Sitemap: into the robot file. $robotcontent = @file_get_contents($filerobot); - $result = preg_replace('@\n@ims', '', $robotcontent); + $result = preg_replace('/\n/ims', '', $robotcontent); if ($result) { $robotcontent = $result; } From 72210dc19b92c7f8e31da594d35a3cce4dd590ce Mon Sep 17 00:00:00 2001 From: MDW Date: Wed, 10 Jan 2024 16:57:10 +0100 Subject: [PATCH 31/31] Fix: discount - add missing db parameter to dol_print_error (#27337) # Fix: discount - add missing db parameter to dol_print_error dol_print_error requires the db instance to be the first parameter --- htdocs/core/class/discount.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php index 86fb546be9a..b1cf3fb7749 100644 --- a/htdocs/core/class/discount.class.php +++ b/htdocs/core/class/discount.class.php @@ -581,7 +581,7 @@ class DiscountAbsolute $sql .= " AND f.type = 3"; } else { $this->error = get_class($this)."::getSumDepositsUsed was called with a bad object as a first parameter"; - dol_print_error($this->error); + dol_print_error($this->db, $this->error); return -1; } @@ -622,7 +622,7 @@ class DiscountAbsolute $sql .= " AND f.type IN (".$this->db->sanitize($invoice::TYPE_STANDARD.", ".$invoice::TYPE_CREDIT_NOTE).")"; // Find discount coming from credit note or excess paid } else { $this->error = get_class($this)."::getSumCreditNotesUsed was called with a bad object as a first parameter"; - dol_print_error($this->error); + dol_print_error($this->db, $this->error); return -1; } @@ -660,7 +660,7 @@ class DiscountAbsolute $sql .= " WHERE rc.fk_invoice_supplier IS NULL AND rc.fk_invoice_supplier_source = ".((int) $invoice->id); } else { $this->error = get_class($this)."::getSumCreditNotesUsed was called with a bad object as a first parameter"; - dol_print_error($this->error); + dol_print_error($this->db, $this->error); return -1; }