Widget/Dashboard: Cleanup object and remove unused stuff

refs #4537
This commit is contained in:
Marius Hein 2014-11-11 14:44:38 +01:00
parent 5f9d394bbe
commit af799d42dc
4 changed files with 133 additions and 236 deletions

View File

@ -20,54 +20,6 @@ use Icinga\Web\Widget\Dashboard;
*/ */
class DashboardController extends ActionController class DashboardController extends ActionController
{ {
/**
* Default configuration
*/
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)
{
$dashboard = new Dashboard();
try {
$dashboardConfig = Config::app($config);
if (count($dashboardConfig) === 0) {
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;
}
/**
* Remove a component from the pane identified by the 'pane' parameter
*/
public function removecomponentAction()
{
$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();
}
}
/** /**
* Display the form for adding new components or add the new component if submitted * Display the form for adding new components or add the new component if submitted
*/ */
@ -93,7 +45,9 @@ class DashboardController extends ActionController
*/ */
public function indexAction() public function indexAction()
{ {
$dashboard = Dashboard::load(); $dashboard = new Dashboard();
$dashboard->setUser($this->getRequest()->getUser());
$dashboard->load();
if (! $dashboard->hasPanes()) { if (! $dashboard->hasPanes()) {
$this->view->title = 'Dashboard'; $this->view->title = 'Dashboard';
@ -103,8 +57,6 @@ class DashboardController extends ActionController
$dashboard->activate($pane); $dashboard->activate($pane);
} }
$this->view->configPath = Config::resolvePath(self::DEFAULT_CONFIG);
if ($dashboard === null) { if ($dashboard === null) {
$this->view->title = 'Dashboard'; $this->view->title = 'Dashboard';
} else { } else {
@ -125,29 +77,4 @@ class DashboardController extends ActionController
} }
} }
} }
/**
* 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
*/
protected function writeConfiguration(Config $config, $target)
{
$writer = new IniWriter(array('config' => $config, 'filename' => $target));
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;
}
} }

View File

@ -5,6 +5,7 @@
namespace Icinga\Forms\Dashboard; namespace Icinga\Forms\Dashboard;
use Icinga\Application\Config; use Icinga\Application\Config;
use Icinga\File\Ini\IniWriter;
use Icinga\Web\Widget\Dashboard; use Icinga\Web\Widget\Dashboard;
use Icinga\Web\Form; use Icinga\Web\Form;
use Icinga\Web\Request; use Icinga\Web\Request;
@ -14,6 +15,13 @@ use Icinga\Web\Request;
*/ */
class AddUrlForm extends Form class AddUrlForm extends Form
{ {
/**
* Config file name
*
* @var string
*/
private $configFile = 'dashboard/dashboard';
/** /**
* Initialize this form * Initialize this form
*/ */
@ -134,16 +142,42 @@ class AddUrlForm extends Form
); );
} }
/**
* Create a dashboard object
*
* @return Dashboard
*/
private function createDashboard()
{
$dashboard = new Dashboard();
$dashboard->readConfig(Config::app($this->getConfigFile()));
return $dashboard;
}
/** /**
* Return the names and titles of the available dashboard panes as key-value array * Return the names and titles of the available dashboard panes as key-value array
* *
* @return array * @return array
*/ */
protected function getDashboardPaneSelectionValues() private function getDashboardPaneSelectionValues()
{ {
$dashboard = new Dashboard(); return $this->createDashboard()->getPaneKeyTitleArray();
$dashboard->readConfig(Config::app('dashboard/dashboard')); }
return $dashboard->getPaneKeyTitleArray();
/**
* @param string $configFile
*/
public function setConfigFile($configFile)
{
$this->configFile = $configFile;
}
/**
* @return string
*/
public function getConfigFile()
{
return $this->configFile;
} }
/** /**
@ -153,6 +187,22 @@ class AddUrlForm extends Form
*/ */
public function onSuccess(Request $request) public function onSuccess(Request $request)
{ {
$dashboard = $this->createDashboard();
$dashboard->setComponentUrl(
$this->getValue('pane'),
$this->getValue('component'),
ltrim($this->getValue('url'), '/')
);
/*
$writer = new IniWriter(
array(
'config' => new Config($dashboard->toArray()),
'filename' => $dashboard->getConfig()->getConfigFile()
)
);
$writer->write();
*/
return false; return false;
} }
@ -163,6 +213,9 @@ class AddUrlForm extends Form
*/ */
public function onRequest(Request $request) public function onRequest(Request $request)
{ {
$data = array(
'url' => $request->getParam('url')
);
$this->populate($data);
} }
} }

View File

