From 38ea3f761399d466d4578a25a7faea4e14f386ef Mon Sep 17 00:00:00 2001 From: HorstOeko Date: Sat, 7 Dec 2024 10:36:47 +0100 Subject: [PATCH] [ENH] Add deterministic Mode to ZugferdDocumentPdfBuilderAbstract (and derived classes). This mode should only used for testing purposes --- src/ZugferdDocumentPdfBuilderAbstract.php | 14 +++++ src/ZugferdPdfWriter.php | 67 ++++++++++++++++++----- 2 files changed, 68 insertions(+), 13 deletions(-) diff --git a/src/ZugferdDocumentPdfBuilderAbstract.php b/src/ZugferdDocumentPdfBuilderAbstract.php index 6f238fe..9309904 100644 --- a/src/ZugferdDocumentPdfBuilderAbstract.php +++ b/src/ZugferdDocumentPdfBuilderAbstract.php @@ -339,6 +339,20 @@ public function attachAdditionalFileByContent(string $content, string $filename, return $this; } + /** + * Set the the deterministic mode. This mode should only be used + * for testing purposes + * + * @param bool $deterministicModeEnabled + * @return static + */ + public function setDeterministicModeEnabled(bool $deterministicModeEnabled) + { + $this->pdfWriter->setDeterministicModeEnabled($deterministicModeEnabled); + + return $this; + } + /** * Get the content of XML to attach * diff --git a/src/ZugferdPdfWriter.php b/src/ZugferdPdfWriter.php index c4b43ba..5c0c053 100644 --- a/src/ZugferdPdfWriter.php +++ b/src/ZugferdPdfWriter.php @@ -80,11 +80,18 @@ class ZugferdPdfWriter extends PdfFpdi protected $openAttachmentPane = false; /** - * Set the PDF version. + * Internal flag deterministic mode. This mode should only be used + * for testing purposes * - * @param string $version Contains the PDF version number. - * @param bool $binary_data This is true for binary data + * @var boolean + */ + protected $deterministicModeEnabled = false; + + /** + * Set the PDF version. * + * @param string $version Contains the PDF version number. + * @param bool $binary_data This is true for binary data * @return void */ public function setPdfVersion($version = '1.3', $binary_data = false): void @@ -92,12 +99,11 @@ public function setPdfVersion($version = '1.3', $binary_data = false): void $this->PDFVersion = sprintf('%.1F', $version); if (true == $binary_data) { - $this->PDFVersion .= - "\n" . '%' . - chr(rand(128, 256)) . - chr(rand(128, 256)) . - chr(rand(128, 256)) . - chr(rand(128, 256)); + if ($this->deterministicModeEnabled === true) { + $this->PDFVersion .= "\n" . '%' . chr(128) . chr(129) . chr(130) . chr(131); + } else { + $this->PDFVersion .= "\n" . '%' . chr(rand(128, 256)) . chr(rand(128, 256)) . chr(rand(128, 256)) . chr(rand(128, 256)); + } } } @@ -176,11 +182,28 @@ public function addMetadataDescriptionNode($description): void * The array with metadata information applied to the pdf * @return void */ - public function setPdfMetadataInfos(array $metaDataInfos): void + public function setPdfMetadataInfos(array &$metaDataInfos): void { + if ($this->deterministicModeEnabled === true) { + $metaDataInfos['createdDate'] = date('Y-m-d\TH:i:s', strtotime("2000-01-01 23:59:59")); + $metaDataInfos['modifiedDate'] = date('Y-m-d\TH:i:s', strtotime("2000-01-01 23:59:59")); + } + $this->metaDataInfos = $metaDataInfos; } + /** + * Set the status of the deterministic mode. This mode should only be used + * for testing purposes + * + * @param bool $deterministicModeEnabled + * @return void + */ + public function setDeterministicModeEnabled(bool $deterministicModeEnabled): void + { + $this->deterministicModeEnabled = $deterministicModeEnabled; + } + /** * Put files. * @@ -251,10 +274,14 @@ protected function putFileStream(array $file_info): void if (false === $fc) { $this->Error('Cannot open file: ' . $file_info['file']); } - if (is_string($file_info['file'])) { - $md = @date('YmdHis', filemtime($file_info['file'])); + if ($this->deterministicModeEnabled === true) { + $md = @date('YmdHis', strtotime("2000-01-01 23:59:59")); } else { - $md = @date('YmdHis'); + if (is_string($file_info['file'])) { + $md = @date('YmdHis', filemtime($file_info['file'])); + } else { + $md = @date('YmdHis'); + } } $fc = gzcompress($fc); $this->_put('/Length ' . strlen($fc)); @@ -429,6 +456,20 @@ protected function _puttrailer(): void $this->_put(sprintf('/ID [<%s><%s>]', $created_id, $modified_id)); } + /** + * Put general information + * + * @return void + */ + protected function _putinfo(): void + { + if ($this->deterministicModeEnabled === true) { + $this->CreationDate = strtotime("2000-01-01 23:59:59"); + } + + parent::_putinfo(); + } + /** * Generate metadata string. *