From 33d328ee75589b6115f33668ff16cf81234905c7 Mon Sep 17 00:00:00 2001 From: TrainZug Date: Wed, 23 Dec 2020 16:32:06 +0100 Subject: [PATCH 1/9] cover and toc option for wkhtmltopdf engine --- src/Pdf/Engine/WkHtmlToPdfEngine.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Pdf/Engine/WkHtmlToPdfEngine.php b/src/Pdf/Engine/WkHtmlToPdfEngine.php index 9d5ad1ba..119fedc4 100644 --- a/src/Pdf/Engine/WkHtmlToPdfEngine.php +++ b/src/Pdf/Engine/WkHtmlToPdfEngine.php @@ -137,9 +137,17 @@ protected function _getCommand(): string $command .= sprintf(' --%s %s %s', $key, escapeshellarg($k), escapeshellarg((string)$v)); } } elseif ($value === true) { - $command .= ' --' . $key; + if ($key === 'toc') { + $command .= ' toc'; + } else { + $command .= ' --' . $key; + } } else { - $command .= sprintf(' --%s %s', $key, escapeshellarg((string)$value)); + if ($key === 'cover') { + $command .= ' cover ' . escapeshellarg((string)$value); + } else { + $command .= sprintf(' --%s %s', $key, escapeshellarg((string)$value)); + } } } $footer = $this->_Pdf->footer(); From 28a6d10b804f0f140e8f239029d596c1ac0a6516 Mon Sep 17 00:00:00 2001 From: TrainZug Date: Thu, 24 Dec 2020 10:53:20 +0100 Subject: [PATCH 2/9] added test --- tests/TestCase/Pdf/Engine/WkHtmlToPdfEngineTest.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/TestCase/Pdf/Engine/WkHtmlToPdfEngineTest.php b/tests/TestCase/Pdf/Engine/WkHtmlToPdfEngineTest.php index f757ccdf..71b45617 100644 --- a/tests/TestCase/Pdf/Engine/WkHtmlToPdfEngineTest.php +++ b/tests/TestCase/Pdf/Engine/WkHtmlToPdfEngineTest.php @@ -75,6 +75,19 @@ public function testGetCommand() $result = $method->invokeArgs($Pdf->engine(), []); $expected = "wkhtmltopdf --quiet --print-media-type --orientation 'portrait' --page-size 'A4' --encoding 'UTF-8' --boolean --string 'value' --integer '42' --array 'first' 'firstValue' --array 'second' 'secondValue' - -"; $this->assertEquals($expected, $result); + + $Pdf = new CakePdf([ + 'engine' => [ + 'className' => 'CakePdf.WkHtmlToPdf', + 'options' => [ + 'cover' => 'cover.html', + 'toc' => true, + ], + ], + ]); + $result = $method->invokeArgs($Pdf->engine(), []); + $expected = "wkhtmltopdf --quiet --print-media-type --orientation 'portrait' --page-size 'A4' --encoding 'UTF-8' cover 'cover.html' toc - -"; + $this->assertEquals($expected, $result); } public function testGetBinaryPath() From a1fc8bc1288a548be4c5acba654dd639d6a4d57c Mon Sep 17 00:00:00 2001 From: TrainZug Date: Fri, 25 Dec 2020 23:55:29 +0100 Subject: [PATCH 3/9] define further options for the toc and cover via array --- src/Pdf/Engine/WkHtmlToPdfEngine.php | 65 +++++++++++---- .../Pdf/Engine/WkHtmlToPdfEngineTest.php | 80 +++++++++++++++++++ 2 files changed, 129 insertions(+), 16 deletions(-) diff --git a/src/Pdf/Engine/WkHtmlToPdfEngine.php b/src/Pdf/Engine/WkHtmlToPdfEngine.php index 119fedc4..1ea7e2c7 100644 --- a/src/Pdf/Engine/WkHtmlToPdfEngine.php +++ b/src/Pdf/Engine/WkHtmlToPdfEngine.php @@ -132,23 +132,8 @@ protected function _getCommand(): string foreach ($options as $key => $value) { if (empty($value)) { continue; - } elseif (is_array($value)) { - foreach ($value as $k => $v) { - $command .= sprintf(' --%s %s %s', $key, escapeshellarg($k), escapeshellarg((string)$v)); - } - } elseif ($value === true) { - if ($key === 'toc') { - $command .= ' toc'; - } else { - $command .= ' --' . $key; - } - } else { - if ($key === 'cover') { - $command .= ' cover ' . escapeshellarg((string)$value); - } else { - $command .= sprintf(' --%s %s', $key, escapeshellarg((string)$value)); - } } + $command .= $this->parseOptions($key, $value); } $footer = $this->_Pdf->footer(); foreach ($footer as $location => $text) { @@ -172,6 +157,54 @@ protected function _getCommand(): string return $command; } + /** + * Parses a value of options to create a part of the command. + * Created to reuse logic to parse the cover and toc options. + * + * @param string $key the option key name + * @param string|boolean|array $value the option value + * @return string part of the command + */ + public function parseOptions(string $key, $value): string + { + $command = ""; + if (is_array($value)) { + if ($key === 'toc') { + $command .= ' toc'; + foreach ($value as $k => $v) { + $command .= $this->parseOptions($k, $v); + } + } elseif ($key === 'cover') { + if(!isset($value['url'])) { + throw new Exception('The url for the cover is missing. Use the "url" index.'); + } + $command .= ' cover ' . escapeshellarg((string)$value['url']); + unset($value['url']); + foreach ($value as $k => $v) { + $command .= $this->parseOptions($k, $v); + } + } else { + foreach ($value as $k => $v) { + $command .= sprintf(' --%s %s %s', $key, escapeshellarg($k), escapeshellarg((string)$v)); + } + } + } elseif ($value === true) { + if ($key === 'toc') { + $command .= ' toc'; + } else { + $command .= ' --' . $key; + } + } else { + if ($key === 'cover') { + $command .= ' cover ' . escapeshellarg((string)$value); + } else { + $command .= sprintf(' --%s %s', $key, escapeshellarg((string)$value)); + } + } + + return $command; + } + /** * Get path to wkhtmltopdf binary. * diff --git a/tests/TestCase/Pdf/Engine/WkHtmlToPdfEngineTest.php b/tests/TestCase/Pdf/Engine/WkHtmlToPdfEngineTest.php index 71b45617..6a4f42d5 100644 --- a/tests/TestCase/Pdf/Engine/WkHtmlToPdfEngineTest.php +++ b/tests/TestCase/Pdf/Engine/WkHtmlToPdfEngineTest.php @@ -88,6 +88,86 @@ public function testGetCommand() $result = $method->invokeArgs($Pdf->engine(), []); $expected = "wkhtmltopdf --quiet --print-media-type --orientation 'portrait' --page-size 'A4' --encoding 'UTF-8' cover 'cover.html' toc - -"; $this->assertEquals($expected, $result); + + $Pdf = new CakePdf([ + 'engine' => [ + 'className' => 'CakePdf.WkHtmlToPdf', + 'options' => [ + 'encoding' => 'UTF-16', + 'title' => 'Test', + 'cover' => 'cover.html', + 'toc' => [ + 'zoom' => 5, + 'encoding' => 'ISO-8859-1', + ], + ], + ], + ]); + $result = $method->invokeArgs($Pdf->engine(), []); + $expected = "wkhtmltopdf --quiet --print-media-type --orientation 'portrait' --page-size 'A4' --encoding 'UTF-16' --title 'Test' cover 'cover.html' toc --zoom '5' --encoding 'ISO-8859-1' - -"; + $this->assertEquals($expected, $result); + + $Pdf = new CakePdf([ + 'engine' => [ + 'className' => 'CakePdf.WkHtmlToPdf', + 'options' => [ + 'cover' => [ + 'url' => 'cover.html', + 'enable-smart-shrinking' => true, + 'zoom' => 10, + ], + 'toc' => true, + ], + ], + ]); + $result = $method->invokeArgs($Pdf->engine(), []); + $expected = "wkhtmltopdf --quiet --print-media-type --orientation 'portrait' --page-size 'A4' --encoding 'UTF-8' cover 'cover.html' --enable-smart-shrinking --zoom '10' toc - -"; + $this->assertEquals($expected, $result); + + $Pdf = new CakePdf([ + 'engine' => [ + 'className' => 'CakePdf.WkHtmlToPdf', + 'options' => [ + 'zoom' => 4, + 'cover' => [ + 'url' => 'cover.html', + 'enable-smart-shrinking' => true, + 'zoom' => 10, + ], + 'toc' => [ + 'disable-dotted-lines' => true, + 'xsl-style-sheet' => 'style.xsl', + 'zoom' => 5, + 'encoding' => 'ISO-8859-1', + ], + ], + ], + ]); + $result = $method->invokeArgs($Pdf->engine(), []); + $expected = "wkhtmltopdf --quiet --print-media-type --orientation 'portrait' --page-size 'A4' --encoding 'UTF-8' --zoom '4' cover 'cover.html' --enable-smart-shrinking --zoom '10' toc --disable-dotted-lines --xsl-style-sheet 'style.xsl' --zoom '5' --encoding 'ISO-8859-1' - -"; + $this->assertEquals($expected, $result); + } + + public function testCoverUrlMissing() + { + $this->expectException(Exception::class); + $this->expectExceptionMessage('The url for the cover is missing. Use the "url" index.'); + + $class = new \ReflectionClass(WkHtmlToPdfEngine::class); + $method = $class->getMethod('_getCommand'); + $method->setAccessible(true); + $Pdf = new CakePdf([ + 'engine' => [ + 'className' => 'CakePdf.WkHtmlToPdf', + 'options' => [ + 'cover' => [ + 'enable-smart-shrinking' => true, + 'zoom' => 10, + ], + ], + ], + ]); + $method->invokeArgs($Pdf->engine(), []); } public function testGetBinaryPath() From 727862944741311c9e5c70f8e4ba13e5313d33e4 Mon Sep 17 00:00:00 2001 From: TrainZug Date: Sat, 26 Dec 2020 00:06:40 +0100 Subject: [PATCH 4/9] phpcs fix --- src/Pdf/Engine/WkHtmlToPdfEngine.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Pdf/Engine/WkHtmlToPdfEngine.php b/src/Pdf/Engine/WkHtmlToPdfEngine.php index 1ea7e2c7..5c935b3b 100644 --- a/src/Pdf/Engine/WkHtmlToPdfEngine.php +++ b/src/Pdf/Engine/WkHtmlToPdfEngine.php @@ -162,12 +162,12 @@ protected function _getCommand(): string * Created to reuse logic to parse the cover and toc options. * * @param string $key the option key name - * @param string|boolean|array $value the option value + * @param string|bool|array $value the option value * @return string part of the command */ public function parseOptions(string $key, $value): string { - $command = ""; + $command = ''; if (is_array($value)) { if ($key === 'toc') { $command .= ' toc'; @@ -175,7 +175,7 @@ public function parseOptions(string $key, $value): string $command .= $this->parseOptions($k, $v); } } elseif ($key === 'cover') { - if(!isset($value['url'])) { + if (!isset($value['url'])) { throw new Exception('The url for the cover is missing. Use the "url" index.'); } $command .= ' cover ' . escapeshellarg((string)$value['url']); From 650564d1db988a68b4862de564c47dd97fa6bd57 Mon Sep 17 00:00:00 2001 From: TrainZug Date: Sat, 26 Dec 2020 11:38:23 +0100 Subject: [PATCH 5/9] made function protected --- src/Pdf/Engine/WkHtmlToPdfEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Pdf/Engine/WkHtmlToPdfEngine.php b/src/Pdf/Engine/WkHtmlToPdfEngine.php index 5c935b3b..3265f106 100644 --- a/src/Pdf/Engine/WkHtmlToPdfEngine.php +++ b/src/Pdf/Engine/WkHtmlToPdfEngine.php @@ -165,7 +165,7 @@ protected function _getCommand(): string * @param string|bool|array $value the option value * @return string part of the command */ - public function parseOptions(string $key, $value): string + protected function parseOptions(string $key, $value): string { $command = ''; if (is_array($value)) { From 403e2081e06885c7a45b98c6185e6b0db93924a9 Mon Sep 17 00:00:00 2001 From: TrainZug Date: Sat, 26 Dec 2020 16:41:39 +0100 Subject: [PATCH 6/9] Update src/Pdf/Engine/WkHtmlToPdfEngine.php Co-authored-by: ADmad --- src/Pdf/Engine/WkHtmlToPdfEngine.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Pdf/Engine/WkHtmlToPdfEngine.php b/src/Pdf/Engine/WkHtmlToPdfEngine.php index 3265f106..15a8e87d 100644 --- a/src/Pdf/Engine/WkHtmlToPdfEngine.php +++ b/src/Pdf/Engine/WkHtmlToPdfEngine.php @@ -162,7 +162,7 @@ protected function _getCommand(): string * Created to reuse logic to parse the cover and toc options. * * @param string $key the option key name - * @param string|bool|array $value the option value + * @param string|true|array $value the option value * @return string part of the command */ protected function parseOptions(string $key, $value): string From e39127e1b785188d0ea7608cf0b7da8d4bc86d29 Mon Sep 17 00:00:00 2001 From: ADmad Date: Sat, 26 Dec 2020 22:19:57 +0530 Subject: [PATCH 7/9] Remove uneeded casting. --- src/Pdf/Engine/WkHtmlToPdfEngine.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Pdf/Engine/WkHtmlToPdfEngine.php b/src/Pdf/Engine/WkHtmlToPdfEngine.php index 15a8e87d..163bc710 100644 --- a/src/Pdf/Engine/WkHtmlToPdfEngine.php +++ b/src/Pdf/Engine/WkHtmlToPdfEngine.php @@ -196,9 +196,9 @@ protected function parseOptions(string $key, $value): string } } else { if ($key === 'cover') { - $command .= ' cover ' . escapeshellarg((string)$value); + $command .= ' cover ' . escapeshellarg($value); } else { - $command .= sprintf(' --%s %s', $key, escapeshellarg((string)$value)); + $command .= sprintf(' --%s %s', $key, escapeshellarg($value)); } } From de60e2a1531db6a70252d427544d0d1738995018 Mon Sep 17 00:00:00 2001 From: ADmad Date: Sat, 26 Dec 2020 22:25:11 +0530 Subject: [PATCH 8/9] Fix docblock and add back string casting --- src/Pdf/Engine/WkHtmlToPdfEngine.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Pdf/Engine/WkHtmlToPdfEngine.php b/src/Pdf/Engine/WkHtmlToPdfEngine.php index 163bc710..a2946406 100644 --- a/src/Pdf/Engine/WkHtmlToPdfEngine.php +++ b/src/Pdf/Engine/WkHtmlToPdfEngine.php @@ -162,7 +162,7 @@ protected function _getCommand(): string * Created to reuse logic to parse the cover and toc options. * * @param string $key the option key name - * @param string|true|array $value the option value + * @param string|true|array|float $value the option value * @return string part of the command */ protected function parseOptions(string $key, $value): string @@ -196,9 +196,9 @@ protected function parseOptions(string $key, $value): string } } else { if ($key === 'cover') { - $command .= ' cover ' . escapeshellarg($value); + $command .= ' cover ' . escapeshellarg((string)$value); } else { - $command .= sprintf(' --%s %s', $key, escapeshellarg($value)); + $command .= sprintf(' --%s %s', $key, escapeshellarg((string)$value)); } } From 85d463b9cad9e9102201b5ca5a1f90ecd51d76c6 Mon Sep 17 00:00:00 2001 From: ADmad Date: Sat, 26 Dec 2020 22:28:48 +0530 Subject: [PATCH 9/9] Update README.md --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 82ae3548..a52e796b 100644 --- a/README.md +++ b/README.md @@ -136,10 +136,16 @@ options for the relevant class. For example: Configure::write('CakePdf', [ 'engine' => [ 'className' => 'CakePdf.WkHtmlToPdf', + // Options usable depend on the engine used. 'options' => [ 'print-media-type' => false, 'outline' => true, - 'dpi' => 96 + 'dpi' => 96, + 'cover' => [ + 'url' => 'cover.html', + 'enable-smart-shrinking' => true, + ], + 'toc' => true, ], /**