Salta ai contenuti

Cli: gestori dei comandi e adattatori per validatori esterni

Il modulo Cli è la superficie a riga di comando alla base della diagnostica e degli strumenti di conformità del motore. Raccoglie gestori dei comandi — benchmark, diff, init, verify, capabilities — e adattatori che incapsulano validatori PDF esterni (veraPDF, il modello Arlington PDF) dietro un’unica interfaccia. Un singolo comando verify può pilotarne uno qualsiasi.

Terminal window
composer require nextpdf/core:^3

Ogni comando è rappresentato da una classe gestore con un execute() che restituisce il codice di uscita del processo. BenchmarkHandler esegue gli scenari di benchmark. DiffHandler confronta i documenti. InitHandler predispone lo scheletro di un progetto. VerifyHandler esegue la verifica di conformità. CapabilitiesHandler riporta ciò che il runtime supporta. CliOutput è il writer leggero di stdout/stderr condiviso dai gestori, così l’output resta verificabile anziché accoppiato alle variabili globali. BinaryFinder risolve il percorso di uno strumento esterno sull’host (@since 2.5.0).

La superficie di validazione è il punto architetturale centrale. AlternateValidatorAdapter è l’interfaccia implementata da un validatore esterno. validate() prende un percorso PDF e un ComplianceFlavour e restituisce un ComplianceValidationResult. isAvailable() indica se lo strumento sottostante è installato. toolIdentifier() lo identifica. VeraPdfCliAdapter, ArlingtonValidatorAdapter e AsyncValidatorAdapter implementano questa interfaccia. Questo significa che il motore non re-implementa i validatori di terze parti: esegue gli strumenti di riferimento e ne normalizza il verdetto. Un validatore non installato riporta isAvailable() === false anziché far fallire l’esecuzione, così la verifica degrada in modo esplicito. Gli adattatori sono @since 3.0.0; i gestori del core sono @since 2.3.0@since 2.5.0.

ClasseMembri chiaveRuolo
BenchmarkHandlerexecute(string $format = 'pretty', ?string $scenario = null): intEsegue gli scenari di benchmark (@since 2.4.0)
VerifyHandlerexecute(): intPilota la verifica di conformità
DiffHandler / InitHandlerexecute(): intDiff tra documenti / scheletro di progetto
CapabilitiesHandlerexecute(string $format = 'pretty'): intRiporta le capacità del runtime (@since 2.3.0)
AlternateValidatorAdapter (interfaccia)validate(), isAvailable(), toolIdentifier()Contratto del validatore esterno (@since 3.0.0)
VeraPdfCliAdapterimplementa l’adattatoreIncapsula la CLI di veraPDF (@since 3.0.0)
ArlingtonValidatorAdapterimplementa l’adattatoreIncapsula il modello Arlington PDF (@since 3.0.0)
AsyncValidatorAdapterimplementa l’adattatoreWrapper per validatore con capacità asincrone (@since 3.0.0)
CliOutputwrite(), writeln(), error()Writer verificabile per stdout/stderr (@since 2.3.0)
BinaryFinderrisoluzione del percorso per strumenti esterniLocalizza gli strumenti dell’host (@since 2.5.0)

Eseguire composer docs:generate-api-php -- --module=Cli per la tabella PHPDoc completa.

Sorgente: examples/33-validate-conformance.php. Selezionare un adattatore di validatore e verificarne la disponibilità prima dell’uso:

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Cli\VeraPdfCliAdapter;
use NextPDF\Compliance\ComplianceFlavour;
$validator = new VeraPdfCliAdapter(/* binary path / process factory */);
if (!$validator->isAvailable()) {
fwrite(STDERR, "veraPDF is not installed; conformance verification skipped.\n");
exit(2);
}
$result = $validator->validate('/srv/out/report.pdf', ComplianceFlavour::PdfA4);
echo $result->isCompliant() ? "PASS\n" : "FAIL\n";

Eseguire la verifica con qualunque validatore sia presente, trattando uno strumento assente come un controllo omesso anziché come un fallimento.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Cli\AlternateValidatorAdapter;
use NextPDF\Compliance\ComplianceFlavour;
use Psr\Log\LoggerInterface;
final readonly class ConformanceGate
{
/** @param list<AlternateValidatorAdapter> $validators */
public function __construct(
private array $validators,
private LoggerInterface $logger,
) {}
public function verify(string $pdfPath, ComplianceFlavour $flavour): bool
{
$ran = false;
foreach ($this->validators as $validator) {
if (!$validator->isAvailable()) {
$this->logger->info('Validator absent; skipped.', ['tool' => $validator->toolIdentifier()]);
continue;
}
$ran = true;
if (!$validator->validate($pdfPath, $flavour)->isCompliant()) {
$this->logger->error('Conformance failed.', ['tool' => $validator->toolIdentifier()]);
return false;
}
}
// No validator available is not a pass — surface it.
return $ran;
}
}
  • Un validatore non disponibile restituisce isAvailable() === false. Non solleva eccezioni. “Nessun validatore disponibile” non è un esito positivo — trattarlo separatamente, come fa l’esempio di produzione.
  • Gli adattatori eseguono binari esterni. Il loro verdetto è il verdetto dello strumento esterno, normalizzato — non una re-implementazione indipendente. Mantenere aggiornati gli strumenti.
  • Il execute() del gestore restituisce il codice di uscita del processo. Un valore diverso da zero è un fallimento. Propagarlo dal proprio wrapper anziché scartarlo.
  • BinaryFinder risolve il percorso di uno strumento sull’host. Un host diverso può risolvere una versione diversa dello strumento. Fissare l’ambiente per una verifica riproducibile.
  • Il profilo di riproducibilità è structural: un report di verifica include marche temporali e versioni degli strumenti, quindi due esecuzioni possono differire in questi campi.

L’overhead del gestore è trascurabile. Il costo è dominato dal processo del validatore esterno, che può essere lento su un documento di grandi dimensioni. AsyncValidatorAdapter serve a sovrapporre quella latenza. Il performance_budget di 1500 ms wall / 64 MB di picco è il riferimento del motore, non un limite per un validatore esterno. L’output del benchmark è deterministico nella struttura, ma per natura riporta dati temporali.

Gli adattatori avviano processi esterni su un percorso PDF. Trattare il PDF come input non attendibile. Eseguire la verifica in un ambiente vincolato. I validatori esterni analizzano dati ostili. Validare e canonicalizzare qualsiasi percorso di file prima di passarlo a un gestore, per evitare path-traversal verso un file non previsto. Non passare input utente non sanificato come argomenti di comando. Gli adattatori costruiscono argomenti di processo, non stringhe di shell. Il file di input stesso resta comunque controllato dall’attaccante. Vedere il modello di minaccia del motore in /modules/core/security/.

Questo modulo non formula affermazioni normative proprie sulla specifica PDF. Orchestra la verifica di conformità delegando a validatori di riferimento (veraPDF per PDF/A e PDF/UA, il modello Arlington PDF per le regole strutturali di ISO 32000-2). Il verdetto di conformità autorevole è quello dello strumento esterno. Questo modulo lo normalizza e lo riporta. La conformità end-to-end e le baseline golden sono descritte in /modules/core/conformance/.