<?php

/**
 * E057_multisignature_incremental.php
 *
 * @since       2026-05-01
 * @category    Library
 * @package     Pdf
 * @author      Nicola Asuni <info@tecnick.com>
 * @copyright   2002-2026 Nicola Asuni - Tecnick.com LTD
 * @license     https://www.gnu.org/copyleft/lesser.html GNU-LGPL v3 (see LICENSE)
 * @link        https://github.com/tecnickcom/tc-lib-pdf
 *
 * This file is part of tc-lib-pdf software library.
 */

// NOTE: local file reads (images, fonts, attachments) are restricted to an allowlist of
// trusted paths that covers this package tree, so run the examples in place. To read assets
// from other locations, list them in the 'allowedPaths' entry of the fileOptions constructor
// parameter (see E047_remote_resources_security.php).

// NOTE: run make fonts in the project root to generate the dependencies and example fonts.

// autoloader when using Composer
require __DIR__ . '/../vendor/autoload.php';

// define fonts directory
\define('K_PATH_FONTS', \realpath(__DIR__ . '/../vendor/tecnickcom/tc-lib-pdf-font/target/fonts'));

/**
 * Demonstrate a multi-signature approval flow.
 *
 * In a real approval workflow a document typically accumulates one signature
 * per approver in sequence (incremental signatures).  tc-lib-pdf supports this
 * pattern by:
 *
 *  1. setSignature()               – primary signing certificate (author / certifier)
 *  2. setSignatureAppearance()     – visible widget for the primary signature
 *  3. addEmptySignatureAppearance() – empty widget placeholders for each subsequent approver
 *
 * The primary signature field (cert_type 2 = MDP/Author) locks the document
 * against further modifications while still permitting subsequent approvals to
 * fill in the reserved empty fields.
 *
 * This example creates a 3-page document:
 *   Page 1 – contract / document body
 *   Page 2 – approval form with 3 signature fields:
 *              · Author     (primary – pre-signed by the library)
 *              · Reviewer   (empty approval field)
 *              · Manager    (empty approval field)
 *   Page 3 – signing guide / workflow description
 */

$certPath = \realpath(__DIR__ . '/data/cert/tcpdf.crt');
if ($certPath === false) {
    throw new \RuntimeException('Missing signing certificate: examples/data/cert/tcpdf.crt');
}

$cert = 'file://' . $certPath;

// main TCPDF object
$pdf = new \Com\Tecnick\Pdf\Tcpdf(
    unit: \Com\Tecnick\Pdf\Page\Unit::Millimeter,
    isunicode: true,
    subsetfont: false,
    compress: true,
    mode: \Com\Tecnick\Pdf\PdfConformance::None,
    objEncrypt: null,
);

$pdf->setCreator('tc-lib-pdf');
$pdf->setAuthor('Nicola Asuni');
$pdf->setSubject('tc-lib-pdf example: 057');
$pdf->setTitle('Multi-Signature Approval Flow');
$pdf->setKeywords('TCPDF tc-lib-pdf example signature approval multi-signature incremental');
$pdf->setPDFFilename('E057_multisignature_incremental.pdf');

$pdf->enableDefaultPageContent();

$bfont = $pdf->font->insert($pdf->pon, 'helvetica', '', 10);
$bfontB = $pdf->font->insert($pdf->pon, 'helvetica', 'B', 12);

// -----------------------------------------------------------------------
// Page 1 – Document body (contract)
// -----------------------------------------------------------------------
$page1 = $pdf->addPage();
$pdf->page->addContent($bfontB['out']);
$pdf->page->addContent($pdf->getTextCell(
    txt: 'SERVICE AGREEMENT EXAMPLE',
    posx: 15,
    posy: 15,
    width: 180,
    height: 0,
    offset: 0,
    linespace: 1,
    valign: \Com\Tecnick\Pdf\TextVAlign::Top,
    halign: \Com\Tecnick\Pdf\TextHAlign::Center,
));
$pdf->page->addContent($bfont['out']);
$pdf->font->insert($pdf->pon, 'helvetica', '', 10);

