diff --git a/application/controllers/DashboardController.php b/application/controllers/DashboardController.php index e1e9e14c2..94a6b383c 100644 --- a/application/controllers/DashboardController.php +++ b/application/controllers/DashboardController.php @@ -2,16 +2,17 @@ // {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}} -use Icinga\Application\Config; use Icinga\Application\Logger; -use Icinga\Exception\ConfigurationError; -use Icinga\Exception\IcingaException; -use Icinga\Exception\NotReadableError; -use Icinga\File\Ini\IniWriter; -use Icinga\Forms\Dashboard\AddUrlForm; +use Icinga\Exception\ProgrammingError; +use Icinga\Forms\ConfirmRemovalForm; +use Icinga\Forms\Dashboard\ComponentForm; +use Icinga\Web\Form; +use Icinga\Web\Notification; use Icinga\Web\Controller\ActionController; +use Icinga\Web\Request; use Icinga\Web\Url; use Icinga\Web\Widget\Dashboard; +use Icinga\Web\Widget\Tabextension\DashboardSettings; /** * Handle creation, removal and displaying of dashboards, panes and components @@ -21,92 +22,203 @@ use Icinga\Web\Widget\Dashboard; class DashboardController extends ActionController { /** - * Default configuration + * @var Dashboard; */ - const DEFAULT_CONFIG = 'dashboard/dashboard'; - - /** - * Retrieve a dashboard from the provided config - * - * @param string $config The config to read the dashboard from, or 'dashboard/dashboard' if none is given - * - * @return \Icinga\Web\Widget\Dashboard - */ - private function getDashboard($config = self::DEFAULT_CONFIG) + private $dashboard; + + public function init() { - $dashboard = new Dashboard(); - try { - $dashboardConfig = Config::app($config); - if ($dashboardConfig->isEmpty()) { - return null; - } - $dashboard->readConfig($dashboardConfig); - } catch (NotReadableError $e) { - Logger::error(new IcingaException('Cannot load dashboard configuration. An exception was thrown:', $e)); - return null; - } - return $dashboard; + $this->dashboard = new Dashboard(); + $this->dashboard->setUser($this->getRequest()->getUser()); + $this->dashboard->load(); } - /** - * Remove a component from the pane identified by the 'pane' parameter - */ - public function removecomponentAction() + public function newComponentAction() { - $pane = $this->_getParam('pane'); - $dashboard = $this->getDashboard(); - try { - $dashboard->removeComponent( - $pane, - $this->_getParam('component') - )->store(); - $this->redirectNow(Url::fromPath('dashboard', array('pane' => $pane))); - } catch (ConfigurationError $exc ) { - $this->_helper->viewRenderer('show_configuration'); - $this->view->exceptionMessage = $exc->getMessage(); - $this->view->iniConfigurationString = $dashboard->toIni(); + $form = new ComponentForm(); + $this->createTabs(); + $dashboard = $this->dashboard; + $form->setDashboard($dashboard); + if ($this->_request->getParam('url')) { + $params = $this->_request->getParams(); + $params['url'] = rawurldecode($this->_request->getParam('url')); + $form->populate($params); } + $action = $this; + $form->setOnSuccess(function (Form $form) use ($dashboard, $action) { + try { + $pane = $dashboard->getPane($form->getValue('pane')); + } catch (ProgrammingError $e) { + $pane = new Dashboard\Pane($form->getValue('pane')); + $pane->setUserWidget(); + $dashboard->addPane($pane); + } + $component = new Dashboard\Component($form->getValue('component'), $form->getValue('url'), $pane); + $component->setUserWidget(); + $pane->addComponent($component); + try { + $dashboard->write(); + } catch (\Zend_Config_Exception $e) { + $action->view->error = $e; + $action->view->config = $dashboard->createWriter(); + $action->render('error'); + return false; + } + Notification::success(t('Component created')); + return true; + }); + $form->setRedirectUrl('dashboard'); + $form->handleRequest(); + $this->view->form = $form; } - /** - * Display the form for adding new components or add the new component if submitted - */ - public function addurlAction() + public function updateComponentAction() { - $this->getTabs()->add( - 'addurl', - array( - 'title' => 'Add Dashboard URL', - 'url' => Url::fromRequest() - ) - )->activate('addurl'); - - $form = new AddUrlForm(); - $request = $this->getRequest(); - if ($request->isPost()) { - if ($form->isValid($request->getPost()) && $form->isSubmitted()) { - $dashboard = $this->getDashboard(); - $dashboard->setComponentUrl( - $form->getValue('pane'), - $form->getValue('component'), - ltrim($form->getValue('url'), '/') - ); - - $configFile = Config::app('dashboard/dashboard')->getConfigFile(); - if ($this->writeConfiguration(Config::fromArray($dashboard->toArray()), $configFile)) { - $this->redirectNow(Url::fromPath('dashboard', array('pane' => $form->getValue('pane')))); - } else { - $this->render('showConfiguration'); - return; - } - } - } else { - $form->create()->setDefault('url', htmlspecialchars_decode($request->getParam('url', ''))); + $this->createTabs(); + $dashboard = $this->dashboard; + $form = new ComponentForm(); + $form->setDashboard($dashboard); + $form->setSubmitLabel(t('Update Component')); + if (! $this->_request->getParam('pane')) { + throw new Zend_Controller_Action_Exception( + 'Missing parameter "pane"', + 400 + ); } + if (! $this->_request->getParam('component')) { + throw new Zend_Controller_Action_Exception( + 'Missing parameter "component"', + 400 + ); + } + $action = $this; + $form->setOnSuccess(function (Form $form) use ($dashboard, $action) { + try { + $pane = $dashboard->getPane($form->getValue('pane')); + } catch (ProgrammingError $e) { + $pane = new Dashboard\Pane($form->getValue('pane')); + $pane->setUserWidget(); + $dashboard->addPane($pane); + } + try { + $component = $pane->getComponent($form->getValue('component')); + $component->setUrl($form->getValue('url')); + } catch (ProgrammingError $e) { + $component = new Dashboard\Component($form->getValue('component'), $form->getValue('url'), $pane); + $pane->addComponent($component); + } + $component->setUserWidget(); + // Rename component + if ($form->getValue('org_component') && $form->getValue('org_component') !== $component->getTitle()) { + $pane->removeComponent($form->getValue('org_component')); + } + // Move + if ($form->getValue('org_pane') && $form->getValue('org_pane') !== $pane->getTitle()) { + $oldPane = $dashboard->getPane($form->getValue('org_pane')); + $oldPane->removeComponent($component->getTitle()); + } + try { + $dashboard->write(); + } catch (\Zend_Config_Exception $e) { + $action->view->error = $e; + $action->view->config = $dashboard->createWriter(); + $action->render('error'); + return false; + } + Notification::success(t('Component updated')); + return true; + }); + $form->setRedirectUrl('dashboard/settings'); + $form->handleRequest(); + $pane = $dashboard->getPane($this->getParam('pane')); + $component = $pane->getComponent($this->getParam('component')); + $form->load($component); $this->view->form = $form; } + public function removeComponentAction() + { + $form = new ConfirmRemovalForm(); + $this->createTabs(); + $dashboard = $this->dashboard; + if (! $this->_request->getParam('pane')) { + throw new Zend_Controller_Action_Exception( + 'Missing parameter "pane"', + 400 + ); + } + if (! $this->_request->getParam('component')) { + throw new Zend_Controller_Action_Exception( + 'Missing parameter "component"', + 400 + ); + } + $pane = $this->_request->getParam('pane'); + $component = $this->_request->getParam('component'); + $action = $this; + $form->setOnSuccess(function (Form $form) use ($dashboard, $component, $pane, $action) { + try { + $pane = $dashboard->getPane($pane); + $pane->removeComponent($component); + $dashboard->write(); + Notification::success(t('Component has been removed from') . ' ' . $pane->getTitle()); + return true; + } catch (\Zend_Config_Exception $e) { + $action->view->error = $e; + $action->view->config = $dashboard->createWriter(); + $action->render('error'); + return false; + } catch (ProgrammingError $e) { + Notification::error($e->getMessage()); + return false; + } + return false; + }); + $form->setRedirectUrl('dashboard/settings'); + $form->handleRequest(); + $this->view->pane = $pane; + $this->view->component = $component; + $this->view->form = $form; + } + + public function removePaneAction() + { + $form = new ConfirmRemovalForm(); + $this->createTabs(); + $dashboard = $this->dashboard; + if (! $this->_request->getParam('pane')) { + throw new Zend_Controller_Action_Exception( + 'Missing parameter "pane"', + 400 + ); + } + $pane = $this->_request->getParam('pane'); + $action = $this; + $form->setOnSuccess(function (Form $form) use ($dashboard, $pane, $action) { + try { + $pane = $dashboard->getPane($pane); + $dashboard->removePane($pane->getTitle()); + $dashboard->write(); + Notification::success(t('Pane has been removed') . ': ' . $pane->getTitle()); + return true; + } catch (\Zend_Config_Exception $e) { + $action->view->error = $e; + $action->view->config = $dashboard->createWriter(); + $action->render('error'); + return false; + } catch (ProgrammingError $e) { + Notification::error($e->getMessage()); + return false; + } + return false; + }); + $form->setRedirectUrl('dashboard/settings'); + $form->handleRequest(); + $this->view->pane = $pane; + $this->view->form = $form; + } + /** * Display the dashboard with the pane set in the 'pane' request parameter * @@ -115,61 +227,49 @@ class DashboardController extends ActionController */ public function indexAction() { - $dashboard = Dashboard::load(); - - if (! $dashboard->hasPanes()) { + $this->createTabs(); + if (! $this->dashboard->hasPanes()) { $this->view->title = 'Dashboard'; } else { if ($this->_getParam('pane')) { $pane = $this->_getParam('pane'); - $dashboard->activate($pane); + $this->dashboard->activate($pane); } - - $this->view->configPath = Config::resolvePath(self::DEFAULT_CONFIG); - - if ($dashboard === null) { + if ($this->dashboard === null) { $this->view->title = 'Dashboard'; } else { - $this->view->title = $dashboard->getActivePane()->getTitle() . ' :: Dashboard'; - $this->view->tabs = $dashboard->getTabs(); - - /* Temporarily removed + $this->view->title = $this->dashboard->getActivePane()->getTitle() . ' :: Dashboard'; + if ($this->hasParam('remove')) { + $this->dashboard->getActivePane()->removeComponent($this->getParam('remove')); + $this->dashboard->write(); + $this->redirectNow(URL::fromRequest()->remove('remove')); + } $this->view->tabs->add( 'Add', array( 'title' => '+', - 'url' => Url::fromPath('dashboard/addurl') + 'url' => Url::fromPath('dashboard/new-component') ) ); - */ - - $this->view->dashboard = $dashboard; + $this->view->dashboard = $this->dashboard; } } } /** - * Store the given configuration as INI file - * - * @param Config $config The configuration to store - * @param string $target The path where to store the configuration - * - * @return bool Whether the configuartion has been successfully stored + * Setting dialog */ - protected function writeConfiguration(Config $config, $target) + public function settingsAction() { - $writer = new IniWriter(array('config' => $config, 'filename' => $target)); + $this->createTabs(); + $this->view->dashboard = $this->dashboard; + } - try { - $writer->write(); - } catch (Exception $e) { - Logger::error(new ConfiguationError("Cannot write dashboard to $target", 0, $e)); - $this->view->configString = $writer->render(); - $this->view->errorMessage = $e->getMessage(); - $this->view->filePath = $target; - return false; - } - - return true; + /** + * Create tab aggregation + */ + private function createTabs() + { + $this->view->tabs = $this->dashboard->getTabs()->extend(new DashboardSettings()); } } diff --git a/application/forms/Dashboard/AddUrlForm.php b/application/forms/Dashboard/AddUrlForm.php deleted file mode 100644 index 7f5a217d1..000000000 --- a/application/forms/Dashboard/AddUrlForm.php +++ /dev/null @@ -1,116 +0,0 @@ -setName('form_dashboard_addurl'); - $this->setSubmitLabel(t('Add To Dashboard')); - } - - /** - * @see Form::createElements() - */ - public function createElements(array $formData) - { - $this->addElement( - 'text', - 'url', - array( - 'required' => true, - 'label' => t('Url'), - 'helptext' => t('The url being loaded in the dashlet') - ) - ); - - $paneSelectionValues = $this->getDashboardPaneSelectionValues(); - if (empty($paneSelectionValues) || - ((isset($formData['create_new_pane']) && $formData['create_new_pane'] != false) && - (false === isset($formData['use_existing_dashboard']) || $formData['use_existing_dashboard'] != true)) - ) { - $this->addElement( - 'text', - 'pane', - array( - 'required' => true, - 'label' => t("The New Pane's Title"), - 'style' => 'display: inline-block' - ) - ); - $this->addElement( // Prevent the button from being displayed again on validation errors - 'hidden', - 'create_new_pane', - array( - 'value' => 1 - ) - ); - if (false === empty($paneSelectionValues)) { - $this->addElement( - 'submit', - 'use_existing_dashboard', - array( - 'ignore' => true, - 'label' => t('Use An Existing Pane'), - 'style' => 'display: inline-block' - ) - ); - } - } else { - $this->addElement( - 'select', - 'pane', - array( - 'required' => true, - 'label' => t('Pane'), - 'style' => 'display: inline-block;', - 'multiOptions' => $paneSelectionValues - ) - ); - $this->addElement( - 'submit', - 'create_new_pane', - array( - 'ignore' => true, - 'label' => t('Create A New Pane'), - 'style' => 'display: inline-block' - ) - ); - } - - $this->addElement( - 'text', - 'component', - array( - 'required' => true, - 'label' => t('Title'), - 'helptext' => t('The title for the dashlet') - ) - ); - } - - /** - * Return the names and titles of the available dashboard panes as key-value array - * - * @return array - */ - protected function getDashboardPaneSelectionValues() - { - $dashboard = new Dashboard(); - $dashboard->readConfig(Config::app('dashboard/dashboard')); - return $dashboard->getPaneKeyTitleArray(); - } -} diff --git a/application/forms/Dashboard/ComponentForm.php b/application/forms/Dashboard/ComponentForm.php new file mode 100644 index 000000000..54aa4c33d --- /dev/null +++ b/application/forms/Dashboard/ComponentForm.php @@ -0,0 +1,193 @@ +setName('form_dashboard_addurl'); + if (! $this->getSubmitLabel()) { + $this->setSubmitLabel(t('Add To Dashboard')); + } + } + + /** + * Build AddUrl form elements + * + * @see Form::createElements() + */ + public function createElements(array $formData) + { + $groupElements = array(); + $panes = array(); + + if ($this->dashboard) { + $panes = $this->dashboard->getPaneKeyTitleArray(); + } + + $this->addElement( + 'hidden', + 'org_pane', + array( + 'required' => false + ) + ); + + $this->addElement( + 'hidden', + 'org_component', + array( + 'required' => false + ) + ); + + $this->addElement( + 'text', + 'url', + array( + 'required' => true, + 'label' => t('Url'), + 'description' => + t('Enter url being loaded in the dashlet. You can paste the full URL, including filters.') + ) + ); + $this->addElement( + 'text', + 'component', + array( + 'required' => true, + 'label' => t('Dashlet Title'), + 'description' => t('Enter a title for the dashlet.') + ) + ); + if (empty($panes) || + ((isset($formData['create_new_pane']) && $formData['create_new_pane'] != false) && + (false === isset($formData['use_existing_dashboard']) || $formData['use_existing_dashboard'] != true)) + ) { + $groupElements[] = $this->createElement( + 'text', + 'pane', + array( + 'required' => true, + 'label' => t("New Pane Title"), + 'description' => + t('Enter a title for the new pane.') + ) + ); + $groupElements[] = $this->createElement( // Prevent the button from being displayed again on validation errors + 'hidden', + 'create_new_pane', + array( + 'value' => 1 + ) + ); + if (false === empty($panes)) { + $buttonExistingPane = $this->createElement( + 'submit', + 'use_existing_dashboard', + array( + 'ignore' => true, + 'label' => t('Use An Existing Pane'), + 'description' => + t('Click on the button to add the dashlet to an existing pane on your dashboard.') + ) + ); + $buttonExistingPane->removeDecorator('Label'); + $groupElements[] = $buttonExistingPane; + } + } else { + $groupElements[] = $this->createElement( + 'select', + 'pane', + array( + 'required' => true, + 'label' => t('Pane'), + 'multiOptions' => $panes, + 'description' => + t('Select a pane you want to add the dashlet.') + ) + ); + $buttonNewPane = $this->createElement( + 'submit', + 'create_new_pane', + array( + 'ignore' => true, + 'label' => t('Create A New Pane'), + 'description' => + t('Click on the button if you want to add the dashlet to a new pane on the dashboard.') + ) + ); + $buttonNewPane->removeDecorator('Label'); + $groupElements[] = $buttonNewPane; + } + $this->addDisplayGroup( + $groupElements, + 'pane_group', + array( + 'legend' => t('Pane'), + 'description' => t( + 'Decide if you want add the dashlet to an existing pane' + . ' or create a new pane. Have a look on the button below.' + ), + 'decorators' => array( + 'FormElements', + array('HtmlTag', array('tag' => 'div', 'class' => 'control-group')), + array( + 'Description', + array('tag' => 'span', 'class' => 'description', 'placement' => 'prepend') + ), + 'Fieldset' + ) + ) + ); + } + + /** + * @param \Icinga\Web\Widget\Dashboard $dashboard + */ + public function setDashboard(Dashboard $dashboard) + { + $this->dashboard = $dashboard; + } + + /** + * @return \Icinga\Web\Widget\Dashboard + */ + public function getDashboard() + { + return $this->dashboard; + } + + /** + * @param Component $component + */ + public function load(Component $component) + { + $this->populate(array( + 'pane' => $component->getPane()->getName(), + 'org_pane' => $component->getPane()->getName(), + 'component' => $component->getTitle(), + 'org_component' => $component->getTitle(), + 'url' => $component->getUrl() + )); + } +} diff --git a/application/views/scripts/authentication/login.phtml b/application/views/scripts/authentication/login.phtml index e931d0448..584d8ad16 100644 --- a/application/views/scripts/authentication/login.phtml +++ b/application/views/scripts/authentication/login.phtml @@ -5,6 +5,7 @@
+

