CoolCMS API

PdfGenerator
in package

FinalYes

Generic PDF generator from a DB template ({@see PdfTemplateVariant}).

Renders the Latte content of a variant (css plus per-language html/header/footer) through mPDF into a file and returns its absolute path. A stateless System service shared across modules (Invoicer via InvoicePdfGenerator), so it knows no domain context: the caller supplies the complete $args (the template key contract) and the target folder.

Rendering uses a standalone Latte engine like SendEmailTrait, with the price/priceFormat/printDate filters registered manually (the DI LatteFactory is file-based, so extension filters do not reach a standalone engine).

IMPORTANT: templates are admin-edited Latte code rendered without a sandbox, so everyone who can edit a template must be trusted.

Exceptions are not swallowed into the UI: they are logged via Debugger::log() and the method returns null, so the best-effort post-commit caller does not fail the invoice.

Layouts: the look (css plus header/html/footer) can be chosen independently of the variant through the optional $layoutId. Content is looked up in PdfTemplateVariantLayoutText (resolveContent()) with a fallback to the default layout. variant_texts (resolveText()) carries only name (meta_title); content always lives on the layout.

Table of Contents

Constants

MPDF_TAG_UNESCAPE  : array<string|int, mixed> = ['#.' => '{', '.#' => '}']
In header/footer templates mPDF `{PAGENO}`/`{nbpg}` are written as `#.PAGENO.#` so Latte does not take them for tags; after rendering `#.`/`.#` is converted back to `{`/`}`.

Properties

$config  : Config
$pdfTemplateLayoutManager  : PdfTemplateLayoutManager
$pdfTemplateManager  : PdfTemplateManager
$priceLatteExtension  : PriceLatteExtension

Methods

__construct()  : mixed
generate()  : string|null
Legacy-compatible entry: finds the variant by id (across all PdfTemplates) and renders it.
generateFromVariant()  : string|null
Core of the render from an already loaded variant (no DB lookup); use it directly when the caller holds the variant.
applyHeaderFooter()  : void
configPath()  : string
Absolute path from `params.{module}.{key}.abs` (see `config/Shared/parameters.neon`).
createEngine()  : Engine
defaultLayoutId()  : int|null
emailTemplatePath()  : string
findVariant()  : PdfTemplateVariant|null
isHtml()  : bool
Heuristic: is the value an HTML fragment (`SetHTMLHeader()` vs plain `SetHeader()`).
latteTempDir()  : string
mpdfTempDir()  : string
renderFragment()  : string
Renders a Latte fragment (header/footer) and converts `#.`/`.#` back to `{`/`}` for mPDF tags.
resolveContent()  : PdfTemplateVariantLayoutText, 1: string}|null
Resolves the content (header/html/footer) and the final css for rendering: the layout (`$layoutId` or the default), falling back to the default layout when the chosen one has no content for this variant. The css is `layout.css . "\n" . variant.css`; `variant.css` is usually empty and remains an optional per-variant addition on top of the layout css.
resolveLayoutText()  : PdfTemplateVariantLayoutText|null
Returns the `layout_texts` row (variant, layout, language) with a language fallback (mirrors `resolveText()`).
resolveText()  : PdfTemplateVariantText|null

Constants

MPDF_TAG_UNESCAPE

In header/footer templates mPDF `{PAGENO}`/`{nbpg}` are written as `#.PAGENO.#` so Latte does not take them for tags; after rendering `#.`/`.#` is converted back to `{`/`}`.

private array<string|int, mixed> MPDF_TAG_UNESCAPE = ['#.' => '{', '.#' => '}']

Properties

Methods

generate()

Legacy-compatible entry: finds the variant by id (across all PdfTemplates) and renders it.

public generate(int $pdfTemplateVariantId, array<string, mixed> $args, string $fileName, string $folderAbs[, int|null $languageId = null ][, int|null $layoutId = null ]) : string|null

Returns the absolute file path, or null on failure.

Parameters
$pdfTemplateVariantId : int
$args : array<string, mixed>
$fileName : string
$folderAbs : string
$languageId : int|null = null
$layoutId : int|null = null
Return values
string|null

generateFromVariant()

Core of the render from an already loaded variant (no DB lookup); use it directly when the caller holds the variant.

public generateFromVariant(PdfTemplateVariant $variant, array<string, mixed> $args, string $fileName, string $folderAbs[, int|null $languageId = null ][, int|null $layoutId = null ]) : string|null
Parameters
$variant : PdfTemplateVariant
$args : array<string, mixed>
$fileName : string
$folderAbs : string
$languageId : int|null = null
$layoutId : int|null = null
Return values
string|null

configPath()

Absolute path from `params.{module}.{key}.abs` (see `config/Shared/parameters.neon`).

private configPath(int $module, string $key) : string
Parameters
$module : int
$key : string
Return values
string

createEngine()

private createEngine() : Engine
Return values
Engine

defaultLayoutId()

private defaultLayoutId() : int|null
Return values
int|null

emailTemplatePath()

private emailTemplatePath() : string
Return values
string

isHtml()

Heuristic: is the value an HTML fragment (`SetHTMLHeader()` vs plain `SetHeader()`).

private isHtml(string $value) : bool
Parameters
$value : string
Return values
bool

latteTempDir()

private latteTempDir() : string
Return values
string

mpdfTempDir()

private mpdfTempDir() : string
Return values
string

renderFragment()

Renders a Latte fragment (header/footer) and converts `#.`/`.#` back to `{`/`}` for mPDF tags.

private renderFragment(Engine $latte, string $html, array<string, mixed> $args) : string
Parameters
$latte : Engine
$html : string
$args : array<string, mixed>
Return values
string

resolveContent()

Resolves the content (header/html/footer) and the final css for rendering: the layout (`$layoutId` or the default), falling back to the default layout when the chosen one has no content for this variant. The css is `layout.css . "\n" . variant.css`; `variant.css` is usually empty and remains an optional per-variant addition on top of the layout css.

private resolveContent(PdfTemplateVariant $variant, int $languageId, int|null $layoutId) : PdfTemplateVariantLayoutText, 1: string}|null
Parameters
$variant : PdfTemplateVariant
$languageId : int
$layoutId : int|null
Return values
PdfTemplateVariantLayoutText, 1: string}|null —

null when no layout (not even the default) has content for this variant; the caller logs it and returns null.

On this page

Search results