diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index e12c237e28e..a92fd02815d 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 @@ -116,7 +116,7 @@ with $file = $tfile; } } - + * Replace in tcpdf.php if (($imgsrc[0] === '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) { @@ -138,7 +138,6 @@ with } elseif (($imgsrc[0] === '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) { - * In tecnickcom/tcpdf/include/tcpdf_static.php, in function fopenLocal, replace if (strpos($filename, '://') === false) { @@ -154,16 +153,16 @@ 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") -* 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) @@ -175,15 +174,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); + } @@ -201,7 +200,7 @@ with: * Fix syntax error 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)) { * Fix php fatal error on php 8.0 on tcpdi.php @@ -292,6 +291,24 @@ RESTLER: empty($value[0]) ? null : empty($value[1]) ? null : +* 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])) { + 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; + } + } + + +With swagger 2 provided into /explorer: ---------------------------------------- @@ -305,16 +322,15 @@ 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)) - { - $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 @@ -347,7 +363,7 @@ Add into Class Google of file OAuth2/Service/Google: } $this->approvalPrompt = $prompt; } - + JEDITABLE.JS 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 ''; 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/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"); 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; } diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index d05854d3435..da861fbfb0d 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -263,12 +263,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 (!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) @@ -1748,7 +1759,7 @@ class CMailFile $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) { @@ -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 @@ -1858,7 +1869,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/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; } 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)); diff --git a/htdocs/don/list.php b/htdocs/don/list.php index c2f89ebc759..5be85314a52 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 = ''; @@ -115,12 +115,15 @@ $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).")"; } 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); @@ -128,6 +131,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/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); } 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; diff --git a/htdocs/fourn/class/fournisseur.facture-rec.class.php b/htdocs/fourn/class/fournisseur.facture-rec.class.php index 322d1ed9285..015b467ec3e 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->id}"; + $laststep = "Validate by user {$user->login}"; if ($result <= 0) { $this->errors = $new_fac_fourn->errors; $this->error = $new_fac_fourn->error; @@ -1333,9 +1333,9 @@ class FactureFournisseurRec extends CommonInvoice if (!$error && $facturerec->generate_pdf) { // We refresh the object in order to have all necessary data (like date_lim_reglement) - $laststep="Refresh {$new_fac_fourn->id}"; + $laststep = "Refresh {$new_fac_fourn->id}"; $new_fac_fourn->fetch($new_fac_fourn->id); - $laststep="GenerateDocument {$new_fac_fourn->id}"; + $laststep = "GenerateDocument {$new_fac_fourn->id}"; $result = $new_fac_fourn->generateDocument($facturerec->model_pdf, $langs); if ($result < 0) { $this->errors = $new_fac_fourn->errors; 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; } } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php index b11506ea86c..a5a1fd98750 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php @@ -1,449 +1,450 @@ - * @copyright 2012 Luracast - * - */ -class AutoLoader -{ - protected static $instance, // the singleton instance reference - $perfectLoaders, // used to keep the ideal list of loaders - $rogueLoaders = array(), // other auto loaders now unregistered - $classMap = array(), // the class to include file mapping - $aliases = array( // aliases and prefixes instead of null list aliases - 'Luracast\\Restler' => null, - 'Luracast\\Restler\\Format' => null, - 'Luracast\\Restler\\Data' => null, - 'Luracast\\Restler\\Filter' => null, - ); + /** + * Class that implements spl_autoload facilities and multiple + * conventions support. + * Supports composer libraries and 100% PSR-0 compliant. + * In addition we enable namespace prefixing and class aliases. + * + * @category Framework + * @package Restler + * @subpackage Helper + * @author Nick Lombard + * @copyright 2012 Luracast + * + */ + class AutoLoader + { + protected static $instance, // the singleton instance reference + $perfectLoaders, // used to keep the ideal list of loaders + $rogueLoaders = array(), // other auto loaders now unregistered + $classMap = array(), // the class to include file mapping + $aliases = array( // aliases and prefixes instead of null list aliases + 'Luracast\\Restler' => null, + 'Luracast\\Restler\\Format' => null, + 'Luracast\\Restler\\Data' => null, + 'Luracast\\Restler\\Filter' => null, + ); - /** - * Singleton instance facility. - * - * @static - * @return AutoLoader the current instance or new instance if none exists. - */ - public static function instance() - { - static::$instance = static::$instance ?: new static(); - return static::thereCanBeOnlyOne(); - } + /** + * Singleton instance facility. + * + * @static + * @return AutoLoader the current instance or new instance if none exists. + */ + public static function instance() + { + static::$instance = static::$instance ?: new static(); + return static::thereCanBeOnlyOne(); + } - /** - * Helper function to add a path to the include path. - * AutoLoader uses the include path to discover classes. - * - * @static - * - * @param $path string absolute or relative path. - * - * @return bool false if the path cannot be resolved - * or the resolved absolute path. - */ - public static function addPath($path) { - if (false === $path = stream_resolve_include_path($path)) - return false; - else - set_include_path($path.PATH_SEPARATOR.get_include_path()); - return $path; - } + /** + * Helper function to add a path to the include path. + * AutoLoader uses the include path to discover classes. + * + * @static + * + * @param $path string absolute or relative path. + * + * @return bool false if the path cannot be resolved + * or the resolved absolute path. + */ + public static function addPath($path) + { + if (false === $path = stream_resolve_include_path($path)) + return false; + else set_include_path($path.PATH_SEPARATOR.get_include_path()); + return $path; + } - /** - * Other autoLoaders interfere and cause duplicate class loading. - * AutoLoader is capable enough to handle all standards so no need - * for others stumbling about. - * - * @return callable the one true auto loader. - */ - public static function thereCanBeOnlyOne() { - if (static::$perfectLoaders === spl_autoload_functions()) - return static::$instance; + /** + * Other autoLoaders interfere and cause duplicate class loading. + * AutoLoader is capable enough to handle all standards so no need + * for others stumbling about. + * + * @return callable the one true auto loader. + */ + public static function thereCanBeOnlyOne() + { + if (static::$perfectLoaders === spl_autoload_functions()) + return static::$instance; - if (false !== $loaders = spl_autoload_functions()) - if (0 < $count = count($loaders)) - for ($i = 0, static::$rogueLoaders += $loaders; - $i < $count && false != ($loader = $loaders[$i]); - $i++) - if ($loader !== static::$perfectLoaders[0]) - spl_autoload_unregister($loader); + if (false !== $loaders = spl_autoload_functions()) + if (0 < $count = count($loaders)) + for ($i = 0, static::$rogueLoaders += $loaders; + $i < $count && false != ($loader = $loaders[$i]); + $i++) + if ($loader !== static::$perfectLoaders[0]) + spl_autoload_unregister($loader); - return static::$instance; - } + return static::$instance; + } - /** - * Seen this before cache handler. - * Facilitates both lookup and persist operations as well as convenience, - * load complete map functionality. The key can only be given a non falsy - * value once, this will be truthy for life. - * - * @param $key mixed class name considered or a collection of - * classMap entries - * @param $value mixed optional not required when doing a query on - * key. Default is false we haven't seen this - * class. Most of the time it will be the filename - * for include and is set to true if we are unable - * to load this class iow true == it does not exist. - * value may also be a callable auto loader function. - * - * @return mixed The known value for the key or false if key has no value - */ - public static function seen($key, $value = false) - { - if (is_array($key)) { - static::$classMap = $key + static::$classMap; - return false; - } + /** + * Seen this before cache handler. + * Facilitates both lookup and persist operations as well as convenience, + * load complete map functionality. The key can only be given a non falsy + * value once, this will be truthy for life. + * + * @param $key mixed class name considered or a collection of + * classMap entries + * @param $value mixed optional not required when doing a query on + * key. Default is false we haven't seen this + * class. Most of the time it will be the filename + * for include and is set to true if we are unable + * to load this class iow true == it does not exist. + * value may also be a callable auto loader function. + * + * @return mixed The known value for the key or false if key has no value + */ + public static function seen($key, $value = false) + { + if (is_array($key)) { + static::$classMap = $key + static::$classMap; + return false; + } - if (empty(static::$classMap[$key])) - static::$classMap[$key] = $value; + if (empty(static::$classMap[$key])) + static::$classMap[$key] = $value; - if (is_string($alias = static::$classMap[$key])) - if (isset(static::$classMap[$alias])) - return static::$classMap[$alias]; + if (is_string($alias = static::$classMap[$key])) + if (isset(static::$classMap[$alias])) + return static::$classMap[$alias]; - return static::$classMap[$key]; - } + return static::$classMap[$key]; + } - /** - * Protected constructor to enforce singleton pattern. - * Populate a default include path. - * All possible includes cant possibly be catered for and if you - * require another path then simply add it calling set_include_path. - */ - protected function __construct() - { - static::$perfectLoaders = array($this); + /** + * Protected constructor to enforce singleton pattern. + * Populate a default include path. + * All possible includes cant possibly be catered for and if you + * require another path then simply add it calling set_include_path. + */ + protected function __construct() + { + static::$perfectLoaders = array($this); - if (false === static::seen('__include_path')) { + if (false === static::seen('__include_path')) { + $paths = explode(PATH_SEPARATOR, get_include_path()); + $slash = DIRECTORY_SEPARATOR; + $dir = dirname(__DIR__); + $source_dir = dirname($dir); + $dir = dirname($source_dir); - $paths = explode(PATH_SEPARATOR, get_include_path()); - $slash = DIRECTORY_SEPARATOR; - $dir = dirname(__DIR__); - $source_dir = dirname($dir); - $dir = dirname($source_dir); + foreach (array( + array($source_dir), + array($dir, '..', '..', 'composer'), + array($dir, 'vendor', 'composer'), + array($dir, '..', '..', '..', 'php'), + array($dir, 'vendor', 'php')) + as $includePath) + if (false !== $path = stream_resolve_include_path( + implode($slash, $includePath) + )) + if ('composer' == end($includePath) && + false !== $classmapPath = stream_resolve_include_path( + "$path{$slash}autoload_classmap.php" + ) + ) { + static::seen(static::loadFile( + $classmapPath + )); + $paths = array_merge( + $paths, + array_values(static::loadFile( + "$path{$slash}autoload_namespaces.php" + )) + ); + } else $paths[] = $path; - foreach ( - array( - array($source_dir), - array($dir, '..', '..', 'composer'), - array($dir, 'vendor', 'composer'), - array($dir, '..', '..', '..', 'php'), - array($dir, 'vendor', 'php')) - as $includePath) - if (false !== $path = stream_resolve_include_path( - implode($slash, $includePath) - )) - if ('composer' == end($includePath) && - false !== $classmapPath = stream_resolve_include_path( - "$path{$slash}autoload_classmap.php" - ) - ) { - static::seen(static::loadFile( - $classmapPath - )); - $paths = array_merge( - $paths, - array_values(static::loadFile( - "$path{$slash}autoload_namespaces.php" - )) - ); - } else - $paths[] = $path; + $paths = array_filter(array_map( + function ($path) { + if (false == $realPath = @realpath($path)) + return null; + return $realPath . DIRECTORY_SEPARATOR; + }, + $paths + )); + natsort($paths); + static::seen( + '__include_path', + implode(PATH_SEPARATOR, array_unique($paths)) + ); + } - $paths = array_filter(array_map( - function ($path) { - if (false == $realPath = @realpath($path)) - return null; - return $realPath . DIRECTORY_SEPARATOR; - }, - $paths - )); - natsort($paths); - static::seen( - '__include_path', - implode(PATH_SEPARATOR, array_unique($paths)) - ); - } + set_include_path(static::seen('__include_path')); + } - set_include_path(static::seen('__include_path')); - } + /** + * Attempt to include the path location. + * Called from a static context which will not expose the AutoLoader + * instance itself. + * + * @param $path string location of php file on the include path + * + * @return bool|mixed returns reference obtained from the include or false + */ + private static function loadFile($path) + { + return \Luracast_Restler_autoloaderInclude($path); + } - /** - * Attempt to include the path location. - * Called from a static context which will not expose the AutoLoader - * instance itself. - * - * @param $path string location of php file on the include path - * - * @return bool|mixed returns reference obtained from the include or false - */ - private static function loadFile($path) - { - return \Luracast_Restler_autoloaderInclude($path); - } + /** + * Attempt to load class with namespace prefixes. + * + * @param $className string class name + * + * @return bool|mixed reference to discovered include or false + */ + private function loadPrefixes($className) + { + $currentClass = $className; + if (false !== $pos = strrpos($className, '\\')) + $className = substr($className, $pos); + else $className = "\\$className"; - /** - * Attempt to load class with namespace prefixes. - * - * @param $className string class name - * - * @return bool|mixed reference to discovered include or false - */ - private function loadPrefixes($className) - { - $currentClass = $className; - if (false !== $pos = strrpos($className, '\\')) - $className = substr($className, $pos); - else - $className = "\\$className"; + for ( + $i = 0, + $file = false, + $count = count(static::$aliases), + $prefixes = array_keys(static::$aliases); + $i < $count + && false === $file + && false === $file = $this->discover( + $variant = $prefixes[$i++].$className, + $currentClass + ); + $file = $this->loadAliases($variant) + ); - for ( - $i = 0, - $file = false, - $count = count(static::$aliases), - $prefixes = array_keys(static::$aliases); - $i < $count - && false === $file - && false === $file = $this->discover( - $variant = $prefixes[$i++].$className, - $currentClass - ); - $file = $this->loadAliases($variant) - ); + return $file; + } - return $file; - } + /** + * Attempt to load configured aliases based on namespace part of class name. + * + * @param $className string fully qualified class name. + * + * @return bool|mixed reference to discovered include or false + */ + private function loadAliases($className) + { + $file = false; + if (preg_match('/(.+)(\\\\\w+$)/U', $className, $parts)) + for ( + $i = 0, + $aliases = isset(static::$aliases[$parts[1]]) + ? static::$aliases[$parts[1]] : array(), + $count = count($aliases); + $i < $count && false === $file; + $file = $this->discover( + "{$aliases[$i++]}$parts[2]", + $className + ) + ) ; - /** - * Attempt to load configured aliases based on namespace part of class name. - * - * @param $className string fully qualified class name. - * - * @return bool|mixed reference to discovered include or false - */ - private function loadAliases($className) - { - $file = false; - if (preg_match('/(.+)(\\\\\w+$)/U', $className, $parts)) - for ( - $i = 0, - $aliases = isset(static::$aliases[$parts[1]]) - ? static::$aliases[$parts[1]] : array(), - $count = count($aliases); - $i < $count && false === $file; - $file = $this->discover( - "{$aliases[$i++]}$parts[2]", - $className - ) - ) ; + return $file; + } - return $file; - } + /** + * Load from rogueLoaders as last resort. + * It may happen that a custom auto loader may load classes in a unique way, + * these classes cannot be seen otherwise nor should we attempt to cover every + * possible deviation. If we still can't find a class, as a last resort, we will + * run through the list of rogue loaders and verify if we succeeded. + * + * @param $className string className that can't be found + * @param null $loader callable loader optional when the loader is known + * + * @return bool false unless className now exists + */ + private function loadLastResort($className, $loader = null) + { + $loaders = array_unique(static::$rogueLoaders, SORT_REGULAR); + if (isset($loader)) { + if (false === array_search($loader, $loaders)) + static::$rogueLoaders[] = $loader; + return $this->loadThisLoader($className, $loader); + } + foreach ($loaders as $loader) + if (false !== $file = $this->loadThisLoader($className, $loader)) + return $file; - /** - * Load from rogueLoaders as last resort. - * It may happen that a custom auto loader may load classes in a unique way, - * these classes cannot be seen otherwise nor should we attempt to cover every - * possible deviation. If we still can't find a class, as a last resort, we will - * run through the list of rogue loaders and verify if we succeeded. - * - * @param $className string className that can't be found - * @param null $loader callable loader optional when the loader is known - * - * @return bool false unless className now exists - */ - private function loadLastResort($className, $loader = null) { - $loaders = array_unique(static::$rogueLoaders, SORT_REGULAR); - if (isset($loader)) { - if (false === array_search($loader, $loaders)) - static::$rogueLoaders[] = $loader; - return $this->loadThisLoader($className, $loader); - } - foreach ($loaders as $loader) - if (false !== $file = $this->loadThisLoader($className, $loader)) - return $file; + return false; + } - return false; - } + /** + * Helper for loadLastResort. + * Use loader with $className and see if className exists. + * + * @param $className string name of a class to load + * @param $loader callable autoLoader method + * + * @return bool false unless className exists + */ + private function loadThisLoader($className, $loader) + { + if (is_array($loader) + && is_callable($loader)) { + $b = new $loader[0]; + //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)) { + return $file; + } + return false; + } - /** - * Helper for loadLastResort. - * Use loader with $className and see if className exists. - * - * @param $className string name of a class to load - * @param $loader callable autoLoader method - * - * @return bool false unless className exists - */ - private function loadThisLoader($className, $loader) - { - 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; - } - } elseif (is_callable($loader) - && false !== $file = $loader($className) - && $this->exists($className, $loader)) { - return $file; - } - return false; - } + /** + * Create an alias for class. + * + * @param $className string the name of the alias class + * @param $currentClass string the current class this alias references + * @return void + */ + private function alias($className, $currentClass) + { + if ($className == 'Luracast\Restler\string') return; + if ($className == 'Luracast\Restler\mixed') return; + if ($className != $currentClass + && false !== strpos($className, $currentClass)) + if (!class_exists($currentClass, false) + && class_alias($className, $currentClass)) + static::seen($currentClass, $className); + } - /** - * Create an alias for class. - * - * @param $className string the name of the alias class - * @param $currentClass string the current class this alias references - */ - private function alias($className, $currentClass) - { - if ($className == 'Luracast\Restler\string') return; - if ($className == 'Luracast\Restler\mixed') return; - if ($className != $currentClass - && false !== strpos($className, $currentClass)) - if (!class_exists($currentClass, false) - && class_alias($className, $currentClass)) - static::seen($currentClass, $className); - } + /** + * Discovery process. + * + * @param $className string class name to discover + * @param $currentClass string optional name of current class when + * looking up an alias + * + * @return bool|mixed resolved include reference or false + */ + private function discover($className, $currentClass = null) + { + $currentClass = $currentClass ?: $className; - /** - * Discovery process. - * - * @param $className string class name to discover - * @param $currentClass string optional name of current class when - * looking up an alias - * - * @return bool|mixed resolved include reference or false - */ - private function discover($className, $currentClass = null) - { - $currentClass = $currentClass ?: $className; + /** The short version we've done this before and found it in cache */ + if (false !== $file = static::seen($className)) { + if (!$this->exists($className)) + if (is_callable($file)) + $file = $this->loadLastResort($className, $file); + elseif ($file = stream_resolve_include_path($file)) + $file = static::loadFile($file); - /** The short version we've done this before and found it in cache */ - if (false !== $file = static::seen($className)) { - if (!$this->exists($className)) - if (is_callable($file)) - $file = $this->loadLastResort($className, $file); - elseif($file = stream_resolve_include_path($file)) - $file = static::loadFile($file); + $this->alias($className, $currentClass); + return $file; + } - $this->alias($className, $currentClass); - return $file; - } + /** We did not find it in cache, lets look for it shall we */ - /** We did not find it in cache, lets look for it shall we */ + /** replace \ with / and _ in CLASS NAME with / = PSR-0 in 3 lines */ + $file = preg_replace("/\\\|_(?=\w+$)/", DIRECTORY_SEPARATOR, $className); + if (false === $file = stream_resolve_include_path("$file.php")) + return false; - /** replace \ with / and _ in CLASS NAME with / = PSR-0 in 3 lines */ - $file = preg_replace("/\\\|_(?=\w+$)/", DIRECTORY_SEPARATOR, $className); - if (false === $file = stream_resolve_include_path("$file.php")) - return false; + /** have we loaded this file before could this be an alias */ + if (in_array($file, get_included_files())) { + if (false !== $sameFile = array_search($file, static::$classMap)) + if (!$this->exists($className, $file)) + if (false !== strpos($sameFile, $className)) + $this->alias($sameFile, $className); - /** have we loaded this file before could this be an alias */ - if (in_array($file, get_included_files())) { - if (false !== $sameFile = array_search($file, static::$classMap)) - if (!$this->exists($className, $file)) - if (false !== strpos($sameFile, $className)) - $this->alias($sameFile, $className); + return $file; + } - return $file; - } + $state = array_merge(get_declared_classes(), get_declared_interfaces()); - $state = array_merge(get_declared_classes(), get_declared_interfaces()); + if (false !== $result = static::loadFile($file)) { + if ($this->exists($className, $file)) + $this->alias($className, $currentClass); + elseif (false != $diff = array_diff( + array_merge(get_declared_classes(), get_declared_interfaces()), $state)) + foreach ($diff as $autoLoaded) + if ($this->exists($autoLoaded, $file)) + if (false !== strpos($autoLoaded, $className)) + $this->alias($autoLoaded, $className); - if (false !== $result = static::loadFile($file)) { + if (!$this->exists($currentClass)) + $result = false; + } - if ($this->exists($className, $file)) - $this->alias($className, $currentClass); - elseif (false != $diff = array_diff( - array_merge(get_declared_classes(), get_declared_interfaces()), $state)) - foreach ($diff as $autoLoaded) - if ($this->exists($autoLoaded, $file)) - if (false !== strpos($autoLoaded, $className)) - $this->alias($autoLoaded, $className); + return $result; + } - if (!$this->exists($currentClass)) - $result = false; - } + /** + * Checks whether supplied string exists in a loaded class or interface. + * As a convenience the supplied $mapping can be the value for seen. + * + * @param $className string The class or interface to verify + * @param $mapping string (optional) value for map/seen if found to exist + * + * @return bool whether the class/interface exists without calling auto loader + */ + private function exists($className, $mapping = null) + { + if (class_exists($className, false) + || interface_exists($className, false)) + if (isset($mapping)) + return static::seen($className, $mapping); + else return true; + return false; + } - return $result; - } + /** + * Auto loader callback through __invoke object as function. + * + * @param $className string class/interface name to auto load + * + * @return mixed|null the reference from the include or null + */ + public function __invoke($className) + { + if (empty($className)) + return false; - /** - * Checks whether supplied string exists in a loaded class or interface. - * As a convenience the supplied $mapping can be the value for seen. - * - * @param $className string The class or interface to verify - * @param $mapping string (optional) value for map/seen if found to exist - * - * @return bool whether the class/interface exists without calling auto loader - */ - private function exists($className, $mapping = null) - { - if (class_exists($className, false) - || interface_exists($className, false)) - if (isset($mapping)) - return static::seen($className, $mapping); - else - return true; - return false; - } + if (false !== $includeReference = $this->discover($className)) + return $includeReference; - /** - * Auto loader callback through __invoke object as function. - * - * @param $className string class/interface name to auto load - * - * @return mixed|null the reference from the include or null - */ - public function __invoke($className) - { - if (empty($className)) - return false; + static::thereCanBeOnlyOne(); - if (false !== $includeReference = $this->discover($className)) - return $includeReference; + if (false !== $includeReference = $this->loadAliases($className)) + return $includeReference; - static::thereCanBeOnlyOne(); + if (false !== $includeReference = $this->loadPrefixes($className)) + return $includeReference; - if (false !== $includeReference = $this->loadAliases($className)) - return $includeReference; + if (false !== $includeReference = $this->loadLastResort($className)) + return $includeReference; - if (false !== $includeReference = $this->loadPrefixes($className)) - return $includeReference; - - if (false !== $includeReference = $this->loadLastResort($className)) - return $includeReference; - - static::seen($className, true); - return null; - } -} + static::seen($className, true); + return null; + } + } } namespace { - /** - * Include function in the root namespace to include files optimized - * for the global context. - * - * @param $path string path of php file to include into the global context. - * - * @return mixed|bool false if the file could not be included. - */ - function Luracast_Restler_autoloaderInclude($path) { - return include $path; - } + /** + * Include function in the root namespace to include files optimized + * for the global context. + * + * @param $path string path of php file to include into the global context. + * + * @return mixed|bool false if the file could not be included. + */ + function Luracast_Restler_autoloaderInclude($path) + { + return include $path; + } } - diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 4af0c6366f1..5a68987162c 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; } \n/ims', '', $robotcontent); + $result = preg_replace('/\n/ims', '', $robotcontent); if ($result) { $robotcontent = $result; } diff --git a/test/phpunit/CMailFileTest.php b/test/phpunit/CMailFileTest.php index 729aa4b4c7f..7413c28ae8c 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/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,116 @@ 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; + } }