Welcome to Icinga Web 2

errorInfo)): ?> diff --git a/application/views/scripts/dashboard/addurl.phtml b/application/views/scripts/dashboard/addurl.phtml index c2d3f7e6c..9c41a7713 100644 --- a/application/views/scripts/dashboard/addurl.phtml +++ b/application/views/scripts/dashboard/addurl.phtml @@ -3,10 +3,6 @@
-

escape($this->translate('This feature is deactivated at the moment.')); ?>

-

- escape($this->translate('Please have a little patience, we are hard working on it, take a look at icingaweb2 issues.')); - ?> -

+

+ form; ?>
\ No newline at end of file diff --git a/application/views/scripts/dashboard/error.phtml b/application/views/scripts/dashboard/error.phtml new file mode 100644 index 000000000..e5a0f3939 --- /dev/null +++ b/application/views/scripts/dashboard/error.phtml @@ -0,0 +1,13 @@ +
+

+

+ + config->getFilename(); ?>;. +
+ +

+
config->render(); ?>
+
+

+

error->getMessage(); ?>

+
diff --git a/application/views/scripts/dashboard/index.phtml b/application/views/scripts/dashboard/index.phtml index 4adad7b66..7c3724dc6 100644 --- a/application/views/scripts/dashboard/index.phtml +++ b/application/views/scripts/dashboard/index.phtml @@ -8,9 +8,11 @@

