Merge remote-tracking branch 'origin/master' into bugfix/broken-badges-7736

This commit is contained in:
Marius Hein 2014-11-19 15:28:27 +01:00
commit 32af89e0a7
53 changed files with 1031 additions and 654 deletions

View File

@ -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());
}
}

View File

@ -1,116 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Forms\Dashboard;
use Icinga\Application\Config;
use Icinga\Web\Widget\Dashboard;
use Icinga\Web\Form;
/**
* Form to add an url a dashboard pane
*/
class AddUrlForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->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();
}
}

View File

@ -0,0 +1,193 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Forms\Dashboard;
use Icinga\Web\Widget\Dashboard;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Web\Widget\Dashboard\Component;
/**
* Form to add an url a dashboard pane
*/
class ComponentForm extends Form
{
/**
* @var Dashboard
*/
private $dashboard;
/**
* Initialize this form
*/
public function init()
{
$this->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()
));
}
}

View File

@ -5,6 +5,7 @@
</div>
</div>
<div class="form" data-base-target="layout">
<h1>Welcome to Icinga Web 2</h1>
<?php
/* TODO: remove this as soon as notifications and forms are ready */
if (isset($this->errorInfo)): ?>

View File

@ -3,10 +3,6 @@
</div>
<div class="content">
<h1><?= $this->escape($this->translate('This feature is deactivated at the moment.')); ?></h1>
<p>
<?=
$this->escape($this->translate('Please have a little patience, we are hard working on it, take a look at icingaweb2 issues.'));
?>
</p>
<h1><?= t('Add URL to Dashboard'); ?></h1>
<?= $this->form; ?>
</div>

View File

@ -0,0 +1,13 @@
<div class="content">
<h1><?= t('Could not persist dashboard'); ?></h1>
<p>
<?= t('Please copy the following dashboard snippet to '); ?>
<strong><?= $this->config->getFilename(); ?>;</strong>.
<br>
<?= t('Make sure that the webserver can write to this file.'); ?>
</p>
<pre><?= (string) $this->config->render(); ?></pre>
<hr>
<h2><?= t('Error details') ?></h2>
<p><?= $this->error->getMessage(); ?></p>
</div>

View File

@ -8,9 +8,11 @@
<?php else: ?>
<div class="content">
<h1><?= $this->escape($this->translate('Welcome to Icinga Web!')) ?></h1>
<p><?= sprintf(
$this->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')
) ?></p>
<p>
<?= sprintf(
$this->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')
) ?>
</p>
</div>
<?php endif ?>

View File

@ -0,0 +1,7 @@
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content">
<h1><?= t('Add Component To Dashboard'); ?></h1>
<?= $this->form; ?>
</div>

View File

@ -0,0 +1,14 @@
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content">
<h1><?= t('Remove Component From Dashboard'); ?></h1>
<p>
<?= $this->translate('Please confirm the removal'); ?>:
<?= $this->pane; ?>/<?= $this->component; ?>
</p>
<?= $this->form; ?>
</div>

View File

@ -0,0 +1,14 @@
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content">
<h1><?= t('Remove Pane'); ?></h1>
<p>
<?= $this->translate('Please confirm the removal of'); ?>:
<?= $this->pane; ?>
</p>
<?= $this->form; ?>
</div>

View File

