PHP code example of lsnepomuceno / laravel-a1-pdf-sign

1. Go to this page and download the library: Download lsnepomuceno/laravel-a1-pdf-sign library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

lsnepomuceno / laravel-a1-pdf-sign example snippets


use LSNepomuceno\Signet\Exceptions\SignetException;

$exceptions->report(function (SignetException $e) { … });

use LSNepomuceno\LaravelA1PdfSign\Facades\A1PdfSign;

$signed = A1PdfSign::newSignature()
    ->certificate($pfxPath, $password)
    ->pdf($pdfPath)
    ->info(name: 'Lucas', reason: 'Contract')
    ->seal()                       // omit for an invisible signature
    ->sign();

$signed->contents;                 // string
$signed->save($path);              // path
$signed->download('contract.pdf'); // BinaryFileResponse

A1PdfSign::newSignature()
    ->certificate($pfx, $password)
    ->from(A1PdfSign::fromDisk('s3', 'contracts/deal.pdf'))
    ->sign()
    ->writeTo(A1PdfSign::toDisk('s3', 'contracts/deal-signed.pdf'));

// or hand over the bytes yourself, from anywhere at all
->pdfContents($bytes, 'deal.pdf')

$this->app->bind(SealRenderer::class, QrCodeSealRenderer::class);

$signing = A1PdfSign::fake();

// … the application runs …

$signing->assertSigned();
$signing->assertSignedTimes(1);
$signing->assertSignedWithProfile(SignatureProfile::PadesBLT);
$signing->assertCertified(CertificationLevel::NoChanges);
$signing->assertSealed();
$signing->assertNothingSigned();

Process::fake();               // the openssl shell-out, for validation and legacy PFX files
Http::fake();                  // the timestamp authority, OCSP and CRL
Http::preventStrayRequests();  // proves a pades-b-b signature reaches no network at all
Storage::fake('s3');           // signing from a disk and writing back to one

app()->instance(SignatureTransport::class, new LocalTimestampAuthority(app(ProcessRunner::class)));

// PKCS#12
A1PdfSign::newSignature()->certificate($pfxPath, $password);

// PEM, key in the same file or in its own
A1PdfSign::newSignature()->certificatePem($certificatePath, $keyPath, $password);

// From an upload or a secret store
A1PdfSign::newSignature()->certificateFromPem($bytes);

A1PdfSign::signFromFile($pfxPath, $password, $pdfPath);
A1PdfSign::signFromPem($pemPath, $password, $pdfPath, $keyPath);
A1PdfSign::signFromUpload($request->file('certificate'), $password, $pdfPath);

$stored = A1PdfSign::encryptCertificate($uploadedOrPath, $password);

$stored->hash;         // the key both values were encrypted with. Required to read them back
$stored->certificate;
$stored->password;

$certificate = A1PdfSign::decryptCertificate($stored->hash, $stored->certificate, $stored->password);

A1PdfSign::newSignature()
    ->certificate($pfx, $password)
    ->pdf($path)
    ->profile('pades-b-lt')   // needs A1_TSA_URL configured
    ->sign();

A1PdfSign::extendArchive($path);

foreach (A1PdfSign::signatureFields($template) as $field) {
    $field->name;        // 'SignatureManager'
    $field->isSigned;    // false
    $field->rectangle;   // [30.0, 200.0, 200.0, 250.0]
}

A1PdfSign::newSignature()
    ->certificate($pfx, $password)
    ->pdf($template)
    ->intoField('SignatureManager')
    ->seal()             // drawn into the field's own rectangle
    ->sign();

A1PdfSign::addSignatureField($pdf, 'Manager')                                    // invisible
A1PdfSign::addSignatureField($pdf, 'Manager', new SealPlacement(60, 400, 120, 40)); // placed

$prepared = A1PdfSign::newSignature()
    ->certificatePublic($certificatePem)   // the public half is enough to reserve the space
    ->pdf($contract)
    ->prepare();

$cms = $yourHsm->sign($prepared->digestValue);   // the only step that touches the key

$signed = A1PdfSign::complete($prepared, $cms);

A1PdfSign::newSignature()->certificate($pfx, $password)->pdf($path)
    ->certify('form-filling')                  // no-changes | form-filling | annotations
    ->lock(FieldLock::only(['Amount']))        // ->lock() for every field
    ->sign();

A1PdfSign::newSignature()
    ->certificate($pfxPath, $certificatePassword)
    ->pdf($path, 'the document password')
    ->sign();

$report = A1PdfSign::validate($pdfPath);

$report->isValid();     // every signature verifies against the bytes it covers
$report->count();       // how many signatures the document carries
$report->signers();     // structured signer identity
$report->isCertified(); // whether the author certified the document

$signature = $report->latest();

$signature?->attestedAt();       // the timestamp authority's time, or null. Never the signer's own clock
$signature?->profile;            // the level it actually satisfies, not the one it claims
$signature?->isRevoked();        // what the document's own OCSP responses and CRLs say
$signature?->coversWholeDocument;

$store = TrustStore::fromFile(storage_path('icp-brasil.pem'));

$report = A1PdfSign::validate($pdfPath, $store);
$report->isTrusted();   // ?bool. null when no store was given: nobody was asked

$signer = A1PdfSign::validate($path)->signers()[0];

$signer->icpBrasil?->cpf;                 // '11144477735'
$signer->icpBrasil?->cnpj;                // the company, for an e-CNPJ
$signer->icpBrasil?->formattedRegistry(); // '11.222.333/0001-81'
$signer->name();                          // the name, without the number glued to it

$report = A1PdfSign::icpBrasil($pfxPath, $password);

$report->conforms();   // 

// config/a1-pdf-sign.php
'agents' => ['disks' => ['contracts']],

// routes/ai.php
Mcp::web('/mcp/signatures', A1PdfSignServer::class)->middleware('auth:sanctum');

public function tools(): iterable
{
    return [
        new McpServerTool(new ValidatePdfSignature()),
        new SignPdf(),   // the certificate comes from a resolver you bind, never from the model
    ];
}

$response = new ContractAssistant()->forUser($user)->prompt('Sign the Acme contract.');

$response->pendingApprovals->first()->reason;
// Sign [acme.pdf] on the disk [contracts] with the certificate of MARIA DA SILVA (111.444.777-35), valid until …
bash
php artisan vendor:publish --tag=a1-pdf-sign-config
bash
php artisan pdf:sign contract.pdf certificate.pfx "password" signed.pdf
php artisan pdf:sign contract.pdf certificate.pem "" signed.pdf --key=private.key
php artisan pdf:validate-signature signed.pdf

php artisan pdf:fields template.pdf
php artisan pdf:add-field template.pdf Manager placed.pdf --x=60 --y=400 --width=120 --height=40
php artisan pdf:extend archived.pdf

php artisan a1-pdf-sign:check