Skip to content

[Core]: wkhtmltopdf PDF driver fatals — instantiates nonexistent Pdf class #661

Description

@nielsdrost7

Found during the 2026-07-18 v1→v2 feature-parity audit (PDF/Templates domain) as a latent bug, not a parity gap. Verified with a failing test on branch chore/verify-pdf-list-stub-and-wkhtmltopdf-bug (commit 036559c): WkhtmltopdfDriverBugTest::it_generates_pdf_output_without_fatal_error fails with:

Error: Class "Modules\Core\Support\PDF\Drivers\Pdf" not found

at Modules/Core/Support/PDF/Drivers/wkhtmltopdf.php:36
  36▕     $pdf = new Pdf(config('ip.pdfBinaryPath'));

Modules/Core/Support/PDF/Drivers/wkhtmltopdf.php instantiates an unqualified Pdf class that is never imported and does not exist anywhere in the codebase. composer.lock has no knplabs/knp-snappy or mikehaertl/php-shellcommand requirement (only stray conflict-constraint entries from an unrelated package, not actual installs) — the wkhtmltopdf/Snappy wrapper this driver expects was never added as a dependency. Selecting IP_PDF_DRIVER=wkhtmltopdf (config/ip.php:43) fatals on the very first PDF generation attempt.

A related dead-code note found in the same file: PDFFactory::getDrivers() (Modules/Core/Support/PDF/PDFFactory.php) iterates a $driverFiles array that is hard-coded to [] (with a commented-out Directory::listContents(...) call) — it always returns an empty array regardless of which driver classes actually exist on disk.

Specific

Either (a) add the missing dependency (knplabs/knp-snappy + a wkhtmltopdf/wkhtmltoimage binary, matching v1's approach) and fix the Pdf instantiation to new \Knp\Snappy\Pdf(...) (or the correct FQCN for whichever wrapper is chosen), or (b) remove the wkhtmltopdf driver entirely from Modules/Core/Support/PDF/Drivers/ and from config('ip.pdfDriver')'s valid values if it is not meant to be supported, so IP_PDF_DRIVER=wkhtmltopdf cannot be configured into a fatal at all. Separately, fix or remove the dead PDFFactory::getDrivers() method.

Measurable

  • With the dependency fixed: setting IP_PDF_DRIVER=wkhtmltopdf and generating a PDF succeeds and returns valid PDF bytes.
  • With the driver removed: IP_PDF_DRIVER=wkhtmltopdf is rejected at config/boot time (or the driver directory no longer lists it), not left to fatal deep inside PDF generation.
  • PDFFactory::getDrivers() either returns the real list of available driver classes or is removed if unused.

Achievable

Small, self-contained fix either way — no other code depends on this driver today (default is domPDF, PR #608 adds a Browsershot driver as the modern alternative).

Relevant

A driver that silently fatals when selected is worse than not having the option at all — this should be resolved before any documentation or settings UI advertises wkhtmltopdf as a valid IP_PDF_DRIVER value.

Time-Bound

Small fix; can land independently of any other PDF/Templates parity work.

Arrange

config(['ip.pdfDriver' => 'wkhtmltopdf']).

Act

PDFFactory::create()->getOutput('<html></html>').

Assert

  • (If fixed) call returns PDF bytes (%PDF magic header) without throwing.
  • (If removed) the driver class and its config option no longer exist, and attempting to select it fails fast with a clear configuration error instead of a runtime fatal.
  • PDFFactory::getDrivers() no longer contains a permanently-empty, dead iteration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingrefinedRefined with SMART plan / test suggestions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions