PDF Driver Manager
Contract for registering named PDF drivers, resolving the configured default driver, and rejecting unknown driver names.
Overview
App\Services\Documents\PdfDriverManager is the document engine seam that maps a driver name such as dompdf onto a concrete App\Contracts\Documents\PdfDriver implementation.
Core binds the manager as a singleton in AppServiceProvider and also binds the PdfDriver contract to PdfDriverManager::driver(), so the default configured driver becomes the application's active PDF renderer.
As a factual note about the current integration, PluginRegistrar::pdfDriver() forwards named driver registrations into this manager; this is not SDK usage guidance.
Public surface
| Method | Purpose |
|---|---|
register() |
Store or replace the driver class for one name |
driver() |
Resolve a named driver or the configured default driver |
availableDrivers() |
Return the currently registered driver names |
Accepted contract and identity
Each registration is a pair of:
- a string driver name
- a
class-string<App\Contracts\Documents\PdfDriver>
The manager stores the class name and resolves it through the flightcase when driver() is called. Driver implementations may therefore depend on other services through normal container construction.
The class-string<PdfDriver> requirement is a PHPDoc and static-analysis contract. register() stores the class string without instantiating or runtime-checking it. Flightcase construction failures or a class that does not satisfy the PdfDriver return type surface only when driver() resolves that registration.
Every driver implements the complete render contract:
render(string $html, array $pageConfig, ?PdfDocumentParts $parts = null): string
$htmlis the HTML body or complete HTML input to convert and is passed through unchanged by the manager.$pageConfigis the template's page configuration and is also passed through unchanged. The shipped drivers interpretpage_size,page_orientation,margins, custom page dimensions, and header/footer heights.$partsis optional structured document context containing the header, footer, branding CSS, styles CSS, and body. Drivers must acceptnull; when parts are present,$htmlremains the body input and the shipped drivers use the header, footer, and CSS fields to assemble styled output with repeating non-empty headers and footers.- the return value is the PDF binary string. Driver-specific rendering or dependency failures are allowed to throw; the manager does not translate them.
Current core registrations
config/documents.php currently ships with:
| Name | Class |
|---|---|
dompdf |
App\Services\Documents\Drivers\DompdfDriver |
browsershot |
App\Services\Documents\Drivers\BrowsershotDriver |
The default selection comes from config('documents.pdf_driver', 'dompdf'). If the config value is omitted, dompdf is the fallback.
Default selection, availability, and collisions
The manager captures documents.drivers once, when the singleton manager is constructed. Later changes to that config key do not rebuild its private map; register() mutates the captured map directly. Driver names and their insertion order in that map are what availableDrivers() returns.
Calling driver() with no argument resolves the default configured driver:
$name ??= (string) config('documents.pdf_driver', 'dompdf');
Calling driver('browsershot') bypasses the default and resolves that named driver directly.
Unlike the driver map, documents.pdf_driver is read each time driver() is called, so changing the configured default after manager construction affects the next unnamed lookup. After choosing a class, the manager asks the flightcase on every successful lookup and does not cache driver objects itself. The flightcase binding for that class therefore determines whether repeated lookups return transient or shared instances.
availableDrivers() returns the current registry keys. There is no extra filtering for environment support; it simply reports what has been registered.
register() stores drivers in an associative array keyed by name. Registering the same name again replaces the earlier driver class. Duplicate names are not rejected.
Failure behaviour
If driver() cannot find the requested name, it throws InvalidArgumentException with:
Unknown document PDF driver [name].
The manager does not fall back from an unknown explicit name to the configured default.
Current consumers
The main framework consumer is DocumentRenderPipeline, which calls the manager when rendering PDF output. Other current direct consumers include PurchaseOrderDocumentController and PrintCatalogueItemLabels.
The inventory also records PluginRegistrar as a current consumer because that is how plugins register additional named drivers today.
Worked example
These are the current behaviours exercised in tests:
config(['documents.pdf_driver' => 'browsershot']);
$default = app(PdfDriverManager::class)->driver(); // BrowsershotDriver
$named = app(PdfDriverManager::class)->driver('dompdf'); // DompdfDriver
$drivers = app(PdfDriverManager::class)->availableDrivers(); // ['dompdf', 'browsershot', ...]
If the name does not exist, driver('missing-driver') throws instead of silently choosing another renderer.