escape($this->translate('Welcome to Icinga Web!')) ?>

-

escape($this->translate('Currently there is no dashlet available. This might change once you enabled some of the available %s.')), - $this->qlink($this->translate('modules'), 'config/modules') - ) ?>

+

+ escape($this->translate('Currently there is no dashlet available. This might change once you enabled some of the available %s.')), + $this->qlink($this->translate('modules'), 'config/modules') + ) ?> +

\ No newline at end of file diff --git a/application/views/scripts/dashboard/new-component.phtml b/application/views/scripts/dashboard/new-component.phtml new file mode 100644 index 000000000..46c8b2255 --- /dev/null +++ b/application/views/scripts/dashboard/new-component.phtml @@ -0,0 +1,7 @@ +
+ tabs ?> +
+
+

+ form; ?> +
\ No newline at end of file diff --git a/application/views/scripts/dashboard/remove-component.phtml b/application/views/scripts/dashboard/remove-component.phtml new file mode 100644 index 000000000..c39472771 --- /dev/null +++ b/application/views/scripts/dashboard/remove-component.phtml @@ -0,0 +1,14 @@ +
+ tabs ?> +
+ +
+

+ +

+ translate('Please confirm the removal'); ?>: + pane; ?>/component; ?> +

+ + form; ?> +
\ No newline at end of file diff --git a/application/views/scripts/dashboard/remove-pane.phtml b/application/views/scripts/dashboard/remove-pane.phtml new file mode 100644 index 000000000..637774cab --- /dev/null +++ b/application/views/scripts/dashboard/remove-pane.phtml @@ -0,0 +1,14 @@ +
+ tabs ?> +
+ +
+

+ +

+ translate('Please confirm the removal of'); ?>: + pane; ?> +

+ + form; ?> +
\ No newline at end of file diff --git a/application/views/scripts/dashboard/settings.phtml b/application/views/scripts/dashboard/settings.phtml new file mode 100644 index 000000000..83fba6588 --- /dev/null +++ b/application/views/scripts/dashboard/settings.phtml @@ -0,0 +1,62 @@ + +
+ tabs ?> +
+
+

+ + + + + + + + + + dashboard->getPanes() as $pane): ?> + + + + + getComponents(); ?> + + + + + + + getDisabled() === true) continue; ?> + + + + + + + + + +
+ + + +
+ getName(); ?> + + + icon('cancel'); ?> + +
+ translate('No compoments added to dashboard') ?>. +
+ + getTitle(); ?> + + + getUrl(); ?> + + + icon('cancel'); ?> + +
+
\ No newline at end of file diff --git a/application/views/scripts/dashboard/show-configuration.phtml b/application/views/scripts/dashboard/show-configuration.phtml deleted file mode 100644 index 7cdce496c..000000000 --- a/application/views/scripts/dashboard/show-configuration.phtml +++ /dev/null @@ -1,28 +0,0 @@ -
-
-

{{WARNING_ICON}}Saving Dashboard Failed

-
-

- Your dashboard couldn't be stored (error: "exceptionMessage; ?>"). This could have one or more - of the following reasons: -

- -
- -