$html1 = <<<HTML
    <p>This Service Agreement ("Agreement") is entered into as of the date of the last signature below
    between <strong>Client</strong> and <strong>Service Provider</strong>.</p>

    <p><b>1. Services.</b> Service Provider agrees to deliver software development services as described
    in Schedule A attached hereto.</p>

    <p><b>2. Payment.</b> Client agrees to pay the fees set forth in Schedule B within 30 days of invoice.</p>

    <p><b>3. Term.</b> This Agreement commences on the Effective Date and continues for 12 months unless
    earlier terminated by either party upon 30 days written notice.</p>

    <p><b>4. Confidentiality.</b> Each party agrees to keep the other party's confidential information
    strictly confidential and not to disclose it to any third party without prior written consent.</p>

    <p><b>5. Governing Law.</b> This Agreement shall be governed by the laws of the applicable jurisdiction.</p>

    <p>The parties have executed this Agreement as of the dates indicated in the signature fields on
    the following page.</p>
    HTML;

$pdf->addHTMLCell(html: $html1, posx: 15, posy: 30, width: 180);

// -----------------------------------------------------------------------
// Page 2 – Approval / signature form
// -----------------------------------------------------------------------
$page2 = $pdf->addPage();
$pdf->page->addContent($bfontB['out']);
$pdf->page->addContent($pdf->getTextCell(
    txt: 'SIGNATURE PAGE EXAMPLE',
    posx: 15,
    posy: 15,
    width: 180,
    height: 0,
    offset: 0,
    linespace: 1,
    valign: \Com\Tecnick\Pdf\TextVAlign::Top,
    halign: \Com\Tecnick\Pdf\TextHAlign::Center,
));
$pdf->page->addContent($bfont['out']);
$pdf->font->insert($pdf->pon, 'helvetica', '', 10);

$pdf->page->addContent($pdf->getTextCell(
    txt: 'The following parties have reviewed and approved this Agreement:',
    posx: 15,
    posy: 30,
    width: 180,
    height: 0,
    offset: 0,
    linespace: 1,
    valign: \Com\Tecnick\Pdf\TextVAlign::Top,
    halign: \Com\Tecnick\Pdf\TextHAlign::Left,
));

// Signature box helper labels (rendered as PDF text cells)
$labels = [
    ['role' => 'Author / Certifier', 'name' => 'John Doe', 'y' => 45],
    ['role' => 'Reviewer', 'name' => '(awaiting sig.)', 'y' => 90],
    ['role' => 'Manager', 'name' => '(awaiting sig.)', 'y' => 135],
];

foreach ($labels as $lbl) {
    $pdf->page->addContent($bfontB['out']);
    $pdf->page->addContent($pdf->getTextCell(
        txt: $lbl['role'],
        posx: 15,
        posy: (float) $lbl['y'],
        width: 85,
        height: 0,
        offset: 0,
        linespace: 1,
        valign: \Com\Tecnick\Pdf\TextVAlign::Top,
        halign: \Com\Tecnick\Pdf\TextHAlign::Left,
    ));
    $pdf->page->addContent($bfont['out']);
    $pdf->page->addContent($pdf->getTextCell(
        txt: 'Name: ' . $lbl['name'],
        posx: 15,
        posy: (float) ($lbl['y'] + 7),
        width: 85,
        height: 0,
        offset: 0,
        linespace: 1,
        valign: \Com\Tecnick\Pdf\TextVAlign::Top,
        halign: \Com\Tecnick\Pdf\TextHAlign::Left,
    ));
    $pdf->page->addContent($pdf->getTextCell(
        txt: 'Date: ___________________',
        posx: 15,
        posy: (float) ($lbl['y'] + 14),
        width: 85,
        height: 0,
        offset: 0,
        linespace: 1,
        valign: \Com\Tecnick\Pdf\TextVAlign::Top,
        halign: \Com\Tecnick\Pdf\TextHAlign::Left,
    ));
}

