Skip to content

Refactor: Reusable single-page PDF rendering method in PDF class#8578

Merged
AngelFQC merged 2 commits into
masterfrom
refactor/certificate-pdf-reusable-method
Jun 11, 2026
Merged

Refactor: Reusable single-page PDF rendering method in PDF class#8578
AngelFQC merged 2 commits into
masterfrom
refactor/certificate-pdf-reusable-method

Conversation

@AngelFQC

@AngelFQC AngelFQC commented Jun 11, 2026

Copy link
Copy Markdown
Member

Context

Follow-up to the SSRF fix in #8577 (commit 8468df8). That fix added the SafeMpdfHttpClient guard to the direct mPDF instantiation inside Certificate::generatePdfFromCustomCertificate(). This PR removes that hand-rolled instantiation and renders the single-page certificate through the PDF class instead, so the SSRF guard and mPDF construction live in a single place.

Why the certificate instantiated mPDF by hand

generatePdfFromCustomCertificate() rendered a single-page certificate with all margins at 0 and mirrorMargins = 0. It could not reuse the PDF class because the constructor hard-coded margin_header = 8 / margin_footer = 8, and content_to_pdf() always calls format_pdf(), which sets mirrorMargins = 1 (book layout) — together these insert blank odd/even pages around a single page.

The change

  1. New PDF::singlePageHtmlToPdfDownload(string $html, string $fileName, string $orientation): builds a PDF instance and reuses its $this->pdf mPDF object with all margins at 0 and mirrorMargins = 0, deliberately not calling format_pdf(). The remote-asset SSRF guard comes from the constructor's existing SafeMpdfHttpClient::container(), so there is now a single new Mpdf call in the whole class.
  2. Constructor now honors margin_header / margin_footer from $params instead of hard-coding both to 8. Both still default to 8 → callers that don't pass them are unaffected.
  3. generatePdfFromCustomCertificate() delegates to the new method, keeping the certificate-specific logic (orientation setting, Resource fallback read, file name).
  4. Removed the now-unused SafeMpdfHttpClient import from certificate.lib.php.

Behavior change to flag

public/main/my_space/lp_tracking.php:239 builds new PDF('A4', 'P', ['margin_footer' => 4, 'top' => 40, 'bottom' => 25]). That margin_footer => 4 was previously discarded (the constructor hard-coded 8, so the footer rendered at 8 mm); it now takes effect (4 mm), matching the caller's original intent. This is the only existing caller passing margin_footer, and no caller passes margin_header. ⚠ The lp_tracking PDF footer spacing changes by 4 mm — worth a visual check during review.

Invariant

A single guarded mPDF construction path for the PDF class. The certificate render is unchanged (A4/A4-L by orientation, all margins 0, mirrorMargins = 0, download + exit).

🤖 Generated with Claude Code

AngelFQC and others added 2 commits June 11, 2026 11:08
… PDF method

generatePdfFromCustomCertificate() instantiated mPDF directly to render the
single-page certificate with zero margins and mirrorMargins=0, bypassing the
PDF class because its constructor hard-codes margin_header/footer=8 and
format_pdf() forces mirrorMargins=1 (book layout), which would insert blank
pages around the certificate.

Move that single-page rendering into a new reusable PDF::singlePageHtmlToPdfDownload()
method that keeps the exact same mPDF configuration (zero margins,
mirrorMargins=0, A4/A4-L by orientation) and routes remote asset fetches
through SafeMpdfHttpClient, so the SSRF guard now lives in one place (pdf.lib.php)
instead of being duplicated at each direct mPDF call site. No change to the
rendered output.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Instead of instantiating a second mPDF object inside
singlePageHtmlToPdfDownload(), build a PDF instance via the constructor and
reuse its $this->pdf. This leaves a single 'new Mpdf' call (and a single
SafeMpdfHttpClient guard) in the whole class.

To allow the zero-margin certificate layout through the constructor, the
constructor now honors 'margin_header'/'margin_footer' from $params instead of
hard-coding both to 8. Both still default to 8, so callers that don't pass
them are unaffected.

Behavior change: lp_tracking.php builds 'new PDF('A4', 'P', ['margin_footer' => 4, ...])';
that value was previously discarded (footer rendered at 8mm) and now takes
effect (4mm), matching the caller's original intent.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@AngelFQC AngelFQC merged commit 516d87e into master Jun 11, 2026
1 of 12 checks passed
@AngelFQC AngelFQC deleted the refactor/certificate-pdf-reusable-method branch June 11, 2026 16:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant