Salta ai contenuti

Boot e discovery di NextPDF Artisan

Artisan è una libreria PSR-4 semplice: non ha service provider, bundle né manifest di auto-discovery del framework. Il suo «boot» avviene nel momento in cui le sue classi diventano caricabili tramite autoload; la discovery è la mappa PSR-4 di Composer, niente di più.

Il file composer.json del pacchetto dichiara due radici PSR-4 — NextPDF\Artisan\src/Artisan/ e NextPDF\Parser\src/Parser/. Non sono presenti extra.laravel, classi bundle di Symfony né registrar di CodeIgniter. Al boot non viene eseguita alcuna scansione, registrazione o associazione di hook.

Il punto di integrazione si trova sul lato nextpdf/core. Document (tramite il concern HasTextOutput) espone writeHtmlChrome(), che esegue un controllo class_exists() a runtime per NextPDF\Parser\PdfReader e NextPDF\Artisan\PageImporter. Quando entrambe vengono risolte tramite l’autoloader, il percorso Chrome è disponibile. In caso contrario, core solleva un’eccezione di layout invece di generare un errore fatale. La «discovery» si riduce quindi a una domanda: le classi di Artisan sono presenti nell’autoloader? A rispondere è Composer — non è coinvolto alcun meccanismo del framework.

Si tratta di una scelta progettuale deliberata. Il bridge è una capability a cui il motore core accede oltre il confine del pacchetto, non un servizio gestito dal framework. Questo consente di usare Artisan allo stesso modo in Laravel, Symfony, CodeIgniter, uno script CLI o un queue worker, senza richiederne nessuno.

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

Non esiste alcun kernel di bootstrap, alcuna registrazione di comandi né alcuna fase di provider differiti. La prima chiamata a writeHtmlChrome() è l’intero punto di ingresso del ciclo di vita.

Artisan non dispone di un container DI e non registra alcun binding. I componenti sono oggetti semplici, iniettati tramite costruttore: creare un ChromeRendererConfig, passarlo a ChromeHtmlRenderer e, facoltativamente, iniettare un logger PSR-3 e un HtmlSecurityPolicyInterface personalizzato. In un container host, registrare manualmente ChromeHtmlRenderer come singleton — vedere l’esempio in /integrations/artisan/production-usage/.

Alcune capability di NextPDF (i contratti e-invoice Premium) vengono normalmente risolte tramite un container del framework. Artisan funziona anche in ambienti privi di container — strumenti CLI, script standalone, runner personalizzati — e per questo include EInvoiceServiceFactory:

MetodoValore restituitoQuando è null
makeEmbedder()EmbedderInterface (Pro)Tier Pro non installato
makeValidator()ValidatorInterface (Enterprise)Tier Enterprise non installato
makeDefaultProfile()ProfileInterface (EN16931, Pro)Tier Pro non installato
makeSchematronRunner()SchematronRunnerInterface (Enterprise)Tier Enterprise non installato

Ogni chiamata restituisce un’istanza nuova (semantica use-once — le chiamate di embed e validate hanno un contesto di parsing XML mutabile e non devono condividere lo stato). La factory è una comodità per il raro caso senza container, non un service locator. Il pattern preferito resta comporre gli oggetti in fase di costruzione e passarli come argomenti del costruttore. Quando il tier non è presente, la restituzione di null rispecchia il comportamento dei pacchetti wrapper del framework, così lo stesso codice chiamante funziona con o senza Premium. Sorgente: src/Artisan/EInvoiceServiceFactory.php; testato a livello di integrazione in tests/Integration/Artisan/EInvoiceServiceFactoryIntegrationTest.php.

Non esiste alcuna cascata di file di configurazione. La configurazione è esattamente ciò che si passa a ChromeRendererConfig:

  1. Argomenti espliciti del costruttore, oppure
  2. ChromeRendererConfig::fromArray() a partire da un array fornito dall’host (chiavi in snake-case; le chiavi non impostate ricadono sui valori predefiniti del costruttore; chrome_binary applicato solo quando è una stringa non vuota).

Una volta risolta, la configurazione è immutabile per l’intera durata di vita del renderer. Per ogni chiave, vedere /integrations/artisan/configuration/.

  • “Il bridge è individuabile?” — se class_exists(\NextPDF\Artisan\PageImporter::class) è true, l’autoloader di Composer rende disponibile la classe; core utilizzerà il percorso Chrome.
  • “È stato eseguito il boot?” — non esiste alcun boot che possa fallire; una dipendenza mancante emerge alla prima chiamata a writeHtmlChrome() come eccezione tipizzata, mappata in /integrations/artisan/troubleshooting/.
  • Verifica Premium senza containerEInvoiceServiceFactory::makeEmbedder() === null indica che il tier Pro non è installato; il percorso di rendering open-source non ne è influenzato.
  • /integrations/artisan/integration/
  • /integrations/artisan/overview/
  • /integrations/artisan/configuration/
  • /integrations/artisan/production-usage/
  • /integrations/artisan/troubleshooting/