diff --git a/application/controllers/DashboardController.php b/application/controllers/DashboardController.php index 923803d5c..7b917e2e7 100644 --- a/application/controllers/DashboardController.php +++ b/application/controllers/DashboardController.php @@ -28,14 +28,16 @@ */ // {{{ICINGA_LICENSE_HEADER}}} -use Icinga\Web\Controller\ActionController; +use \Zend_Config; use Icinga\Web\Url; -use Icinga\Web\Widget\Dashboard; -use Icinga\Application\Config as IcingaConfig; -use Icinga\Form\Dashboard\AddUrlForm; -use Icinga\Exception\ConfigurationError; -use Icinga\Exception\NotReadableError; use Icinga\Logger\Logger; +use Icinga\Config\PreservingIniWriter; +use Icinga\Application\Config as IcingaConfig; +use Icinga\Web\Widget\Dashboard; +use Icinga\Form\Dashboard\AddUrlForm; +use Icinga\Exception\NotReadableError; +use Icinga\Exception\ConfigurationError; +use Icinga\Web\Controller\ActionController; /** * Handle creation, removal and displaying of dashboards, panes and components @@ -88,13 +90,19 @@ class DashboardController extends ActionController */ public function addurlAction() { - $this->getTabs()->add('addurl', array( - 'title' => 'Add Dashboard URL', - 'url' => Url::fromRequest() - ))->activate('addurl'); + $this->getTabs()->add( + 'addurl', + array( + 'title' => 'Add Dashboard URL', + 'url' => Url::fromRequest() + ) + )->activate('addurl'); + $form = new AddUrlForm(); - $form->setRequest($this->_request); + $form->setRequest($this->getRequest()); + $form->setAction(Url::fromRequest()->setParams(array())->getAbsoluteUrl()); $this->view->form = $form; + if ($form->isSubmittedAndValid()) { $dashboard = $this->getDashboard(); $dashboard->setComponentUrl( @@ -102,15 +110,12 @@ class DashboardController extends ActionController $form->getValue('component'), ltrim($form->getValue('url'), '/') ); - try { - $dashboard->store(); - $this->redirectNow( - Url::fromPath('dashboard', array('pane' => $form->getValue('pane'))) - ); - } catch (ConfigurationError $exc) { - $this->_helper->viewRenderer('show_configuration'); - $this->view->exceptionMessage = $exc->getMessage(); - $this->view->iniConfigurationString = $dashboard->toIni(); + + $configFile = IcingaConfig::app('dashboard/dashboard')->getConfigFile(); + if ($this->writeConfiguration(new Zend_Config($dashboard->toArray()), $configFile)) { + $this->redirectNow(Url::fromPath('dashboard', array('pane' => $form->getValue('pane')))); + } else { + $this->render('show-configuration'); } } } @@ -141,5 +146,30 @@ class DashboardController extends ActionController */ $this->view->dashboard = $dashboard; } + + /** + * Store the given configuration as INI file + * + * @param Zend_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 + */ + protected function writeConfiguration(Zend_Config $config, $target) + { + $writer = new PreservingIniWriter(array('config' => $config, 'filename' => $target)); + + try { + $writer->write(); + } catch (Exception $e) { + Logger::error(new ConfiguationError("Cannot write dashboard to $target", 0, $e)); + $this->view->iniConfigurationString = $writer->render(); + $this->view->exceptionMessage = $e->getMessage(); + $this->view->file = $target; + return false; + } + + return true; + } } // @codeCoverageIgnoreEnd diff --git a/application/forms/Dashboard/AddUrlForm.php b/application/forms/Dashboard/AddUrlForm.php index 65c6fd25f..8a914f868 100644 --- a/application/forms/Dashboard/AddUrlForm.php +++ b/application/forms/Dashboard/AddUrlForm.php @@ -43,7 +43,6 @@ use Zend_Form_Element_Select; */ class AddUrlForm extends Form { - /** * Add a selection box for different panes to the form * @@ -140,7 +139,7 @@ class AddUrlForm extends Form array( 'label' => 'Url', 'required' => true, - 'value' => $this->getRequest()->getParam('url', null) + 'value' => htmlspecialchars_decode($this->getRequest()->getParam('url', '')) ) ); $elems = $dashboard->getPaneKeyTitleArray(); diff --git a/library/Icinga/Web/Widget/Dashboard.php b/library/Icinga/Web/Widget/Dashboard.php index dee8720a8..107e4c0a6 100644 --- a/library/Icinga/Web/Widget/Dashboard.php +++ b/library/Icinga/Web/Widget/Dashboard.php @@ -31,8 +31,6 @@ namespace Icinga\Web\Widget; use Icinga\Application\Icinga; use Icinga\Application\Config as IcingaConfig; -use Icinga\Logger\Logger; -use Icinga\Exception\ConfigurationError; use Icinga\Exception\ProgrammingError; use Icinga\Web\Widget\AbstractWidget; use Icinga\Web\Widget\Dashboard\Pane; @@ -114,46 +112,6 @@ class Dashboard extends AbstractWidget return $this->tabs; } - /** - * Store the current dashboard with all it's panes and components to the given file (or the default one if none is - * given) - * - * - * @param string $file The filename to store this dashboard as an ini - * - * @return $this - * @throws \Icinga\Exception\ConfigurationError If persisting fails, details are written to the log - * - */ - public function store($file = null) - { - if ($file === null) { - $file = IcingaConfig::app('dashboard/dashboard')->getConfigFile(); - } - - if (!is_writable($file)) { - Logger::error('Tried to persist dashboard to %s, but path is not writeable', $file); - throw new ConfigurationError('Can\'t persist dashboard'); - } - // make sure empty dashboards don't cause errors - $iniString = trim($this->toIni()); - if (!$iniString) { - $iniString = ' '; - } - if (!@file_put_contents($file, $iniString)) { - $error = error_get_last(); - if ($error == null) { - $error = 'Unknown Error'; - } else { - $error = $error['message']; - } - Logger::error('Tried to persist dashboard to %s, but got error: %s', $file, $error); - throw new ConfigurationError('Can\'t Persist Dashboard'); - } else { - return $this; - } - } - /** * Populate this dashboard via the given configuration file * @@ -351,17 +309,18 @@ class Dashboard extends AbstractWidget } /** - * Return the ini string describing this dashboard + * Return this dashboard's structure as array * - * @return string + * @return array */ - public function toIni() + public function toArray() { - $ini = ''; + $array = array(); foreach ($this->panes as $pane) { - $ini .= $pane->toIni(); + $array += $pane->toArray(); } - return $ini; + + return $array; } /** diff --git a/library/Icinga/Web/Widget/Dashboard/Component.php b/library/Icinga/Web/Widget/Dashboard/Component.php index ad984c5fb..6b355e3e0 100644 --- a/library/Icinga/Web/Widget/Dashboard/Component.php +++ b/library/Icinga/Web/Widget/Dashboard/Component.php @@ -144,17 +144,18 @@ EOD; } /** - * Return this component in a suitable format and encoding for ini files + * Return this component's structure as array * - * @return string + * @return array */ - public function toIni() + public function toArray() { - $ini = 'url = "' . $this->url->getRelativeUrl() . '"' . PHP_EOL; - foreach ($this->url->getParams() as $key => $val) { - $ini .= $key.' = "' . $val . '"' . PHP_EOL; + $array = array('url' => $this->url->getPath()); + foreach ($this->url->getParams() as $key => $value) { + $array[$key] = $value; } - return $ini; + + return $array; } /** diff --git a/library/Icinga/Web/Widget/Dashboard/Pane.php b/library/Icinga/Web/Widget/Dashboard/Pane.php index d9d943fab..24b43040d 100644 --- a/library/Icinga/Web/Widget/Dashboard/Pane.php +++ b/library/Icinga/Web/Widget/Dashboard/Pane.php @@ -29,15 +29,13 @@ namespace Icinga\Web\Widget\Dashboard; -use Icinga\Exception\ConfigurationError; -use Icinga\Exception\ProgrammingError; -use Icinga\Web\Widget\AbstractWidget; use Zend_Config; -use Zend_View_Abstract; +use Icinga\Web\Widget\AbstractWidget; +use Icinga\Exception\ProgrammingError; +use Icinga\Exception\ConfigurationError; /** * A pane, displaying different Dashboard components - * */ class Pane extends AbstractWidget { @@ -190,25 +188,18 @@ class Pane extends AbstractWidget } /** - * Return the ini representation of this pane as a string + * Return the this pane's structure as array * - * @return string + * @return array */ - public function toIni() + public function toArray() { - if (empty($this->components)) { - return ''; - } - $ini = '[' . $this->getName() . ']' . PHP_EOL. - 'title = "' . $this->getTitle() . '"' . PHP_EOL; - + $array = array($this->getName() => array('title' => $this->getTitle())); foreach ($this->components as $title => $component) { - // component header - $ini .= '[' . $this->getName() . '.' . $title . ']' . PHP_EOL; - // component content - $ini .= $component->toIni() . PHP_EOL; + $array[$this->getName() . ".$title"] = $component->toArray(); } - return $ini; + + return $array; } /** diff --git a/modules/monitoring/application/controllers/ConfigController.php b/modules/monitoring/application/controllers/ConfigController.php index f10ecf826..5bd6b3b3c 100644 --- a/modules/monitoring/application/controllers/ConfigController.php +++ b/modules/monitoring/application/controllers/ConfigController.php @@ -263,19 +263,19 @@ class Monitoring_ConfigController extends BaseConfigController { */ private function writeConfiguration($config, $file) { + $target = IcingaConfig::module('monitoring', $file)->getConfigFile(); + $writer = new PreservingIniWriter(array('filename' => $target, 'config' => $config)); + try { - $writer = new PreservingIniWriter(array( - 'filename' => IcingaConfig::module('monitoring', $file)->getConfigFile(), - 'config' => $config - )); $writer->write(); - return true; } catch (Exception $exc) { $this->view->exceptionMessage = $exc->getMessage(); $this->view->iniConfigurationString = $writer->render(); - $this->view->file = IcingaConfig::module('monitoring', $file)->getConfigFile(); + $this->view->file = $target; return false; } + + return true; } /**