* @copyright 2002-2026 Nicola Asuni - Tecnick.com LTD
* @license https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
* @link https://github.com/tecnickcom/tc-lib-pdf
*
* This file is part of tc-lib-pdf software library.
*/
// NOTE: local file reads (images, fonts, attachments) are restricted to an allowlist of
// trusted paths that covers this package tree, so run the examples in place. To read assets
// from other locations, list them in the 'allowedPaths' entry of the fileOptions constructor
// parameter (see E047_remote_resources_security.php).
// NOTE: run make fonts in the project root to generate the dependencies and example fonts.
// autoloader when using Composer
require __DIR__ . '/../vendor/autoload.php';
// define fonts directory
\define('K_PATH_FONTS', \realpath(__DIR__ . '/../vendor/tecnickcom/tc-lib-pdf-font/target/fonts'));
/**
* Demonstrate custom XMP namespace injection via setCustomXMP().
*
* PDF files carry an XMP metadata stream alongside the classic Info dictionary.
* The tc-lib-pdf library always emits standard namespaces (dc:, xmp:, pdf:,
* xmpMM:, pdfaid:, etc.). setCustomXMP() lets you inject arbitrary additional
* XMP fragments into specific positions within the XMP envelope.
*
* Valid keys and their injection points
* ──────────────────────────────────────
* 'x:xmpmeta'
* Inserted just before — top-level envelope extension.
*
* 'x:xmpmeta.rdf:RDF'
* Inserted just before — adds a new rdf:Description block.
*
* 'x:xmpmeta.rdf:RDF.rdf:Description'
* Inserted into the main rdf:Description — adds properties to the
* existing shared description block (dc, xmp, pdf properties).
*
* 'x:xmpmeta.rdf:RDF.rdf:Description.pdfaExtension:schemas'
* 'x:xmpmeta.rdf:RDF.rdf:Description.pdfaExtension:schemas.rdf:Bag'
* PDF/A extension schema declarations (only meaningful in PDF/A mode).
*
* IMPORTANT: the injected XML is NOT validated by the library. You are
* responsible for well-formed, namespace-correct XMP. Malformed XMP will
* not prevent PDF generation but may confuse metadata readers.
*
* Use cases illustrated here:
* 1. IPTC Core rights metadata (photojournalism / stock-photography DAM)
* 2. XMP-MM version history (document management / DAM systems)
* 3. Custom application metadata (arbitrary key-value pairs for integration)
*/
$pdf = new \Com\Tecnick\Pdf\Tcpdf(
unit: \Com\Tecnick\Pdf\Page\Unit::Millimeter,
isunicode: true,
subsetfont: false,
compress: true,
mode: \Com\Tecnick\Pdf\PdfConformance::None,
objEncrypt: null,
);
$pdf->setCreator('tc-lib-pdf');
$pdf->setAuthor('Nicola Asuni');
$pdf->setSubject('tc-lib-pdf example: 060');
$pdf->setTitle('Custom XMP Metadata Injection');
$pdf->setKeywords('TCPDF tc-lib-pdf example xmp metadata iptc dublin core dam archiving');
$pdf->setPDFFilename('E060_custom_xmp_metadata.pdf');
$pdf->setViewerPreferences(['DisplayDocTitle' => true]);
$pdf->enableDefaultPageContent();
// -----------------------------------------------------------------------
// 1. IPTC Core rights and creator metadata
// Injected as a new rdf:Description block inside rdf:RDF.
// -----------------------------------------------------------------------
$iptcXmp = <<<'XMP'
This PDF embeds three custom XMP metadata blocks beyond the standard dc:/xmp:
namespaces that tc-lib-pdf emits automatically. Inspect the XMP stream with
a PDF inspector or exiftool -XMP -b output.pdf to verify.
Namespace: Iptc4xmpCore (http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/)
Injection key: x:xmpmeta.rdf:RDF
Contains: CopyrightNotice, CreatorContactInfo (email, URL), UsageTerms.
Typical use: photojournalism DAM, stock-photography catalogues.
Namespace: xmpMM (http://ns.adobe.com/xap/1.0/mm/)
Injection key: x:xmpmeta.rdf:RDF
Contains: DocumentID, InstanceID, VersionID, History (sequence of events), DerivedFrom.
Typical use: document management systems, digital asset lineage tracking.
Namespace: tcpdf (https://github.com/tecnickcom/tc-lib-pdf/ns/xmp/1.0/)
Injection key: x:xmpmeta.rdf:RDF
Contains: exampleId, generatedBy, generationDate, featureTag.
Typical use: integration metadata for build pipelines, print-MIS systems, or
any workflow that needs to carry arbitrary key-value pairs inside the PDF
without modifying the Info dictionary.
• The injected XML is embedded as-is; the library does NOT validate XMP well-formedness.
• Multiple calls with the same key are concatenated in insertion order.
• Injection into x:xmpmeta.rdf:RDF.rdf:Description adds properties to the
shared Description block; prefer a standalone Description block (as done here) to
keep namespace declarations self-contained.
• All standard metadata (title, author, subject, keywords, dates, producer) is still
emitted automatically and is not affected by setCustomXMP().