Ir al contenido

Arranque y descubrimiento de NextPDF Artisan

Artisan es una biblioteca PSR-4 simple: no incluye proveedor de servicios, bundle ni manifiesto de descubrimiento automático del framework. Su «arranque» ocurre en cuanto sus clases pueden cargarse automáticamente; el descubrimiento no es más que el mapa PSR-4 de Composer.

El paquete composer.json declara dos raíces PSR-4: NextPDF\Artisan\src/Artisan/ y NextPDF\Parser\src/Parser/. No hay extra.laravel, clase de bundle de Symfony ni registrador de CodeIgniter. Nada se escanea, se registra ni se engancha durante el arranque.

El punto de integración está en nextpdf/core. Document (mediante el concern HasTextOutput) expone writeHtmlChrome(), que comprueba en tiempo de ejecución con class_exists() la presencia de NextPDF\Parser\PdfReader y NextPDF\Artisan\PageImporter. Cuando ambas se resuelven a través del autoloader, la ruta de Chrome queda disponible. Cuando no se resuelven, core lanza una excepción de maquetación en lugar de provocar un error fatal. Por tanto, el «descubrimiento» se reduce a esto: ¿están las clases de Artisan en el autoloader? Composer responde a esa pregunta; no interviene ningún mecanismo del framework.

Esto responde a un diseño deliberado. El puente es una capacidad a la que el motor de core accede a través de un límite de paquete, no un servicio gestionado por el framework. Así, Artisan puede usarse de la misma forma en Laravel, Symfony, CodeIgniter, un script de CLI o un worker de cola, porque ninguno de ellos es obligatorio.

no

yes

Composer autoload (PSR-4)

Application constructs Document

Document::setChromeRendererConfig(config)

Document::writeHtmlChrome(html)

class_exists PdfReader

and PageImporter?

core raises layout exception

resolve ChromeHtmlRenderer

render → parse → import Form XObject

Diagram

No hay kernel de arranque, registro de comandos ni fase de proveedor diferido. La primera llamada a writeHtmlChrome() constituye todo el punto de entrada del ciclo de vida.

Artisan no tiene contenedor de inyección de dependencias ni registra ningún enlace. Los componentes son objetos simples inyectados por constructor: se construye un ChromeRendererConfig, se pasa a ChromeHtmlRenderer y, opcionalmente, se inyecta un logger PSR-3 y un HtmlSecurityPolicyInterface personalizado. En un contenedor anfitrión, ChromeHtmlRenderer debe registrarse como singleton de forma explícita; consultar el ejemplo en /integrations/artisan/production-usage/.

Algunas capacidades de NextPDF (los contratos de factura electrónica de Premium) suelen resolverse a través de un contenedor del framework. Artisan también se ejecuta en entornos sin contenedor (herramientas de CLI, scripts independientes, runners personalizados), por lo que incluye EInvoiceServiceFactory:

MétodoDevuelveCuándo devuelve null
makeEmbedder()EmbedderInterface (Pro)El nivel Pro no está instalado
makeValidator()ValidatorInterface (Enterprise)El nivel Enterprise no está instalado
makeDefaultProfile()ProfileInterface (EN16931, Pro)El nivel Pro no está instalado
makeSchematronRunner()SchematronRunnerInterface (Enterprise)El nivel Enterprise no está instalado

Cada llamada devuelve una instancia nueva (semántica de un solo uso: las llamadas de incrustación y validación mantienen un contexto mutable de análisis de XML y no deben compartir estado). La factory es una comodidad para el caso poco frecuente sin contenedor, no un localizador de servicios. El patrón preferido sigue siendo componer los objetos al construirlos y pasarlos como argumentos del constructor. El comportamiento de devolver null cuando el servicio está ausente replica el de los paquetes envoltorio del framework, de modo que el mismo código de llamada funcione con o sin Premium. Fuente: src/Artisan/EInvoiceServiceFactory.php; probado con tests de integración en tests/Integration/Artisan/EInvoiceServiceFactoryIntegrationTest.php.

No hay cascada de archivos de configuración. La configuración es la que se pase a ChromeRendererConfig:

  1. Argumentos explícitos del constructor, o
  2. ChromeRendererConfig::fromArray() con un array proporcionado por el anfitrión (claves en snake-case; las claves sin definir usan los valores predeterminados del constructor; chrome_binary se aplica solo cuando es una cadena no vacía).

La configuración resuelta permanece inmutable durante toda la vida del renderer. Consultar /integrations/artisan/configuration/ para conocer todas las claves.

  • «¿Es detectable el puente?» — si class_exists(\NextPDF\Artisan\PageImporter::class) es true, el autoloader de Composer puede resolverla; core usará la ruta de Chrome.
  • «¿Arrancó?» — no hay un arranque que pueda fallar; una dependencia ausente se manifiesta en la primera llamada a writeHtmlChrome() como una excepción tipada, mapeada en /integrations/artisan/troubleshooting/.
  • Comprobación de Premium sin contenedorEInvoiceServiceFactory::makeEmbedder() === null significa que el nivel Pro no está instalado; la ruta de renderizado de código abierto no queda afectada.
  • /integrations/artisan/integration/
  • /integrations/artisan/overview/
  • /integrations/artisan/configuration/
  • /integrations/artisan/production-usage/
  • /integrations/artisan/troubleshooting/