@ -0,0 +1,62 @@
<?php
?>
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content">
<h1><?= t('Dashboard Settings'); ?></h1>
<table class="avp" data-base-target="_next">
<thead>
<tr>
<th>
<strong><?= t('Component Name') ?></strong>
</th>
<th>
<strong><?= t('Url') ?></strong>
</th>
</tr>
</thead>
<tbody>
<?php foreach ($this->dashboard->getPanes() as $pane): ?>
<tr style="background-color: #f1f1f1;">
<th colspan="2" style="text-align: left; padding: 0.5em;">
<?= $pane->getName(); ?>
</th>
<th>
<a href="<?= $this->href('dashboard/remove-pane', array('pane' => $pane->getName())); ?>">
<?= $this->icon('cancel'); ?>
</a>
</th>
</tr>
<?php $components = $pane->getComponents(); ?>
<?php if(empty($components)): ?>
<tr>
<td colspan="3">
<?= $this->translate('No compoments added to dashboard') ?>.
</td>
</tr>
<?php else: ?>
<?php foreach ($components as $component): ?>
<?php if ($component->getDisabled() === true) continue; ?>
<tr>
<td>
<a href="<?= $this->href('dashboard/update-component', array('pane' => $pane->getName(), 'component' => $component->getTitle())); ?>">
<?= $component->getTitle(); ?>
</a>
</td>
<td>
<a href="<?= $this->href($component->getUrl()); ?>"><?= $component->getUrl(); ?></a>
</td>
<td>
<a href="<?= $this->href('dashboard/remove-component', array('pane' => $pane->getName(), 'component' => $component->getTitle())); ?>">
<?= $this->icon('cancel'); ?>
</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
<?php endforeach; ?>
</tbody>
</table>
</div>

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

@ -0,0 +1,8 @@
<div class="controls">
<?= $this->tabs ?>
</div>
<div class="content">
<h1><?= t('Edit Component'); ?></h1>
<?= $this->form; ?>
</div>

View File

@ -229,4 +229,14 @@ class IniWriter extends Zend_Config_Writer_FileAbstract
return $combinations;
}
/**
* Getter for filename
*
* @return string
*/
public function getFilename()
{
return $this->_filename;
}
}

View File

@ -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
*

View File

@ -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';
}
}

View File

@ -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'
<div class="container" data-icinga-url="{URL}">
<h1>{REMOVE}<a href="{FULL_URL}" data-base-target="col1">{TITLE}</a></h1>
<h1><a href="{FULL_URL}" data-base-target="col1">{TITLE}</a></h1>
<noscript>
<iframe src="{IFRAME_URL}" style="height:100%; width:99%" frameborder="no"></iframe>
</noscript>
@ -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(
'<a data-base-target="main" href="%s">%s</a>',
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;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,37 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web\Widget\Dashboard;
use Icinga\Web\Widget\AbstractWidget;
abstract class UserWidget extends AbstractWidget
{
/**
* Flag if widget is created by an user
*
* @var bool
*/
protected $userWidget = false;
/**
* Set the user widget flag
*
* @param boolean $userWidget
*/
public function setUserWidget($userWidget = true)
{
$this->userWidget = (bool) $userWidget;
}
/**
* Getter for user widget flag
*
* @return boolean
*/
public function isUserWidget()
{
return $this->userWidget;
}
}

View File

@ -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())
)

View File

@ -0,0 +1,40 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Web\Widget\Tabextension;
use Icinga\Web\Url;
use Icinga\Web\Widget\Tabs;
/**
* Dashboard settings
*/
class DashboardSettings implements Tabextension
{
/**
* Apply this tabextension to the provided tabs
*
* @param Tabs $tabs The tabbar to modify
*/
public function apply(Tabs $tabs)
{
$tabs->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')
)
);
}
}

View File

@ -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' => '<img src="' . $iconUrl . '"> ' . mt('monitoring', 'Check now'),
'label' => '<i class="icon-reschedule"></i> ' . mt('monitoring', 'Check now'),
'decorators' => array('ViewHelper'),
'escape' => false,
'class' => 'link-like'

View File

@ -1,2 +0,0 @@
PLEASE DO NOT USE THIS YET. Still preparing basic stuff, should be ready
with 2.0.0-beta1

View File

@ -1,2 +1,3 @@
packages/files/bin/icingacli usr/bin
etc/bash_completion.d etc/bash_completion.d
application/clicommands usr/share/icingaweb/application

View File

@ -0,0 +1,2 @@
application/locales usr/share/icingaweb/application
modules usr/share/icingaweb

View File

@ -0,0 +1 @@
modules/doc usr/share/icingaweb/modules

View File

@ -0,0 +1 @@
modules/doc usr/share/icingaweb/modules

View File

@ -0,0 +1 @@
modules/setup usr/share/icingaweb/modules

View File

@ -0,0 +1 @@
modules/test usr/share/icingaweb/modules

