Make dashboard components using the ini writer class

fixes #5524
This commit is contained in:
Johannes Meyer 2014-04-29 11:30:34 +02:00
parent e1d8ad820e
commit e2ba172a8e
6 changed files with 82 additions and 102 deletions

View File

@ -28,14 +28,16 @@
*/ */
// {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Web\Controller\ActionController; use \Zend_Config;
use Icinga\Web\Url; 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\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 * Handle creation, removal and displaying of dashboards, panes and components
@ -88,13 +90,19 @@ class DashboardController extends ActionController
*/ */
public function addurlAction() public function addurlAction()
{ {
$this->getTabs()->add('addurl', array( $this->getTabs()->add(
'title' => 'Add Dashboard URL', 'addurl',
'url' => Url::fromRequest() array(
))->activate('addurl'); 'title' => 'Add Dashboard URL',
'url' => Url::fromRequest()
)
)->activate('addurl');
$form = new AddUrlForm(); $form = new AddUrlForm();
$form->setRequest($this->_request); $form->setRequest($this->getRequest());
$form->setAction(Url::fromRequest()->setParams(array())->getAbsoluteUrl());
$this->view->form = $form; $this->view->form = $form;
if ($form->isSubmittedAndValid()) { if ($form->isSubmittedAndValid()) {
$dashboard = $this->getDashboard(); $dashboard = $this->getDashboard();
$dashboard->setComponentUrl( $dashboard->setComponentUrl(
@ -102,15 +110,12 @@ class DashboardController extends ActionController
$form->getValue('component'), $form->getValue('component'),
ltrim($form->getValue('url'), '/') ltrim($form->getValue('url'), '/')
); );
try {
$dashboard->store(); $configFile = IcingaConfig::app('dashboard/dashboard')->getConfigFile();
$this->redirectNow( if ($this->writeConfiguration(new Zend_Config($dashboard->toArray()), $configFile)) {
Url::fromPath('dashboard', array('pane' => $form->getValue('pane'))) $this->redirectNow(Url::fromPath('dashboard', array('pane' => $form->getValue('pane'))));
); } else {
} catch (ConfigurationError $exc) { $this->render('show-configuration');
$this->_helper->viewRenderer('show_configuration');
$this->view->exceptionMessage = $exc->getMessage();
$this->view->iniConfigurationString = $dashboard->toIni();
} }
} }
} }
@ -141,5 +146,30 @@ class DashboardController extends ActionController
*/ */
$this->view->dashboard = $dashboard; $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 // @codeCoverageIgnoreEnd

View File

@ -43,7 +43,6 @@ use Zend_Form_Element_Select;
*/ */
class AddUrlForm extends Form class AddUrlForm extends Form
{ {
/** /**
* Add a selection box for different panes to the form * Add a selection box for different panes to the form
* *
@ -140,7 +139,7 @@ class AddUrlForm extends Form
array( array(
'label' => 'Url', 'label' => 'Url',
'required' => true, 'required' => true,
'value' => $this->getRequest()->getParam('url', null) 'value' => htmlspecialchars_decode($this->getRequest()->getParam('url', ''))
) )
); );
$elems = $dashboard->getPaneKeyTitleArray(); $elems = $dashboard->getPaneKeyTitleArray();

View File

@ -31,8 +31,6 @@ namespace Icinga\Web\Widget;
use Icinga\Application\Icinga; use Icinga\Application\Icinga;
use Icinga\Application\Config as IcingaConfig; use Icinga\Application\Config as IcingaConfig;
use Icinga\Logger\Logger;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\ProgrammingError; use Icinga\Exception\ProgrammingError;
use Icinga\Web\Widget\AbstractWidget; use Icinga\Web\Widget\AbstractWidget;
use Icinga\Web\Widget\Dashboard\Pane; use Icinga\Web\Widget\Dashboard\Pane;
@ -114,46 +112,6 @@ class Dashboard extends AbstractWidget
return $this->tabs; 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 * 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) { foreach ($this->panes as $pane) {
$ini .= $pane->toIni(); $array += $pane->toArray();
} }
return $ini;
return $array;
} }
/** /**

View File

@ -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; $array = array('url' => $this->url->getPath());
foreach ($this->url->getParams() as $key => $val) { foreach ($this->url->getParams() as $key => $value) {
$ini .= $key.' = "' . $val . '"' . PHP_EOL; $array[$key] = $value;
} }
return $ini;
return $array;
} }
/** /**

View File

@ -29,15 +29,13 @@
namespace Icinga\Web\Widget\Dashboard; namespace Icinga\Web\Widget\Dashboard;
use Icinga\Exception\ConfigurationError;
use Icinga\Exception\ProgrammingError;
use Icinga\Web\Widget\AbstractWidget;
use Zend_Config; 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 * A pane, displaying different Dashboard components
*
*/ */
class Pane extends AbstractWidget 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)) { $array = array($this->getName() => array('title' => $this->getTitle()));
return '';
}
$ini = '[' . $this->getName() . ']' . PHP_EOL.
'title = "' . $this->getTitle() . '"' . PHP_EOL;
foreach ($this->components as $title => $component) { foreach ($this->components as $title => $component) {
// component header $array[$this->getName() . ".$title"] = $component->toArray();
$ini .= '[' . $this->getName() . '.' . $title . ']' . PHP_EOL;
// component content
$ini .= $component->toIni() . PHP_EOL;
} }
return $ini;
return $array;
} }
/** /**

View File

@ -263,19 +263,19 @@ class Monitoring_ConfigController extends BaseConfigController {
*/ */
private function writeConfiguration($config, $file) private function writeConfiguration($config, $file)
{ {
$target = IcingaConfig::module('monitoring', $file)->getConfigFile();
$writer = new PreservingIniWriter(array('filename' => $target, 'config' => $config));
try { try {
$writer = new PreservingIniWriter(array(
'filename' => IcingaConfig::module('monitoring', $file)->getConfigFile(),
'config' => $config
));
$writer->write(); $writer->write();
return true;
} catch (Exception $exc) { } catch (Exception $exc) {
$this->view->exceptionMessage = $exc->getMessage(); $this->view->exceptionMessage = $exc->getMessage();
$this->view->iniConfigurationString = $writer->render(); $this->view->iniConfigurationString = $writer->render();
$this->view->file = IcingaConfig::module('monitoring', $file)->getConfigFile(); $this->view->file = $target;
return false; return false;
} }
return true;
} }
/** /**