diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index cbf57df3ab7..ac8bf5b43f3 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -685,7 +685,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"); diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index bb1d56a36fc..523897ab916 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -264,12 +264,23 @@ class CMailFile // This convert an embedd file with src="/viewimage.php?modulepart... into a cid link // TODO Exclude viewimage used for the read tracker ? $findimg = $this->findHtmlImages($dolibarr_main_data_root.'/medias'); + if ($findimg<0) { + dol_syslog("CMailFile::CMailfile: Error on findHtmlImages"); + $this->error = 'ErrorInAddAttachementsImageBaseOnMedia'; + return; + } } if (getDolGlobalString('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) @@ -1902,7 +1913,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 @@ -1913,7 +1924,7 @@ class CMailFile return -1; } - $i = 0; + $i = count($this->html_images); foreach ($matches[1] as $key => $ext) { // We save the image to send in disk $filecontent = $matches[2][$key]; diff --git a/htdocs/don/list.php b/htdocs/don/list.php index 4c323d9fded..12fd413f0de 100644 --- a/htdocs/don/list.php +++ b/htdocs/don/list.php @@ -72,7 +72,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x' $search_all = ""; $search_ref = ""; $search_company = ""; - $search_thirdparty = ""; + $search_thirdparty = ""; $search_name = ""; $search_amount = ""; $search_status = ''; @@ -135,7 +135,10 @@ $sql .= " p.rowid as pid, p.ref, p.title, p.public"; $sqlfields = $sql; // $sql fields to remove for count total $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).")"; } @@ -148,6 +151,9 @@ if (trim($search_all) != '') { if (trim($search_company) != '') { $sql .= natural_search('d.societe', $search_company); } +if (trim($search_thirdparty) != '') { + $sql .= natural_search("s.nom", $search_thirdparty); +} if (trim($search_name) != '') { $sql .= natural_search(array('d.lastname', 'd.firstname'), $search_name); } diff --git a/htdocs/includes/odtphp/odf.php b/htdocs/includes/odtphp/odf.php index ae1827e8b2c..caffd83a1da 100644 --- a/htdocs/includes/odtphp/odf.php +++ b/htdocs/includes/odtphp/odf.php @@ -253,23 +253,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'])) { @@ -306,12 +306,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; } } diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 58a2421c0d8..dd4d58b8f06 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -5187,6 +5187,7 @@ div.ui-tooltip.mytooltip { color: var(--tooltipfontcolor); line-height: 1.6em; min-width: 550px; + pointer-events: none; } 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; /** @@ -43,7 +44,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 { @@ -64,13 +65,13 @@ class CMailFileTest extends PHPUnit\Framework\TestCase parent::__construct($name); //$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"; } @@ -82,23 +83,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"; } /** @@ -108,24 +109,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"; } /** @@ -135,16 +137,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; @@ -157,54 +159,115 @@ 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; } + + /** + * 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; + + 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 (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; + } }