From 978a1651bac3faf5e91ddba327bf39aeb6a4cb63 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 14 Apr 2024 15:28:59 +0200 Subject: Adding upstream version 0.10.0. Signed-off-by: Daniel Baumann --- application/controllers/ConfigController.php | 41 ++++ .../controllers/PlugController.php.disabled | 72 +++++++ application/controllers/ReportController.php | 208 +++++++++++++++++++++ application/controllers/ReportController.php.modal | 126 +++++++++++++ application/controllers/ReportsController.php | 104 +++++++++++ application/controllers/TemplateController.php | 89 +++++++++ application/controllers/TemplatesController.php | 106 +++++++++++ application/controllers/TestController.php | 47 +++++ application/controllers/TimeframeController.php | 47 +++++ application/controllers/TimeframesController.php | 103 ++++++++++ 10 files changed, 943 insertions(+) create mode 100644 application/controllers/ConfigController.php create mode 100644 application/controllers/PlugController.php.disabled create mode 100644 application/controllers/ReportController.php create mode 100644 application/controllers/ReportController.php.modal create mode 100644 application/controllers/ReportsController.php create mode 100644 application/controllers/TemplateController.php create mode 100644 application/controllers/TemplatesController.php create mode 100644 application/controllers/TestController.php create mode 100644 application/controllers/TimeframeController.php create mode 100644 application/controllers/TimeframesController.php (limited to 'application/controllers') diff --git a/application/controllers/ConfigController.php b/application/controllers/ConfigController.php new file mode 100644 index 0000000..30fcc67 --- /dev/null +++ b/application/controllers/ConfigController.php @@ -0,0 +1,41 @@ +assertPermission('config/modules'); + + parent::init(); + } + + public function backendAction() + { + $form = (new SelectBackendForm()) + ->setIniConfig(Config::module('reporting')); + + $form->handleRequest(); + + $this->view->tabs = $this->Module()->getConfigTabs()->activate('backend'); + $this->view->form = $form; + } + + public function mailAction() + { + $form = (new ConfigureMailForm()) + ->setIniConfig(Config::module('reporting')); + + $form->handleRequest(); + + $this->view->tabs = $this->Module()->getConfigTabs()->activate('mail'); + $this->view->form = $form; + } +} diff --git a/application/controllers/PlugController.php.disabled b/application/controllers/PlugController.php.disabled new file mode 100644 index 0000000..a2c6453 --- /dev/null +++ b/application/controllers/PlugController.php.disabled @@ -0,0 +1,72 @@ +params->get('module', 'reporting')); + + $reportsByModule = []; + + foreach (ReportHook::getReports() as $class => $report) { + $moduleName = $report->getModuleName(); + + if (! isset($reportsByModule[$moduleName])) { + $reportsByModule[$moduleName] = []; + } + + $reportsByModule[$moduleName][$class] = $report; + } + + $editor = Html::tag('div', ['class' => 'editor']); + + $nav = []; + + $cards = []; + + foreach ($reportsByModule as $moduleName => $reports) { + $link = Html::tag('a', ['href' => Url::fromRequest(['module' => $moduleName])], $moduleName); + + $nav[] = $link; + + if ($moduleName !== $moduleToShow) { + continue; + } + + $link->getAttributes()->add('class', 'active'); + + foreach ($reports as $report) { + $cards[] = Html::tag( + 'div', + ['class' => 'card'], + [ + Html::tag('div', ['class' => 'card-top'], $report->getPreview()), + Html::tag( + 'div', + ['class' => 'card-content'], + Html::tag('h5', ['class' => 'card-title'], $report->getName()), + Html::tag('p', ['class' => 'card-text'], $report->getDescription()) + ) + ] + ); + } + } + + $editor->add(Html::tag('div', ['class' => 'editor-nav'], $nav)); + $editor->add(Html::tag('div', ['class' => 'editor-content'], $cards)); + + $this->addContent($editor); + + $this->addContent(Html::tag('a', ['href' => 'plug', 'class' => 'modal-toggle', 'data-base-target' => 'modal-container'], 'Modal')); + } +} diff --git a/application/controllers/ReportController.php b/application/controllers/ReportController.php new file mode 100644 index 0000000..090c759 --- /dev/null +++ b/application/controllers/ReportController.php @@ -0,0 +1,208 @@ +report = Report::fromDb($this->params->getRequired('id')); + } + + public function indexAction() + { + $this->addTitleTab($this->report->getName()); + + $this->addControl($this->assembleActions()); + + Environment::raiseExecutionTime(); + Environment::raiseMemoryLimit(); + + try { + $this->addContent($this->report->toHtml()); + } catch (\Exception $e) { + $this->addContent(Error::show($e)); + } + } + + public function editAction() + { + $this->assertPermission('reporting/reports'); + $this->addTitleTab('Edit Report'); + + $values = [ + 'name' => $this->report->getName(), + // TODO(el): Must cast to string here because ipl/html does not + // support integer return values for attribute callbacks + 'timeframe' => (string) $this->report->getTimeframe()->getId(), + ]; + + $reportlet = $this->report->getReportlets()[0]; + + $values['reportlet'] = $reportlet->getClass(); + + foreach ($reportlet->getConfig() as $name => $value) { + $values[$name] = $value; + } + + $form = new ReportForm(); + $form->setId($this->report->getId()); + $form->populate($values); + $form->handleRequest(ServerRequest::fromGlobals()); + + $this->redirectForm($form, 'reporting/reports'); + + $this->addContent($form); + } + + public function sendAction() + { + $this->addTitleTab('Send Report'); + + Environment::raiseExecutionTime(); + Environment::raiseMemoryLimit(); + + $form = new SendForm(); + $form + ->setReport($this->report) + ->handleRequest(ServerRequest::fromGlobals()); + + $this->redirectForm($form, "reporting/report?id={$this->report->getId()}"); + + $this->addContent($form); + } + + public function scheduleAction() + { + $this->assertPermission('reporting/schedules'); + $this->addTitleTab('Schedule'); + + $form = new ScheduleForm(); + $form + ->setReport($this->report) + ->handleRequest(ServerRequest::fromGlobals()); + + $this->redirectForm($form, "reporting/report?id={$this->report->getId()}"); + + $this->addContent($form); + } + + public function downloadAction() + { + $type = $this->params->getRequired('type'); + + Environment::raiseExecutionTime(); + Environment::raiseMemoryLimit(); + + $name = sprintf( + '%s (%s) %s', + $this->report->getName(), + $this->report->getTimeframe()->getName(), + date('Y-m-d H:i') + ); + + switch ($type) { + case 'pdf': + /** @var Hook\PdfexportHook */ + Pdfexport::first()->streamPdfFromHtml($this->report->toPdf(), $name); + exit; + case 'csv': + $response = $this->getResponse(); + $response + ->setHeader('Content-Type', 'text/csv') + ->setHeader('Cache-Control', 'no-store') + ->setHeader( + 'Content-Disposition', + 'attachment; filename=' . $name . '.csv' + ) + ->appendBody($this->report->toCsv()) + ->sendResponse(); + exit; + case 'json': + $response = $this->getResponse(); + $response + ->setHeader('Content-Type', 'application/json') + ->setHeader('Cache-Control', 'no-store') + ->setHeader( + 'Content-Disposition', + 'inline; filename=' . $name . '.json' + ) + ->appendBody($this->report->toJson()) + ->sendResponse(); + exit; + } + } + + protected function assembleActions() + { + $reportId = $this->report->getId(); + + $download = (new CompatDropdown('Download')) + ->addLink( + 'PDF', + Url::fromPath('reporting/report/download?type=pdf', ['id' => $reportId]), + null, + ['target' => '_blank'] + ); + + if ($this->report->providesData()) { + $download->addLink( + 'CSV', + Url::fromPath('reporting/report/download?type=csv', ['id' => $reportId]), + null, + ['target' => '_blank'] + ); + $download->addLink( + 'JSON', + Url::fromPath('reporting/report/download?type=json', ['id' => $reportId]), + null, + ['target' => '_blank'] + ); + } + + $actions = new ActionBar(); + + if ($this->hasPermission('reporting/reports')) { + $actions->addLink( + 'Modify', + Url::fromPath('reporting/report/edit', ['id' => $reportId]), + 'edit' + ); + } + + if ($this->hasPermission('reporting/schedules')) { + $actions->addLink( + 'Schedule', + Url::fromPath('reporting/report/schedule', ['id' => $reportId]), + 'calendar-empty' + ); + } + + $actions + ->add($download) + ->addLink('Send', Url::fromPath('reporting/report/send', ['id' => $reportId]), 'forward'); + + return $actions; + } +} diff --git a/application/controllers/ReportController.php.modal b/application/controllers/ReportController.php.modal new file mode 100644 index 0000000..915bf2b --- /dev/null +++ b/application/controllers/ReportController.php.modal @@ -0,0 +1,126 @@ +report = Report::fromDb($this->params->getRequired('id')); + } + + public function indexAction() + { + $this->setTitle($this->report->getName()); + + $this->addControl($this->assembleActions()); + + $this->addContent($this->report->toHtml()); + } + + public function editAction() + { + $this->setTitle('Edit Report'); + + $values = [ + 'name' => $this->report->getName(), + 'timeframe' => $this->report->getTimeframe()->getId(), + ]; + + $reportlet = $this->report->getReportlets()[0]; + + $values['reportlet'] = $reportlet->getClass(); + + foreach ($reportlet->getConfig() as $name => $value) { + $values[$name] = $value; + } + + $form = new ReportForm(); + $form->setId($this->report->getId()); + $form->populate($values); + $form->handleRequest(ServerRequest::fromGlobals()); + + $this->redirectForm($form, 'reporting/reports'); + + $this->addContent($form); + } + + public function sendAction() + { + $this->setTitle('Send Report'); + + $form = new SendForm(); + $form + ->setReport($this->report) + ->handleRequest(ServerRequest::fromGlobals()); + + $this->redirectForm($form, "reporting/report?id={$this->report->getId()}"); + + $this->addContent(new Modal($form)); + } + + public function scheduleAction() + { + $this->setTitle('Schedule'); + + $form = new ScheduleForm(); + $form + ->setReport($this->report) + ->handleRequest(ServerRequest::fromGlobals()); + + $this->redirectForm($form, "reporting/report?id={$this->report->getId()}"); + + $this->addContent(new Modal($form)); + + $this->getResponse()->setHeader('X-Icinga-History', 'no', true); + } + + protected function assembleActions() + { + $reportId = $this->report->getId(); + + $download = (new DropdownLink('Download')) + ->addLink('PDF', Url::fromPath('reporting/report/download?type=pdf', ['id' => $reportId])); + + $send = (new DropdownLink('Send', 'forward')) + ->addLink('PDF', Url::fromPath('reporting/report/send?type=pdf', ['id' => $reportId])); + + if ($this->report->providesCsv()) { + $download->addLink('CSV', Url::fromPath('reporting/report/download?type=csv', ['id' => $reportId])); + $send->addLink('CSV', Url::fromPath('reporting/report/send?type=csv', ['id' => $reportId])); + } + + if ($this->report->providesJson()) { + $download->addLink('JSON', Url::fromPath('reporting/report/download?type=json', ['id' => $reportId])); + $send->addLink('JSON', Url::fromPath('reporting/report/send?type=json', ['id' => $reportId])); + } + + $actions = new ActionBar(); + + $actions + ->addLink('Modify', Url::fromPath('reporting/report/edit', ['id' => $reportId]), 'edit') + ->add(new ModalToggle('Schedule', Url::fromPath('reporting/report/schedule', ['id' => $reportId]), 'calendar-empty')) + ->add($download) + ->addLink('Send', Url::fromPath('reporting/report/send', ['id' => $reportId]), 'forward'); + + return $actions; + } +} diff --git a/application/controllers/ReportsController.php b/application/controllers/ReportsController.php new file mode 100644 index 0000000..7971897 --- /dev/null +++ b/application/controllers/ReportsController.php @@ -0,0 +1,104 @@ +createTabs()->activate('reports'); + + if ($this->hasPermission('reporting/reports')) { + $this->addControl(new ButtonLink( + $this->translate('New Report'), + Url::fromPath('reporting/reports/new'), + 'plus' + )); + } + + $tableRows = []; + + $select = (new Select()) + ->from('report r') + ->columns(['r.*', 'timeframe' => 't.name']) + ->join('timeframe t', 'r.timeframe_id = t.id') + ->orderBy('r.mtime', SORT_DESC); + + foreach ($this->getDb()->select($select) as $report) { + $url = Url::fromPath('reporting/report', ['id' => $report->id])->getAbsoluteUrl('&'); + + $tableRows[] = Html::tag('tr', ['href' => $url], [ + Html::tag('td', null, $report->name), + Html::tag('td', null, $report->author), + Html::tag('td', null, $report->timeframe), + Html::tag('td', null, date('Y-m-d H:i', $report->ctime / 1000)), + Html::tag('td', null, date('Y-m-d H:i', $report->mtime / 1000)), + Html::tag('td', ['class' => 'icon-col'], [ + new Link( + new Icon('edit'), + Url::fromPath('reporting/report/edit', ['id' => $report->id]) + ) + ]) + ]); + } + + if (! empty($tableRows)) { + $table = Html::tag( + 'table', + ['class' => 'common-table table-row-selectable', 'data-base-target' => '_next'], + [ + Html::tag( + 'thead', + null, + Html::tag( + 'tr', + null, + [ + Html::tag('th', null, 'Name'), + Html::tag('th', null, 'Author'), + Html::tag('th', null, 'Timeframe'), + Html::tag('th', null, 'Date Created'), + Html::tag('th', null, 'Date Modified'), + Html::tag('th') + ] + ) + ), + Html::tag('tbody', null, $tableRows) + ] + ); + + $this->addContent($table); + } else { + $this->addContent(Html::tag('p', null, 'No reports created yet.')); + } + } + + public function newAction() + { + $this->assertPermission('reporting/reports'); + $this->addTitleTab($this->translate('New Report')); + + $form = new ReportForm(); + $form->handleRequest(ServerRequest::fromGlobals()); + + $this->redirectForm($form, 'reporting/reports'); + + $this->addContent($form); + } +} diff --git a/application/controllers/TemplateController.php b/application/controllers/TemplateController.php new file mode 100644 index 0000000..bb37b3c --- /dev/null +++ b/application/controllers/TemplateController.php @@ -0,0 +1,89 @@ +createTabs()->activate('preview'); + + $template = Template::fromDb($this->params->getRequired('id')); + + if ($template === null) { + throw new \Exception('Template not found'); + } + + $template + ->setMacros([ + 'date' => (new DateTime())->format('jS M, Y'), + 'time_frame' => 'Time Frame', + 'time_frame_absolute' => 'Time Frame (absolute)', + 'title' => 'Icinga Report Preview' + ]) + ->setPreview(true); + + $this->addContent($template); + } + + public function editAction() + { + $this->assertPermission('reporting/templates'); + + $this->createTabs()->activate('edit'); + + $select = (new Select()) + ->from('template') + ->columns(['id', 'settings']) + ->where(['id = ?' => $this->params->getRequired('id')]); + + $template = $this->getDb()->select($select)->fetch(); + + if ($template === false) { + throw new \Exception('Template not found'); + } + + $template->settings = json_decode($template->settings, true); + + $form = (new TemplateForm()) + ->setTemplate($template); + + $form->handleRequest(ServerRequest::fromGlobals()); + + $this->redirectForm($form, 'reporting/templates'); + + $this->addContent($form); + } + + protected function createTabs() + { + $tabs = $this->getTabs(); + + if ($this->hasPermission('reporting/templates')) { + $tabs->add('edit', [ + 'title' => $this->translate('Edit template'), + 'label' => $this->translate('Edit Template'), + 'url' => 'reporting/template/edit?id=' . $this->params->getRequired('id') + ]); + } + + $tabs->add('preview', [ + 'title' => $this->translate('Preview template'), + 'label' => $this->translate('Preview'), + 'url' => 'reporting/template?id=' . $this->params->getRequired('id') + ]); + + return $tabs; + } +} diff --git a/application/controllers/TemplatesController.php b/application/controllers/TemplatesController.php new file mode 100644 index 0000000..91a82b1 --- /dev/null +++ b/application/controllers/TemplatesController.php @@ -0,0 +1,106 @@ +createTabs()->activate('templates'); + + $canManage = $this->hasPermission('reporting/templates'); + + if ($canManage) { + $this->addControl(new ButtonLink( + $this->translate('New Template'), + Url::fromPath('reporting/templates/new'), + 'plus' + )); + } + + $select = (new Select()) + ->from('template') + ->columns(['id', 'name', 'author', 'ctime', 'mtime']) + ->orderBy('mtime', SORT_DESC); + + foreach ($this->getDb()->select($select) as $template) { + if ($canManage) { + // Edit URL + $subjectUrl = Url::fromPath( + 'reporting/template/edit', + ['id' => $template->id] + ); + } else { + // Preview URL + $subjectUrl = Url::fromPath( + 'reporting/template', + ['id' => $template->id] + ); + } + + $tableRows[] = Html::tag('tr', null, [ + Html::tag('td', null, new Link($template->name, $subjectUrl)), + Html::tag('td', null, $template->author), + Html::tag('td', null, date('Y-m-d H:i', $template->ctime / 1000)), + Html::tag('td', null, date('Y-m-d H:i', $template->mtime / 1000)) + ]); + } + + if (! empty($tableRows)) { + $table = Html::tag( + 'table', + ['class' => 'common-table table-row-selectable', 'data-base-target' => '_next'], + [ + Html::tag( + 'thead', + null, + Html::tag( + 'tr', + null, + [ + Html::tag('th', null, 'Name'), + Html::tag('th', null, 'Author'), + Html::tag('th', null, 'Date Created'), + Html::tag('th', null, 'Date Modified') + ] + ) + ), + Html::tag('tbody', null, $tableRows) + ] + ); + + $this->addContent($table); + } else { + $this->addContent(Html::tag('p', null, 'No templates created yet.')); + } + } + + public function newAction() + { + $this->assertPermission('reporting/templates'); + $this->addTitleTab('New Template'); + + $form = new TemplateForm(); + + $form->handleRequest(ServerRequest::fromGlobals()); + + $this->redirectForm($form, 'reporting/templates'); + + $this->addContent($form); + } +} diff --git a/application/controllers/TestController.php b/application/controllers/TestController.php new file mode 100644 index 0000000..f666085 --- /dev/null +++ b/application/controllers/TestController.php @@ -0,0 +1,47 @@ +from('timeframe') + ->columns('*'); + + $table = new Table(); + + $table->getAttributes()->add('class', 'common-table'); + + $table->getHeader()->add(Table::row(['Name', 'Title', 'Start', 'End'], null, 'th')); + + foreach ($this->getDb()->select($select) as $row) { + $timeframe = (new Timeframe()) + ->setName($row->name) + ->setTitle($row->title) + ->setStart($row->start) + ->setEnd($row->end); + + $table->getBody()->add(Table::row([ + $timeframe->getName(), + $timeframe->getTitle(), + $timeframe->getTimerange()->getStart()->format('Y-m-d H:i:s'), + $timeframe->getTimerange()->getEnd()->format('Y-m-d H:i:s') + ])); + } + + $this->addTitleTab('Timeframes'); + + $this->addContent($table); + } +} diff --git a/application/controllers/TimeframeController.php b/application/controllers/TimeframeController.php new file mode 100644 index 0000000..ca67b0b --- /dev/null +++ b/application/controllers/TimeframeController.php @@ -0,0 +1,47 @@ +timeframe = Timeframe::fromDb($this->params->getRequired('id')); + } + + public function editAction() + { + $this->assertPermission('reporting/timeframes'); + $this->addTitleTab($this->translate('Edit Time Frame')); + + $values = [ + 'name' => $this->timeframe->getName(), + 'start' => $this->timeframe->getStart(), + 'end' => $this->timeframe->getEnd() + ]; + + + $form = (new TimeframeForm()) + ->setId($this->timeframe->getId()); + + $form->populate($values); + + $form->handleRequest(ServerRequest::fromGlobals()); + + $this->redirectForm($form, 'reporting/timeframes'); + + $this->addContent($form); + } +} diff --git a/application/controllers/TimeframesController.php b/application/controllers/TimeframesController.php new file mode 100644 index 0000000..505d8d9 --- /dev/null +++ b/application/controllers/TimeframesController.php @@ -0,0 +1,103 @@ +createTabs()->activate('timeframes'); + + $canManage = $this->hasPermission('reporting/timeframes'); + + if ($canManage) { + $this->addControl(new ButtonLink( + $this->translate('New Timeframe'), + Url::fromPath('reporting/timeframes/new'), + 'plus' + )); + } + + $tableRows = []; + + $select = (new Select()) + ->from('timeframe t') + ->columns('*'); + + foreach ($this->getDb()->select($select) as $timeframe) { + $subject = $timeframe->name; + + if ($canManage) { + $subject = new Link($timeframe->name, Url::fromPath( + 'reporting/timeframe/edit', + ['id' => $timeframe->id] + )); + } + + $tableRows[] = Html::tag('tr', null, [ + Html::tag('td', null, $subject), + Html::tag('td', null, $timeframe->start), + Html::tag('td', null, $timeframe->end), + Html::tag('td', null, date('Y-m-d H:i', $timeframe->ctime / 1000)), + Html::tag('td', null, date('Y-m-d H:i', $timeframe->mtime / 1000)) + ]); + } + + if (! empty($tableRows)) { + $table = Html::tag( + 'table', + ['class' => 'common-table table-row-selectable', 'data-base-target' => '_next'], + [ + Html::tag( + 'thead', + null, + Html::tag( + 'tr', + null, + [ + Html::tag('th', null, 'Name'), + Html::tag('th', null, 'Start'), + Html::tag('th', null, 'End'), + Html::tag('th', null, 'Date Created'), + Html::tag('th', null, 'Date Modified') + ] + ) + ), + Html::tag('tbody', null, $tableRows) + ] + ); + + $this->addContent($table); + } else { + $this->addContent(Html::tag('p', null, 'No timeframes created yet.')); + } + } + + public function newAction() + { + $this->assertPermission('reporting/timeframes'); + $this->addTitleTab($this->translate('New Timeframe')); + + $form = new TimeframeForm(); + $form->handleRequest(ServerRequest::fromGlobals()); + + $this->redirectForm($form, 'reporting/timeframes'); + + $this->addContent($form); + } +} -- cgit v1.2.3