Skip to content

Commit

Permalink
Merge pull request #305 from TrainZug/master
Browse files Browse the repository at this point in the history
cover and toc option for wkhtmltopdf engine
  • Loading branch information
ADmad authored Dec 26, 2020
2 parents e236692 + 85d463b commit 21c0de1
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 9 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
],

/**
Expand Down
57 changes: 49 additions & 8 deletions src/Pdf/Engine/WkHtmlToPdfEngine.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +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) {
$command .= ' --' . $key;
} else {
$command .= sprintf(' --%s %s', $key, escapeshellarg((string)$value));
}
$command .= $this->parseOptions($key, $value);
}
$footer = $this->_Pdf->footer();
foreach ($footer as $location => $text) {
Expand All @@ -164,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|true|array|float $value the option value
* @return string part of the command
*/
protected 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.
*
Expand Down
93 changes: 93 additions & 0 deletions tests/TestCase/Pdf/Engine/WkHtmlToPdfEngineTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,99 @@ 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);

$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()
Expand Down

0 comments on commit 21c0de1

Please sign in to comment.