Salta ai contenuti

Contratti / Estrazione

Il dominio di estrazione raccoglie i contratti per leggere e validare i PDF e per trasformarne il contenuto in dati strutturati. Comprende l’inspector, i validatori di conformità, il gestore PDF/A, i contratti per gli oggetti importati, i contratti per l’embedding e l’indice vettoriale e il sotto-namespace del validatore di fatture elettroniche.

Terminal window
composer require nextpdf/core:^3

InspectorInterface legge un PDF non elaborato. Restituisce un InspectResult strutturato. Il risultato elenca gli oggetti presenti nel file. Usarlo per qualsiasi strumento che debba leggere un PDF non scritto dal motore.

ExternalComplianceValidatorInterface funge da ponte verso un verificatore esterno come veraPDF. Il verificatore controlla PDF/A e PDF/UA. L’implementazione null restituisce un risultato «non disponibile» quando non è configurato alcun verificatore. Un sito senza veraPDF continua comunque a funzionare. ProfileValidatorInterface verifica il runtime rispetto a un profilo di distribuzione. Esamina le estensioni richieste e consigliate. Restituisce un verdetto tipizzato.

PdfAManagerInterface mantiene la conformità PDF/A durante la scrittura di un file. Blocca JavaScript, le azioni JavaScript dei moduli e la cifratura integrata. PDF/A vieta tutti e tre. Verifica inoltre che ogni font sia incorporato. Imposta metadati conformi alla specifica. Scrive gli oggetti necessari prima del catalogo. La classe reale è fornita nell’edizione Pro. Core la individua con class_exists() e la converte nel tipo del contratto. Il motore open source non ha quindi alcuna dipendenza a pagamento.

Due contratti coprono gli oggetti importati: ImportedFormObjectInterface e EmbeddedPdfObjectInterface. Forniscono accesso tipizzato agli oggetti letti da un PDF esistente. Il motore può quindi reincorporarli. Un percorso senza perdita conserva i byte non elaborati del dizionario. Un percorso di fallback fornisce un array di dizionario analizzato per gli oggetti estratti dai flussi di oggetti. Ogni oggetto reincorporato è un oggetto indiretto PDF. Lo identificano un numero di oggetto e un numero di generazione — ISO 32000-2 §7.3.10.

I contratti di embedding sono pensati per la ricerca. EmbeddingServiceInterface trasforma il testo in un vettore denso. Restituisce la dimensione e il nome del modello. Il chiamante si adatta a runtime. L’edizione Pro esegue un modello su CPU. L’edizione Enterprise esegue un modello su GPU. VectorIndexInterface costruisce un indice nearest-neighbour e vi effettua le ricerche. È l’indice in-process leggero per l’uso in Core. La ricerca su scala maggiore risiede in un contratto disponibile solo nell’edizione Enterprise.

Il gruppo EInvoice contiene il validatore di fatture elettroniche trasversale ai livelli. ValidatorInterface esegue i controlli preliminari su un payload CII o UBL. SchematronRunnerInterface esegue la fase delle regole di business. ValidationResult raccoglie i rilievi e le violazioni delle regole. Il validatore deve rifiutare un input non valido con un risultato, non con un’eccezione. Deve inoltre proteggersi dai payload con DOCTYPE e di dimensioni eccessive.

TipoGenereMembri principaliStabilitàDa
InspectorInterfaceinterfacciainspect(string, InspectConfig): InspectResultsperimentale2.2.0
ExternalComplianceValidatorInterfaceinterfacciavalidate(string, ComplianceFlavour), isAvailable()sperimentale2.4.0
ProfileValidatorInterfaceinterfacciavalidate(DeploymentProfile): DeploymentProfileResultsperimentale2.4.0
PdfAManagerInterfaceinterfacciavalidateNoJavaScript(), validateFont(), validateNoEncryption(), applyOutputProfile(), writeRequiredObjects()stabile1.10.0
ImportedFormObjectInterfaceinterfacciagetWidth(), getHeight(), getEmbeddedObjects(), getResourcesDict(), getMediaBox(), getContentStream()stabile1.8.0
EmbeddedPdfObjectInterfaceinterfacciagetRawDictionaryBytes(), getRawStreamData(), getDictionary()stabile1.8.0
EmbeddingServiceInterfaceinterfacciaembed(), batchEmbed(), getDimension(), getModelName()sperimentale2.1.0
VectorIndexInterfaceinterfacciabuild(), search(), delete(), count()sperimentale2.1.0
EInvoice\ValidatorInterfaceinterfacciavalidate(string, ValidatorContext): ValidationResultsperimentale5.1.0
EInvoice\ValidationResultclasse final readonly$isValid, getErrors(), getWarnings(), fail()sperimentale5.1.0

Il namespace EInvoice espone inoltre SchematronRunnerInterface, ProfileInterface, ValidationFinding, RuleViolation e le enumerazioni ProfileType, RuleSeverity e ValidationFindingLevel.

examples/contracts/extraction-quickstart.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\InspectorInterface;
use NextPDF\Inspect\InspectConfig;
/**
* Inspect a PDF and report its object count.
*
* @param InspectorInterface $inspector A configured inspector.
* @param string $pdfData Raw PDF bytes.
*/
function describe(InspectorInterface $inspector, string $pdfData): \NextPDF\Inspect\InspectResult
{
return $inspector->inspect($pdfData, new InspectConfig());
}

La funzione dipende dal contratto. Qualsiasi implementazione di inspector può soddisfarla.

