diff options
Diffstat (limited to 'application')
-rw-r--r-- | application/clicommands/ScheduleCommand.php | 24 | ||||
-rw-r--r-- | application/controllers/ConfigController.php | 41 | ||||
-rw-r--r-- | application/controllers/PlugController.php.disabled | 72 | ||||
-rw-r--r-- | application/controllers/ReportController.php | 208 | ||||
-rw-r--r-- | application/controllers/ReportController.php.modal | 126 | ||||
-rw-r--r-- | application/controllers/ReportsController.php | 104 | ||||
-rw-r--r-- | application/controllers/TemplateController.php | 89 | ||||
-rw-r--r-- | application/controllers/TemplatesController.php | 106 | ||||
-rw-r--r-- | application/controllers/TestController.php | 47 | ||||
-rw-r--r-- | application/controllers/TimeframeController.php | 47 | ||||
-rw-r--r-- | application/controllers/TimeframesController.php | 103 | ||||
-rw-r--r-- | application/forms/ConfigureMailForm.php | 23 | ||||
-rw-r--r-- | application/forms/SelectBackendForm.php | 35 | ||||
-rw-r--r-- | application/views/scripts/config/backend.phtml | 6 | ||||
-rw-r--r-- | application/views/scripts/config/mail.phtml | 6 |
15 files changed, 1037 insertions, 0 deletions
diff --git a/application/clicommands/ScheduleCommand.php b/application/clicommands/ScheduleCommand.php new file mode 100644 index 0000000..e554138 --- /dev/null +++ b/application/clicommands/ScheduleCommand.php @@ -0,0 +1,24 @@ +<?php +// Icinga Reporting | (c) 2018 Icinga GmbH | GPLv2 + +namespace Icinga\Module\Reporting\Clicommands; + +use Icinga\Module\Reporting\Cli\Command; +use Icinga\Module\Reporting\Scheduler; + +class ScheduleCommand extends Command +{ + /** + * Run all configured reports based on their schedule + * + * USAGE: + * + * icingacli reporting schedule run + */ + public function runAction() + { + $scheduler = new Scheduler($this->getDb()); + + $scheduler->run(); + } +} 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 @@ +<?php +// Icinga Reporting | (c) 2018 Icinga GmbH | GPLv2 + +namespace Icinga\Module\Reporting\Controllers; + +use Icinga\Application\Config; +use Icinga\Module\Reporting\Forms\ConfigureMailForm; +use Icinga\Module\Reporting\Forms\SelectBackendForm; +use Icinga\Web\Controller; + +class ConfigController extends Controller +{ + public function init() + { + $this->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 @@ +<?php + +namespace Icinga\Module\Reporting\Controllers; + +use GuzzleHttp\Psr7\ServerRequest; +use Icinga\Module\Reporting\Hook\ReportHook; +use Icinga\Module\Reporting\Web\Forms\ReportForm; +use Icinga\Module\Reporting\Web\Controller; +use Icinga\Web\Hook; +use Icinga\Web\Url; +use ipl\Html\Html; + +class PlugController extends Controller +{ + public function indexAction() + { + $moduleToShow = strtolower($this->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 @@ +<?php +// Icinga Reporting | (c) 2018 Icinga GmbH | GPLv2 + +namespace Icinga\Module\Reporting\Controllers; + +use GuzzleHttp\Psr7\ServerRequest; +use Icinga\Application\Hook; +use Icinga\Module\Pdfexport\ProvidedHook\Pdfexport; +use Icinga\Module\Reporting\Database; +use Icinga\Module\Reporting\Report; +use Icinga\Module\Reporting\Web\Controller; +use Icinga\Module\Reporting\Web\Forms\ReportForm; +use Icinga\Module\Reporting\Web\Forms\ScheduleForm; +use Icinga\Module\Reporting\Web\Forms\SendForm; +use Icinga\Module\Reporting\Web\Widget\CompatDropdown; +use ipl\Html\Error; +use ipl\Web\Url; +use ipl\Web\Widget\ActionBar; +use Icinga\Util\Environment; + +class ReportController extends Controller +{ + use Database; + + /** @var Report */ + protected $report; + + public function init() + { + $this->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 @@ +<?php + +namespace Icinga\Module\Reporting\Controllers; + +use GuzzleHttp\Psr7\ServerRequest; +use Icinga\Module\Reporting\Database; +use Icinga\Module\Reporting\Report; +use Icinga\Module\Reporting\Web\Controller; +use Icinga\Module\Reporting\Web\Forms\ReportForm; +use Icinga\Module\Reporting\Web\Forms\ScheduleForm; +use Icinga\Module\Reporting\Web\Forms\SendForm; +use ipl\Web\Widget\ModalToggle; +use ipl\Web\Widget\Modal; +use reportingipl\Web\Url; +use reportingipl\Web\Widget\ActionBar; +use reportingipl\Web\Widget\DropdownLink; + +class ReportController extends Controller +{ + use Database; + + /** @var Report */ + protected $report; + + public function init() + { + $this->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 @@ +<?php +// Icinga Reporting | (c) 2018 Icinga GmbH | GPLv2 + +namespace Icinga\Module\Reporting\Controllers; + +use GuzzleHttp\Psr7\ServerRequest; +use Icinga\Module\Reporting\Database; +use Icinga\Module\Reporting\Web\Controller; +use Icinga\Module\Reporting\Web\Forms\ReportForm; +use Icinga\Module\Reporting\Web\ReportsTimeframesAndTemplatesTabs; +use ipl\Html\Html; +use ipl\Sql\Select; +use ipl\Web\Url; +use ipl\Web\Widget\ButtonLink; +use ipl\Web\Widget\Icon; +use ipl\Web\Widget\Link; + +class ReportsController extends Controller +{ + use Database; + use ReportsTimeframesAndTemplatesTabs; + + public function indexAction() + { + $this->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 @@ +<?php +// Icinga Reporting | (c) 2019 Icinga GmbH | GPLv2 + +namespace Icinga\Module\Reporting\Controllers; + +use DateTime; +use GuzzleHttp\Psr7\ServerRequest; +use Icinga\Module\Reporting\Database; +use Icinga\Module\Reporting\Web\Controller; +use Icinga\Module\Reporting\Web\Forms\TemplateForm; +use Icinga\Module\Reporting\Web\Widget\Template; +use ipl\Sql\Select; + +class TemplateController extends Controller +{ + use Database; + + public function indexAction() + { + $this->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 @@ +<?php +// Icinga Reporting | (c) 2019 Icinga GmbH | GPLv2 + +namespace Icinga\Module\Reporting\Controllers; + +use GuzzleHttp\Psr7\ServerRequest; +use Icinga\Module\Reporting\Database; +use Icinga\Module\Reporting\Web\Controller; +use Icinga\Module\Reporting\Web\Forms\TemplateForm; +use Icinga\Module\Reporting\Web\ReportsTimeframesAndTemplatesTabs; +use ipl\Html\Html; +use ipl\Sql\Select; +use ipl\Web\Url; +use ipl\Web\Widget\ButtonLink; +use ipl\Web\Widget\Link; + +class TemplatesController extends Controller +{ + use Database; + use ReportsTimeframesAndTemplatesTabs; + + public function indexAction() + { + $this->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 @@ +<?php +// Icinga Reporting | (c) 2018 Icinga GmbH | GPLv2 + +namespace Icinga\Module\Reporting\Controllers; + +use Icinga\Module\Reporting\Database; +use Icinga\Module\Reporting\Timeframe; +use Icinga\Module\Reporting\Web\Controller; +use ipl\Html\Table; +use ipl\Sql\Select; + +class TestController extends Controller +{ + use Database; + + public function timeframesAction() + { + $select = (new Select()) + ->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 @@ +<?php +// Icinga Reporting | (c) 2019 Icinga GmbH | GPLv2 + +namespace Icinga\Module\Reporting\Controllers; + +use GuzzleHttp\Psr7\ServerRequest; +use Icinga\Module\Reporting\Database; +use Icinga\Module\Reporting\Timeframe; +use Icinga\Module\Reporting\Web\Controller; +use Icinga\Module\Reporting\Web\Forms\TimeframeForm; + +class TimeframeController extends Controller +{ + use Database; + + /** @var Timeframe */ + protected $timeframe; + + public function init() + { + $this->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 @@ +<?php +// Icinga Reporting | (c) 2019 Icinga GmbH | GPLv2 + +namespace Icinga\Module\Reporting\Controllers; + +use GuzzleHttp\Psr7\ServerRequest; +use Icinga\Module\Reporting\Database; +use Icinga\Module\Reporting\Web\Controller; +use Icinga\Module\Reporting\Web\Forms\TimeframeForm; +use Icinga\Module\Reporting\Web\ReportsTimeframesAndTemplatesTabs; +use ipl\Html\Html; +use ipl\Sql\Select; +use ipl\Web\Url; +use ipl\Web\Widget\ButtonLink; +use ipl\Web\Widget\Link; + +class TimeframesController extends Controller +{ + use Database; + use ReportsTimeframesAndTemplatesTabs; + + public function indexAction() + { + $this->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); + } +} diff --git a/application/forms/ConfigureMailForm.php b/application/forms/ConfigureMailForm.php new file mode 100644 index 0000000..c27c934 --- /dev/null +++ b/application/forms/ConfigureMailForm.php @@ -0,0 +1,23 @@ +<?php +// Icinga Reporting | (c) 2019 Icinga GmbH | GPLv2 + +namespace Icinga\Module\Reporting\Forms; + +use Icinga\Forms\ConfigForm; + +class ConfigureMailForm extends ConfigForm +{ + public function init() + { + $this->setName('reporting_mail'); + $this->setSubmitLabel($this->translate('Save Changes')); + } + + public function createElements(array $formData) + { + $this->addElement('text', 'mail_from', [ + 'label' => $this->translate('From'), + 'placeholder' => 'reporting@icinga' + ]); + } +} diff --git a/application/forms/SelectBackendForm.php b/application/forms/SelectBackendForm.php new file mode 100644 index 0000000..4ba9610 --- /dev/null +++ b/application/forms/SelectBackendForm.php @@ -0,0 +1,35 @@ +<?php +// Icinga Reporting | (c) 2018 Icinga GmbH | GPLv2 + +namespace Icinga\Module\Reporting\Forms; + +use Icinga\Data\ResourceFactory; +use Icinga\Forms\ConfigForm; + +class SelectBackendForm extends ConfigForm +{ + public function init() + { + $this->setName('reporting_backend'); + $this->setSubmitLabel($this->translate('Save Changes')); + } + + public function createElements(array $formData) + { + $dbResources = ResourceFactory::getResourceConfigs('db')->keys(); + $options = array_combine($dbResources, $dbResources); + + $default = null; + if (isset($options['reporting'])) { + $default = 'reporting'; + } + + $this->addElement('select', 'backend_resource', [ + 'label' => $this->translate('Database'), + 'description' => $this->translate('Database resource'), + 'multiOptions' => $options, + 'value' => $default, + 'required' => true + ]); + } +} diff --git a/application/views/scripts/config/backend.phtml b/application/views/scripts/config/backend.phtml new file mode 100644 index 0000000..2574402 --- /dev/null +++ b/application/views/scripts/config/backend.phtml @@ -0,0 +1,6 @@ +<div class="controls"> + <?= /** @var \Icinga\Web\Widget\Tabs $tabs */ $tabs ?> +</div> +<div class="content"> + <?= /** @var \Icinga\Module\Reporting\Forms\SelectBackendForm $form */ $form ?> +</div> diff --git a/application/views/scripts/config/mail.phtml b/application/views/scripts/config/mail.phtml new file mode 100644 index 0000000..d647a82 --- /dev/null +++ b/application/views/scripts/config/mail.phtml @@ -0,0 +1,6 @@ +<div class="controls"> + <?= /** @var \Icinga\Web\Widget\Tabs $tabs */ $tabs ?> +</div> +<div class="content"> + <?= /** @var \Icinga\Module\Reporting\Forms\ConfigureMailForm $form */ $form ?> +</div> |