Pular para o conteúdo

Inicialização e descoberta no NextPDF Artisan

O Artisan é uma biblioteca simples que segue a PHP Standard Recommendation 4 (PSR-4). Ele não tem service provider, bundle nem manifesto de descoberta automática de framework. A inicialização acontece assim que as classes passam a ser carregáveis pelo autoload. A descoberta é o mapa PSR-4 do Composer, e nada além disso.

O composer.json do pacote declara duas raízes PSR-4: NextPDF\Artisan\src/Artisan/ e NextPDF\Parser\src/Parser/. Ele não inclui extra.laravel, classe de bundle do Symfony nem registrar do CodeIgniter. Nada executa varredura, registro ou hook durante a inicialização.

O ponto de integração fica em nextpdf/core. Document (por meio do concern HasTextOutput) expõe writeHtmlChrome(), que verifica class_exists() em tempo de execução para NextPDF\Parser\PdfReader e NextPDF\Artisan\PageImporter. Quando o autoloader consegue resolver as duas classes, o caminho do Chrome fica disponível. Quando não consegue, o core lança uma exceção de layout em vez de falhar com um erro fatal. Portanto, a descoberta faz uma única pergunta: as classes do Artisan estão no autoloader? O Composer responde a isso; nenhum mecanismo de framework está envolvido.

Isso é proposital. A ponte é um recurso que o motor do core alcança por meio de uma fronteira de pacote, não um serviço gerenciado pelo framework. Você pode usar o Artisan da mesma forma no Laravel, no Symfony, no CodeIgniter, em um script de interface de linha de comando (CLI) ou em um queue worker, porque nenhum desses hosts é obrigatório.

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

O Artisan não tem kernel de bootstrap, registro de comandos nem fase de deferred provider. A primeira chamada a writeHtmlChrome() é o único ponto de entrada em todo o ciclo de vida.

O Artisan não tem container de injeção de dependências (DI) e não registra bindings. Seus componentes são objetos simples injetados pelo construtor: crie um ChromeRendererConfig, passe-o para o ChromeHtmlRenderer e, opcionalmente, injete um logger PSR-3 e um HtmlSecurityPolicyInterface personalizado. Em um container do host, registre você mesmo o ChromeHtmlRenderer como um singleton; veja o exemplo em /integrations/artisan/production-usage/.

Alguns recursos do NextPDF, incluindo os contratos Premium de e-invoice, normalmente são resolvidos por meio de um container do framework. O Artisan também roda em ambientes sem container, como ferramentas de CLI, scripts independentes e runners personalizados; por isso, ele inclui o EInvoiceServiceFactory:

MétodoRetornaQuando é null
makeEmbedder()EmbedderInterface (Pro)Camada Pro não instalada
makeValidator()ValidatorInterface (Enterprise)Camada Enterprise não instalada
makeDefaultProfile()ProfileInterface (EN16931, Pro)Camada Pro não instalada
makeSchematronRunner()SchematronRunnerInterface (Enterprise)Camada Enterprise não instalada

Cada chamada retorna uma instância nova. Esse comportamento de uso único é importante porque as chamadas de embed e validate controlam um contexto mutável de análise de Extensible Markup Language (XML) e não devem compartilhar estado. A factory é uma conveniência para o caso raro de ausência de container, não um service locator. O padrão preferido continua sendo compor os objetos na construção e passá-los como argumentos do construtor. Retornar null quando uma camada está ausente espelha os pacotes wrapper do framework, de modo que o mesmo código chamador rode com ou sem o Premium. Fonte: src/Artisan/EInvoiceServiceFactory.php; testado por integração em tests/Integration/Artisan/EInvoiceServiceFactoryIntegrationTest.php.

Não há cascata de arquivos de configuração. A configuração é exatamente aquilo que você passa para o ChromeRendererConfig:

  1. Argumentos do construtor que você passa explicitamente, ou
  2. ChromeRendererConfig::fromArray() a partir de um array fornecido pelo host (chaves em snake-case; chaves não definidas voltam aos padrões do construtor; chrome_binary só se aplica quando é uma string não vazia).

A configuração resolvida permanece imutável durante todo o ciclo de vida do renderer. Consulte /integrations/artisan/configuration/ para conhecer todas as chaves.

  • “A ponte pode ser descoberta?” — se class_exists(\NextPDF\Artisan\PageImporter::class) for true, o autoloader do Composer consegue encontrá-la e o core usará o caminho do Chrome.
  • “Ele foi inicializado?” — não há fase de inicialização que possa falhar; uma dependência ausente aparece na primeira chamada a writeHtmlChrome() como uma exceção tipada, mapeada em /integrations/artisan/troubleshooting/.
  • Verificação do Premium sem containerEInvoiceServiceFactory::makeEmbedder() === null significa que a camada Pro não está instalada; o caminho de renderização open-source não é afetado.
  • /integrations/artisan/integration/
  • /integrations/artisan/overview/
  • /integrations/artisan/configuration/
  • /integrations/artisan/production-usage/
  • /integrations/artisan/troubleshooting/