1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
<?php
/* Icinga PDF Export | (c) 2018 Icinga GmbH | GPLv2 */
namespace Icinga\Module\Pdfexport\ProvidedHook;
use Exception;
use Icinga\Application\Config;
use Icinga\Application\Hook;
use Icinga\Application\Hook\PdfexportHook;
use Icinga\Application\Icinga;
use Icinga\Module\Pdfexport\HeadlessChrome;
use Icinga\Module\Pdfexport\PrintableHtmlDocument;
use iio\libmergepdf\Driver\TcpdiDriver;
use iio\libmergepdf\Merger;
class Pdfexport extends PdfexportHook
{
public static function first()
{
$pdfexport = null;
if (Hook::has('Pdfexport')) {
$pdfexport = Hook::first('Pdfexport');
if (! $pdfexport->isSupported()) {
throw new Exception(
sprintf("Can't export: %s does not support exporting PDFs", get_class($pdfexport))
);
}
}
if (! $pdfexport) {
throw new Exception("Can't export: No module found which provides PDF export");
}
return $pdfexport;
}
public static function getBinary()
{
return Config::module('pdfexport')->get('chrome', 'binary', '/usr/bin/google-chrome');
}
public static function getForceTempStorage()
{
return (bool) Config::module('pdfexport')->get('chrome', 'force_temp_storage', '0');
}
public static function getHost()
{
return Config::module('pdfexport')->get('chrome', 'host');
}
public static function getPort()
{
return Config::module('pdfexport')->get('chrome', 'port', 9222);
}
public function isSupported()
{
try {
return $this->chrome()->getVersion() >= 59;
} catch (Exception $e) {
return false;
}
}
public function htmlToPdf($html)
{
// Keep reference to the chrome object because it is using temp files which are automatically removed when
// the object is destructed
$chrome = $this->chrome();
$pdf = $chrome->fromHtml($html, static::getForceTempStorage())->toPdf();
if ($html instanceof PrintableHtmlDocument && ($coverPage = $html->getCoverPage()) !== null) {
$coverPagePdf = $chrome
->fromHtml(
(new PrintableHtmlDocument())
->add($coverPage)
->addAttributes($html->getAttributes())
->removeMargins(),
static::getForceTempStorage()
)
->toPdf();
$merger = new Merger(new TcpdiDriver());
$merger->addRaw($coverPagePdf);
$merger->addRaw($pdf);
$pdf = $merger->merge();
}
return $pdf;
}
public function streamPdfFromHtml($html, $filename)
{
$filename = basename($filename, '.pdf') . '.pdf';
// Keep reference to the chrome object because it is using temp files which are automatically removed when
// the object is destructed
$chrome = $this->chrome();
$pdf = $chrome->fromHtml($html, static::getForceTempStorage())->toPdf();
if ($html instanceof PrintableHtmlDocument && ($coverPage = $html->getCoverPage()) !== null) {
$coverPagePdf = $chrome
->fromHtml(
(new PrintableHtmlDocument())
->add($coverPage)
->addAttributes($html->getAttributes())
->removeMargins(),
static::getForceTempStorage()
)
->toPdf();
$merger = new Merger(new TcpdiDriver());
$merger->addRaw($coverPagePdf);
$merger->addRaw($pdf);
$pdf = $merger->merge();
}
Icinga::app()->getResponse()
->setHeader('Content-Type', 'application/pdf', true)
->setHeader('Content-Disposition', "inline; filename=\"$filename\"", true)
->setBody($pdf)
->sendResponse();
exit;
}
/**
* Create an instance of HeadlessChrome from configuration
*
* @return HeadlessChrome
*/
protected function chrome()
{
$chrome = new HeadlessChrome();
$chrome->setBinary(static::getBinary());
if (($host = static::getHost()) !== null) {
$chrome->setRemote($host, static::getPort());
}
return $chrome;
}
}
|