Skip to content

Commit 21c0de1

Browse files
authored
Merge pull request #305 from TrainZug/master
cover and toc option for wkhtmltopdf engine
2 parents e236692 + 85d463b commit 21c0de1

File tree

3 files changed

+149
-9
lines changed

3 files changed

+149
-9
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,16 @@ options for the relevant class. For example:
136136
Configure::write('CakePdf', [
137137
'engine' => [
138138
'className' => 'CakePdf.WkHtmlToPdf',
139+
// Options usable depend on the engine used.
139140
'options' => [
140141
'print-media-type' => false,
141142
'outline' => true,
142-
'dpi' => 96
143+
'dpi' => 96,
144+
'cover' => [
145+
'url' => 'cover.html',
146+
'enable-smart-shrinking' => true,
147+
],
148+
'toc' => true,
143149
],
144150

145151
/**

src/Pdf/Engine/WkHtmlToPdfEngine.php

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -132,15 +132,8 @@ protected function _getCommand(): string
132132
foreach ($options as $key => $value) {
133133
if (empty($value)) {
134134
continue;
135-
} elseif (is_array($value)) {
136-
foreach ($value as $k => $v) {
137-
$command .= sprintf(' --%s %s %s', $key, escapeshellarg($k), escapeshellarg((string)$v));
138-
}
139-
} elseif ($value === true) {
140-
$command .= ' --' . $key;
141-
} else {
142-
$command .= sprintf(' --%s %s', $key, escapeshellarg((string)$value));
143135
}
136+
$command .= $this->parseOptions($key, $value);
144137
}
145138
$footer = $this->_Pdf->footer();
146139
foreach ($footer as $location => $text) {
@@ -164,6 +157,54 @@ protected function _getCommand(): string
164157
return $command;
165158
}
166159

160+
/**
161+
* Parses a value of options to create a part of the command.
162+
* Created to reuse logic to parse the cover and toc options.
163+
*
164+
* @param string $key the option key name
165+
* @param string|true|array|float $value the option value
166+
* @return string part of the command
167+
*/
168+
protected function parseOptions(string $key, $value): string
169+
{
170+
$command = '';
171+
if (is_array($value)) {
172+
if ($key === 'toc') {
173+
$command .= ' toc';
174+
foreach ($value as $k => $v) {
175+
$command .= $this->parseOptions($k, $v);
176+
}
177+
} elseif ($key === 'cover') {
178+
if (!isset($value['url'])) {
179+
throw new Exception('The url for the cover is missing. Use the "url" index.');
180+
}
181+
$command .= ' cover ' . escapeshellarg((string)$value['url']);
182+
unset($value['url']);
183+
foreach ($value as $k => $v) {
184+
$command .= $this->parseOptions($k, $v);
185+
}
186+
} else {
187+
foreach ($value as $k => $v) {
188+
$command .= sprintf(' --%s %s %s', $key, escapeshellarg($k), escapeshellarg((string)$v));
189+
}
190+
}
191+
} elseif ($value === true) {
192+
if ($key === 'toc') {
193+
$command .= ' toc';
194+
} else {
195+
$command .= ' --' . $key;
196+
}
197+
} else {
198+
if ($key === 'cover') {
199+
$command .= ' cover ' . escapeshellarg((string)$value);
200+
} else {
201+
$command .= sprintf(' --%s %s', $key, escapeshellarg((string)$value));
202+
}
203+
}
204+
205+
return $command;
206+
}
207+
167208
/**
168209
* Get path to wkhtmltopdf binary.
169210
*

tests/TestCase/Pdf/Engine/WkHtmlToPdfEngineTest.php

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,99 @@ public function testGetCommand()
7575
$result = $method->invokeArgs($Pdf->engine(), []);
7676
$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' - -";
7777
$this->assertEquals($expected, $result);
78+
79+
$Pdf = new CakePdf([
80+
'engine' => [
81+
'className' => 'CakePdf.WkHtmlToPdf',
82+
'options' => [
83+
'cover' => 'cover.html',
84+
'toc' => true,
85+
],
86+
],
87+
]);
88+
$result = $method->invokeArgs($Pdf->engine(), []);
89+
$expected = "wkhtmltopdf --quiet --print-media-type --orientation 'portrait' --page-size 'A4' --encoding 'UTF-8' cover 'cover.html' toc - -";
90+
$this->assertEquals($expected, $result);
91+
92+
$Pdf = new CakePdf([
93+
'engine' => [
94+
'className' => 'CakePdf.WkHtmlToPdf',
95+
'options' => [
96+
'encoding' => 'UTF-16',
97+
'title' => 'Test',
98+
'cover' => 'cover.html',
99+
'toc' => [
100+
'zoom' => 5,
101+
'encoding' => 'ISO-8859-1',
102+
],
103+
],
104+
],
105+
]);
106+
$result = $method->invokeArgs($Pdf->engine(), []);
107+
$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' - -";
108+
$this->assertEquals($expected, $result);
109+
110+
$Pdf = new CakePdf([
111+
'engine' => [
112+
'className' => 'CakePdf.WkHtmlToPdf',
113+
'options' => [
114+
'cover' => [
115+
'url' => 'cover.html',
116+
'enable-smart-shrinking' => true,
117+
'zoom' => 10,
118+
],
119+
'toc' => true,
120+
],
121+
],
122+
]);
123+
$result = $method->invokeArgs($Pdf->engine(), []);
124+
$expected = "wkhtmltopdf --quiet --print-media-type --orientation 'portrait' --page-size 'A4' --encoding 'UTF-8' cover 'cover.html' --enable-smart-shrinking --zoom '10' toc - -";
125+
$this->assertEquals($expected, $result);
126+
127+
$Pdf = new CakePdf([
128+
'engine' => [
129+
'className' => 'CakePdf.WkHtmlToPdf',
130+
'options' => [
131+
'zoom' => 4,
132+
'cover' => [
133+
'url' => 'cover.html',
134+
'enable-smart-shrinking' => true,
135+
'zoom' => 10,
136+
],
137+
'toc' => [
138+
'disable-dotted-lines' => true,
139+
'xsl-style-sheet' => 'style.xsl',
140+
'zoom' => 5,
141+
'encoding' => 'ISO-8859-1',
142+
],
143+
],
144+
],
145+
]);
146+
$result = $method->invokeArgs($Pdf->engine(), []);
147+
$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' - -";
148+
$this->assertEquals($expected, $result);
149+
}
150+
151+
public function testCoverUrlMissing()
152+
{
153+
$this->expectException(Exception::class);
154+
$this->expectExceptionMessage('The url for the cover is missing. Use the "url" index.');
155+
156+
$class = new \ReflectionClass(WkHtmlToPdfEngine::class);
157+
$method = $class->getMethod('_getCommand');
158+
$method->setAccessible(true);
159+
$Pdf = new CakePdf([
160+
'engine' => [
161+
'className' => 'CakePdf.WkHtmlToPdf',
162+
'options' => [
163+
'cover' => [
164+
'enable-smart-shrinking' => true,
165+
'zoom' => 10,
166+
],
167+
],
168+
],
169+
]);
170+
$method->invokeArgs($Pdf->engine(), []);
78171
}
79172

80173
public function testGetBinaryPath()

0 commit comments

Comments
 (0)