summaryrefslogtreecommitdiffstats
path: root/library/Pdfexport/ProvidedHook/Pdfexport.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Pdfexport/ProvidedHook/Pdfexport.php')
-rw-r--r--library/Pdfexport/ProvidedHook/Pdfexport.php151
1 files changed, 151 insertions, 0 deletions
diff --git a/library/Pdfexport/ProvidedHook/Pdfexport.php b/library/Pdfexport/ProvidedHook/Pdfexport.php
new file mode 100644
index 0000000..113eff0
--- /dev/null
+++ b/library/Pdfexport/ProvidedHook/Pdfexport.php
@@ -0,0 +1,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;
+ }
+}