Important
We are updating the images for OroCommerce version 6.1 to align with the latest changes in the back-office design. During this transition, some images may still show older versions. Thank you for your patience as we work to update all visuals to reflect these changes.
Architecture Details
The bundle is designed to be flexible and extensible, allowing developers to integrate additional PDF generation engines in the future.
Glossary
PDF builder factory
- a factory that creates the appropriate PDF builder for the specifiedPDF options preset
.PDF builder
- a builder that collects thePDF options
to generate aPDF file
.PDF options preset
- a string that denotes a set of options to be stored in thePDF options
DTO.PDF options
- a DTO that contains the options for generating aPDF file
that will to be passed to thePDF engine
.PDF options configurator
- a configurator that configures thePDF options
via theOptionsResolver
.PDF template
- a model that contains the Twig template (path or template wrapper) and context (variables).PDF template asset
- a model that represents an asset (e.g. image, CSS, JS) that is used in thePDF template
.PDF template renderer
- a service that renders aPDF template
via own Twig environment.PDF engine
- an engine that is responsible for generating the PDF file by interacting with the configured engine.PDF file
- a model that represents the actual PDF file generated by the engine.PDF document operator registry
- a registry that retrieves the appropriatePDF document operator
for the specified entity class andPDF document generation mode
.PDF document generation mode
- a mode that defines how thePDF document
is generated, e.g. instant or deferred.PDF document operator
- an operator that is responsible for generatingPDF documents
for a specific entity class.PDF document demand
- a DTO that contains the necessary information to create aPDF document
.PDF document
- an entity that represents the PDF document created by thePDF document operator
.PDF document factory
- a factory that creates thePDF document
based on the providedPDF document demand
.PDF document resolver
- a resolver that ensures thePDF document
is up-to-date, e.g. generates the PDF file if it is missing.PDF document generator
- a generator that is responsible for generating thePDF file
for specificPDF document type
, i.e. using the specified Twig templates, payload andPDF options preset
.PDF document type
- a string that represents the type of thePDF document
, i.e., e.g.us_standard_invoice
,eu_standard_invoice
, etc. In other words, it allows to generate different PDF documents using differentPDF document generators
that enclose their own logic for generating PDF files for specificPDF document types
.PDF document template
- aPDF template
that is used to generate thePDF file
for thePDF document
.PDF document template provider
- a provider that retrieves the appropriatePDF document template
for the specifiedPDF document type
.PDF document state
- a string that represents the state of thePDF document
, e.g.new
,pending
,resolved
, etc.
PDF Document Flow
The PDF document
generation flow starts with the PDF document operator
registry \Oro\Bundle\PdfGeneratorBundle\PdfDocument\Operator\PdfDocumentOperatorRegistry
that has the following methods:
getOperator(string $entityClass, string $pdfGenerationMode): PdfDocumentOperatorInterface
- retrieves the PDF document operator for the specified entity class andPDF document generation mode
. Falls back to the default operator if no specific operator is found.hasOperator(string $entityClass, string $pdfGenerationMode): bool
- checks if a PDF document operator exists for the specified entity class andPDF document generation mode
.
PDF document generation mode
is expected to be a constant from the \Oro\Bundle\PdfGeneratorBundle\PdfDocument\PdfDocumentGenerationMode
class, which defines the following modes of PDF generation:
instant - PDF documents are generated immediately.
deferred - PDF documents are generated when explicitly requested, e.g., via controller.
PDF document operator
is responsible for generating PDF documents for a specific entity class. The operators are collected in the registry by the service container tag oro_pdf_generator.pdf_document.operator
.
Out-of-the-box, the PDF document operator
is implemented by \Oro\Bundle\PdfGeneratorBundle\PdfDocument\Operator\GenericPdfDocumentOperator
that has the following methods:
createPdfDocument(AbstractPdfDocumentDemand $pdfDocumentDemand): AbstractPdfDocument
- creates aPDF document
based on the providedPDF document demand
.updatePdfDocument(AbstractPdfDocument $pdfDocument): void
- re-generates thePDF file
for the existingPDF document
.isResolvedPdfDocument(AbstractPdfDocument $pdfDocument): bool
- checks if thePDF document
is resolved (e.g., thePDF file
is generated).resolvePdfDocument(AbstractPdfDocument $pdfDocument): void
- resolves thePDF document
to ensure it is up-to-date, e.g. generates thePDF file
if it is missing.deletePdfDocument(AbstractPdfDocument $pdfDocument): void
- deletes thePDF document
.
Hint
You can create your own PDF document operator
by creating a new class that implements \Oro\Bundle\PdfGeneratorBundle\PdfDocument\Operator\PdfDocumentOperatorInterface
and registering it as a service with the tag oro_pdf_generator.pdf_document.operator
.
PDF document demand
is a DTO that contains the necessary information to create a PDF document
. Out-of-the-box, the bundle provides the generic PDF document demand
\Oro\Bundle\PdfGeneratorBundle\PdfDocument\Demand\GenericPdfDocumentDemand
that can be used to create any PDF document
.
PDF document
is represented by entity \Oro\Bundle\PdfGeneratorBundle\Entity\PdfDocument
that contains the PDF file
and metadata about how it was generated. The properties of the PDF document
are:
id
- the identifier of the PDF document.uuid
- the universally unique identifier (UUID), e.g., to identify the document in a URL.pdfDocumentName
- the name of the PDF document (e.g., order-0101). To be used in the file name.pdfDocumentType
- the type of the PDF document, e.g., us_standard_invoice, eu_standard_invoice, etc. It is used to group the documents by type.pdfDocumentFile
- the actual PDF file, reference to the\Oro\Bundle\AttachmentBundle\Entity\File
entity.sourceEntityClass
- the fully qualified class name of the entity for which the PDF document was generated.sourceEntityId
- the identifier of the entity for which the PDF document was generated.pdfDocumentPayload
- the payload that was used to generate the PDF document, serialized as JSON. It can contain additional data that was used during the PDF generation, e.g., customer notes, etc.pdfOptionsPreset
- thePDF options preset
that were used to generate the PDF document, e.g. default.pdfDocumentState
- thePDF document state
, e.g.,resolved
,pending
, etc. It is used to track the state of the PDF document and its generation process.pdfDocumentGenerationMode
- thePDF document generation mode
, e.g., instant, deferred.
Under the hood, the GenericPdfDocumentOperator
delegates the responsibility to the PDF document factory
and the PDF document resolver
.
PDF document factory
is implemented by the \Oro\Bundle\PdfGeneratorBundle\PdfDocument\Factory\GenericPdfDocumentFactory
and is responsible for creating the PDF document
based on the provided PDF document demand
.
Hint
You can alter the creation process by creating listeners for the \Oro\Bundle\PdfGeneratorBundle\Event\BeforePdfDocumentCreatedEvent
or \Oro\Bundle\PdfGeneratorBundle\Event\AfterPdfDocumentCreatedEvent
events.
PDF document resolver
is responsible for resolving the PDF document
to ensure it is up-to-date with desired PDF document state
, i.e, it. generates the PDF file
if it is missing. The bundle provides two resolvers out-of-the-box:
\Oro\Bundle\PdfGeneratorBundle\PdfDocument\Resolver\DeferredPdfDocumentResolver
- resolves thePDF document
when explicitly requested, e.g., via controller.
\Oro\Bundle\PdfGeneratorBundle\PdfDocument\Resolver\InstantPdfDocumentResolver
- resolves thePDF document
immediately when it is created
Hint
You can alter the resolution process by creating listeners for the \Oro\Bundle\PdfGeneratorBundle\Event\BeforePdfDocumentResolvedEvent
or \Oro\Bundle\PdfGeneratorBundle\Event\AfterPdfDocumentResolvedEvent
events. In case you need more control over the resolution process, you can create your own PDF document resolver
by creating a new class that implements the \Oro\Bundle\PdfGeneratorBundle\PdfDocument\Resolver\PdfDocumentResolverInterface
and registering it as a service with the tag oro_pdf_generator.pdf_document.resolver
.
PDF document state
represents the state of the PDF document
. States available out-of-the-box are listed in the``OroBundlePdfGeneratorBundlePdfDocumentPdfDocumentState`` class:
new - the initial state of the
PDF document
when it is created.pending - the state when the
PDF file
is waiting to be resolved.deferred - the state when the
PDF file
is not yet generated and waits for the explicit request to generate it.in_progress - the state when the
PDF file
is being generated.resolved - the state when the
PDF file
is successfully generated and available for download.failed - the state when the
PDF file
generation failed.
Under the hood, the InstantPdfDocumentResolver
delegates the PDF file
generation to the PDF document generator
. After the PDF file
is generated, it sets it to the PDF document
and updates its state to resolved. If the generation fails, it sets the state to failed.
Out-of-the-box the PDF document generator
is implemented by \Oro\Bundle\PdfGeneratorBundle\PdfDocument\Generator\PdfDocumentGeneratorComposite
that is a composite of inner generators that implement the \Oro\Bundle\PdfGeneratorBundle\PdfDocument\Generator\PdfDocumentGeneratorInterface
and collected by the service container tag oro_pdf_generator.pdf_document.generator
.
The bundle provides a generic generator \Oro\Bundle\PdfGeneratorBundle\PdfDocument\Generator\GenericPdfDocumentGenerator
that retrieves the appropriate PDF document templates
from PDF document template provider
. It is suitable for cases that do not require a complex logic.
Hint
You can change the generation process by creating a listener for the \Oro\Bundle\PdfGeneratorBundle\Event\BeforePdfDocumentGeneratedEvent
event. This event is dispatched before the PDF document is generated and allows you to modify the PDF document payload. If you need more control over the generation process, you can create your own PDF document generator
by creating a new class that implements the \Oro\Bundle\PdfGeneratorBundle\PdfDocument\Generator\PdfDocumentGeneratorInterface
and registering it as a service with the tag oro_pdf_generator.pdf_document.generator
.
PDF document template provider
is implemented by \Oro\Bundle\PdfGeneratorBundle\PdfDocument\PdfTemplate\PdfDocumentTemplateProviderComposite
that is a composite of inner providers that implement the \Oro\Bundle\PdfGeneratorBundle\PdfDocument\PdfTemplate\PdfDocumentTemplateProviderInterface
and are collected by the service container tag oro_pdf_generator.pdf_document.pdf_template.provider
.
Out-of-the-box, the bundle provides the following template providers:
\Oro\Bundle\PdfGeneratorBundle\PdfDocument\PdfTemplate\GenericPdfDocumentTemplateProvider
- returns static template paths pre-configured via constructor for the specifiedPDF document type
.\Oro\Bundle\PdfGeneratorBundle\PdfDocument\PdfTemplate\LayoutThemeAwarePdfDocumentTemplateProvider
- returns the template paths based on the current layout theme for the specifiedPDF document type
. It is suitable for cases when you want to have different templates for different layout themes.
PDF File Flow
The PDF file flow
starts with the PDF builder factory
\Oro\Bundle\PdfGeneratorBundle\PdfBuilder\PdfBuilderFactory
responsible for creating the appropriate PDF builder
for the specified PDF options preset
.
PDF builder
is responsible for collecting the PDF options
to generate a PDF file
, then it delegates the generation to the configured PDF engine
.
Out-of-the-box, the bundle provides the generic PDF builder \Oro\Bundle\PdfGeneratorBundle\PdfBuilder\GenericPdfBuilder
that can be used to create any PDF file
.
PDF options preset
is a string that denotes a set of options to be stored in the PDF options
DTO. The available presets that come standard are defined in the \Oro\Bundle\PdfGeneratorBundle\PdfOptionsPreset\PdfOptionsPreset
class. Currently, the only available preset is default.
PDF options
is a DTO that contains the settings for generating a PDF file
to be passed to the PDF engine
. It is implemented by \Oro\Bundle\PdfGeneratorBundle\PdfOptions\PdfOptions
class out-of-the-box. The PDF options
may include parameters, such as page size, margins, engine-specific settings like API URL, binary path, etc.
PDF options
DTO is configured by the PDF options configurator
that actually makes use of the \Symfony\Component\OptionsResolver\OptionsResolver
. The options are resolved in the PDF builder
before being passed to the configured PDF engine
.
Hint
PDF options
DTO becomes immutable after getting resolved. The last chance to alter it is to create a listener for the \Oro\Bundle\PdfGeneratorBundle\Event\BeforePdfOptionsResolvedEvent
event.
The default preset declares the options common for all engines. It is configured by the \Oro\Bundle\PdfGeneratorBundle\PdfOptionsPreset\DefaultPdfOptionsPresetConfigurator
that configures the following options:
content - the main content template, required.
header - the header template, optional.
footer - the footer template, optional.
assets - the list of assets to be included during generation PDF generation, optional. Should contain all assets that appear in the the main template. Filled automatically from the
PDF template assets collector
-\Oro\Bundle\PdfGeneratorBundle\PdfTemplateRenderer\AssetsCollector\PdfTemplateAssetsCollector
.page_width - the width of the page, optional. Defaults to the corresponding setting of the
PDF engine
. For the Gotenberg engine, it is8.5in
, the width of a Letter format.page_height - the height of the page, optional. Defaults to the corresponding setting of the
PDF engine
. For the Gotenberg engine, it is11in
, the height of a Letter format.margin_top - the top margin of the page, optional. Defaults to the corresponding setting of the
PDF engine
. For the Gotenberg engine, it is0.39in
.margin_right - the right margin of the page, optional. Defaults to the corresponding setting of the
PDF engine
. For the Gotenberg engine, it is0.39in
.margin_bottom - the bottom margin of the page, optional. Defaults to the corresponding setting of the
PDF engine
. For the Gotenberg engine, it is0.39in
.margin_left - the left margin of the page, optional. Defaults to the corresponding setting of the
PDF engine
. For the Gotenberg engine, it is0.39in
.landscape - whether the page should be in landscape orientation, optional. Defaults to
false
.scale - the scale of the page, optional. Defaults to
1.0
.custom_options - additional custom options that can be used by the
PDF engine
, optional. For the Gotenberg engine, it is an array of options that are passed directly to theChromiumPdf
builder.
Hint
You can create your own PDF options preset
by creating a new class that implements the \Oro\Bundle\PdfGeneratorBundle\PdfOptionsPreset\PdfOptionsPresetConfiguratorInterface
and registering it as a service with the tag oro_pdf_generator.pdf_options_preset_configurator
.
PDF engine
is responsible for generating the PDF file
by interacting with the configured engine. The bundle provides the Gotenberg engine out-of-the-box, which is implemented by the \Oro\Bundle\PdfGeneratorBundle\PdfEngine\GotenbergPdfEngine
class. It uses the Gotenberg API to generate the PDF file
based on the provided PDF options
.
GotenbergPdfEngine
makes use of PDF template renderer
to render the PDF templates
before sending them to Gotenberg API
. You can find more details about how PDF templates
are rendered in the PDF Template Renderer section of the documentation.
Hint
You can implement your own PDF engine
by creating a new class that implements the \Oro\Bundle\PdfGeneratorBundle\PdfEngine\PdfEngineInterface
and registering it as a service with the tag oro_pdf_generator.pdf_engine
.
PDF file
is a model that represents the actual PDF file generated by the engine. Out-of-the-box, it is represented by the \Oro\Bundle\PdfGeneratorBundle\PdfFile\PdfFile
class that can work both with the file path and the file content (stream).
To store the generated PDF in an entity, a \Oro\Bundle\AttachmentBundle\Entity\File
entity can be created from a PDF file
using the \Oro\Bundle\PdfGeneratorBundle\PdfFile\Factory\FileEntityFromPdfFileFactory
factory.