@ -1,28 +0,0 @@
<br/>
<div class="alert alert-error">
<h4><i>{{WARNING_ICON}}</i>Saving Dashboard Failed</h4>
<br/>
<p>
Your dashboard couldn't be stored (error: "<?= $this->exceptionMessage; ?>"). This could have one or more
of the following reasons:
</p>
<ul>
<li>You don't have permissions to write to the dashboard file</li>
<li>Something went wrong while writing the file</li>
<li>There's an application error preventing you from persisting the configuration</li>
</ul>
</div>
<p>
Details can be seen in your application log (if you don't have access to this file, call your administrator in this case).
<br/>
In case you can access the configuration file (config/dashboard/dashboard.ini) by yourself, you can open it and
insert the config manually:
</p>
<p>
<pre>
<code>
<?= $this->escape($this->iniConfigurationString); ?>
</code>
</pre>
</p>

View File

@ -8,6 +8,7 @@ use Icinga\Application\Icinga;
use Icinga\Application\Config; use Icinga\Application\Config;
use Icinga\Exception\ConfigurationError; use Icinga\Exception\ConfigurationError;
use Icinga\Exception\ProgrammingError; use Icinga\Exception\ProgrammingError;
use Icinga\User;
use Icinga\Web\Widget\Dashboard\Pane; use Icinga\Web\Widget\Dashboard\Pane;
use Icinga\Web\Widget\Dashboard\Component as DashboardComponent; use Icinga\Web\Widget\Dashboard\Component as DashboardComponent;
use Icinga\Web\Url; use Icinga\Web\Url;
@ -23,13 +24,6 @@ use Icinga\Web\Url;
*/ */
class Dashboard extends AbstractWidget class Dashboard extends AbstractWidget
{ {
/**
* The configuration containing information about this dashboard
*
* @var Config;
*/
private $config;
/** /**
* An array containing all panes of this dashboard * An array containing all panes of this dashboard
* *
@ -51,6 +45,11 @@ class Dashboard extends AbstractWidget
*/ */
private $tabParam = 'pane'; private $tabParam = 'pane';
/**
* @var User
*/
private $user;
/** /**
* Set the given tab name as active. * Set the given tab name as active.
* *
@ -67,23 +66,71 @@ class Dashboard extends AbstractWidget
* *
* @return self * @return self
*/ */
public static function load() public function load()
{ {
/** @var $dashboard Dashboard */
$dashboard = new static('dashboard');
$manager = Icinga::app()->getModuleManager(); $manager = Icinga::app()->getModuleManager();
foreach ($manager->getLoadedModules() as $module) { foreach ($manager->getLoadedModules() as $module) {
/** @var $module \Icinga\Application\Modules\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;
}
/**
* @return bool
*/
private function loadUserDashboards()
{
$configFile = '/var/lib/icingaweb/' . $this->user->getUsername() . '/dashboard.ini';
$config = Config::fromIni($configFile);
if (! count($config)) {
return false;
}
$panes = array();
$components = array();
foreach ($config as $key => $part) {
if (strpos($key, '.') === false) {
$panes[$key] = new Pane($key);
$panes[$key]->setTitle($part->title);
} 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;
}
$pane->addComponent(
new DashboardComponent(
$componentData->title,
$componentData->url,
$pane
)
);
}
$this->mergePanes($panes);
return true;
} }
/** /**
* Merge panes with existing panes * Merge panes with existing panes
* *
* @param array $panes * @param array $panes
*
* @return $this * @return $this
*/ */
public function mergePanes(array $panes) public function mergePanes(array $panes)
@ -134,23 +181,10 @@ class Dashboard extends AbstractWidget
*/ */
public function getPanes() public function getPanes()
{ {
return '';
return $this->panes; 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 * Creates a new empty pane with the given title
@ -168,34 +202,6 @@ class Dashboard extends AbstractWidget
return $this; 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 * Checks if the current dashboard has any panes
* *
@ -206,52 +212,6 @@ class Dashboard extends AbstractWidget
return ! empty($this->panes); return ! empty($this->panes);
} }
/**
* Check if this dashboard has a specific pane
*
* @param $pane string The name of the 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;
}
/** /**
* Add a pane object to this dashboard * Add a pane object to this dashboard
* *
@ -319,6 +279,9 @@ class Dashboard extends AbstractWidget
/** /**
* Determine the active pane either by the selected tab or the current request * Determine the active pane either by the selected tab or the current request
* *
* @throws \Icinga\Exception\ConfigurationError
* @throws \Icinga\Exception\ProgrammingError
*
* @return Pane The currently active pane * @return Pane The currently active pane
*/ */
public function determineActivePane() public function determineActivePane()
@ -346,36 +309,18 @@ class Dashboard extends AbstractWidget
} }
/** /**
* Return this dashboard's structure as array * @param \Icinga\User $user
*
* @return array
*/ */
public function toArray() public function setUser($user)
{ {
$array = array(); $this->user = $user;
foreach ($this->panes as $pane) {
$array += $pane->toArray();
}
return $array;
} }
/** /**
* Load all config panes from @see Dashboard::$config * @return \Icinga\User
*
*/ */
private function loadConfigPanes() public function getUser()
{ {
$items = $this->config; return $this->user;
foreach ($items->keys() as $key) {
$item = $this->config->get($key, false);
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));
}
}
} }
} }