examples/contracts/extraction-production.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use NextPDF\Contracts\EInvoice\ValidatorInterface;
use NextPDF\Contracts\EInvoice\ValidatorContext;
use NextPDF\Contracts\ExternalComplianceValidatorInterface;
use NextPDF\ValueObjects\ComplianceFlavour;
use Psr\Log\LoggerInterface;
final readonly class InvoiceConformanceService
{
public function __construct(
private ValidatorInterface $invoiceValidator,
private ExternalComplianceValidatorInterface $pdfaValidator,
private LoggerInterface $logger,
) {}
/**
* Validate the invoice XML, then the PDF/A-3 carrier.
*
* @param string $xml The CII or UBL invoice payload.
* @param string $pdfPath Absolute path to the PDF/A-3 carrier.
*/
public function validate(string $xml, string $pdfPath, ValidatorContext $ctx): bool
{
$result = $this->invoiceValidator->validate($xml, $ctx);
if (!$result->isValid) {
$this->logger->warning('Invoice XML invalid', [
'errors' => \count($result->getErrors()),
]);
return false;
}
if (!$this->pdfaValidator->isAvailable()) {
$this->logger->info('PDF/A validator unavailable; skipping carrier check.');
return true;
}
$carrier = $this->pdfaValidator->validate($pdfPath, ComplianceFlavour::PdfA3b);
return $carrier->isConformant();
}
}

Il servizio gestisce esplicitamente il caso del validatore non disponibile, invece di presumere che un validatore sia presente.

  • EInvoice\ValidatorInterface::validate() restituisce un ValidationResult con esito negativo per un input malformato. Non solleva eccezioni in caso di violazioni della correttezza formale. Controllare $isValid, senza racchiudere la chiamata in un try/catch per quel caso.
  • ExternalComplianceValidatorInterface::isAvailable() va controllato prima di fare affidamento su un verdetto. L’implementazione null restituisce «non disponibile». Trattarlo come «non conforme» produce falsi negativi.
  • EmbeddedPdfObjectInterface::getRawDictionaryBytes() restituisce null per gli oggetti estratti da un flusso di oggetti. Ricorrere a getDictionary(). Non presumere che i byte non elaborati esistano.
  • EmbeddingServiceInterface::getDimension() varia in base al livello. Il codice che alloca un vettore a larghezza fissa deve leggere la dimensione a runtime, senza codificarla in modo statico.
  • VectorIndexInterface::build() richiede che gli elenchi di vettori e id abbiano la stessa lunghezza e dimensioni coerenti. Una mancata corrispondenza solleva InvalidArgumentException. Validare prima di costruire.

Il costo dell’ispezione e della validazione cresce con la dimensione del documento e il numero di oggetti. Il performance_budget di 1500 ms di tempo reale e 64 MB di picco copre un singolo documento di dimensioni moderate. Una chiamata esterna a veraPDF aggiunge il tempo di elaborazione del validatore. Quel tempo di elaborazione è esterno al budget del motore e dovrebbe essere eseguito fuori dal percorso della richiesta. Il costo dell’embedding cresce con la lunghezza del testo ed è molto più conveniente in batch che dentro un ciclo, in particolare su un modello GPU. Preferire batchEmbed(). La ricerca vettoriale è sub-lineare rispetto alla dimensione dell’indice per l’indice in-process. Il profilo di riproducibilità è structural. Un report di validazione registra una marca temporale e un’impronta dell’ambiente. Due esecuzioni differiscono in quei campi, mentre il verdetto di conformità rimane identico.

L’estrazione legge documenti non creati dal motore, quindi nessun input va considerato attendibile. L’inspector e il validatore di fatture elettroniche analizzano entrambi byte forniti dall’esterno. Il validatore di fatture elettroniche deve filtrare i payload con DOCTYPE, di dimensioni eccessive e con caratteri di controllo vietati prima dell’analisi, per prevenire gli attacchi XML external-entity e billion-laughs. Il reincorporamento degli oggetti importati copia i byte da un PDF esterno. Un oggetto di origine malevolo può contenere contenuto ostile, quindi il reincorporamento conserva i byte senza eseguirli. L’applicazione di PDF/A rimuove JavaScript e azioni. Il gestore PDF/A rifiuta JavaScript e cifratura perché entrambi sono vietati nel profilo ed entrambi sono vettori di abuso in un documento di archiviazione a lunga conservazione. Trattare il contenuto ispezionato, gli oggetti importati e l’XML delle fatture come input ostile in ogni fase.

DichiarazioneStandardClausolaEvidenza
PDF/A-4 vieta JavaScript e le azioni JavaScript dei moduli; il gestore PDF/A rifiuta entrambi.ISO 19005-4§6.7.1citato per clausola (non nel corpus)
Ogni oggetto reincorporato è un oggetto indiretto PDF identificato dal numero di oggetto e dalla generazione.ISO 32000-2§7.3.10

ISO 19005-4 è citato per clausola. Non è presente nel corpus di citazioni verificabili, quindi non viene registrato alcun reference_id. La dichiarazione sull’oggetto indiretto di ISO 32000-2 è ancorata al glossario. Entrambe le dichiarazioni sono parafrasate. Il motore non riproduce alcun testo normativo.

Core definisce e congela i contratti di estrazione. Il codice di produzione alla base di PdfAManagerInterface, EmbeddingServiceInterface e VectorIndexInterface è fornito nelle edizioni Pro ed Enterprise, inclusi i modelli di embedding su CPU e GPU e il percorso completo di applicazione di PDF/A. Core li risolve a runtime con class_exists(). Il motore open source non introduce quindi alcuna dipendenza commerciale e l’API non cambia con l’aggiornamento.