summaryrefslogtreecommitdiffstats
path: root/library/Icinga/Common
diff options
context:
space:
mode:
Diffstat (limited to 'library/Icinga/Common')
-rw-r--r--library/Icinga/Common/Database.php56
-rw-r--r--library/Icinga/Common/PdfExport.php105
2 files changed, 161 insertions, 0 deletions
diff --git a/library/Icinga/Common/Database.php b/library/Icinga/Common/Database.php
new file mode 100644
index 0000000..d54eb25
--- /dev/null
+++ b/library/Icinga/Common/Database.php
@@ -0,0 +1,56 @@
+<?php
+/* Icinga Web 2 | (c) 2020 Icinga GmbH | GPLv2+ */
+
+namespace Icinga\Common;
+
+use Icinga\Application\Config as IcingaConfig;
+use Icinga\Data\ResourceFactory;
+use ipl\Sql\Config as SqlConfig;
+use ipl\Sql\Connection;
+use LogicException;
+use PDO;
+
+/**
+ * Trait for accessing the Icinga Web database
+ */
+trait Database
+{
+ /**
+ * Get a connection to the Icinga Web database
+ *
+ * @return Connection
+ *
+ * @throws \Icinga\Exception\ConfigurationError
+ */
+ protected function getDb(): Connection
+ {
+ if (! $this->hasDb()) {
+ throw new LogicException('Please check if a db instance exists at all');
+ }
+
+ $config = new SqlConfig(ResourceFactory::getResourceConfig(
+ IcingaConfig::app()->get('global', 'config_resource')
+ ));
+ if ($config->db === 'mysql') {
+ $config->charset = 'utf8mb4';
+ }
+
+ $config->options = [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ];
+ if ($config->db === 'mysql') {
+ $config->options[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET SESSION SQL_MODE='STRICT_TRANS_TABLES"
+ . ",NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'";
+ }
+
+ return new Connection($config);
+ }
+
+ /**
+ * Check if db exists
+ *
+ * @return bool true if a database was found otherwise false
+ */
+ protected function hasDb()
+ {
+ return (bool) IcingaConfig::app()->get('global', 'config_resource');
+ }
+}
diff --git a/library/Icinga/Common/PdfExport.php b/library/Icinga/Common/PdfExport.php
new file mode 100644
index 0000000..afea9bf
--- /dev/null
+++ b/library/Icinga/Common/PdfExport.php
@@ -0,0 +1,105 @@
+<?php
+/* Icinga Web 2 | (c) 2022 Icinga GmbH | GPLv2+ */
+
+namespace Icinga\Common;
+
+use Icinga\Application\Icinga;
+use Icinga\Date\DateFormatter;
+use Icinga\Exception\ConfigurationError;
+use Icinga\Module\Pdfexport\PrintableHtmlDocument;
+use Icinga\Util\Environment;
+use Icinga\Web\Controller;
+use ipl\Html\Html;
+use ipl\Html\HtmlString;
+use ipl\Html\ValidHtml;
+use ipl\Web\Compat\CompatController;
+use ipl\Web\Url;
+
+trait PdfExport
+{
+ /** @var string The image to show in a pdf exports page header */
+ private $pdfHeaderImage = 'img/icinga-logo-big-dark.png';
+
+ /**
+ * Export the requested action to PDF and send it
+ *
+ * @return never
+ * @throws ConfigurationError If the pdfexport module is not available
+ */
+ protected function sendAsPdf()
+ {
+ if (! Icinga::app()->getModuleManager()->has('pdfexport')) {
+ throw new ConfigurationError('The pdfexport module is required for exports to PDF');
+ }
+
+ putenv('ICINGAWEB_EXPORT_FORMAT=pdf');
+ Environment::raiseMemoryLimit('512M');
+ Environment::raiseExecutionTime(300);
+
+ $time = DateFormatter::formatDateTime(time());
+ $iconPath = is_readable($this->pdfHeaderImage)
+ ? $this->pdfHeaderImage
+ : Icinga::app()->getBootstrapDirectory() . '/' . $this->pdfHeaderImage;
+ $encodedIcon = is_readable($iconPath) ? base64_encode(file_get_contents($iconPath)) : null;
+ $html = $this instanceof CompatController && ! $this->content->isEmpty()
+ ? $this->content
+ : $this->renderControllerAction();
+
+ $doc = (new PrintableHtmlDocument())
+ ->setTitle($this->view->title)
+ ->setHeader(Html::wantHtml([
+ Html::tag('span', ['class' => 'title']),
+ $encodedIcon
+ ? Html::tag('img', ['height' => 13, 'src' => 'data:image/png;base64,' . $encodedIcon])
+ : null,
+ Html::tag('time', null, $time)
+ ]))
+ ->setFooter(Html::wantHtml([
+ Html::tag('span', null, [
+ t('Page') . ' ',
+ Html::tag('span', ['class' => 'pageNumber']),
+ ' / ',
+ Html::tag('span', ['class' => 'totalPages'])
+ ]),
+ Html::tag('p', null, rawurldecode(Url::fromRequest()->setParams($this->params)))
+ ]))
+ ->addHtml($html);
+
+ if (($moduleName = $this->getRequest()->getModuleName()) !== 'default') {
+ $doc->getAttributes()->add('class', 'icinga-module module-' . $moduleName);
+ }
+
+ \Icinga\Module\Pdfexport\ProvidedHook\Pdfexport::first()->streamPdfFromHtml($doc, sprintf(
+ '%s-%s',
+ $this->view->title ?: $this->getRequest()->getActionName(),
+ $time
+ ));
+ }
+
+ /**
+ * Render the requested action
+ *
+ * @return ValidHtml
+ */
+ protected function renderControllerAction()
+ {
+ /** @var Controller $this */
+ $this->view->compact = true;
+
+ $viewRenderer = $this->getHelper('viewRenderer');
+ $viewRenderer->postDispatch();
+
+ $layoutHelper = $this->getHelper('layout');
+ $oldLayout = $layoutHelper->getLayout();
+ $layout = $layoutHelper->setLayout('inline');
+
+ $layout->content = $this->getResponse();
+ $html = $layout->render();
+
+ // Restore previous layout and reset content, to properly show errors
+ $this->getResponse()->clearBody($viewRenderer->getResponseSegment());
+ $layoutHelper->setLayout($oldLayout);
+
+ return HtmlString::create($html);
+ }
+}