- Details can be seen in your application log (if you don't have access to this file, call your administrator in this case). -
- In case you can access the configuration file (config/dashboard/dashboard.ini) by yourself, you can open it and - insert the config manually: -

-

-

-        
-escape($this->iniConfigurationString); ?>
-        
-    
-

\ No newline at end of file diff --git a/application/views/scripts/dashboard/update-component.phtml b/application/views/scripts/dashboard/update-component.phtml new file mode 100644 index 000000000..0493f5613 --- /dev/null +++ b/application/views/scripts/dashboard/update-component.phtml @@ -0,0 +1,8 @@ +
+ tabs ?> +
+ +
+

+ form; ?> +
\ No newline at end of file diff --git a/library/Icinga/File/Ini/IniWriter.php b/library/Icinga/File/Ini/IniWriter.php index cf9355b56..e3b757b78 100644 --- a/library/Icinga/File/Ini/IniWriter.php +++ b/library/Icinga/File/Ini/IniWriter.php @@ -229,4 +229,14 @@ class IniWriter extends Zend_Config_Writer_FileAbstract return $combinations; } + + /** + * Getter for filename + * + * @return string + */ + public function getFilename() + { + return $this->_filename; + } } diff --git a/library/Icinga/Web/Form.php b/library/Icinga/Web/Form.php index 8d75a9df3..863d4f1c1 100644 --- a/library/Icinga/Web/Form.php +++ b/library/Icinga/Web/Form.php @@ -163,6 +163,26 @@ class Form extends Zend_Form parent::__construct($options); } + /** + * Set a callback that is called instead of this form's onSuccess method + * + * It is called using the following signature: (Request $request, Form $form). + * + * @param callable $onSuccess Callback + * + * @return $this + * + * @throws LogicException If the callback is not callable + */ + public function setOnSuccess($onSuccess) + { + if (! is_callable($onSuccess)) { + throw new LogicException('The option `onSuccess\' is not callable'); + } + $this->onSuccess = $onSuccess; + return $this; + } + /** * Set the label to use for the standard submit button * diff --git a/library/Icinga/Web/Widget/Dashboard.php b/library/Icinga/Web/Widget/Dashboard.php index f7daa5d02..c97bdf578 100644 --- a/library/Icinga/Web/Widget/Dashboard.php +++ b/library/Icinga/Web/Widget/Dashboard.php @@ -6,8 +6,13 @@ namespace Icinga\Web\Widget; use Icinga\Application\Icinga; use Icinga\Application\Config; +use Icinga\Data\ConfigObject; use Icinga\Exception\ConfigurationError; +use Icinga\Exception\NotReadableError; use Icinga\Exception\ProgrammingError; +use Icinga\Exception\SystemPermissionException; +use Icinga\File\Ini\IniWriter; +use Icinga\User; use Icinga\Web\Widget\Dashboard\Pane; use Icinga\Web\Widget\Dashboard\Component as DashboardComponent; use Icinga\Web\Url; @@ -23,13 +28,6 @@ use Icinga\Web\Url; */ class Dashboard extends AbstractWidget { - /** - * The configuration containing information about this dashboard - * - * @var Config; - */ - private $config; - /** * An array containing all panes of this dashboard * @@ -51,6 +49,11 @@ class Dashboard extends AbstractWidget */ private $tabParam = 'pane'; + /** + * @var User + */ + private $user; + /** * Set the given tab name as active. * @@ -67,30 +70,136 @@ class Dashboard extends AbstractWidget * * @return self */ - public static function load() + public function load() { - /** @var $dashboard Dashboard */ - $dashboard = new static('dashboard'); $manager = Icinga::app()->getModuleManager(); foreach ($manager->getLoadedModules() as $module) { /** @var $module \Icinga\Application\Modules\Module */ - $dashboard->mergePanes($module->getPaneItems()); + $this->mergePanes($module->getPaneItems()); } - return $dashboard; + if ($this->user !== null) { + $this->loadUserDashboards(); + } + + return $this; + } + + /** + * Create a writer object + * + * @return IniWriter + */ + public function createWriter() + { + $configFile = $this->getConfigFile(); + $output = array(); + foreach ($this->panes as $pane) { + if ($pane->isUserWidget() === true) { + $output[$pane->getName()] = $pane->toArray(); + } + foreach ($pane->getComponents() as $component) { + if ($component->isUserWidget() === true) { + $output[$pane->getName() . '.' . $component->getTitle()] = $component->toArray(); + } + } + } + + $co = new ConfigObject($output); + $config = new Config($co); + return new IniWriter(array('config' => $config, 'filename' => $configFile)); + } + + /** + * Write user specific dashboards to disk + */ + public function write() + { + $this->createWriter()->write(); + } + + /** + * @return bool + */ + private function loadUserDashboards() + { + try { + $config = Config::fromIni($this->getConfigFile()); + } catch (NotReadableError $e) { + return; + } + if (! count($config)) { + return false; + } + $panes = array(); + $components = array(); + foreach ($config as $key => $part) { + if (strpos($key, '.') === false) { + if ($this->hasPane($part->title)) { + $panes[$key] = $this->getPane($part->title); + } else { + $panes[$key] = new Pane($key); + $panes[$key]->setTitle($part->title); + } + $panes[$key]->setUserWidget(); + if ((bool) $part->get('disabled', false) === true) { + $panes[$key]->setDisabled(); + } + + } else { + list($paneName, $componentName) = explode('.', $key, 2); + $part->pane = $paneName; + $part->component = $componentName; + $components[] = $part; + } + } + foreach ($components as $componentData) { + $pane = null; + + if (array_key_exists($componentData->pane, $panes) === true) { + $pane = $panes[$componentData->pane]; + } elseif (array_key_exists($componentData->pane, $this->panes) === true) { + $pane = $this->panes[$componentData->pane]; + } else { + continue; + } + $component = new DashboardComponent( + $componentData->title, + $componentData->url, + $pane + ); + + if ((bool) $componentData->get('disabled', false) === true) { + $component->setDisabled(true); + } + + $component->setUserWidget(); + $pane->addComponent($component); + } + + $this->mergePanes($panes); + + return true; } /** * Merge panes with existing panes * - * @param array $panes - * @return $this + * @param array $panes + * + * @return $this */ public function mergePanes(array $panes) { /** @var $pane Pane */ foreach ($panes as $pane) { - if (array_key_exists($pane->getName(), $this->panes)) { + if ($pane->getDisabled()) { + if ($this->hasPane($pane->getTitle()) === true) { + $this->removePane($pane->getTitle()); + } + continue; + } + if ($this->hasPane($pane->getTitle()) === true) { /** @var $current Pane */ $current = $this->panes[$pane->getName()]; $current->addComponents($pane->getComponents()); @@ -109,7 +218,7 @@ class Dashboard extends AbstractWidget */ public function getTabs() { - $url = Url::fromRequest()->getUrlWithout($this->tabParam); + $url = Url::fromPath('dashboard')->getUrlWithout($this->tabParam); if ($this->tabs === null) { $this->tabs = new Tabs(); @@ -137,20 +246,6 @@ class Dashboard extends AbstractWidget return $this->panes; } - /** - * Populate this dashboard via the given configuration file - * - * @param Config $config The configuration file to populate this dashboard with - * - * @return self - */ - public function readConfig(Config $config) - { - $this->config = $config; - $this->panes = array(); - $this->loadConfigPanes(); - return $this; - } /** * Creates a new empty pane with the given title @@ -168,34 +263,6 @@ class Dashboard extends AbstractWidget return $this; } - /** - * Update or adds a new component with the given url to a pane - * - * @TODO: Should only allow component objects to be added directly as soon as we store more information - * - * @param string $pane The pane to add the component to - * @param Component|string $component The component to add or the title of the newly created component - * @param string|null $url The url to use for the component - * - * @return self - */ - public function setComponentUrl($pane, $component, $url) - { - if ($component === null && strpos($pane, '.')) { - list($pane, $component) = preg_split('~\.~', $pane, 2); - } - if (!isset($this->panes[$pane])) { - $this->createPane($pane); - } - $pane = $this->getPane($pane); - if ($pane->hasComponent($component)) { - $pane->getComponent($component)->setUrl($url); - } else { - $pane->addComponent($component, $url); - } - return $this; - } - /** * Checks if the current dashboard has any panes * @@ -207,49 +274,14 @@ class Dashboard extends AbstractWidget } /** - * Check if this dashboard has a specific pane + * Check if a panel exist * - * @param $pane string The name of the pane - * @return bool + * @param string $pane + * @return bool */ public function hasPane($pane) { - return array_key_exists($pane, $this->panes); - } - - /** - * Remove a component $component from the given pane - * - * @param string $pane The pane to remove the component from - * @param Component|string $component The component to remove or it's name - * - * @return self - */ - public function removeComponent($pane, $component) - { - if ($component === null && strpos($pane, '.')) { - list($pane, $component) = preg_split('~\.~', $pane, 2); - } - $pane = $this->getPane($pane); - if ($pane !== null) { - $pane->removeComponent($component); - } - - return $this; - } - - /** - * Return an array with pane name=>title format used for comboboxes - * - * @return array - */ - public function getPaneKeyTitleArray() - { - $list = array(); - foreach ($this->panes as $name => $pane) { - $list[$name] = $pane->getTitle(); - } - return $list; + return $pane && array_key_exists($pane, $this->panes); } /** @@ -265,6 +297,21 @@ class Dashboard extends AbstractWidget return $this; } + public function removePane($title) + { + if ($this->hasPane($title) === true) { + $pane = $this->getPane($title); + if ($pane->isUserWidget() === true) { + unset($this->panes[$pane->getName()]); + } else { + $pane->setDisabled(); + $pane->setUserWidget(); + } + } else { + throw new ProgrammingError('Pane not found: ' . $title); + } + } + /** * Return the pane with the provided name * @@ -284,6 +331,20 @@ class Dashboard extends AbstractWidget return $this->panes[$name]; } + /** + * Return an array with pane name=>title format used for comboboxes + * + * @return array + */ + public function getPaneKeyTitleArray() + { + $list = array(); + foreach ($this->panes as $name => $pane) { + $list[$name] = $pane->getTitle(); + } + return $list; + } + /** * @see Icinga\Web\Widget::render */ @@ -292,6 +353,7 @@ class Dashboard extends AbstractWidget if (empty($this->panes)) { return ''; } + return $this->determineActivePane()->render(); } @@ -319,7 +381,10 @@ class Dashboard extends AbstractWidget /** * Determine the active pane either by the selected tab or the current request * - * @return Pane The currently active pane + * @throws \Icinga\Exception\ConfigurationError + * @throws \Icinga\Exception\ProgrammingError + * + * @return Pane The currently active pane */ public function determineActivePane() { @@ -346,34 +411,55 @@ class Dashboard extends AbstractWidget } /** - * Return this dashboard's structure as array + * Setter for user object * - * @return array + * @param User $user */ - public function toArray() + public function setUser(User $user) { - $array = array(); - foreach ($this->panes as $pane) { - $array += $pane->toArray(); - } - - return $array; + $this->user = $user; } /** - * Load all config panes from @see Dashboard::$config + * Getter for user object * + * @return User */ - private function loadConfigPanes() + public function getUser() { - foreach ($this->config as $key => $item) { - if (false === strstr($key, '.')) { - $this->addPane(Pane::fromIni($key, $item)); - } else { - list($paneName, $title) = explode('.', $key, 2); - $pane = $this->getPane($paneName); - $pane->addComponent(DashboardComponent::fromIni($title, $item, $pane)); + return $this->user; + } + + /** + * Get config file + * + * @return string + */ + public function getConfigFile() + { + if ($this->user === null) { + return ''; + } + + $baseDir = '/var/lib/icingaweb'; + + if (! file_exists($baseDir)) { + throw new NotReadableError('Could not read: ' . $baseDir); + } + + $userDir = $baseDir . '/' . $this->user->getUsername(); + + if (! file_exists($userDir)) { + $success = @mkdir($userDir); + if (!$success) { + throw new SystemPermissionException('Could not create: ' . $userDir); } } + + if (! file_exists($userDir)) { + throw new NotReadableError('Could not read: ' . $userDir); + } + + return $userDir . '/dashboard.ini'; } } diff --git a/library/Icinga/Web/Widget/Dashboard/Component.php b/library/Icinga/Web/Widget/Dashboard/Component.php index e0ac4b3d7..1ab0ff60d 100644 --- a/library/Icinga/Web/Widget/Dashboard/Component.php +++ b/library/Icinga/Web/Widget/Dashboard/Component.php @@ -17,7 +17,7 @@ use Icinga\Exception\IcingaException; * This is the element displaying a specific view in icinga2web * */ -class Component extends AbstractWidget +class Component extends UserWidget { /** * The url of this Component @@ -53,7 +53,7 @@ class Component extends AbstractWidget private $template =<<<'EOD'
-

{REMOVE}{TITLE}

+

{TITLE}

@@ -93,6 +93,14 @@ EOD; return $this->title; } + /** + * @param string $title + */ + public function setTitle($title) + { + $this->title = $title; + } + /** * Retrieve the components url * @@ -147,7 +155,13 @@ EOD; */ public function toArray() { - $array = array('url' => $this->url->getPath()); + $array = array( + 'url' => $this->url->getPath(), + 'title' => $this->getTitle() + ); + if ($this->getDisabled() === true) { + $array['disabled'] = 1; + } foreach ($this->url->getParams()->toArray() as $param) { $array[$param[0]] = $param[1]; } @@ -169,13 +183,23 @@ EOD; $iframeUrl = clone($url); $iframeUrl->setParam('isIframe'); - $html = str_replace('{URL}', $url, $this->template); - $html = str_replace('{IFRAME_URL}', $iframeUrl, $html); - $html = str_replace('{FULL_URL}', $url->getUrlWithout(array('view', 'limit')), $html); - $html = str_replace('{REMOVE_BTN}', $this->getRemoveForm($view), $html); - $html = str_replace('{TITLE}', $view->escape($this->getTitle()), $html); - $html = str_replace('{REMOVE}', $this->getRemoveForm(), $html); - return $html; + $searchTokens = array( + '{URL}', + '{IFRAME_URL}', + '{FULL_URL}', + '{TITLE}', + '{REMOVE}' + ); + + $replaceTokens = array( + $url, + $iframeUrl, + $url->getUrlWithout(array('view', 'limit')), + $view->escape($this->getTitle()), + $this->getRemoveLink() + ); + + return str_replace($searchTokens, $replaceTokens, $this->template); } /** @@ -183,32 +207,16 @@ EOD; * * @return string The html representation of the form */ - protected function getRemoveForm() + protected function getRemoveLink() { - // TODO: temporarily disabled, should point to a form asking for confirmal - return ''; - $removeUrl = Url::fromPath( - '/dashboard/removecomponent', - array( - 'pane' => $this->pane->getName(), - 'component' => $this->getTitle() - ) + return sprintf( + '%s', + Url::fromPath('dashboard/remove-component', array( + 'component' => $this->getTitle(), + 'pane' => $this->pane->getTitle() + )), + t('Remove') ); - $form = new Form(); - $form->setMethod('POST'); - $form->setAttrib('class', 'inline'); - $form->setAction($removeUrl); - $form->addElement( - new Zend_Form_Element_Button( - 'remove_pane_btn', - array( - 'class'=> 'link-like pull-right', - 'type' => 'submit', - 'label' => 'x' - ) - ) - ); - return $form; } /** @@ -231,4 +239,20 @@ EOD; $cmp = new Component($title, Url::fromPath($url, $parameters), $pane); return $cmp; } + + /** + * @param \Icinga\Web\Widget\Dashboard\Pane $pane + */ + public function setPane(Panel $pane) + { + $this->pane = $pane; + } + + /** + * @return \Icinga\Web\Widget\Dashboard\Pane + */ + public function getPane() + { + return $this->pane; + } } diff --git a/library/Icinga/Web/Widget/Dashboard/Pane.php b/library/Icinga/Web/Widget/Dashboard/Pane.php index 92523578f..4ba9f27dc 100644 --- a/library/Icinga/Web/Widget/Dashboard/Pane.php +++ b/library/Icinga/Web/Widget/Dashboard/Pane.php @@ -12,7 +12,7 @@ use Icinga\Exception\ConfigurationError; /** * A pane, displaying different Dashboard components */ -class Pane extends AbstractWidget +class Pane extends UserWidget { /** * The name of this pane, as defined in the ini file @@ -36,6 +36,13 @@ class Pane extends AbstractWidget */ private $components = array(); + /** + * Disabled flag of a pane + * + * @var bool + */ + private $disabled; + /** * Create a new pane * @@ -130,7 +137,15 @@ class Pane extends AbstractWidget public function removeComponent($title) { if ($this->hasComponent($title)) { - unset($this->components[$title]); + $component = $this->getComponent($title); + if ($component->isUserWidget() === true) { + unset($this->components[$title]); + } else { + $component->setDisabled(true); + $component->setUserWidget(); + } + } else { + throw new ProgrammingError('Component does not exist: ' . $title); } return $this; } @@ -168,7 +183,13 @@ class Pane extends AbstractWidget */ public function render() { - return implode("\n", $this->components) . "\n"; + $components = array_filter( + $this->components, + function ($e) { + return ! $e->getDisabled(); + } + ); + return implode("\n", $components) . "\n"; } /** @@ -241,12 +262,15 @@ class Pane extends AbstractWidget */ public function toArray() { - $array = array($this->getName() => array('title' => $this->getTitle())); - foreach ($this->components as $title => $component) { - $array[$this->getName() . ".$title"] = $component->toArray(); + $pane = array( + 'title' => $this->getTitle(), + ); + + if ($this->getDisabled() === true) { + $pane['disabled'] = 1; } - return $array; + return $pane; } /** @@ -265,4 +289,26 @@ class Pane extends AbstractWidget } return $pane; } + + /** + * Setter for disabled + * + * @param boolean $disabled + */ + public function setDisabled($disabled = true) + { + $this->disabled = (bool) $disabled; + } + + /** + * Getter for disabled + * + * @return boolean + */ + public function getDisabled() + { + return $this->disabled; + } + + } diff --git a/library/Icinga/Web/Widget/Dashboard/UserWidget.php b/library/Icinga/Web/Widget/Dashboard/UserWidget.php new file mode 100644 index 000000000..0b171964e --- /dev/null +++ b/library/Icinga/Web/Widget/Dashboard/UserWidget.php @@ -0,0 +1,37 @@ +userWidget = (bool) $userWidget; + } + + /** + * Getter for user widget flag + * + * @return boolean + */ + public function isUserWidget() + { + return $this->userWidget; + } +} diff --git a/library/Icinga/Web/Widget/Tabextension/DashboardAction.php b/library/Icinga/Web/Widget/Tabextension/DashboardAction.php index a8cce1cc0..9ed5f34ef 100644 --- a/library/Icinga/Web/Widget/Tabextension/DashboardAction.php +++ b/library/Icinga/Web/Widget/Tabextension/DashboardAction.php @@ -26,7 +26,7 @@ class DashboardAction implements Tabextension array( 'icon' => 'dashboard', 'title' => 'Add To Dashboard', - 'url' => Url::fromPath('dashboard/addurl'), + 'url' => Url::fromPath('dashboard/new-component'), 'urlParams' => array( 'url' => rawurlencode(Url::fromRequest()->getRelativeUrl()) ) diff --git a/library/Icinga/Web/Widget/Tabextension/DashboardSettings.php b/library/Icinga/Web/Widget/Tabextension/DashboardSettings.php new file mode 100644 index 000000000..c30db4235 --- /dev/null +++ b/library/Icinga/Web/Widget/Tabextension/DashboardSettings.php @@ -0,0 +1,40 @@ +addAsDropdown( + 'dashboard_add', + array( + 'icon' => 'img/icons/dashboard.png', + 'title' => t('Add To Dashboard'), + 'url' => Url::fromPath('dashboard/new-component') + ) + ); + + $tabs->addAsDropdown( + 'dashboard_settings', + array( + 'icon' => 'img/icons/dashboard.png', + 'title' => t('Settings'), + 'url' => Url::fromPath('dashboard/settings') + ) + ); + } +} \ No newline at end of file diff --git a/modules/monitoring/application/forms/Command/Object/CheckNowCommandForm.php b/modules/monitoring/application/forms/Command/Object/CheckNowCommandForm.php index 477624bb6..01006683f 100644 --- a/modules/monitoring/application/forms/Command/Object/CheckNowCommandForm.php +++ b/modules/monitoring/application/forms/Command/Object/CheckNowCommandForm.php @@ -28,8 +28,6 @@ class CheckNowCommandForm extends ObjectsCommandForm */ public function addSubmitButton() { - $iconUrl = $this->getView()->href('img/icons/refresh_petrol.png'); - $this->addElements(array( array( 'button', @@ -38,7 +36,7 @@ class CheckNowCommandForm extends ObjectsCommandForm 'ignore' => true, 'type' => 'submit', 'value' => mt('monitoring', 'Check now'), - 'label' => ' ' . mt('monitoring', 'Check now'), + 'label' => ' ' . mt('monitoring', 'Check now'), 'decorators' => array('ViewHelper'), 'escape' => false, 'class' => 'link-like' diff --git a/packages/rpm/README.md b/packages/RPM.md similarity index 100% rename from packages/rpm/README.md rename to packages/RPM.md diff --git a/packages/debian/README.first b/packages/debian/README.first deleted file mode 100644 index 00799671f..000000000 --- a/packages/debian/README.first +++ /dev/null @@ -1,2 +0,0 @@ -PLEASE DO NOT USE THIS YET. Still preparing basic stuff, should be ready -with 2.0.0-beta1 diff --git a/packages/debian/icingacli.install b/packages/debian/icingacli.install index de1bccf4c..be3db5e1c 100644 --- a/packages/debian/icingacli.install +++ b/packages/debian/icingacli.install @@ -1,2 +1,3 @@ packages/files/bin/icingacli usr/bin etc/bash_completion.d etc/bash_completion.d +application/clicommands usr/share/icingaweb/application diff --git a/packages/debian/libicinga-common-php.dirs b/packages/debian/icingaweb-common.dirs similarity index 100% rename from packages/debian/libicinga-common-php.dirs rename to packages/debian/icingaweb-common.dirs diff --git a/packages/debian/icingaweb-common.install b/packages/debian/icingaweb-common.install new file mode 100644 index 000000000..91a34bcee --- /dev/null +++ b/packages/debian/icingaweb-common.install @@ -0,0 +1,2 @@ +application/locales usr/share/icingaweb/application +modules usr/share/icingaweb diff --git a/packages/debian/icingaweb-module-doc.install b/packages/debian/icingaweb-module-doc.install new file mode 100644 index 000000000..1482e8c66 --- /dev/null +++ b/packages/debian/icingaweb-module-doc.install @@ -0,0 +1 @@ +modules/doc usr/share/icingaweb/modules diff --git a/packages/debian/icingaweb-module-monitoring.install b/packages/debian/icingaweb-module-monitoring.install new file mode 100644 index 000000000..1482e8c66 --- /dev/null +++ b/packages/debian/icingaweb-module-monitoring.install @@ -0,0 +1 @@ +modules/doc usr/share/icingaweb/modules diff --git a/packages/debian/icingaweb-module-setup.install b/packages/debian/icingaweb-module-setup.install new file mode 100644 index 000000000..4fdd070d2 --- /dev/null +++ b/packages/debian/icingaweb-module-setup.install @@ -0,0 +1 @@ +modules/setup usr/share/icingaweb/modules diff --git a/packages/debian/icingaweb-module-test.install b/packages/debian/icingaweb-module-test.install new file mode 100644 index 000000000..e0db79bca --- /dev/null +++ b/packages/debian/icingaweb-module-test.install @@ -0,0 +1 @@ +modules/test usr/share/icingaweb/modules diff --git a/packages/debian/icingaweb-module-translation.install b/packages/debian/icingaweb-module-translation.install new file mode 100644 index 000000000..5a89d3d4d --- /dev/null +++ b/packages/debian/icingaweb-module-translation.install @@ -0,0 +1 @@ +modules/translation usr/share/icingaweb/modules diff --git a/packages/debian/icingaweb-vendor-htmlpurifier.install b/packages/debian/icingaweb-vendor-htmlpurifier.install new file mode 100644 index 000000000..298284f29 --- /dev/null +++ b/packages/debian/icingaweb-vendor-htmlpurifier.install @@ -0,0 +1 @@ +library/vendor/HTMLPurifier usr/share/icingaweb/library/vendor diff --git a/packages/debian/icingaweb-vendor-jshrink.install b/packages/debian/icingaweb-vendor-jshrink.install new file mode 100644 index 000000000..0db6b408b --- /dev/null +++ b/packages/debian/icingaweb-vendor-jshrink.install @@ -0,0 +1 @@ +library/vendor/JShrink usr/share/icingaweb/library/vendor diff --git a/packages/debian/icingaweb-vendor-lessphp.install b/packages/debian/icingaweb-vendor-lessphp.install new file mode 100644 index 000000000..1ace5481e --- /dev/null +++ b/packages/debian/icingaweb-vendor-lessphp.install @@ -0,0 +1 @@ +library/vendor/Zend usr/share/icingaweb/library/vendor diff --git a/packages/debian/icingaweb-vendor-parsedown.install b/packages/debian/icingaweb-vendor-parsedown.install new file mode 100644 index 000000000..13954e16b --- /dev/null +++ b/packages/debian/icingaweb-vendor-parsedown.install @@ -0,0 +1 @@ +library/vendor/Parsedown usr/share/icingaweb/library/vendor diff --git a/packages/debian/icingaweb-vendor-zend.install b/packages/debian/icingaweb-vendor-zend.install new file mode 100644 index 000000000..1ace5481e --- /dev/null +++ b/packages/debian/icingaweb-vendor-zend.install @@ -0,0 +1 @@ +library/vendor/Zend usr/share/icingaweb/library/vendor diff --git a/packages/debian/icingaweb.install b/packages/debian/icingaweb.install index 8642199b1..0fdee4dc0 100644 --- a/packages/debian/icingaweb.install +++ b/packages/debian/icingaweb.install @@ -1,5 +1,10 @@ public/css usr/share/icingaweb/public public/img usr/share/icingaweb/public -public/js usr/share/icingaweb/public +public/js usr/share/icingaweb/public +public/error_norewrite.html usr/share/icingaweb/public +application/controllers usr/share/icingaweb/application +application/fonts usr/share/icingaweb/application +application/layouts usr/share/icingaweb/application +application/views usr/share/icingaweb/application packages/files/public/index.php usr/share/icingaweb/public -packages/files/icingaweb-apache2.conf etc/apache2/conf.d +packages/files/apache/icingaweb.conf etc/apache2/conf.d diff --git a/packages/debian/libicinga-common-php.install b/packages/debian/libicinga-common-php.install deleted file mode 100644 index 65bd2f999..000000000 --- a/packages/debian/libicinga-common-php.install +++ /dev/null @@ -1,2 +0,0 @@ -application usr/share/icingaweb -modules usr/share/icingaweb diff --git a/packages/debian/libicinga-vendor-php.install b/packages/debian/libicinga-vendor-php.install deleted file mode 100644 index c2dd6e0e6..000000000 --- a/packages/debian/libicinga-vendor-php.install +++ /dev/null @@ -1 +0,0 @@ -library/IcingaVendor usr/share/php diff --git a/packages/debian/rules b/packages/debian/rules index c91eb8230..fbe100736 100755 --- a/packages/debian/rules +++ b/packages/debian/rules @@ -23,7 +23,7 @@ binary: dh_installdebconf dh_installinfo dh_installinit - dpkg-statoverride --force --add root www-data 2775 /etc/icingaweb + dpkg-statoverride --force --add root www-data 2770 /etc/icingaweb dh_compress dh_fixperms dh_strip diff --git a/packages/files/apache/icingaweb.conf b/packages/files/apache/icingaweb.conf new file mode 100644 index 000000000..e8c0c8f00 --- /dev/null +++ b/packages/files/apache/icingaweb.conf @@ -0,0 +1,38 @@ +Alias /icingaweb "/usr/share/icingaweb/public" + + + Options SymLinksIfOwnerMatch + AllowOverride None + + + # Apache 2.4 + + Require all granted + + + + + # Apache 2.2 + Order allow,deny + Allow from all + + + SetEnv ICINGAWEB_CONFIGDIR "/etc/icingaweb" + + EnableSendfile Off + + + RewriteEngine on + RewriteBase /icingaweb/ + RewriteCond %{REQUEST_FILENAME} -s [OR] + RewriteCond %{REQUEST_FILENAME} -l [OR] + RewriteCond %{REQUEST_FILENAME} -d + RewriteRule ^.*$ - [NC,L] + RewriteRule ^.*$ index.php [NC,L] + + + + DirectoryIndex error_norewrite.html + ErrorDocument 404 /error_norewrite.html + + diff --git a/packages/files/bin/icingacli b/packages/files/bin/icingacli index 1e9b0ef12..10b4857aa 100755 --- a/packages/files/bin/icingacli +++ b/packages/files/bin/icingacli @@ -1,6 +1,6 @@ #!/usr/bin/php dispatch(); +require_once '/usr/share/php/Icinga/Application/Cli.php'; + +Icinga\Application\Cli::start('/usr/share/icingaweb')->dispatch(); diff --git a/packages/files/icingaweb-apache2.conf b/packages/files/icingaweb-apache2.conf deleted file mode 100644 index cde9aeec3..000000000 --- a/packages/files/icingaweb-apache2.conf +++ /dev/null @@ -1,19 +0,0 @@ -Alias /icingaweb "/usr/share/icingaweb/public" - - - Options SymLinksIfOwnerMatch - AllowOverride None - Order allow,deny - Allow from all - - # SetEnv ICINGAWEB_CONFIGDIR /etc/icingaweb - - RewriteEngine on - RewriteBase /icingaweb/ - RewriteCond %{REQUEST_FILENAME} -s [OR] - RewriteCond %{REQUEST_FILENAME} -l [OR] - RewriteCond %{REQUEST_FILENAME} -d - RewriteRule ^.*$ - [NC,L] - RewriteRule ^.*$ index.php [NC,L] - - diff --git a/packages/files/public/index.php b/packages/files/public/index.php index 1acee9445..ebd223c03 100644 --- a/packages/files/public/index.php +++ b/packages/files/public/index.php @@ -1,6 +1,3 @@ - Options SymLinksIfOwnerMatch - AllowOverride None - - - # Apache 2.4 - - Require all granted - - - - - # Apache 2.2 - Order allow,deny - Allow from all - - - SetEnv ICINGAWEB_CONFIGDIR /etc/icingaweb2 - - EnableSendfile Off - - RewriteEngine on - RewriteBase /icingaweb/ - RewriteCond %{REQUEST_FILENAME} -s [OR] - RewriteCond %{REQUEST_FILENAME} -l [OR] - RewriteCond %{REQUEST_FILENAME} -d - RewriteRule ^.*$ - [NC,L] - RewriteRule ^.*$ index.php [NC,L] - - diff --git a/packages/rpm/etc/icingaweb2/authentication.ini b/packages/rpm/etc/icingaweb2/authentication.ini deleted file mode 100644 index 3ec9c033a..000000000 --- a/packages/rpm/etc/icingaweb2/authentication.ini +++ /dev/null @@ -1,6 +0,0 @@ -[autologin] -backend = autologin - -[internal_db_authentication] -backend = db -resource = internal_db diff --git a/packages/rpm/etc/icingaweb2/modules/monitoring/backends.ini b/packages/rpm/etc/icingaweb2/modules/monitoring/backends.ini deleted file mode 100644 index 6dd67d4b5..000000000 --- a/packages/rpm/etc/icingaweb2/modules/monitoring/backends.ini +++ /dev/null @@ -1,8 +0,0 @@ -[localdb] -type = ido -resource = "ido" - -[locallive] -disabled = "1" -type = livestatus -resource = livestatus diff --git a/packages/rpm/etc/icingaweb2/modules/monitoring/instances.ini b/packages/rpm/etc/icingaweb2/modules/monitoring/instances.ini deleted file mode 100644 index 037baa8b9..000000000 --- a/packages/rpm/etc/icingaweb2/modules/monitoring/instances.ini +++ /dev/null @@ -1,2 +0,0 @@ -[icinga] -path = "/var/run/icinga2/cmd/icinga2.cmd" diff --git a/packages/rpm/etc/icingaweb2/resources.ini b/packages/rpm/etc/icingaweb2/resources.ini deleted file mode 100644 index 833f84ba8..000000000 --- a/packages/rpm/etc/icingaweb2/resources.ini +++ /dev/null @@ -1,28 +0,0 @@ -[internal_db] -type = db -db = mysql -host = localhost -port = 3306 -password = icingaweb -username = icingaweb -dbname = icingaweb - -[ido] -type = db -db = mysql -host = localhost -port = 3306 -password = icinga -username = icinga -dbname = icinga - -[livestatus] -type = livestatus -socket = /var/run/icinga2/cmd/livestatus - -[logfile] -type = file -filename = "/var/log/icingaweb2/icingaweb2.log" -fields = "/^(?[0-9]{4}(-[0-9]{2}){2}T[0-9]{2}(:[0-9]{2}){2}(\\+[0-9]{2}:[0-9]{2})?) - (?[A-Za-z]+) - (?.*)$/" -; format: PCRE -; diff --git a/packages/rpm/usr/bin/icingacli b/packages/rpm/usr/bin/icingacli deleted file mode 100755 index d6c4010b6..000000000 --- a/packages/rpm/usr/bin/icingacli +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/php -dispatch(); diff --git a/public/css/icinga/login.less b/public/css/icinga/login.less index 8eb4e2258..cfae3c478 100644 --- a/public/css/icinga/login.less +++ b/public/css/icinga/login.less @@ -39,18 +39,17 @@ .form { position: absolute; font-size: 0.9em; - top: 50%; + top: 45%; left: 0; bottom: 0; right: 0; } .form h1 { - text-align: left; + text-align: center; font-size: 1.5em; - margin-left: auto; - margin-right: auto; - width: 12em; + margin-left: 2.3em; + border: none; color: @colorTextDefault; } @@ -75,7 +74,7 @@ form { margin-left: auto; margin-right: auto; - width: 40em; + width: 35em; } form input { @@ -108,9 +107,10 @@ } .footer { - margin-top: 2em; + margin-top: 7em; font-size: 0.9em; - text-align: center; + text-align: center; + margin-left: 5em; } div.config-note { diff --git a/test/php/library/Icinga/Web/Widget/DashboardTest.php b/test/php/library/Icinga/Web/Widget/DashboardTest.php index be11c42fe..21727480b 100644 --- a/test/php/library/Icinga/Web/Widget/DashboardTest.php +++ b/test/php/library/Icinga/Web/Widget/DashboardTest.php @@ -131,7 +131,8 @@ class DashboardTest extends BaseTestCase */ public function testLoadPaneItemsProvidedByEnabledModules() { - $dashboard = Dashboard::load(); + $dashboard = new Dashboard(); + $dashboard->load(); $this->assertCount( 1, @@ -270,71 +271,15 @@ class DashboardTest extends BaseTestCase $component2 = new Component('test2', 'test2', $pane); $pane->addComponent($component2); - $dashboard->removeComponent('test1', 'test'); - + $dashboard->getPane('test1')->removeComponent('test'); $result = $dashboard->getPane('test1')->hasComponent('test'); - $this->assertFalse( + $this->assertTrue( $result, 'Dashboard::removeComponent() could not remove component from the pane' ); } - /** - * @depends testWhetherGetPaneReturnsAPaneByName - */ - public function testWhetherRemoveComponentRemovesComponentByConcatenation() - { - $dashboard = new Dashboard(); - $dashboard->createPane('test1'); - $pane = $dashboard->getPane('test1'); - - $component = new Component('test', 'test', $pane); - $pane->addComponent($component); - - $component2 = new Component('test2', 'test2', $pane); - $pane->addComponent($component2); - - $dashboard->removeComponent('test1.test', null); - - $result = $dashboard->getPane('test1')->hasComponent('test'); - - $this->assertFalse( - $result, - 'Dashboard::removeComponent() could not remove component from the pane' - ); - } - - /** - * @depends testWhetherGetPaneReturnsAPaneByName - */ - public function testWhetherToArrayReturnsDashboardStructureAsArray() - { - $dashboard = new Dashboard(); - $dashboard->createPane('test1'); - $pane = $dashboard->getPane('test1'); - - $component = new Component('test', 'test', $pane); - $pane->addComponent($component); - - $result = $dashboard->toArray(); - - $expected = array( - 'test1' => array( - 'title' => 'test1' - ), - 'test1.test' => array( - 'url' => 'test' - ) - ); - - $this->assertEquals( - $expected, - $result, - 'Dashboard::toArray() could not return valid expectation' - ); - } - /** * @depends testWhetherGetPaneReturnsAPaneByName */ @@ -346,7 +291,7 @@ class DashboardTest extends BaseTestCase $component = new Component('test', 'test', $pane); $pane->addComponent($component); - $dashboard->setComponentUrl('test1', 'test', 'new'); + $dashboard->getPane('test1')->getComponent('test')->setUrl('new'); $this->assertEquals( 'new', @@ -355,48 +300,6 @@ class DashboardTest extends BaseTestCase ); } - /** - * @depends testWhetherGetPaneReturnsAPaneByName - */ - public function testWhetherSetComponentUrlUpdatesTheComponentUrlConcatenation() - { - $dashboard = new Dashboard(); - $dashboard->createPane('test1'); - $pane = $dashboard->getPane('test1'); - $component = new Component('test', 'test', $pane); - $pane->addComponent($component); - - $dashboard->setComponentUrl('test1.test', null, 'new'); - - $this->assertEquals( - 'new', - $component->getUrl()->getPath(), - 'Dashboard::setComponentUrl() could not return valid expectation' - ); - } - - /** - * @depends testWhetherGetPaneReturnsAPaneByName - */ - public function testWhetherSetComponentUrlUpdatesTheComponentUrlNotExistentPane() - { - $dashboard = new Dashboard(); - $dashboard->createPane('test1'); - $pane = $dashboard->getPane('test1'); - $component = new Component('test', 'test', $pane); - $pane->addComponent($component); - - $dashboard->setComponentUrl('test3.test', null, 'new'); - - $result = $dashboard->getPane('test3')->getComponent('test'); - - $this->assertEquals( - 'new', - $result->getUrl()->getPath(), - 'Dashboard::setComponentUrl() could not return valid expectation' - ); - } - /** * @expectedException \Icinga\Exception\ConfigurationError */