View File

@ -0,0 +1 @@
modules/translation usr/share/icingaweb/modules

View File

@ -0,0 +1 @@
library/vendor/HTMLPurifier usr/share/icingaweb/library/vendor

View File

@ -0,0 +1 @@
library/vendor/JShrink usr/share/icingaweb/library/vendor

View File

@ -0,0 +1 @@
library/vendor/Zend usr/share/icingaweb/library/vendor

View File

@ -0,0 +1 @@
library/vendor/Parsedown usr/share/icingaweb/library/vendor

View File

@ -0,0 +1 @@
library/vendor/Zend usr/share/icingaweb/library/vendor

View File

@ -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

View File

@ -1,2 +0,0 @@
application usr/share/icingaweb
modules usr/share/icingaweb

View File

@ -1 +0,0 @@
library/IcingaVendor usr/share/php

View File

@ -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

View File

@ -0,0 +1,38 @@
Alias /icingaweb "/usr/share/icingaweb/public"
<Directory "/usr/share/icingaweb/public">
Options SymLinksIfOwnerMatch
AllowOverride None
<IfModule mod_authz_core.c>
# Apache 2.4
<RequireAll>
Require all granted
</RequireAll>
</IfModule>
<IfModule !mod_authz_core.c>
# Apache 2.2
Order allow,deny
Allow from all
</IfModule>
SetEnv ICINGAWEB_CONFIGDIR "/etc/icingaweb"
EnableSendfile Off
<IfModule mod_rewrite.c>
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]
</IfModule>
<IfModule !mod_rewrite.c>
DirectoryIndex error_norewrite.html
ErrorDocument 404 /error_norewrite.html
</IfModule>
</Directory>

View File

@ -1,6 +1,6 @@
#!/usr/bin/php
<?php
define('ICINGAWEB_APPDIR', '/usr/share/icingaweb/application');
require_once 'Icinga/Application/Cli.php';
Icinga\Application\Cli::start()->dispatch();
require_once '/usr/share/php/Icinga/Application/Cli.php';
Icinga\Application\Cli::start('/usr/share/icingaweb')->dispatch();

View File

@ -1,19 +0,0 @@
Alias /icingaweb "/usr/share/icingaweb/public"
<Directory "/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]
</Directory>

View File

@ -1,6 +1,3 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
define('ICINGAWEB_APPDIR', dirname(__DIR__) . '/application');
require_once 'Icinga/Application/webrouter.php';
require_once '/usr/share/php/Icinga/Application/webrouter.php';

View File

@ -1,32 +0,0 @@
Alias /icingaweb "/usr/share/icingaweb2/public"
<Directory "/usr/share/icingaweb2/public">
Options SymLinksIfOwnerMatch
AllowOverride None
<IfModule mod_authz_core.c>
# Apache 2.4
<RequireAll>
Require all granted
</RequireAll>
</IfModule>
<IfModule !mod_authz_core.c>
# Apache 2.2
Order allow,deny
Allow from all
</IfModule>
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]
</Directory>

View File

@ -1,6 +0,0 @@
[autologin]
backend = autologin
[internal_db_authentication]
backend = db
resource = internal_db

View File

@ -1,8 +0,0 @@
[localdb]
type = ido
resource = "ido"
[locallive]
disabled = "1"
type = livestatus
resource = livestatus

View File

@ -1,2 +0,0 @@
[icinga]
path = "/var/run/icinga2/cmd/icinga2.cmd"

View File

@ -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 = "/^(?<datetime>[0-9]{4}(-[0-9]{2}){2}T[0-9]{2}(:[0-9]{2}){2}(\\+[0-9]{2}:[0-9]{2})?) - (?<loglevel>[A-Za-z]+) - (?<message>.*)$/"
; format: PCRE
;

View File

@ -1,6 +0,0 @@
#!/usr/bin/php
<?php
use Icinga\Application\Cli;
require_once '/usr/share/icingaweb2/library/Icinga/Application/Cli.php';
Cli::start()->dispatch();

View File

@ -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 {

View File

@ -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
*/