diff options
Diffstat (limited to 'library/Icingadb/Hook/TabHook/HookActions.php')
-rw-r--r-- | library/Icingadb/Hook/TabHook/HookActions.php | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/library/Icingadb/Hook/TabHook/HookActions.php b/library/Icingadb/Hook/TabHook/HookActions.php new file mode 100644 index 0000000..d2801a5 --- /dev/null +++ b/library/Icingadb/Hook/TabHook/HookActions.php @@ -0,0 +1,148 @@ +<?php + +/* Icinga DB Web | (c) 2021 Icinga GmbH | GPLv2 */ + +namespace Icinga\Module\Icingadb\Hook\TabHook; + +use Exception; +use Generator; +use Icinga\Application\Hook; +use Icinga\Application\Logger; +use Icinga\Module\Icingadb\Hook\TabHook; +use ipl\Html\ValidHtml; +use ipl\Orm\Model; +use ipl\Stdlib\Str; + +/** + * Trait HookActions + */ +trait HookActions +{ + /** @var Model The object to load tabs for */ + protected $objectToLoadTabsFor; + + /** @var TabHook[] Loaded tab hooks */ + protected $tabHooks; + + /** + * Get default control elements + * + * @return ValidHtml[] + */ + abstract protected function getDefaultTabControls(): array; + + public function __call($methodName, $args) + { + if (substr($methodName, -6) === 'Action') { + $hookName = substr($methodName, 0, -6); + + $hooks = $this->loadTabHooks(); + if (isset($hooks[$hookName])) { + $this->showTabHook($hooks[$hookName]); + return; + } + } + + parent::__call($methodName, $args); + } + + /** + * Register the object for which to load additional tabs + * + * @param Model $object + * + * @return void + */ + protected function loadTabsForObject(Model $object) + { + $this->objectToLoadTabsFor = $object; + } + + /** + * Load tab hooks + * + * @return array<string, TabHook> + */ + protected function loadTabHooks(): array + { + if ($this->objectToLoadTabsFor === null) { + return []; + } elseif ($this->tabHooks !== null) { + return $this->tabHooks; + } + + $this->tabHooks = []; + foreach (Hook::all('Icingadb\\Tab') as $hook) { + /** @var TabHook $hook */ + try { + if ($hook->shouldBeShown($this->objectToLoadTabsFor)) { + $this->tabHooks[Str::camel($hook->getName())] = $hook; + } + } catch (Exception $e) { + Logger::error("Failed to load tab hook: %s\n%s", $e, $e->getTraceAsString()); + } + } + + return $this->tabHooks; + } + + /** + * Load additional tabs + * + * @return Generator<string, array{label: string, url: string}> + */ + protected function loadAdditionalTabs(): Generator + { + foreach ($this->loadTabHooks() as $hook) { + yield $hook->getName() => [ + 'label' => $hook->getLabel(), + 'url' => 'icingadb/' . $this->getRequest()->getControllerName() . '/' . $hook->getName() + ]; + } + } + + /** + * Render the given tab hook + * + * @param TabHook $hook + * + * @return void + */ + protected function showTabHook(TabHook $hook) + { + $moduleName = $hook->getModule()->getName(); + + foreach ($hook->getControls($this->objectToLoadTabsFor) as $control) { + $this->addControl($control); + } + + if (! empty($this->controls->getContent())) { + $this->controls->addAttributes([ + 'class' => ['icinga-module', 'module-' . $moduleName], + 'data-icinga-module' => $moduleName + ]); + } else { + foreach ($this->getDefaultTabControls() as $control) { + $this->addControl($control); + } + } + + foreach ($hook->getContent($this->objectToLoadTabsFor) as $content) { + $this->addContent($content); + } + + $this->content->addAttributes([ + 'class' => ['icinga-module', 'module-' . $moduleName], + 'data-icinga-module' => $moduleName + ]); + + foreach ($hook->getFooter($this->objectToLoadTabsFor) as $footer) { + $this->addFooter($footer); + } + + $this->footer->addAttributes([ + 'class' => ['icinga-module', 'module-' . $moduleName], + 'data-icinga-module' => $moduleName + ]); + } +} |