Ir al contenido

Genera una salida PDF/A-4 y valídala con el oráculo veraPDF

Esta recipe genera una salida PDF/A-4 mediante el PdfAManager de Premium, ejecuta veraPDF y trata su veredicto como gate de compilación. La biblioteca produce los artefactos; el validador determina la conformidad. La recipe sigue examples/32-pdfa4-icc.php.

  • Núcleo instalado: composer require nextpdf/core:^3.
  • Premium instalado: composer require nextpdf/pro. PDF/A-4 es una característica del nivel Premium (ADR-011). Sin Premium, enablePdfA() lanza InvalidConfigException e indica una ruta de actualización.
  • veraPDF en el PATH para el gate.
  1. Consulta el registro de capacidades de security.pdfa para que una instalación solo del núcleo reciba un mensaje claro en lugar de un seguimiento de pila.
  2. Crea el documento y llama a enablePdfA() antes de añadir contenido.
  3. Define los metadatos y escribe el contenido. No llames a setEncryption(); PDF/A prohíbe la clave Encrypt.
  4. Guarda el documento. Durante save(), el PdfAManager emite el OutputIntent, el perfil ICC incrustado y los esquemas de extensión XMP.
  5. Ejecuta verapdf --flavour 4 sobre la salida. Haz que la compilación falle ante un código de salida distinto de cero. El veredicto del validador es el gate.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
use NextPDF\Exception\InvalidConfigException;
use NextPDF\Support\CapabilityRegistry;
$out = __DIR__ . '/archival.pdf';
// Step 1 — probe before activating a Premium-gated feature.
$registry = CapabilityRegistry::getInstance();
if (!$registry->get('security.pdfa')->isAvailable()) {
fwrite(STDERR, "PDF/A-4 requires nextpdf/pro. Run: composer require nextpdf/pro\n");
exit(1);
}
try {
$doc = Document::createStandalone();
// Step 2 — enable PDF/A-4 before content. Defaults to PdfA4.
$doc->enablePdfA();
// Step 3 — metadata and content. No setEncryption() on a PDF/A document.
$doc->setTitle('Archival Record 2026-0042');
$doc->setLanguage('en');
$doc->addPage();
$doc->setFont('helvetica', '', 12);
$doc->cell(0, 10, 'This document targets PDF/A-4.', newLine: true);
// Step 4 — save. PdfAManager emits OutputIntent + ICC + XMP here.
$doc->save($out);
} catch (InvalidConfigException $e) {
fwrite(STDERR, "PDF/A-4 activation failed: {$e->getMessage()}\n");
exit(1);
}
// Step 5 — the gate. veraPDF, not the library, asserts conformance.
$exitCode = 0;
$output = [];
exec('verapdf --flavour 4 ' . escapeshellarg($out), $output, $exitCode);
if ($exitCode !== 0) {
fwrite(STDERR, "veraPDF FAILED — output is not PDF/A-4 conforming\n");
fwrite(STDERR, implode("\n", $output) . "\n");
exit(1);
}
echo "veraPDF PASS — archival.pdf is reported PDF/A-4 conforming by veraPDF\n";

Cuando veraPDF devuelve PASS:

veraPDF PASS — archival.pdf is reported PDF/A-4 conforming by veraPDF

Cuando falta el paquete Premium, el script termina con un código distinto de cero, muestra un mensaje accionable y no escribe ningún archivo.

  • Gate de Premium. enablePdfA() en una instalación solo del núcleo lanza InvalidConfigException, menciona security.pdfa e indica el remedio composer require nextpdf/pro. Consulta primero el registro.
  • Conflicto de cifrado. Llamar a setEncryption(), useAesGcm() o setPublicKeyEncryption() en un documento PDF/A genera una excepción de incompatibilidad en cualquier orden de llamada. PDF/A prohíbe la clave del tráiler Encrypt.
  • Variante de conformidad. Pasa un PdfAVersion a enablePdfA() para 4e o 4f. El valor predeterminado es 4.
  • El gate es el validador, no el motor. Un save() correcto significa que NextPDF emitió los artefactos que PDF/A-4 requiere. Por sí solo, no demuestra la conformidad. veraPDF afirma la conformidad; esta recipe convierte su veredicto en el gate. No afirmes que un archivo es conforme con PDF/A-4 hasta que el validador lo apruebe.
DeclaraciónEspecificaciónCláusulareference_id
Un archivo PDF/A-4 puede especificar sus características de color con un OutputIntent de PDF/A que hace referencia a un perfil ICC incrustado (el color independiente del dispositivo puede especificarse directamente en su lugar; §6.2.4.1).ISO 19005-4§6.2.3
El cifrado está prohibido en PDF/A-4.ISO 19005-4§6.6.4
PDF/A-4 incluye la identificación pdfaid en los metadatos XMP.ISO 19005-4§6.7.5

El validador afirma la conformidad. La biblioteca produce una salida destinada a ser conforme; el oráculo decide.