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)."/");