// -----------------------------------------------------------------------
// Register the primary (author/certifier) digital signature.
// cert_type = 2  →  MDP / author signature
// -----------------------------------------------------------------------
$pdf->setSignature([
    'cert_type' => 2,
    'info' => [
        'ContactInfo' => 'https://github.com/tecnickcom/tc-lib-pdf',
        'Location' => 'Demo Office',
        'Name' => 'John Doe',
        'Reason' => 'Author / certifier signature – approval workflow example',
    ],
    'password' => '',
    'privkey' => $cert,
    'signcert' => $cert,
]);

// Primary signature appearance – placed on page 2 at the first slot.
$pdf->setSignatureAppearance(posx: 100, posy: 45, width: 90, height: 35, page: $page2['pid'], name: 'Author');

// Empty approval fields for the remaining approvers.
$pdf->addEmptySignatureAppearance(posx: 100, posy: 90, width: 90, height: 35, page: $page2['pid'], name: 'Reviewer');
$pdf->addEmptySignatureAppearance(posx: 100, posy: 135, width: 90, height: 35, page: $page2['pid'], name: 'Manager');

// -----------------------------------------------------------------------
// Page 3 – Workflow guide
// -----------------------------------------------------------------------
$page3 = $pdf->addPage();
$pdf->page->addContent($bfontB['out']);
$pdf->page->addContent($pdf->getTextCell(
    txt: 'Multi-Signature Workflow Guide',
    posx: 15,
    posy: 15,
    width: 180,
    height: 0,
    offset: 0,
    linespace: 1,
    valign: \Com\Tecnick\Pdf\TextVAlign::Top,
    halign: \Com\Tecnick\Pdf\TextHAlign::Left,
));
$pdf->page->addContent($bfont['out']);
$pdf->font->insert($pdf->pon, 'helvetica', '', 10);

$html3 = <<<HTML
    <p><b>How incremental multi-signature works in tc-lib-pdf</b></p>

    <p>A PDF approval workflow typically progresses through these steps:</p>
    <ol>
      <li><b>Author creates and certifies the document.</b>
      The primary signature (Author field) is applied by <code>setSignature()</code> with
      <em>cert_type 2</em> (MDP). This locks the document against structural changes
      while reserving the empty approval fields for subsequent signers.</li>

      <li><b>Reviewer opens the document, validates the Author signature, and applies their
      signature to the Reviewer field.</b> In a PDF viewer (e.g. Acrobat) the reviewer
      uses the reserved empty widget.  Each subsequent signature is appended to the file
      as an incremental update, preserving all prior signature data.</li>

      <li><b>Manager repeats the same process for the Manager field.</b></li>
    </ol>

    <p><b>tc-lib-pdf API summary</b></p>
    <table border="1" cellpadding="4" cellspacing="0">
      <tr><th>Method</th><th>Purpose</th></tr>
      <tr><td>setSignature()</td><td>Register the primary signing certificate and options.</td></tr>
      <tr><td>setSignatureAppearance()</td><td>Visible widget for the primary signature.</td></tr>
      <tr><td>addEmptySignatureAppearance()</td><td>Reserve an empty widget for a future approver.</td></tr>
      <tr><td>setSignTimeStamp()</td><td>Optionally attach an RFC 3161 TSA timestamp (see E008).</td></tr>
    </table>

    <p><b>Certification levels (cert_type)</b></p>
    <table border="1" cellpadding="4" cellspacing="0">
      <tr><th>cert_type</th><th>Meaning</th></tr>
      <tr><td>1</td><td>No changes permitted after signing.</td></tr>
      <tr><td>2</td><td>Form fills and approval signatures permitted (MDP).</td></tr>
      <tr><td>3</td><td>Annotations and form fills permitted.</td></tr>
    </table>
    HTML;

$pdf->addHTMLCell(html: $html3, posx: 15, posy: 30, width: 180);

// -----------------------------------------------------------------------
// Output
// -----------------------------------------------------------------------
$rawpdf = $pdf->getOutPDFString();
$pdf->renderPDF(rawpdf: $rawpdf);
