controlaltjeff/p7m-fattura-decoder

PHP library per decodificare file PKCS#7 (.p7m) ed estrarre il contenuto XML.

Maintainers

Package info

github.com/controlaltjeff/p7m-fattura-decoder

pkg:composer/controlaltjeff/p7m-fattura-decoder

Transparency log

Statistics

Installs: 7

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.3 2026-06-18 15:31 UTC

This package is auto-updated.

Last update: 2026-07-18 22:38:30 UTC


README

CI Packagist Version Packagist Downloads PHP Version Require License PHPStan Level

PHP library per decodificare file .p7m (PKCS#7 signed) ed estrarre il contenuto XML. Progettata per la Fattura Elettronica italiana ma funziona con qualsiasi file P7M.

Indice

Installazione

composer require controlaltjeff/p7m-fattura-decoder

Requisiti

  • PHP 5.3+ (runtime) / PHP 8.1+ (strumenti di sviluppo)
  • ext-dom, ext-libxml (sempre richieste)
  • ext-openssl (consigliata — usata come strategia di decodifica primaria)
  • openssl CLI (opzionale — usato per la verifica DER/PEM)

Nota per ambienti PHP 5.3/7.x: gli strumenti di sviluppo (PHPUnit, PHPStan) richiedono PHP 8.1+. Installa con --no-dev per evitare conflitti:

composer require controlaltjeff/p7m-fattura-decoder --no-dev

Utilizzo rapido

use Controlaltjeff\P7MDecoder\P7MDecoder;

// Decodifica da file
$xml = P7MDecoder::decodeFile('fattura.xml.p7m');

// Decodifica da stringa
$xml = P7MDecoder::decodeString($p7mContent);

if ($xml === null) {
    throw new \RuntimeException('Impossibile decodificare il file P7M');
}

// Correzioni automatiche applicate durante la decodifica
$corrections = P7MDecoder::getLastCorrections();
foreach ($corrections as $fix) {
    echo "Tag corretto: {$fix['from']}{$fix['to']}\n";
}

API

P7MDecoder::decodeFile(string $path): ?string

Decodifica un file .p7m e restituisce il suo contenuto XML, oppure null in caso di errore.

$xml = P7MDecoder::decodeFile('/percorso/della/fattura.p7m');

P7MDecoder::decodeString(string $content): ?string

Decodifica contenuto P7M da una stringa (DER, PEM, Base64, o XML valido).

$content = file_get_contents('fattura.p7m');
$xml = P7MDecoder::decodeString($content);

P7MDecoder::getLastCorrections(): array

Restituisce la lista delle correzioni ai tag applicate durante l'ultimo'operazione di decodifica.

// Dopo una chiamata a decodeFile/decodeString
$corrections = P7MDecoder::getLastCorrections();
// Restituisce: [['from' => 'DettHaglioLinee', 'to' => 'DettaglioLinee', 'distance' => 1], ...]

Come funziona

La libreria tenta la decodifica usando 8 strategie in ordine, fermandosi al primo successo:

# Strategia Descrizione
1 Plain XML Se il contenuto e' gia' XML valido, lo restituisce direttamente
2 OpenSSL DER openssl smime -verify -inform DER
3 Base64 → DER Decodifica Base64 + verifica DER
4 OpenSSL PEM openssl smime -verify -inform PEM (include conversione Base64 → PEM)
5 PHP openssl_pkcs7_verify() Fallback via estensione PHP
6 Estrazione manuale Ricerca fragment XML nel binario
7 Correzione tag Ricerca fuzzy (Levenshtein) su tag XML danneggiati
8 Base64 + estrazione manuale Decodifica Base64 + fragment XML

Correzioni automatiche

Oltre alla decodifica, la libreria applica correzioni automatiche su:

  • Tag XML — Correzione fuzzy con distance ≤ 1 rispetto alla lista tag FatturaPA validi
  • Errori OCR/encoding — 30+ pattern di correzione per errori tipici di OCR e trasmissione:
    • UnitaMisurahUnitaMisura
    • DettHaglioLineeDettaglioLinee
    • Quant2itaQuantita
    • e molti altri...

Le correzioni applicate sono accessibili via P7MDecoder::getLastCorrections().

Casi d'uso

Elaborare file FatturaPA ricevuti dal SDI

use Controlaltjeff\P7MDecoder\P7MDecoder;

// Decodifica un file FatturaPA .p7m ricevuto dal SDI
$xml = P7MDecoder::decodeFile('IT01234567890_FPR12_001.xml.p7m');

if ($xml === null) {
    die('Decodifica fallita');
}

// Analizza l'XML
$dom = new DOMDocument();
$dom->loadXML($xml);

// Accedi ai dati della fattura
$xpath = new DOMXPath($dom);
$numeroFattura = $xpath->query('//Numero')->item(0)->nodeValue;
$importoTotale = $xpath->query('//ImportoTotaleDocumento')->item(0)->nodeValue;

Elaborare piu' file

use Controlaltjeff\P7MDecoder\P7MDecoder;

$files = glob('/percorso/delle/fatture/*.p7m');
foreach ($files as $file) {
    $xml = P7MDecoder::decodeFile($file);
    if ($xml !== null) {
        file_put_contents(str_replace('.p7m', '.xml', $file), $xml);
        echo "Decodificato: " . basename($file) . "\n";
    } else {
        echo "Fallito: " . basename($file) . "\n";
    }
}

Gestire file danneggiati da OCR

use Controlaltjeff\P7MDecoder\P7MDecoder;

$xml = P7MDecoder::decodeFile('fattura-corrotta.p7m');
$corrections = P7MDecoder::getLastCorrections();

if (!empty($corrections)) {
    echo count($corrections) . " correzioni automatiche applicate:\n";
    foreach ($corrections as $fix) {
        echo "  {$fix['from']}{$fix['to']}\n";
    }
}

Sviluppo

git clone https://github.com/controlaltjeff/p7m-fattura-decoder.git
cd p7m-fattura-decoder
composer install
composer test       # PHPUnit (24 test)
composer stan       # PHPStan livello 8
composer fix-dry    # PHP-CS-Fixer (dry-run)
composer check      # Test + Stan + CS Fixer

Per mutation testing (richiede pcov o xdebug):

composer require --dev infection/infection:^0.29
composer mutate

Contribuire

I contributi sono ben accetti! Consulta CONTRIBUTING.md per le linee guida.

Licenza

Licenza MIT. Vedi LICENSE per i dettagli.