[TikiWiki-commits] [Git][tikiwiki/tiki][master] Pdflib fixes upstreamed from a 27 fork
"Jonny Bradley \(@jonnybradley\) via TikiWiki-cvs" <[email protected]>
| Newsgroups | gmane.comp.cms.tiki.cvs |
|---|---|
| Message-ID | <69f1fa7f2b66_3818f7cc76d3@gitlab-sidekiq-low-urgency-cpu-bound-v2-84c8499fcb-h9nkd.mail> |
Jonny Bradley pushed to branch master at Tiki Wiki CMS Groupware / Tiki
Commits:
c7783485 by Jonny Bradley at 2026-04-29T12:14:31+00:00
Pdflib fixes upstreamed from a 27 fork
---
* [FIX] mpdf: Seems feedback doesn't get shown in this context so use die() to at least show the error or exception
* phpstan - no idea why 'stan says "class Mpdf\MpdfException not found" - so try this?
* phpstan namespace fix take #2
* phpstan namespace fix
* [FIX] mpdf: Prevent the chunking to avoid the pcre.backtrace_limit error from splitting html tags in half
husky is so annoying!?
(could be improved to prevent <tags> being split from closing</tags> across page feeds)
* phpcs fix
* [FIX] mpdf: Various mPDF fixes
* [FIX] mpdf: Rename the `pcre.backtrack_limit` var to be more useful
* [FIX] mpdf: Keep the body classes so we can use css to target mPDF output using `body.tiki.tiki-print.print` (or just some of them), also insert the main inline `<style>` block in the `<head>` element rather than in the `body` (and don't remove `.tiki` from the css).
* [FIX] mpdf: Remove unnecessary processing of css - mPDF supports `<strong>` now and ignores @media statements.
bloody husky wasting my time!!!!!
[FIX] mpdf: More fixes for pdflib - `SetHTMLHeader` and `SetHTMLFooter` only set header and footer for ODD pages, so do them for EVEN as well, use `AddPageByArray` instead of `AddPage` (deprecated since mPDF 5ish) and reformat some silly long lines
See merge request tikiwiki/tiki!10096
- - - - -
2 changed files:
- lib/pdflib.php
- − themes/base_files/css/printqueries.css
Changes:
=====================================
lib/pdflib.php
=====================================
@@ -5,6 +5,7 @@
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
+use Mpdf\Mpdf;
use Tiki\Lib\Auth\Tokens;
use Tiki\Lib\Theme\ThemeLib;
@@ -295,7 +296,19 @@ class PdfGenerator
if ($pdfSettings['tocheading']) {
$tocpreHTML = htmlspecialchars("<h1>" . $pdfSettings['tocheading'] . "</h1>", ENT_QUOTES);
}
- $html = "<html><tocpagebreak toc-odd-footer-name=\"footer-without-pagination\" toc-odd-footer-value=\"1\"" . $links . " toc-preHTML=\"" . $tocpreHTML . "\" toc-resetpagenum=\"1\" toc-suppress=\"on\" />" . $html . "</html>";
+ $html = <<<HTML
+<html>
+ <tocpagebreak
+ toc-odd-footer-name="footer-without-pagination"
+ toc-odd-footer-value="1"
+ $links
+ toc-preHTML="$tocpreHTML"
+ toc-resetpagenum="1"
+ toc-suppress="on"
+ />
+ $html
+</html>
+HTML;
}
$this->_parseHTML($html);
$this->_getImages($html, $tempImgArr);
@@ -321,7 +334,7 @@ class PdfGenerator
mkdir($mpdfConfig['tempDir'], 0770, true);
}
- $mpdf = new \Mpdf\Mpdf($mpdfConfig); // @phpstan-ignore class.notFound (depends on MPdf, installed through packages)
+ $mpdf = new Mpdf($mpdfConfig); // @phpstan-ignore class.notFound (depends on MPdf, installed through packages)
$mpdf->curlAllowUnsafeSslRequests = ($prefs['print_pdf_mpdf_allow_unsafe_ssl_requests'] ?? 'y') === 'y';
$basePath = $params['base_path'] ?? TIKI_PATH ;
@@ -372,7 +385,6 @@ class PdfGenerator
$themecss = '';
if ($pdfSettings['print_pdf_mpdf_printfriendly'] === 'y') {
$printcss = file_get_contents('themes/base_files/css/printpdf.css'); // external css
- $bodycss = 'tiki tiki-print'; //execluding theme css in case print friendly is set to yes.
} else {
//getting theme css
$themeLib = TikiLib::lib('theme');
@@ -430,14 +442,8 @@ class PdfGenerator
if ($themePath) {
$themecss .= file_get_contents($themePath);
}
-
- $themecss .= "\nb,strong{font-weight:bold !important;}";
- // preserving theme styles by removing media print styles to print what is shown on screen
- $themecss = str_replace(["media print", "color : fff"], ["media p","color : #fff"], $themecss);
- // for bootstrap print hidden, screen hidden styles on divs
- $printcss = file_get_contents('themes/base_files/css/printqueries.css');
- $bodycss = '';
}
+ $bodyClass = 'tiki tiki-print print';
if (! empty($pdfSettings['coverpage_wiki'])) {
$coverWikiPage = $pdfSettings['coverpage_wiki'];
@@ -482,7 +488,7 @@ class PdfGenerator
$coverHtml = '<div style="' . $coverStyle . '">' . $coverHtml . '</div>';
- $coverMpdf = new \Mpdf\Mpdf($mpdfConfig); // @phpstan-ignore class.notFound (depends on MPdf, installed through packages)
+ $coverMpdf = new Mpdf($mpdfConfig); // @phpstan-ignore class.notFound (depends on MPdf, installed through packages)
$coverMpdf->SetHTMLHeader();
$coverMpdf->SetHTMLFooter();
$coverMpdf->AddPage(
@@ -530,8 +536,8 @@ class PdfGenerator
'</style>';
$cssStyles = str_replace(
- [".tiki","opacity: 0;","page-break-inside: avoid;"],
- ["","fill: #fff;opacity:0.3;stroke:black;","page-break-inside: auto;"],
+ ["opacity: 0;","page-break-inside: avoid;"],
+ ["fill: #fff;opacity:0.3;stroke:black;","page-break-inside: auto;"],
$allCss
);
//PDF import templates will not work if background color is set, need to replace in css
@@ -613,7 +619,7 @@ class PdfGenerator
}
$pageNo = 1;
$pagesTotal = 1;
- $pdfLimit = ini_get('pcre.backtrack_limit');
+ $pcreBacktrackLimit = (int) ini_get('pcre.backtrack_limit');
//end of coverpage generation
foreach ($pdfPages as $pdfPage) {
$resetPage = '';
@@ -716,12 +722,24 @@ class PdfGenerator
} elseif ($pdfPage['footer']) {
$footer = $pdfPage['footer'];
}
- //Add the header to the first page
$mpdf->SetHTMLHeader($this->processHeaderFooter($header, $params['page'] ?? ''), "O");
$mpdf->SetHTMLHeader($this->processHeaderFooter($header, $params['page'] ?? ''), "E");
- $mpdf->AddPage($pdfPage['orientation'], '', $resetPage, '', '', $pdfPage['margin_left'], $pdfPage['margin_right'], $pdfPage['margin_top'], $pdfPage['margin_bottom'], $pdfPage['margin_header'], $pdfPage['margin_footer'], '', '', '', '', '', '', '', '', '', $pdfPage['pagesize']);
+ $mpdf->AddPageByArray(
+ [
+ 'orientation' => $pdfPage['orientation'],
+ 'resetpagenum' => $resetPage,
+ 'margin-left' => $pdfPage['margin_left'],
+ 'margin-right' => $pdfPage['margin_right'],
+ 'margin-top' => $pdfPage['margin_top'],
+ 'margin-bottom' => $pdfPage['margin_bottom'],
+ //$pdfPage['margin_header'],
+ //$pdfPage['margin_footer'],
+ 'sheet-size' => $pdfPage['pagesize'],
+ ]
+ );
$mpdf->SetHTMLHeader($this->processHeaderFooter($header, $params['page'] ?? '')); //Add the header to other pages
$mpdf->SetHTMLFooter($this->processHeaderFooter($footer, $params['page'] ?? '', 'top')); //footer needs to be reset after page content is added
+ $mpdf->SetHTMLFooter($this->processHeaderFooter($footer, $params['page'] ?? '', 'top'), 'E');
//checking watermark on page
$mpdf->SetWatermarkText($pdfPage['watermark']);
$mpdf->showWatermarkText = true;
@@ -750,20 +768,42 @@ class PdfGenerator
$pdfPage['pageContent'] = $this->getHtmlLayout($pdfPage['pageContent']);
$this->_getImages($pdfPage['pageContent'], $tempImgArr);
- $htmlChunk = '<html><body class="' . $bodycss . '" style="margin:0px;padding:0px;">' . $cssStyles;
+ $htmlChunk = '<html><head>' . $cssStyles . '</head><body class="' . $bodyClass . '" style="margin:0;padding:0;">';
if ($prefs['print_pdf_mpdf_debug'] === 'y') {
$debugOutput .= $htmlChunk;
}
$mpdf->WriteHTML($htmlChunk);
- $pagesTotal += floor(strlen($pdfPage['pageContent']) / 3000);
+
//checking if page content is less than mPDF character limit, otherwise split it and loop to writeHTML
- for ($charLimit = 0; $charLimit <= strlen($pdfPage['pageContent']); $charLimit += $pdfLimit) {
- $content_slice = substr($pdfPage['pageContent'], $charLimit, $pdfLimit);
+ $pageContentLength = strlen($pdfPage['pageContent']);
+ $chunkStartPos = 0;
+ while ($chunkStartPos <= $pageContentLength) {
+ $content_slice = substr($pdfPage['pageContent'], $chunkStartPos, $pcreBacktrackLimit);
+ if ($pageContentLength - $chunkStartPos > $pcreBacktrackLimit) {
+ // more to come?
+ $lastTagStart = strrpos($content_slice, '<');
+ $lastTagEnd = strrpos($content_slice, '>');
+ if ($lastTagStart > $lastTagEnd) {
+ // truncate before the last unclosed tag, often a base64 data src image
+ $newChunkStartPos = $chunkStartPos + $lastTagStart;
+ $content_slice = substr($pdfPage['pageContent'], $chunkStartPos, $newChunkStartPos - $chunkStartPos);
+ $chunkStartPos = $newChunkStartPos;
+ } else {
+ $chunkStartPos += $pcreBacktrackLimit;
+ }
+ } else {
+ $chunkStartPos += $pcreBacktrackLimit;
+ }
if ($content_slice) {
if ($prefs['print_pdf_mpdf_debug'] === 'y') {
$debugOutput .= $content_slice;
}
- $mpdf->WriteHTML($content_slice);
+ try {
+ $mpdf->WriteHTML($content_slice);
+ } catch (ErrorException $e) {
+ \Feedback::error($e->getMessage());
+ die($e->getMessage());
+ }
}
}
$htmlChunk = '</body></html>';
=====================================
themes/base_files/css/printqueries.css deleted
=====================================
@@ -1,34 +0,0 @@
-@charset "utf-8";
-/* CSS Document */
-@media print {
- .visible-print {
- display: block !important;
- }
- table.visible-print {
- display: table !important;
- }
- tr.visible-print {
- display: table-row !important;
- }
- th.visible-print,
- td.visible-print {
- display: table-cell !important;
- }
- .visible-print-block {
- display: block !important;
- }
- .visible-print-inline {
- display: inline !important;
- }
- .visible-print-inline-block {
- display: inline-block !important;
- }
- .hidden-print {
- display: none !important;
- }
- .icon_copy_code {
- display: none !important;
- }
-}
-
-
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/c77834859156f9db750c2a4cdb5a9a7a1cfacaa9
--
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/c77834859156f9db750c2a4cdb5a9a7a1cfacaa9
You're receiving this email because of your account on gitlab.com. Manage all notifications: https://gitlab.com/-/profile/notifications | Help: https://gitlab.com/help
_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs