diff --git a/ChangeLog b/ChangeLog index bc49acb9ef2..0ac6d7906a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -238,6 +238,7 @@ The following changes may create regressions for some external modules, but were * The trigger code CATEGORY_LINK and CATEGORY_UNLINK have been replaced with code CATEGORY_MODIFY. You can read ->context['linkto'] or ->context['unlinkoff'] to detect if we want to make a link or unlink. * The property ->domiciliation and ->propio on bank accounts has been deprecated and replaced with property ->address and ->owner_name everywhere. * If you were using the substitution key __MEMBER_CIVILITY__, you must now use __MEMBER_TITLE__ +* The hidden title of tab that was hidden by the CSS class tabTitleText has been completely removed from HTML content. ***** ChangeLog for 20.0.4 compared to 20.0.3 ***** diff --git a/htdocs/admin/tools/export_files.php b/htdocs/admin/tools/export_files.php index 19d39a72336..5fb8df51469 100644 --- a/htdocs/admin/tools/export_files.php +++ b/htdocs/admin/tools/export_files.php @@ -165,6 +165,7 @@ if ($compression == 'zip') { } } + global $errormsg; $ret = dol_compress_dir($fulldirtocompress, $outputdir."/".$file, $compression, $excludefiles, $rootdirinzip); // Can modify $errormsg if ($ret < 0) { if ($ret == -2) { diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index 8d8fff229b8..a2a431b00db 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -291,7 +291,12 @@ abstract class CommonInvoice extends CommonObject $alreadypaid += $this->getSumDepositsUsed($multicurrency); $alreadypaid += $this->getSumCreditNotesUsed($multicurrency); - $remaintopay = price2num($this->total_ttc - $alreadypaid, 'MT'); + if ((int) $multicurrency > 0) { + $totalamount = $this->multicurrency_total_ttc; + } else { + $totalamount = $this->total_ttc; + } + $remaintopay = price2num($totalamount - $alreadypaid, 'MT'); if ($this->status == self::STATUS_CLOSED && $this->close_code == 'discount_vat') { // If invoice closed with discount for anticipated payment $remaintopay = 0.0; } diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index 30b233204ff..dd8e788e8e4 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -973,10 +973,7 @@ class FormFile $out .= ''; - $documenturl = DOL_URL_ROOT.'/document.php'; - if (isset($conf->global->DOL_URL_ROOT_DOCUMENT_PHP)) { - $documenturl = getDolGlobalString('DOL_URL_ROOT_DOCUMENT_PHP'); // To use another wrapper - } + $documenturl = getDolGlobalString('DOL_URL_ROOT_DOCUMENT_PHP', DOL_URL_ROOT.'/document.php'); // DOL_URL_ROOT_DOCUMENT_PHP can be used to set another wrapper // Show file name with link to download $imgpreview = $this->showPreview($file, $modulepart, $relativepath, 0, $param); diff --git a/htdocs/core/class/html.formsetup.class.php b/htdocs/core/class/html.formsetup.class.php index 43757d1128b..0d64de41ed3 100644 --- a/htdocs/core/class/html.formsetup.class.php +++ b/htdocs/core/class/html.formsetup.class.php @@ -705,10 +705,10 @@ class FormSetupItem { global $conf; if (isset($conf->global->{$this->confKey})) { - $this->fieldValue = getDolGlobalString($this->confKey); + $this->fieldValue = getDolGlobalString($this->confKey, null); return true; } else { - $this->fieldValue = ''; + $this->fieldValue = null; return false; } } diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 13f0967e9d1..d6fd9f751ff 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -12817,7 +12817,7 @@ function dolGetBadge($label, $html = '', $type = 'primary', $mode = '', $url = ' // TODO: add hook // escape all attribute - $attr = array_map('dol_escape_htmltag', $attr); + $attr = array_map('dolPrintHtmlForAttribute', $attr); $TCompiledAttr = array(); foreach ($attr as $key => $value) { diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index 8a2fdc2f978..11213353a15 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -329,7 +329,8 @@ function pdf_getHeightForLogo($logo, $url = false) } /** - * Function to try to calculate height of a HTML Content + * Function to try to calculate height of a HTML Content. + * WARNING: Do not use this function inside a TCPDF transaction. * * @param TCPDF $pdf PDF initialized object * @param string $htmlcontent HTML Content @@ -340,6 +341,9 @@ function pdfGetHeightForHtmlContent(&$pdf, $htmlcontent) { // store current object $pdf->startTransaction(); + // To avoid pagebreak effect or strange behavior of writeHTMLCell when we are out of page, we imagine we are at the begin of page to test the height of the text + // Another solution would be to do the test on another PDF instance with samefont, width... + $pdf->setY(0); // store starting values $start_y = $pdf->GetY(); //var_dump($start_y); @@ -1214,7 +1218,7 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $pdf->SetDrawColor(224, 224, 224); // Option for footer text color if (getDolGlobalString('PDF_FOOTER_TEXT_COLOR')) { - list($r, $g, $b) = sscanf($conf->global->PDF_FOOTER_TEXT_COLOR, '%d, %d, %d'); + list($r, $g, $b) = sscanf(getDolGlobalString('PDF_FOOTER_TEXT_COLOR'), '%d, %d, %d'); $pdf->SetTextColor($r, $g, $b); } @@ -1233,7 +1237,7 @@ function pdf_pagefoot(&$pdf, $outputlangs, $paramfreetext, $fromcompany, $marge_ $freetextheight = $pdf->getStringHeight($width, $line); } else { $freetextheight = pdfGetHeightForHtmlContent($pdf, dol_htmlentitiesbr($line, 1, 'UTF-8', 0)); // New method (works for HTML content) - //print '
'.$freetextheight;exit; + //print '
'.$freetextheight; } } @@ -1455,6 +1459,8 @@ function pdf_writelinedesc(&$pdf, $object, $i, $outputlangs, $w, $h, $posx, $pos } $parameters = array('pdf' => $pdf, 'i' => $i, 'outputlangs' => $outputlangs, 'w' => $w, 'h' => $h, 'posx' => $posx, 'posy' => $posy, 'hideref' => $hideref, 'hidedesc' => $hidedesc, 'issupplierline' => $issupplierline, 'special_code' => $special_code); $action = ''; + // WARNING: A hook must not close/open the PDF transaction. Doing this generates a lot of trouble. + // Test to know if content added by the hooks is already done by the main caller of pdf_writelinedesc $reshook = $hookmanager->executeHooks('pdf_writelinedesc', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if (!empty($hookmanager->resPrint)) { diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index af2c363ffd6..a02ee3ec9a3 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -558,7 +558,7 @@ function redirectToContainer($containerref, $containeraliasalt = '', $containeri unset($tmpwebsitepage); } if ($result > 0) { - $currenturi = $_SERVER["REQUEST_URI"]; // Example: /public/website/index.php?website=mywebsite.com&pageref=mywebsite-home&nocache=1708177483 + $currenturi = $_SERVER["REQUEST_URI"]; // Example: /public/website/index.php?website=mywebsite.com&pageref=mywebsite-home&cache=3600 $regtmp = array(); if (preg_match('/&pageref=([^&]+)/', $currenturi, $regtmp)) { if ($regtmp[0] == $containerref) { diff --git a/htdocs/core/lib/website2.lib.php b/htdocs/core/lib/website2.lib.php index 36c81798d37..f8c0763d5ff 100644 --- a/htdocs/core/lib/website2.lib.php +++ b/htdocs/core/lib/website2.lib.php @@ -186,7 +186,7 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, $tplcontent .= "} // Not already loaded\n"; $tplcontent .= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n"; $tplcontent .= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n"; - if (in_array($objectpage->type_container, array('page', 'blogpost'))) { + if (in_array($objectpage->type_container, array('page', 'blogpost', 'service'))) { $tplcontent .= 'dol_syslog("--- Prepare content of page '.((int) $objectpage->id).' - '.$objectpage->pageurl.'");'."\n"; } $tplcontent .= "ob_start();\n"; @@ -378,7 +378,7 @@ function dolSavePageContent($filetpl, Website $object, WebsitePage $objectpage, $tplcontent .= "} // Not already loaded\n"; $tplcontent .= "require_once DOL_DOCUMENT_ROOT.'/core/lib/website.lib.php';\n"; $tplcontent .= "require_once DOL_DOCUMENT_ROOT.'/core/website.inc.php';\n"; - if (in_array($objectpage->type_container, array('page', 'blogpost'))) { + if (in_array($objectpage->type_container, array('page', 'blogpost', 'service'))) { $tplcontent .= 'dol_syslog("--- Prepare content of page '.((int) $objectpage->id).' - '.$objectpage->pageurl.'");'."\n"; } $tplcontent .= "// END PHP ?>\n"; diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index 8b1f893cb43..bdf3cd1c060 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -831,7 +831,7 @@ class pdf_crabe extends ModelePDFFactures } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); } - $this->_pagefoot($pdf, $object, $outputlangs, 1, $this->getHeightForQRInvoice($pagenb, $object, $langs)); + $this->_pagefoot($pdf, $object, $outputlangs, 1, $this->getHeightForQRInvoice($pagenb, $object, $outputlangs)); $pagenb++; $pdf->setPage($pagenb); $pdf->setPageOrientation('', true, 0); // The only function to edit the bottom margin of current page to set it. @@ -849,7 +849,7 @@ class pdf_crabe extends ModelePDFFactures } else { $this->_tableau($pdf, $tab_top_newpage, $this->page_hauteur - $tab_top_newpage - $heightforfooter, 0, $outputlangs, 1, 1, $object->multicurrency_code); } - $this->_pagefoot($pdf, $object, $outputlangs, 1, $this->getHeightForQRInvoice($pagenb, $object, $langs)); + $this->_pagefoot($pdf, $object, $outputlangs, 1, $this->getHeightForQRInvoice($pagenb, $object, $outputlangs)); // New page $pdf->AddPage(); if (!empty($tplidx)) { @@ -1359,6 +1359,7 @@ class pdf_crabe extends ModelePDFFactures $langs->loadLangs(array('payment', 'paybox', 'stripe')); $servicename = $langs->transnoentities('Online'); + $paiement_url = getOnlinePaymentUrl(0, 'invoice', $object->ref, 0, '', 0); $linktopay = $langs->trans("ToOfferALinkForOnlinePayment", $servicename).' '.$outputlangs->transnoentities("ClickHere").''; diff --git a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php index 62f3dbf90e7..c93c91d4ae9 100644 --- a/htdocs/core/modules/facture/doc/pdf_sponge.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_sponge.modules.php @@ -344,7 +344,7 @@ class pdf_sponge extends ModelePDFFactures $this->heightforfreetext = getDolGlobalInt('MAIN_PDF_FREETEXT_HEIGHT', 5); // Height reserved to output the free text on last page $this->heightforfooter = $this->marge_basse + (!getDolGlobalString('MAIN_GENERATE_DOCUMENTS_SHOW_FOOT_DETAILS') ? 12 : 22); // Height reserved to output the footer (value include bottom margin) - $heightforqrinvoice = $heightforqrinvoice_firstpage = 0; + $heightforqrinvoice = 0; if (getDolGlobalString('INVOICE_ADD_SWISS_QR_CODE') == 'bottom') { if ($this->getHeightForQRInvoice(1, $object, $langs) > 0) { // Shrink infotot to a base 30 diff --git a/htdocs/ecm/class/ecmfiles.class.php b/htdocs/ecm/class/ecmfiles.class.php index 28db17eceb0..0bd44eceb31 100644 --- a/htdocs/ecm/class/ecmfiles.class.php +++ b/htdocs/ecm/class/ecmfiles.class.php @@ -1009,9 +1009,9 @@ class EcmFiles extends CommonObject if ($option) { if ($option == 'facture_fournisseur') { - $tmppath = preg_replace('/^fournisseur\/facture\//', '', $this->filepath); + $tmppath = preg_replace('/^(\d+\/)?fournisseur\/facture\//', '', $this->filepath); } elseif ($option == 'commande_fournisseur') { - $tmppath = preg_replace('/^fournisseur\/commande\//', '', $this->filepath); + $tmppath = preg_replace('/^(\d+\/)?fournisseur\/commande\//', '', $this->filepath); } else { if ((int) $this->entity > 1) { // Remove the part "entityid/commande/" into "entityid/commande/REFXXX" to get only the ref diff --git a/htdocs/theme/eldy/global.inc.php b/htdocs/theme/eldy/global.inc.php index 43f8ff2b0ab..bc00627a04b 100644 --- a/htdocs/theme/eldy/global.inc.php +++ b/htdocs/theme/eldy/global.inc.php @@ -4014,9 +4014,6 @@ a.tabTitle { text-decoration: none; white-space: nowrap; } -.tabTitleText { - display: none; -} .imgTabTitle { max-height: 14px; } diff --git a/htdocs/theme/md/style.css.php b/htdocs/theme/md/style.css.php index b21d2160f57..e6663bf1448 100644 --- a/htdocs/theme/md/style.css.php +++ b/htdocs/theme/md/style.css.php @@ -4160,9 +4160,6 @@ a.tabTitle { text-decoration: none; white-space: nowrap; } -.tabTitleText { - display: none; -} .imgTabTitle { max-height: 14px; } diff --git a/htdocs/viewimage.php b/htdocs/viewimage.php index a235d54d41f..41d1a43db13 100644 --- a/htdocs/viewimage.php +++ b/htdocs/viewimage.php @@ -193,20 +193,17 @@ if ($modulepart == 'fckeditor') { * View */ -if (GETPOST("cache", 'alpha')) { +$cachestring = GETPOST("cache", 'aZ09'); // May be 1, or an int, or a hash +if ($cachestring) { // Important: The following code is to avoid a page request by the browser and PHP CPU at each Dolibarr page access. // We are here when param cache=xxx to force a cache policy: // xxx=1 means cache of 3600s // xxx=abcdef or 123456789 means a cache of 1 week (the key will be modified to get break cache use) if (empty($dolibarr_nocache)) { - if (GETPOST('cache', 'alpha') != '1') { - $delaycache = 3600 * 24 * 7; - } else { - $delaycache = 3600; - } + $delaycache = ((is_numeric($cachestring) && (int) $cachestring > 1 && (int) $cachestring < 999999) ? $cachestring : '3600'); header('Cache-Control: max-age='.$delaycache.', public, must-revalidate'); header('Pragma: cache'); // This is to avoid to have Pragma: no-cache set by proxy or web server - header('Expires: '.gmdate('D, d M Y H:i:s', time() + $delaycache).' GMT'); // This is to avoid to have Expires set by proxy or web server + header('Expires: '.gmdate('D, d M Y H:i:s', time() + (int) $delaycache).' GMT'); // This is to avoid to have Expires set by proxy or web server } else { // If any cache on files were disable by config file (for test purpose) header('Cache-Control: no-cache'); diff --git a/htdocs/website/samples/wrapper.php b/htdocs/website/samples/wrapper.php index 462b2bbe030..a61c29f5b1b 100644 --- a/htdocs/website/samples/wrapper.php +++ b/htdocs/website/samples/wrapper.php @@ -39,7 +39,6 @@ $limit = GETPOSTINT('limit'); if ($limit <= 0 || $limit > 100) { $limit = 20; } -$cachedelay = GETPOSTINT('cachedelay'); // The delay in second of the cache // Parameters for RSS $rss = GETPOST('rss', 'aZ09'); @@ -130,12 +129,13 @@ if (GETPOSTISSET('type')) { $original_file = str_replace("../", "/", $original_file); // Cache or not -$cachestring = GETPOST("cache", 'aZ09'); // May be 1, or an int, or a hash +$cachestring = GETPOST("cache", 'aZ09'); // May be 1, or an int (delay in second of the cache if < 999999, or a timestamp), or a hash if ($cachestring || image_format_supported($original_file) >= 0) { - // Important: Following code is to avoid page request by browser and PHP CPU at - // each Dolibarr page access. - header('Cache-Control: max-age='.((is_numeric($cachestring) && (int) $cachestring > 1 && (int) $cachestring < 999999) ? $cachestring : '3600').', public, must-revalidate'); + // Important: Following code is to avoid page request by browser and PHP CPU at each Dolibarr page access. + $delaycache = GETPOSTINT('cachedelay') ? GETPOSTINT('cachedelay') : ((is_numeric($cachestring) && (int) $cachestring > 1 && (int) $cachestring < 999999) ? $cachestring : '3600'); + header('Cache-Control: max-age='.$delaycache.', public, must-revalidate'); header('Pragma: cache'); // This is to avoid having Pragma: no-cache + header('Expires: '.gmdate('D, d M Y H:i:s', time() + (int) $delaycache).' GMT'); // This is to avoid to have Expires set by proxy or web server } $refname = basename(dirname($original_file)."/");