Merge branch '17.0' into 17_FIX_too_long_output

This commit is contained in:
Laurent Destailleur
2024-01-15 14:16:12 +01:00
committed by GitHub
17 changed files with 653 additions and 544 deletions

View File

@@ -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

View File

@@ -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 '<tr>';
print '<td class="titlefieldcreate fieldrequired">'.$langs->trans("Docdate").'</td>';
print '<td>';
print $html->selectDate('', 'doc_date', '', '', '', "create_mvt", 1, 1);
print $form->selectDate('', 'doc_date', '', '', '', "create_mvt", 1, 1);
print '</td>';
print '</tr>';

View File

@@ -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;

View File

@@ -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");

View File

@@ -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;
}

View File

@@ -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 <img src="data:image/ext;base64,..." to replace them with an embedded file
// This convert an embedded file with src="data:image... into a cid link + attached file
$findimg = $this->findHtmlImagesIsSrcData($upload_dir_tmp);
$resultImageData = $this->findHtmlImagesIsSrcData($upload_dir_tmp);
if ($resultImageData<0) {
dol_syslog("CMailFile::CMailfile: Error on findHtmlImagesInSrcData");
$this->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:
// <img alt="" src="/viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/picture.jpg" style="height:356px; width:1040px" />
// <img alt="" src="/src="data:image....;base64,...." />
$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];

View File

@@ -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;
}

View File

@@ -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));

View File

@@ -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);
}

View File

@@ -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 .= '<br>';
$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);
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -246,23 +246,23 @@ class Odf
break;
case 'strong':
case 'b':
$odtResult .= '<text:span text:style-name="boldText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
$odtResult .= '<text:span text:style-name="boldText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
break;
case 'i':
case 'em':
$odtResult .= '<text:span text:style-name="italicText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
$odtResult .= '<text:span text:style-name="italicText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
break;
case 'u':
$odtResult .= '<text:span text:style-name="underlineText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
$odtResult .= '<text:span text:style-name="underlineText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
break;
case 's':
$odtResult .= '<text:span text:style-name="strikethroughText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
$odtResult .= '<text:span text:style-name="strikethroughText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
break;
case 'sub':
$odtResult .= '<text:span text:style-name="subText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
$odtResult .= '<text:span text:style-name="subText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
break;
case 'sup':
$odtResult .= '<text:span text:style-name="supText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
$odtResult .= '<text:span text:style-name="supText">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
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 .= '<text:span text:style-name="customStyle' . $key . '">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
$odtResult .= '<text:span text:style-name="customStyle' . $key . '">' . ($tag['children'] != null ? $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode) : $this->encode_chars($tag['innerText'], $encode, $charset)) . '</text:span>';
}
}
break;
default:
$odtResult .= $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations);
$odtResult .= $this->_replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations, $encode);
break;
}
}

View File

@@ -1,449 +1,450 @@
<?php
namespace Luracast\Restler {
/**
* 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 <github@jigsoft.co.za>
* @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 <github@jigsoft.co.za>
* @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;
}
}

View File

@@ -5058,6 +5058,7 @@ div.ui-tooltip.mytooltip {
color: var(--tooltipfontcolor);
line-height: 1.6em;
min-width: 550px;
pointer-events: none;
}
<?php

View File

@@ -2673,7 +2673,7 @@ if ($action == 'generatesitemaps' && $usercanedit) {
// Add the entry Sitemap: into the robot file.
$robotcontent = @file_get_contents($filerobot);
$result = preg_replace('/<?php // BEGIN PHP[^?]END PHP ?>\n/ims', '', $robotcontent);
$result = preg_replace('/<?php \/\/ BEGIN PHP[^?]END PHP ?>\n/ims', '', $robotcontent);
if ($result) {
$robotcontent = $result;
}

View File

@@ -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 <john@doe.com>';
$result=$localobject->getValidAddress($src, 0);
print __METHOD__." result=".$result."\n";
$src = 'John Doe <john@doe.com>';
$result = $localobject->getValidAddress($src, 0);
print __METHOD__ . " result=" . $result . "\n";
$this->assertEquals($result, 'John Doe <john@doe.com>');
$src='John Doe <john@doe.com>';
$result=$localobject->getValidAddress($src, 1);
print __METHOD__." result=".$result."\n";
$src = 'John Doe <john@doe.com>';
$result = $localobject->getValidAddress($src, 1);
print __METHOD__ . " result=" . $result . "\n";
$this->assertEquals($result, '<john@doe.com>');
$src='John Doe <john@doe.com>';
$result=$localobject->getValidAddress($src, 2);
print __METHOD__." result=".$result."\n";
$src = 'John Doe <john@doe.com>';
$result = $localobject->getValidAddress($src, 2);
print __METHOD__ . " result=" . $result . "\n";
$this->assertEquals($result, 'john@doe.com');
$src='John Doe <john@doe.com>';
$result=$localobject->getValidAddress($src, 3, 0);
print __METHOD__." result=".$result."\n";
$src = 'John Doe <john@doe.com>';
$result = $localobject->getValidAddress($src, 3, 0);
print __METHOD__ . " result=" . $result . "\n";
$this->assertEquals($result, '"John Doe" <john@doe.com>');
$src='John Doe <john@doe.com>';
$result=$localobject->getValidAddress($src, 3, 1);
print __METHOD__." result=".$result."\n";
$src = 'John Doe <john@doe.com>';
$result = $localobject->getValidAddress($src, 3, 1);
print __METHOD__ . " result=" . $result . "\n";
$this->assertEquals($result, '"=?UTF-8?B?Sm9obiBEb2U=?=" <john@doe.com>');
$src='John Doe <john@doe.com>';
$result=$localobject->getValidAddress($src, 4);
print __METHOD__." result=".$result."\n";
$src = 'John Doe <john@doe.com>';
$result = $localobject->getValidAddress($src, 4);
print __METHOD__ . " result=" . $result . "\n";
$this->assertEquals($result, 'John Doe');
$src='John Doe <john@doe.com>, John Doe2 <john@doe3.com>, John Doe3 <john@doe2.com>';
$result=$localobject->getValidAddress($src, 4);
print __METHOD__." result=".$result."\n";
$src = 'John Doe <john@doe.com>, John Doe2 <john@doe3.com>, John Doe3 <john@doe2.com>';
$result = $localobject->getValidAddress($src, 4);
print __METHOD__ . " result=" . $result . "\n";
$this->assertEquals($result, 'John Doe,John Doe2,John Doe3');
$src='John Doe <john@doe.com>, John Doe2 <john@doe3.com>, John Doe3 <john@doe2.com>';
$result=$localobject->getValidAddress($src, 4, 0, 2);
print __METHOD__." result=".$result."\n";
$src = 'John Doe <john@doe.com>, John Doe2 <john@doe3.com>, John Doe3 <john@doe2.com>';
$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 = '<html><body>';
$msg .= '<img alt="" src="/viewimage.php?modulepart=medias&amp;entity=1&amp;file=image/img250x20.png" style="height:39px; width:150px" />';
$msg .= ' <p>From wikipedia</p> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Red dot" />';
$msg .= '</body></html>';
$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;
}
}