Files
putnamrec/vendor/tecnickcom/tc-lib-pdf/test/TestableOutput.php
T

848 lines
24 KiB
PHP
Raw Normal View History

2026-08-20 11:41:17 +00:00
<?php
/**
* TestableOutput.php
*
* @since 2002-08-03
* @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.
*/
namespace Test;
/**
* @phpstan-import-type TAnnot from \Com\Tecnick\Pdf\Output
* @phpstan-import-type TObjID from \Com\Tecnick\Pdf\Output
* @phpstan-import-type TOutline from \Com\Tecnick\Pdf\Output
* @phpstan-import-type TSignDocPrepared from \Com\Tecnick\Pdf\Output
* @phpstan-import-type TSVGMaskObject from \Com\Tecnick\Pdf\Base
*/
class TestableOutput extends \Com\Tecnick\Pdf\Tcpdf
{
protected string $mockTsaResp = '';
protected bool $mockTsaThrows = false;
protected string $tsaReq = '';
protected string $mockOcspResp = '';
protected bool $mockOcspThrows = false;
protected string $ocspReq = '';
protected string $ocspUrl = '';
protected string $mockCrlResp = '';
protected bool $mockCrlThrows = false;
protected string $crlUrl = '';
/**
* @phpstan-param array<string, mixed> $annotData
* @phpstan-return TAnnot
*/
private function toAnnot(array $annotData): array
{
$base = [
'n' => 1,
'x' => 0.0,
'y' => 0.0,
'w' => 0.0,
'h' => 0.0,
'txt' => '',
'opt' => ['subtype' => 'text'],
];
/** @var TAnnot */
return \array_replace_recursive($base, $annotData);
}
/** @phpstan-return array<int> */
public function exposeGetPDFObjectOffsets(string $data): array
{
return $this->getPDFObjectOffsets($data);
}
/** @phpstan-param array<int> $offset */
public function exposeGetOutPDFXref(array $offset): string
{
return $this->getOutPDFXref($offset);
}
public function exposeGetOutPDFTrailer(): string
{
return $this->getOutPDFTrailer();
}
/** @phpstan-param array<float|int> $color */
public function exposeGetColorStringFromPercArray(array $color): string
{
return self::getColorStringFromPercArray($color);
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetAnnotationBorder(array $annot): string
{
return $this->getAnnotationBorder($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationFlags(array $annot): string
{
return $this->getOutAnnotationFlags($this->toAnnot($annot));
}
/** @phpstan-param array<string>|int $flags */
public function exposeGetAnnotationFlagsCode(int|array $flags): int
{
return $this->getAnnotationFlagsCode($flags);
}
public function exposeGetOnOff(mixed $val): string
{
return $this->getOnOff($val);
}
/**
* @param array<string, true> $transpNames
*/
public function exposeStreamUsesTransparency(string $stream, array $transpNames): bool
{
return $this->streamUsesTransparency($stream, $transpNames);
}
/** @return array<string, true> */
public function exposeGetTransparencyResourceNames(): array
{
return $this->getTransparencyResourceNames();
}
/** @throws \Throwable */
public function exposeGetOutDestinations(): string
{
return $this->getOutDestinations();
}
public function exposeSortBookmarks(): void
{
$this->sortBookmarks();
}
public function exposeProcessPrevNextBookmarks(): int
{
return $this->processPrevNextBookmarks();
}
/** @throws \Throwable */
public function exposeGetOutBookmarks(): string
{
return $this->getOutBookmarks();
}
/** @throws \Throwable */
public function exposeGetOutJavascript(): string
{
return $this->getOutJavascript();
}
public function exposeGetXObjectDict(): string
{
return $this->getXObjectDict();
}
public function exposeGetLayerDict(): string
{
return $this->getLayerDict();
}
public function exposeGetOutResourcesDict(): string
{
return $this->getOutResourcesDict();
}
public function exposeGetPatternStreamResourceDict(string $stream): string
{
return $this->getPatternStreamResourceDict($stream);
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeLine(array $annot): string
{
return $this->getOutAnnotationOptSubtypeLine($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeSquare(array $annot): string
{
return $this->getOutAnnotationOptSubtypeSquare($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeCircle(array $annot): string
{
return $this->getOutAnnotationOptSubtypeCircle($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypePolygon(array $annot): string
{
return $this->getOutAnnotationOptSubtypePolygon($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypePolyline(array $annot): string
{
return $this->getOutAnnotationOptSubtypePolyline($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeHighlight(array $annot): string
{
return $this->getOutAnnotationOptSubtypeHighlight($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeUnderline(array $annot): string
{
return $this->getOutAnnotationOptSubtypeUnderline($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeSquiggly(array $annot): string
{
return $this->getOutAnnotationOptSubtypeSquiggly($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeStrikeout(array $annot): string
{
return $this->getOutAnnotationOptSubtypeStrikeout($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeStamp(array $annot): string
{
return $this->getOutAnnotationOptSubtypeStamp($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeCaret(array $annot): string
{
return $this->getOutAnnotationOptSubtypeCaret($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeInk(array $annot): string
{
return $this->getOutAnnotationOptSubtypeInk($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypePopup(array $annot): string
{
return $this->getOutAnnotationOptSubtypePopup($this->toAnnot($annot));
}
/**
* @phpstan-param array<string, mixed> $annot
* @throws \Throwable
*/
public function exposeGetOutAnnotationOptSubtypeMovie(array $annot): string
{
return $this->getOutAnnotationOptSubtypeMovie($this->toAnnot($annot));
}
/**
* @phpstan-param array<string, mixed> $annot
* @throws \Throwable
*/
public function exposeGetOutAnnotationOptSubtypeScreen(array $annot): string
{
return $this->getOutAnnotationOptSubtypeScreen($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypePrintermark(array $annot): string
{
return $this->getOutAnnotationOptSubtypePrintermark($this->toAnnot($annot));
}
/**
* @phpstan-param array<string, mixed> $annot
* @throws \Throwable
*/
public function exposeGetOutAnnotationOptSubtypeRedact(array $annot): string
{
return $this->getOutAnnotationOptSubtypeRedact($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeTrapnet(array $annot): string
{
return $this->getOutAnnotationOptSubtypeTrapnet($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeWatermark(array $annot): string
{
return $this->getOutAnnotationOptSubtypeWatermark($this->toAnnot($annot));
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtype3D(array $annot): string
{
return $this->getOutAnnotationOptSubtype3D($this->toAnnot($annot));
}
/**
* @phpstan-param array<string, mixed> $annot
* @throws \Throwable
*/
public function exposeGetAnnotationRadioButtons(array $annot): string
{
return $this->getAnnotationRadioButtons($this->toAnnot($annot));
}
/**
* @phpstan-param array<string, mixed> $annot
* @return array{string, string}
* @throws \Throwable
*/
public function exposeGetAnnotationAppearanceStream(array $annot, float $width = 0, float $height = 0): array
{
$method = new \ReflectionMethod($this, 'getAnnotationAppearanceStream');
/** @var array{string, string} */
return $method->invokeArgs($this, [$this->toAnnot($annot), $width, $height]);
}
/**
* @phpstan-param array<string, mixed> $annot
* @throws \Throwable
*/
public function exposeGetOutAnnotationMarkups(array $annot, int $oid): string
{
return $this->getOutAnnotationMarkups($this->toAnnot($annot), $oid);
}
/**
* @phpstan-param array<string, mixed> $annot
* @throws \Throwable
*/
public function exposeGetOutAnnotationOptSubtype(array $annot, int $pagenum, int $oid, int $key): string
{
return $this->getOutAnnotationOptSubtype($this->toAnnot($annot), $pagenum, $oid, $key);
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeText(array $annot): string
{
return $this->getOutAnnotationOptSubtypeText($this->toAnnot($annot));
}
/**
* @phpstan-param array<string, mixed> $annot
* @throws \Throwable
*/
public function exposeGetOutAnnotationOptSubtypeLink(array $annot, int $pagenum, int $oid): string
{
return $this->getOutAnnotationOptSubtypeLink($this->toAnnot($annot), $pagenum, $oid);
}
/**
* @phpstan-param array<string, mixed> $annot
* @throws \Throwable
*/
public function exposeGetOutAnnotationOptSubtypeFreetext(array $annot, int $oid): string
{
return $this->getOutAnnotationOptSubtypeFreetext($this->toAnnot($annot), $oid);
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeFileattachment(array $annot, int $key): string
{
return $this->getOutAnnotationOptSubtypeFileattachment($this->toAnnot($annot), $key);
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationOptSubtypeSound(array $annot): string
{
return $this->getOutAnnotationOptSubtypeSound($this->toAnnot($annot));
}
/**
* @phpstan-param array<string, mixed> $annot
* @throws \Throwable
*/
public function exposeGetOutAnnotationOptSubtypeWidget(array $annot, int $oid): string
{
return $this->getOutAnnotationOptSubtypeWidget($this->toAnnot($annot), $oid);
}
public function exposeGetOutPDFHeader(): string
{
return $this->getOutPDFHeader();
}
/** @throws \Throwable */
public function exposeGetOutPDFBody(): string
{
return $this->getOutPDFBody();
}
/** @throws \Throwable */
public function exposeGetOutCatalog(): string
{
return $this->getOutCatalog();
}
/** @throws \Throwable */
public function exposeAppendDssRevision(string $pdf): string
{
return $this->appendDssRevision($pdf);
}
/** @throws \Throwable */
public function exposeAppendDocTimeStampRevision(string $pdf): string
{
return $this->appendDocTimeStampRevision($pdf);
}
public function exposeExtractSignatureContents(string $pdf): string
{
return $this->extractSignatureContents($pdf);
}
/** @throws \Throwable */
public function exposeGetOutICC(): string
{
return $this->getOutICC();
}
/** @throws \Throwable */
public function exposeGetOutputIntentsSrgb(): string
{
return $this->getOutputIntentsSrgb();
}
/** @throws \Throwable */
public function exposeGetOutputIntentsPdfX(): string
{
return $this->getOutputIntentsPdfX();
}
/** @throws \Throwable */
public function exposeGetOutputIntents(): string
{
return $this->getOutputIntents();
}
/** @throws \Throwable */
public function exposeGetPDFLayers(): string
{
return $this->getPDFLayers();
}
/** @throws \Throwable */
public function exposeGetOutOCG(): string
{
return $this->getOutOCG();
}
/** @throws \Throwable */
public function exposeGetOutAPXObjects(float $width = 0, float $height = 0, string $stream = ''): string
{
return $this->getOutAPXObjects($width, $height, $stream);
}
/** @throws \Throwable */
public function exposeGetOutXObjects(): string
{
return $this->getOutXObjects();
}
/** @throws \Throwable */
public function exposeGetOutPatterns(): string
{
return $this->getOutPatterns();
}
/** @throws \Throwable */
public function exposeGetOutEmbeddedFiles(): string
{
return $this->getOutEmbeddedFiles();
}
/** @throws \Throwable */
public function exposeGetOutAnnotations(): string
{
return $this->getOutAnnotations();
}
/** @throws \Throwable */
public function exposeGetOutSignatureFields(): string
{
return $this->getOutSignatureFields();
}
/**
* @phpstan-return TSignDocPrepared
*/
public function exposePrepareDocumentForSignature(string $pdfdoc): array
{
return $this->prepareDocumentForSignature($pdfdoc);
}
/** @throws \Throwable */
public function exposeConvertBinarySignatureToHex(string $signature): string
{
return $this->convertBinarySignatureToHex($signature);
}
/**
* @return array{certs: list<string>, ocsp: list<string>, crls: list<string>}
* @throws \Throwable
*/
public function exposeCollectDssMaterial(): array
{
return $this->collectDssMaterial();
}
public function setMockTimestampResponse(string $response): void
{
$this->mockTsaResp = $response;
}
public function setMockTimestampThrows(bool $throws): void
{
$this->mockTsaThrows = $throws;
}
public function getCapturedTimestampRequest(): string
{
return $this->tsaReq;
}
public function setMockOcspResponse(string $response): void
{
$this->mockOcspResp = $response;
}
public function setMockOcspThrows(bool $throws): void
{
$this->mockOcspThrows = $throws;
}
public function getCapturedOcspRequest(): string
{
return $this->ocspReq;
}
public function getCapturedOcspUrl(): string
{
return $this->ocspUrl;
}
public function setMockCrlResponse(string $response): void
{
$this->mockCrlResp = $response;
}
public function setMockCrlThrows(bool $throws): void
{
$this->mockCrlThrows = $throws;
}
public function getCapturedCrlUrl(): string
{
return $this->crlUrl;
}
protected function postTimestampRequest(string $request): string
{
$this->tsaReq = $request;
if ($this->mockTsaThrows) {
throw new \Com\Tecnick\Pdf\Exception('mock tsa transport error');
}
if ($this->mockTsaResp !== '') {
return $this->mockTsaResp;
}
return parent::postTimestampRequest($request);
}
protected function postOcspRequest(string $url, string $request): string
{
$this->ocspUrl = $url;
$this->ocspReq = $request;
if ($this->mockOcspThrows) {
throw new \Com\Tecnick\Pdf\Exception('mock ocsp transport error');
}
if ($this->mockOcspResp !== '') {
return $this->mockOcspResp;
}
return parent::postOcspRequest($url, $request);
}
protected function getCrlData(string $url): string
{
$this->crlUrl = $url;
if ($this->mockCrlThrows) {
throw new \Com\Tecnick\Pdf\Exception('mock crl transport error');
}
if ($this->mockCrlResp !== '') {
return $this->mockCrlResp;
}
return parent::getCrlData($url);
}
/** @throws \Throwable */
public function exposeSignDocument(string $pdfdoc): string
{
return $this->signDocument($pdfdoc);
}
/** @throws \Throwable */
public function exposeBuildSignatureCms(string $content): string
{
return $this->buildSignatureCms($content);
}
public function exposeSignatureSubFilter(): string
{
return $this->signatureSubFilter();
}
public function exposeSignatureDigestAlgorithm(): string
{
return $this->signatureDigestAlgorithm();
}
public function exposeSignatureContentsLength(): int
{
return $this->signatureContentsLength();
}
/**
* @param array<int, string> $objects
* @throws \Throwable
*/
public function exposeAppendIncrementalRevision(string $pdf, array $objects): string
{
return $this->appendIncrementalRevision($pdf, $objects);
}
/**
* @return list<string>
* @throws \Throwable
*/
public function exposeLoadExtraCertificates(string $extracerts): array
{
return $this->loadExtraCertificates($extracerts);
}
/** @throws \Throwable */
public function exposeGetOutSignature(): string
{
return $this->getOutSignature();
}
public function exposeGetOutSignatureDocMDP(): string
{
return $this->getOutSignatureDocMDP();
}
public function exposeGetOutSignatureUserRights(): string
{
return $this->getOutSignatureUserRights();
}
/** @phpstan-param array<string, int|array<int>> $objid */
public function setOutputState(int $pon, array $objid, string $fileid = 'ABC123', int $encryptObjId = 0): void
{
$this->pon = $pon;
$form = $objid['form'] ?? null;
if (\is_array($form)) {
$typedForm = \array_map(static fn($objId): int => (int) $objId, $form);
$this->objid['form'] = $typedForm;
}
$intKeys = ['catalog', 'dests', 'dss', 'info', 'pages', 'resdic', 'signature', 'srgbicc', 'xmp'];
foreach ($intKeys as $key) {
$value = $objid[$key] ?? null;
if (!\is_int($value)) {
continue;
}
switch ($key) {
case 'catalog':
$this->objid['catalog'] = $value;
break;
case 'dests':
$this->objid['dests'] = $value;
break;
case 'dss':
$this->objid['dss'] = $value;
break;
case 'info':
$this->objid['info'] = $value;
break;
case 'pages':
$this->objid['pages'] = $value;
break;
case 'resdic':
$this->objid['resdic'] = $value;
break;
case 'signature':
$this->objid['signature'] = $value;
break;
case 'srgbicc':
$this->objid['srgbicc'] = $value;
break;
case 'xmp':
$this->objid['xmp'] = $value;
break;
}
}
$this->fileid = $fileid;
$ref = new \ReflectionObject($this->encrypt);
$prop = $ref->getProperty('encryptdata');
/** @var array<string, mixed> $data */
$data = $prop->getValue($this->encrypt);
$data['objid'] = $encryptObjId;
$prop->setValue($this->encrypt, $data);
}
public function setPdfaMode(int $pdfa): void
{
$this->pdfa = $pdfa;
}
/** @phpstan-return array<int, TOutline> */
public function getOutlinesState(): array
{
return $this->outlines;
}
public function getJavascriptTree(): string
{
return $this->jstree;
}
/** @throws \Throwable */
public function exposeGetOutSVGMasks(): string
{
return $this->getOutSVGMasks();
}
public function exposeGetSVGMaskExtGStateEntries(): string
{
return $this->getSVGMaskExtGStateEntries();
}
/** @phpstan-param array<string, array<string, mixed>> $masks */
public function setSvgMasks(array $masks): void
{
/** @var array<string, TSVGMaskObject> $typedMasks */
$typedMasks = [];
foreach ($masks as $key => $mask) {
if (!isset($mask['bbox']) || !\is_array($mask['bbox'])) {
continue;
}
$bbox = $mask['bbox'];
$bbox0 = isset($bbox[0]) && \is_numeric($bbox[0]) ? (float) $bbox[0] : 0.0;
$bbox1 = isset($bbox[1]) && \is_numeric($bbox[1]) ? (float) $bbox[1] : 0.0;
$bbox2 = isset($bbox[2]) && \is_numeric($bbox[2]) ? (float) $bbox[2] : 0.0;
$bbox3 = isset($bbox[3]) && \is_numeric($bbox[3]) ? (float) $bbox[3] : 0.0;
$typedMasks[$key] = [
'id' => isset($mask['id']) ? (string) $mask['id'] : $key,
'stream' => isset($mask['stream']) ? (string) $mask['stream'] : '',
'bbox' => [
$bbox0,
$bbox1,
$bbox2,
$bbox3,
],
'gs_n' => (int) ($mask['gs_n'] ?? 0),
];
}
$this->svgmasks = $typedMasks;
}
/** @return array<string, mixed> */
public function getSvgMasks(): array
{
return $this->svgmasks;
}
/**
* @param array<string> $names
*/
public function exposeExtractNamedResourceRefs(string $dict, array $names): string
{
return $this->extractNamedResourceRefs($dict, $names);
}
/** @throws \Throwable */
public function exposeGetOutStructTreeRoot(): string
{
return $this->getOutStructTreeRoot();
}
/** @phpstan-param array<string, mixed> $annot */
public function exposeGetOutAnnotationRD(array $annot): string
{
return $this->getOutAnnotationRectDifferences($annot);
}
public function exposeSetPageStructParents(string $pdfpages): string
{
return $this->setPageStructParents($pdfpages);
}
/** @throws \Throwable */
public function exposePostTimestampRequest(string $request): string
{
return $this->postTimestampRequest($request);
}
/** @throws \Throwable */
public function exposeParentPostTimestampRequest(string $request): string
{
return parent::postTimestampRequest($request);
}
/** @throws \Throwable */
public function exposeGetCertificateSourceContent(string $source): string
{
return $this->getCertificateSourceContent($source);
}
/**
* @return array<int, string>
* @throws \Throwable
*/
public function exposeExtractPemCertificates(string $content): array
{
return $this->extractPemCertificates($content);
}
public function exposeGetPatternDict(): string
{
return $this->getPatternDict();
}
/** @throws \Throwable */
public function exposeWriteRawPdfOutput(string $rawpdf): void
{
$this->writeRawPdfOutput($rawpdf);
}
}