Observe PDF lifecycle events when embedding NextPDF Connect
At a glance
Section titled “At a glance”You can observe and react to PDF lifecycle events — document created, page added, font loaded, signature applied, output produced — without subclassing the document. This is a library-embedding capability, not a Connect tool. The remote Connect transport surface (Model Context Protocol (MCP) / REST / gRPC) exposes no event-listener tool. You observe events only when you host the engine in-process and wire a dispatcher. This page draws that boundary and shows the in-process pattern clearly, so callers do not expect a remote hook.
Install
Section titled “Install”composer require nextpdf/serverUse this pattern when your application embeds the engine and calls it directly in PHP, such as from a custom server host. Over a remote transport, observe the system at the transport boundary with telemetry instead.
Conceptual overview
Section titled “Conceptual overview”The engine fires events through a PSR-14-style dispatcher. You create a
listener provider and dispatcher, register listeners by event class, and then
attach the dispatcher to a document. From there, events fire automatically as
the document is built. When no dispatcher is attached, the event system adds
zero cost because every dispatch point is a null check. Classes resolve
through the autoload class→file mapping (PSR-4 §3), and all sample code
declares strict types and follows the coding standard (PSR-12 §2.1).
API surface
Section titled “API surface”There is no Connect tool for event hooks. The
tool catalog is the catalog of record, and it
lists none. The in-process surface is the engine’s event classes
(DocumentCreatedEvent, PageAddedEvent, FontLoadedEvent,
SignatureAppliedEvent, EncryptionAppliedEvent, DocumentOutputEvent)
together with the listener provider and dispatcher. The tools available over a
transport depend on the installed tier, and event hooks are never among them.
Code sample — Quick start
Section titled “Code sample — Quick start”<?php
declare(strict_types=1);
use NextPDF\Core\Document;use NextPDF\Event\EventDispatcher;use NextPDF\Event\ListenerProvider;use NextPDF\Event\Document\DocumentCreatedEvent;use NextPDF\Event\Document\PageAddedEvent;
$provider = new ListenerProvider();$dispatcher = new EventDispatcher($provider);
$provider->addListener( DocumentCreatedEvent::class, static function (DocumentCreatedEvent $event): void { // react to creation },);
$provider->addListener( PageAddedEvent::class, static function (PageAddedEvent $event): void { // react to a new page: $event->pageIndex },);
$pdf = Document::createStandalone();$pdf->setEventDispatcher($dispatcher);$pdf->addPage()->setFont('Helvetica', '', 12)->cell(0, 10, 'Hello')->save('/tmp/out.pdf');Code sample — Production
Section titled “Code sample — Production”Use these common in-process patterns:
- Audit logging. Register a listener on the base event class with a low priority so that it always runs last, and record the event name and context.
- License/limit enforcement. Listen on
PageAddedEventwith a high priority. Past a page cap, stop propagation and raise a typed exception. - Post-processing. Listen on
DocumentOutputEvent, and then transform the PDF bytes before they are returned. - Security monitoring. Listen on
SignatureAppliedEvent/EncryptionAppliedEvent, and record the level/algorithm and permission flags to an audit log.
Priority guide: ≥1000 for security/limit checks, 0 for normal listeners, and ≤−1000 for audit/telemetry.
Edge cases & gotchas
Section titled “Edge cases & gotchas”- Not available over a remote transport. A remote MCP/REST/gRPC client cannot register a listener, so do not document or expect a remote hook.
- Zero-overhead only without a dispatcher. Attaching a dispatcher adds the cost of its listeners, so keep hot-path listeners cheap.
- Propagation control. Stopping propagation prevents later listeners from running, so order by priority deliberately.
Performance
Section titled “Performance”With no dispatcher, the cost is zero. With listeners, the cost is the sum of
their work. The profile is structural for produced documents.
Security notes
Section titled “Security notes”Listeners can see signing and encryption events, so treat every audit sink as sensitive. A post-processing listener that mutates output bytes is a trust point, so keep it minimal and reviewed.
Conformance
Section titled “Conformance”| Statement | Spec | Clause | reference_id |
|---|---|---|---|
| Event classes resolve via the autoload mapping. | PSR-4 | §3 | |
| Sample code declares strict types per the standard. | PSR-12 | §2.1 |
Commercial context
Section titled “Commercial context”Not applicable — the event system is Core, and it is not part of the remote Connect tool surface.
Transport availability
Section titled “Transport availability”| Transport | Available | Notes |
|---|---|---|
| MCP (stdio) | No | No event-listener tool is exposed. |
| REST | No | No event-listener endpoint. |
| gRPC | No | No event-listener RPC. |
| In-process (library embed) | Yes | The PSR-14 dispatcher pattern above. |
For remote deployments, observe at the transport boundary with telemetry instead of expecting engine event hooks.
HITL risk tier
Section titled “HITL risk tier”Not applicable — there is no Connect tool here, so the confirmation gate is not involved. The host must guard any in-process post-processing that writes files.
Confirmation gate JSON envelope
Section titled “Confirmation gate JSON envelope”Not applicable — no tool call is made. (For tool-call gating see output-approval.)