Merge branch 'bugfix/rebuild-form-builder-5525' into bugfix/commands-6593

Conflicts:
	application/forms/Preference/GeneralForm.php
This commit is contained in:
Eric Lippmann 2014-09-15 09:27:07 +02:00
commit 9e0d6657b7
74 changed files with 1813 additions and 2801 deletions
application
doc
library
modules
public
test/php

@ -46,7 +46,7 @@ class ConfigController extends ActionController
public function indexAction()
{
$form = new GeneralConfigForm();
$form->setConfig(IcingaConfig::app());
$form->setIniConfig(IcingaConfig::app());
$form->handleRequest();
$this->view->form = $form;
@ -131,7 +131,7 @@ class ConfigController extends ActionController
public function authenticationAction()
{
$form = new AuthenticationBackendReorderForm();
$form->setConfig(IcingaConfig::app('authentication'));
$form->setIniConfig(IcingaConfig::app('authentication'));
$form->handleRequest();
$this->view->form = $form;
@ -145,7 +145,7 @@ class ConfigController extends ActionController
public function createauthenticationbackendAction()
{
$form = new AuthenticationBackendConfigForm();
$form->setConfig(IcingaConfig::app('authentication'));
$form->setIniConfig(IcingaConfig::app('authentication'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('config/authentication');
$form->handleRequest();
@ -161,7 +161,7 @@ class ConfigController extends ActionController
public function editauthenticationbackendAction()
{
$form = new AuthenticationBackendConfigForm();
$form->setConfig(IcingaConfig::app('authentication'));
$form->setIniConfig(IcingaConfig::app('authentication'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('config/authentication');
$form->handleRequest();
@ -179,7 +179,7 @@ class ConfigController extends ActionController
$form = new ConfirmRemovalForm(array(
'onSuccess' => function ($request) {
$configForm = new AuthenticationBackendConfigForm();
$configForm->setConfig(IcingaConfig::app('authentication'));
$configForm->setIniConfig(IcingaConfig::app('authentication'));
$authBackend = $request->getQuery('auth_backend');
try {
@ -222,7 +222,7 @@ class ConfigController extends ActionController
public function createresourceAction()
{
$form = new ResourceConfigForm();
$form->setConfig(IcingaConfig::app('resources'));
$form->setIniConfig(IcingaConfig::app('resources'));
$form->setRedirectUrl('config/resource');
$form->handleRequest();
@ -236,7 +236,7 @@ class ConfigController extends ActionController
public function editresourceAction()
{
$form = new ResourceConfigForm();
$form->setConfig(IcingaConfig::app('resources'));
$form->setIniConfig(IcingaConfig::app('resources'));
$form->setRedirectUrl('config/resource');
$form->handleRequest();
@ -252,7 +252,7 @@ class ConfigController extends ActionController
$form = new ConfirmRemovalForm(array(
'onSuccess' => function ($request) {
$configForm = new ResourceConfigForm();
$configForm->setConfig(IcingaConfig::app('resources'));
$configForm->setIniConfig(IcingaConfig::app('resources'));
$resource = $request->getQuery('resource');
try {

@ -96,7 +96,7 @@ class DashboardController extends ActionController
if ($this->writeConfiguration(new Zend_Config($dashboard->toArray()), $configFile)) {
$this->redirectNow(Url::fromPath('dashboard', array('pane' => $form->getValue('pane'))));
} else {
$this->render('show-configuration');
$this->render('showConfiguration');
return;
}
}
@ -164,9 +164,9 @@ class DashboardController extends ActionController
$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;
$this->view->configString = $writer->render();
$this->view->errorMessage = $e->getMessage();
$this->view->filePath = $target;
return false;
}

@ -18,10 +18,12 @@ class LayoutController extends ActionController
*/
public function menuAction()
{
$this->setAutorefreshInterval(15);
$this->_helper->layout()->disableLayout();
$this->view->menuRenderer = new MenuRenderer(
Menu::load(), Url::fromRequest()->without('renderLayout')->getRelativeUrl()
);
$url = Url::fromRequest();
$menu = new MenuRenderer(Menu::load(), $url->getRelativeUrl());
$this->view->menuRenderer = $menu->useCustomRenderer();
}
/**

@ -3,10 +3,12 @@
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Web\Controller\BasePreferenceController;
use Icinga\Web\Widget\Tab;
use Icinga\Web\Url;
use Icinga\Form\Preference\GeneralForm;
use Icinga\Web\Notification;
use Icinga\Web\Widget\Tab;
use Icinga\Application\Config;
use Icinga\Form\PreferenceForm;
use Icinga\Exception\ConfigurationError;
use Icinga\User\Preferences\PreferencesStore;
/**
* Application wide preference controller for user preferences
@ -33,33 +35,22 @@ class PreferenceController extends BasePreferenceController
}
/**
* General settings for date and time
* Show form to adjust user preferences
*/
public function indexAction()
{
$this->getTabs()->activate('general');
$form = new GeneralForm();
$request = $this->getRequest();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
try {
$this->savePreferences($form->getPreferences()->toArray());
Notification::success($this->translate('Preferences updated successfully'));
$this->redirectNow('preference');
} catch (Exception $e) {
Notification::error(
sprintf(
$this->translate('Failed to persist preferences. (%s)'),
$e->getMessage()
)
);
}
}
} else {
$form->setPreferences($request->getUser()->getPreferences());
$storeConfig = Config::app()->preferences;
if ($storeConfig === null) {
throw new ConfigurationError(t('You need to configure how to store preferences first.'));
}
$user = $this->getRequest()->getUser();
$form = new PreferenceForm();
$form->setPreferences($user->getPreferences());
$form->setStore(PreferencesStore::create($storeConfig, $user));
$form->handleRequest();
$this->view->form = $form;
$this->getTabs()->activate('general');
}
}

@ -59,13 +59,12 @@ class StaticController extends ActionController
public function imgAction()
{
$module = $this->_getParam('module_name');
// TODO: This is more than dangerous, must be fixed!!
$file = $this->_getParam('file');
$basedir = Icinga::app()->getModuleManager()->getModule($module)->getBaseDir();
$filePath = $basedir . '/public/img/' . $file;
if (! file_exists($filePath)) {
$filePath = realpath($basedir . '/public/img/' . $file);
if (! $filePath || strpos($filePath, $basedir) !== 0) {
throw new ActionException(sprintf(
'%s does not exist',
$filePath

@ -53,7 +53,5 @@ class LoginForm extends Form
'value' => Url::fromRequest()->getParam('redirect')
)
);
return $this;
}
}

@ -6,6 +6,7 @@ namespace Icinga\Form\Config\Authentication;
use Exception;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Data\ResourceFactory;
use Icinga\Authentication\Backend\LdapUserBackend;

@ -318,7 +318,5 @@ class AuthenticationBackendConfigForm extends ConfigForm
}
$this->addElements($this->getBackendForm($backendType)->createElements($formData)->getElements());
return $this;
}
}

@ -62,7 +62,7 @@ class AuthenticationBackendReorderForm extends ConfigForm
protected function getConfigForm()
{
$form = new AuthenticationBackendConfigForm();
$form->setConfig($this->config);
$form->setIniConfig($this->config);
return $form;
}
}

@ -33,8 +33,6 @@ class GeneralConfigForm extends ConfigForm
$loggingConfigForm = new LoggingConfigForm();
$this->addElements($appConfigForm->createElements($formData)->getElements());
$this->addElements($loggingConfigForm->createElements($formData)->getElements());
return $this;
}
/**

@ -252,7 +252,5 @@ class ResourceConfigForm extends ConfigForm
}
$this->addElements($this->getResourceForm($resourceType)->createElements($formData)->getElements());
return $this;
}
}

@ -28,7 +28,7 @@ class ConfigForm extends Form
*
* @return self
*/
public function setConfig(Config $config)
public function setIniConfig(Config $config)
{
$this->config = $config;
return $this;
@ -54,6 +54,7 @@ class ConfigForm extends Form
$writer->write();
} catch (Exception $e) {
$this->addDecorator('ViewScript', array(
'viewModule' => 'default',
'viewScript' => 'showConfiguration.phtml',
'errorMessage' => $e->getMessage(),
'configString' => $writer->render(),

@ -27,15 +27,13 @@ class AddUrlForm extends Form
*/
public function createElements(array $formData)
{
$elements = array(
$this->createElement(
'text',
'url',
array(
'required' => true,
'label' => t('Url'),
'helptext' => t('The url being loaded in the dashlet')
)
$this->addElement(
'text',
'url',
array(
'required' => true,
'label' => t('Url'),
'helptext' => t('The url being loaded in the dashlet')
)
);
@ -44,7 +42,7 @@ class AddUrlForm extends Form
((isset($formData['create_new_pane']) && $formData['create_new_pane'] != false) &&
(false === isset($formData['use_existing_dashboard']) || $formData['use_existing_dashboard'] != true))
) {
$elements[] = $this->createElement(
$this->addElement(
'text',
'pane',
array(
@ -53,7 +51,7 @@ class AddUrlForm extends Form
'style' => 'display: inline-block'
)
);
$elements[] = $this->createElement( // Prevent the button from being displayed again on validation errors
$this->addElement( // Prevent the button from being displayed again on validation errors
'hidden',
'create_new_pane',
array(
@ -61,7 +59,7 @@ class AddUrlForm extends Form
)
);
if (false === empty($paneSelectionValues)) {
$elements[] = $this->createElement(
$this->addElement(
'submit',
'use_existing_dashboard',
array(
@ -72,7 +70,7 @@ class AddUrlForm extends Form
);
}
} else {
$elements[] = $this->createElement(
$this->addElement(
'select',
'pane',
array(
@ -82,7 +80,7 @@ class AddUrlForm extends Form
'multiOptions' => $paneSelectionValues
)
);
$elements[] = $this->createElement(
$this->addElement(
'submit',
'create_new_pane',
array(
@ -93,7 +91,7 @@ class AddUrlForm extends Form
);
}
$elements[] = $this->createElement(
$this->addElement(
'text',
'component',
array(
@ -102,7 +100,6 @@ class AddUrlForm extends Form
'helptext' => t('The title for the dashlet')
)
);
return $elements;
}
/**

@ -1,171 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form\Preference;
use DateTimeZone;
use Icinga\Web\Form;
use Icinga\Util\Translator;
use Icinga\User\Preferences;
/**
* General user preferences
*/
class GeneralForm extends Form
{
/**
* Initialize this preferences config form
*/
public function init()
{
$this->setName('form_config_preferences');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* Add a select field for setting the user's language
*
* Possible values are determined by Translator::getAvailableLocaleCodes.
* Also, a 'use browser language' checkbox is added in order to allow a user to discard his setting
*
* @param array $formData The data sent by the user
*/
protected function getLanguageElements(array $formData)
{
$languages = array();
foreach (Translator::getAvailableLocaleCodes() as $language) {
$languages[$language] = $language;
}
$useBrowserLanguage = isset($formData['browser_language']) ? $formData['browser_language'] == 1 : true;
$selectOptions = array(
'label' => t('Your Current Language'),
'required' => false === $useBrowserLanguage,
'multiOptions' => $languages,
'helptext' => t('Use the following language to display texts and messages'),
'value' => substr(setlocale(LC_ALL, 0), 0, 5)
);
if ($useBrowserLanguage) {
$selectOptions['disabled'] = 'disabled';
}
return array(
$this->createElement(
'checkbox',
'browser_language',
array(
'required' => true,
'class' => 'autosubmit',
'label' => t('Use your browser\'s language suggestions'),
'value' => $useBrowserLanguage
)
),
$this->createElement('select', 'language', $selectOptions)
);
}
/**
* Add a select field for setting the user's timezone
*
* Possible values are determined by DateTimeZone::listIdentifiers.
* Also, a 'use local timezone' checkbox is added in order to allow a user to discard his overwritten setting
*
* @param array $formData The data sent by the user
*/
protected function getTimezoneElements(array $formData)
{
$tzList = array();
foreach (DateTimeZone::listIdentifiers() as $tz) {
$tzList[$tz] = $tz;
}
$useLocalTimezone = isset($formData['local_timezone']) ? $formData['local_timezone'] == 1 : true;
$selectOptions = array(
'label' => 'Your Current Timezone',
'required' => false === $useLocalTimezone,
'multiOptions' => $tzList,
'helptext' => t('Use the following timezone for dates and times'),
'value' => date_default_timezone_get()
);
if ($useLocalTimezone) {
$selectOptions['disabled'] = 'disabled';
}
return array(
$this->createElement(
'checkbox',
'local_timezone',
array(
'required' => true,
'class' => 'autosubmit',
'label' => t('Use your local timezone'),
'value' => $useLocalTimezone,
)
),
$this->createElement('select', 'timezone', $selectOptions)
);
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$elements = array_merge($this->getLanguageElements($formData), $this->getTimezoneElements($formData));
$elements[] = $this->createElement(
'checkbox',
'show_benchmark',
array(
'label' => t('Use benchmark')
)
);
return $elements;
}
/**
* Populate the form with the given preferences
*
* @param Preferences $preferences The preferences to populate the form with
*
* @return self
*/
public function setPreferences(Preferences $preferences)
{
$defaults = array(
'browser_language' => $preferences->get('app.language') === null,
'local_timezone' => $preferences->get('app.timezone') === null
);
if ($preferences->get('app.language') !== null) {
$defaults['language'] = $preferences->get('app.language');
}
if ($preferences->get('app.timezone') !== null) {
$defaults['timezone'] = $preferences->get('app.timezone');
}
if ($preferences->get('app.show_benchmark')) {
$defaults['show_benchmark'] = $preferences->get('app.show_benchmark');
}
$this->setDefaults($defaults);
return $this;
}
/**
* Return the configured preferences
*
* @return Preferences
*/
public function getPreferences()
{
$values = $this->getValues();
return new Preferences(
array(
'app.language' => $values['browser_language'] ? null : $values['language'],
'app.timezone' => $values['local_timezone'] ? null : $values['timezone'],
'app.show_benchmark' => $values['show_benchmark'] ? $values['show_benchmark'] : null
)
);
}
}

@ -0,0 +1,225 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Form;
use Exception;
use DateTimeZone;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Web\Session;
use Icinga\Web\Notification;
use Icinga\Util\Translator;
use Icinga\Util\TimezoneDetect;
use Icinga\User\Preferences;
use Icinga\User\Preferences\PreferencesStore;
/**
* Form class to adjust user preferences
*/
class PreferenceForm extends Form
{
/**
* The preferences to work with
*
* @var Preferences
*/
protected $preferences;
/**
* The preference store to use
*
* @var PreferencesStore
*/
protected $store;
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_preferences');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* Set preferences to work with
*
* @param Preferences $preferences The preferences to work with
*
* @return self
*/
public function setPreferences(Preferences $preferences)
{
$this->preferences = $preferences;
return $this;
}
/**
* Set the preference store to use
*
* @param PreferencesStore $store The preference store to use
*
* @return self
*/
public function setStore(PreferencesStore $store)
{
$this->store = $store;
}
/**
* Persist preferences
*
* @return self
*/
public function save()
{
$this->store->load(); // Necessary for patching existing preferences
$this->store->save($this->preferences);
return $this;
}
/**
* Adjust preferences and persist them
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
$webPreferences = $this->preferences->get('icingaweb', array());
foreach ($this->getValues() as $key => $value) {
if ($value === null) {
if (isset($webPreferences[$key])) {
unset($webPreferences[$key]);
}
} else {
$webPreferences[$key] = $value;
}
}
$this->preferences->icingaweb = $webPreferences;
// TODO: Is this even necessary in case the session is written on response?
$session = Session::getSession();
$session->user->setPreferences($this->preferences);
$session->write();
try {
$this->save();
Notification::success(t('Preferences successfully saved'));
} catch (Exception $e) {
Notification::error($e->getMessage());
}
}
/**
* Populate preferences
*
* @see Form::onRequest()
*/
public function onRequest(Request $request)
{
$values = $this->preferences->get('icingaweb', array());
$values['browser_language'] = false === isset($values['language']);
$values['local_timezone'] = false === isset($values['timezone']);
$this->populate($values);
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$languages = array();
foreach (Translator::getAvailableLocaleCodes() as $language) {
$languages[$language] = $language;
}
$tzList = array();
foreach (DateTimeZone::listIdentifiers() as $tz) {
$tzList[$tz] = $tz;
}
$this->addElement(
'checkbox',
'browser_language',
array(
'ignore' => true,
'required' => true,
'autosubmit' => true,
'value' => true,
'label' => t('Use your browser\'s language suggestions')
)
);
$useBrowserLanguage = isset($formData['browser_language']) ? $formData['browser_language'] == 1 : true;
$languageSelection = $this->createElement(
'select',
'language',
array(
'required' => false === $useBrowserLanguage,
'label' => t('Your Current Language'),
'description' => t('Use the following language to display texts and messages'),
'multiOptions' => $languages,
'value' => substr(setlocale(LC_ALL, 0), 0, 5)
)
);
if ($useBrowserLanguage) {
$languageSelection->setAttrib('disabled', 'disabled');
}
$this->addElement($languageSelection);
$this->addElement(
'checkbox',
'local_timezone',
array(
'ignore' => true,
'required' => true,
'autosubmit' => true,
'value' => true,
'label' => t('Use your local timezone')
)
);
$useLocalTimezone = isset($formData['local_timezone']) ? $formData['local_timezone'] == 1 : true;
$timezoneSelection = $this->createElement(
'select',
'timezone',
array(
'required' => false === $useLocalTimezone,
'label' => t('Your Current Timezone'),
'description' => t('Use the following timezone for dates and times'),
'multiOptions' => $tzList,
'value' => $this->getDefaultTimezone()
)
);
if ($useLocalTimezone) {
$timezoneSelection->setAttrib('disabled', 'disabled');
}
$this->addElement($timezoneSelection);
$this->addElement(
'checkbox',
'show_benchmark',
array(
'required' => true,
'label' => t('Use benchmark')
)
);
}
/**
* Return the current default timezone
*
* @return string
*/
protected function getDefaultTimezone()
{
$detect = new TimezoneDetect();
if ($detect->success()) {
return $detect->getTimezoneName();
} else {
return date_default_timezone_get();
}
}
}

@ -11,11 +11,15 @@ if (! $this->auth()->isAuthenticated()) {
}
?>
<div id="menu" data-base-target="_main">
<div
id="menu" data-last-update="<?= (time() - 14) ?>000" data-base-target="_main" class="container" data-icinga-url="<?=$this->href('layout/menu');?>"
data-icinga-refresh="15"
>
<? if (SearchDashboard::search('dummy')->getPane('search')->hasComponents()): ?>
<form action="<?= $this->href('search') ?>" method="get" role="search">
<input type="text" name="q" class="search autofocus" placeholder="<?= $this->translate('Search...') ?>" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" />
</form>
<form action="<?= $this->href('search') ?>" method="get" role="search">
<input type="text" name="q" class="search autofocus" placeholder="<?= $this->translate('Search...') ?>"
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false" />
</form>
<? endif; ?>
<?= new MenuRenderer(Menu::load(), Url::fromRequest()->without('renderLayout')->getRelativeUrl()); ?>
<?= new MenuRenderer(Menu::load(), Url::fromRequest()->without('renderLayout')->getRelativeUrl()); ?>
</div>

@ -1,31 +0,0 @@
<?= $this->tabs->render($this); ?>
<br/>
<div>
<h4><i>WARNING ICON</i>Saving "<?= $this->escape($this->file); ?>.ini" Failed</h4>
<br/>
<p>
Your <?= $this->escape($this->file); ?> configuration couldn't be stored (error: "<?= $this->exceptionMessage; ?>").<br/>
This could have one or more of the following reasons:
</p>
<ul>
<li>You don't have file-system permissions to write to the <?= $this->escape($this->file); ?>.ini 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/<?= $this->escape($this->file); ?>.ini) by yourself, you can open it and
insert the config manually:
</p>
<p>
<pre>
<code>
<?= $this->escape($this->iniConfigurationString); ?>
</code>
</pre>
</p>

@ -1 +1,13 @@
<?= $menuRenderer; ?>
<?php
use Icinga\Web\Widget\SearchDashboard;
?>
<? if (SearchDashboard::search('dummy')->getPane('search')->hasComponents()): ?>
<form action="<?= $this->href('search') ?>" method="get" role="search">
<input
type="text" name="q" class="search autofocus" placeholder="<?= $this->translate('Search...') ?>"
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
/>
</form>
<? endif; ?>
<?= $menuRenderer; ?>

@ -1,7 +1,7 @@
<div class="controls">
<?= $this->tabs->render($this); ?>
<?= $tabs; ?>
</div>
<div class="content">
<?= $this->form ?>
</div>
<?= $form; ?>
</div>

@ -1,130 +0,0 @@
# Frontend components
Frontend components are JavaScript modules that can be required directly through the HTML markup of
your view, to provide additional functionality for the user. Although its best practice to
make all features available without JavaScript, these components can be used to provide a richer
and more comfortable user experience in case JavaScript is available.
There is a certain set of frontend components which come directly with the Icinga2-Web core application,
but it is also possible to define new components directly in Icinga2-Web modules.
## How do components work?
Components are defined in JavaScript files that provide a set of functionality that will be added to the
targeted HTML node. Icinga2-Web uses [RequireJS](http://requirejs.org) to load
all frontend components, so each frontend component is in fact
[defined exactly like a RequireJS-Module](http://requirejs.org/docs/api.html#define) .
The important difference to plain RequireJS is, that the loading and execution of these components is
done automatically through the HTML markup. The attribute *data-icinga-component* in a DIV
element will indicate that this element is a container for a frontend component and will trigger
the component loader to create a component instance for this HTML node. The component loader
keeps track of all available components and makes it possible to retrieve this instance when needed.
### Component names
A component name consists of two parts: the namespace and the name of the component itself. The component
is named exactly like its JavaScript file, while the namespace is the name of the Icinga2-Web module that contains
the component. Each Icinga2-Web module can contain its own components in the folder *public/js*.
<module>/<component>
NOTE: The namespace used for modules defined in the Icinga2-Web core application is "app". In opposition to
the modules the core application keeps its modules located in *public/js/icinga/components*
instead of *public/js*.
#### Example Names
The full name for the component *modules/monitoring/public/js/someComponent.js* in the module "monitoring" would be:
"monitoring/someComponent"
The full component name for the component *public/js/icinga/components/datetime.js* in the Icinga2-Web core application
would:
"app/datetime"
## Creating a component
As described in the chapters above, components are defined exactly like RequireJS modules, but
with the additional requirement that they must always return a class constructor. The component below will
search all date pickers, set the time format and create a JavaScript date picker when there is no native one
available.
/**
* Ensures that our date/time controls will work on every browser (natively or javascript based)
*/
define(['jquery', 'datetimepicker'], function($) {
"use strict";
var DateTimePicker = function(target) {
$(target).find('.datetime input')
.attr('data-format', 'yyyy-MM-dd hh:mm:ss');
$(target).find('.datetime')
.addClass('input-append')
.append('<span class="add-on">' +
'<i data-time-icon="icon-time" data-date-icon="icon-calendar"></i></span>')
.datetimepicker();
};
return DateTimePicker;
});
## Loading a component
The following code will load the module *datetime*, which will ensure that there is always a datetime-picker
with right time-format available.
<div id="date-time-picker" data-icinga-component="app/datetime">
<div class="datetime">
<input data-format="dd/MM/yyyy hh:mm:ss" type="text"/>
</div>
</div>
### Component ids
When an ID is assigned to the HTML element, it will be used by the component loader to reference this
component. Otherwise an ID in the form "icinga-component-&lt;ID&gt;" will be created and the ID attribute in the
HTML Element will be updated accordingly.
### Component "target"
The div-element with the *data-icinga-component* will be used as the "target" for the loaded component,
which means that the component will perform its actions on this HTML node.
# Retrieving a component
Sometimes it can be necessary to retrieve the instances of the components itself, for example when they implement
additional functions that can be called. The component loader is available in the Icinga object and can be used
to retrieve component instances using their ID or their full component name.
## By component id
var component = Icinga.components.getById("component-id");
component.doSomething();
## By full component name
var components = Icinga.components.getByType("app/datetime");
// ... do something with every component of the type app/datetime
## All components
var components = Icinga.components.getComponents();
// ... do something with every component

@ -8,6 +8,7 @@ use Exception;
use Zend_Config;
use Zend_Controller_Router_Route_Abstract;
use Zend_Controller_Router_Route as Route;
use Zend_Controller_Router_Route_Regex as RegexRoute;
use Icinga\Application\ApplicationBootstrap;
use Icinga\Application\Config;
use Icinga\Application\Icinga;
@ -821,12 +822,15 @@ class Module
);
$router->addRoute(
$this->name . '_img',
new Route(
'img/' . $this->name . '/:file',
new RegexRoute(
'img/' . $this->name . '/(.+)',
array(
'controller' => 'static',
'action' => 'img',
'module_name' => $this->name
),
array(
1 => 'file'
)
)
);

@ -67,7 +67,7 @@ class Tooltip
*/
public function __construct (
$data = array(),
$format = '<b>{title}</b></b><br> {value} of {sum} {label}'
$format = '<b>{title}</b></b><br/> {value} of {sum} {label}'
) {
$this->data = array_merge($this->data, $data);
$this->defaultFormat = $format;

@ -25,20 +25,16 @@ namespace Icinga\Test {
use RuntimeException;
use Mockery;
use Zend_Config;
use Zend_Controller_Request_Abstract;
use Zend_Controller_Request_HttpTestCase;
use PHPUnit_Framework_TestCase;
use Icinga\Application\Icinga;
use Icinga\Util\DateTimeFactory;
use Icinga\Data\ResourceFactory;
use Icinga\Data\Db\DbConnection;
use Icinga\User\Preferences;
use Icinga\Web\Form;
/**
* Class BaseTestCase
*/
class BaseTestCase extends PHPUnit_Framework_TestCase implements DbTest, FormTest
class BaseTestCase extends PHPUnit_Framework_TestCase implements DbTest
{
/**
* Path to application/
@ -82,13 +78,6 @@ namespace Icinga\Test {
*/
public static $moduleDir;
/**
* Store request for form tests
*
* @var Zend_Controller_Request_HttpTestCase
*/
private $request;
/**
* Resource configuration for different database types
*
@ -151,28 +140,54 @@ namespace Icinga\Test {
public function setUp()
{
parent::setUp();
$requestMock = Mockery::mock('Icinga\Web\Request');
$requestMock->shouldReceive('getPathInfo')->andReturn('')
->shouldReceive('getBaseUrl')->andReturn('/')
->shouldReceive('getQuery')->andReturn(array());
$this->setupIcingaMock($requestMock);
$this->setupIcingaMock();
}
/**
* Setup mock object for the application's bootstrap
*
* @param Zend_Controller_Request_Abstract $request The request to be returned by
* Icinga::app()->getFrontController()->getRequest()
* @return Mockery\Mock
*/
protected function setupIcingaMock(Zend_Controller_Request_Abstract $request)
protected function setupIcingaMock()
{
$requestMock = Mockery::mock('Icinga\Web\Request')->shouldDeferMissing();
$requestMock->shouldReceive('getPathInfo')->andReturn('')->byDefault()
->shouldReceive('getBaseUrl')->andReturn('/')->byDefault()
->shouldReceive('getQuery')->andReturn(array())->byDefault()
->shouldReceive('getParam')->with(Mockery::type('string'), Mockery::type('string'))
->andReturnUsing(function ($name, $default) { return $default; })->byDefault();
$responseMock = Mockery::mock('Icinga\Web\Response')->shouldDeferMissing();
// Can't express this as demeter chains. See: https://github.com/padraic/mockery/issues/59
$bootstrapMock = Mockery::mock('Icinga\Application\ApplicationBootstrap')->shouldDeferMissing();
$bootstrapMock->shouldReceive('getFrontController->getRequest')->andReturnUsing(
function () use ($request) { return $request; }
)->shouldReceive('getApplicationDir')->andReturn(self::$appDir);
$bootstrapMock->shouldReceive('getFrontController')->andReturn($bootstrapMock)
->shouldReceive('getApplicationDir')->andReturn(self::$appDir)
->shouldReceive('getRequest')->andReturn($requestMock)
->shouldReceive('getResponse')->andReturn($responseMock);
Icinga::setApp($bootstrapMock, true);
return $bootstrapMock;
}
/**
* Return the currently active request mock object
*
* @return Icinga\Web\Request
*/
public function getRequestMock()
{
return Icinga::app()->getFrontController()->getRequest();
}
/**
* Return the currently active response mock object
*
* @return Icinga\Web\Response
*/
public function getResponseMock()
{
return Icinga::app()->getFrontController()->getResponse();
}
/**
@ -298,51 +313,6 @@ namespace Icinga\Test {
$adapter->exec('DROP TABLE ' . $table . ';');
}
}
/**
* Instantiate a form
*
* If the form has CSRF protection enabled, creates the form's token element and adds the generated token to the
* request data
*
* @param string $formClass Qualified class name of the form to create. Note that the class has to be
* defined as no attempt is made to require the class before instantiating.
* @param array $requestData Request data for the form
*
* @return Form
* @throws RuntimeException
*/
public function createForm($formClass, array $requestData = array())
{
$form = new $formClass;
$form->setTokenDisabled(); // Disable CSRF protection else all calls to isSubmittedAndValid will fail
$request = $this->getRequest();
$request->setMethod('POST');
$request->setPost($requestData);
$form->setRequest($request);
$form->setUserPreferences(
new Preferences(
array()
)
);
return $form;
}
/**
* Retrieve test case request object
*
* This is a mock methods borrowed from Zend Controller Test Case to handle form tests properly (#6106)
*
* @return Zend_Controller_Request_HttpTestCase
*/
public function getRequest()
{
if (null === $this->request) {
require_once 'Zend/Controller/Request/HttpTestCase.php';
$this->request = new Zend_Controller_Request_HttpTestCase;
}
return $this->request;
}
}
BaseTestCase::setupTimezone();

@ -1,23 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Test;
use Icinga\Web\Form;
/**
* Interface to test form objects
*/
interface FormTest
{
/**
* Instantiate a new form object
*
* @param string $formClass Form class to instantiate
* @param array $requestData Request data for the form
*
* @return Form
*/
public function createForm($formClass, array $requestData = array());
}

@ -4,11 +4,6 @@
namespace Icinga\Web\Controller;
use Icinga\Application\Config as IcingaConfig;
use Icinga\Exception\ConfigurationError;
use Icinga\Web\Session;
use Icinga\User\Preferences\PreferencesStore;
/**
* Base class for Preference Controllers
*
@ -42,27 +37,4 @@ class BasePreferenceController extends ActionController
parent::init();
$this->view->tabs = ControllerTabCollector::collectControllerTabs('PreferenceController');
}
protected function savePreferences(array $preferences)
{
$session = Session::getSession();
$currentPreferences = $session->user->getPreferences();
foreach ($preferences as $key => $value) {
if ($value === null) {
$currentPreferences->remove($key);
} else {
$currentPreferences->{$key} = $value;
}
}
$session->write();
if (($preferencesConfig = IcingaConfig::app()->preferences) === null) {
throw new ConfigurationError(
'Cannot save preferences changes since you\'ve not configured a preferences backend'
);
}
$store = PreferencesStore::create($preferencesConfig, $session->user);
$store->load(); // Necessary for patching existing preferences
$store->save($currentPreferences);
}
}

@ -67,6 +67,13 @@ class Form extends Zend_Form
*/
protected $tokenElementName = 'CSRFToken';
/**
* Whether this form should add a UID element being used to distinct different forms posting to the same action
*
* @var bool
*/
protected $uidDisabled = false;
/**
* Name of the form identification element
*
@ -155,8 +162,9 @@ class Form extends Zend_Form
public function getRedirectUrl()
{
if ($this->redirectUrl === null) {
$url = Url::fromRequest(array(), $this->getRequest());
// Be sure to remove all form dependent params because we do not want to submit it again
$this->redirectUrl = Url::fromRequest()->without(array_keys($this->getElements()));
$this->redirectUrl = $url->without(array_keys($this->getElements()));
}
return $this->redirectUrl;
@ -236,6 +244,34 @@ class Form extends Zend_Form
return $this->tokenElementName;
}
/**
* Disable form identification and remove its field if already added
*
* @param bool $disabled Set true in order to disable identification for this form, otherwise false
*
* @return self
*/
public function setUidDisabled($disabled = true)
{
$this->uidDisabled = (bool) $disabled;
if ($disabled && $this->getElement($this->uidElementName) !== null) {
$this->removeElement($this->uidElementName);
}
return $this;
}
/**
* Return whether identification is disabled for this form
*
* @return bool
*/
public function getUidDisabled()
{
return $this->uidDisabled;
}
/**
* Set the name to use for the form identification element
*
@ -269,15 +305,15 @@ class Form extends Zend_Form
public function create(array $formData = array())
{
if (false === $this->created) {
$this->createElements($formData)
->addFormIdentification()
$this->createElements($formData);
$this->addFormIdentification()
->addCsrfCounterMeasure()
->addSubmitButton();
if ($this->getAction() === '') {
// We MUST set an action as JS gets confused otherwise, if
// this form is being displayed in an additional column
$this->setAction(Url::fromRequest()->getUrlWithout(array_keys($this->getElements())));
$this->setAction(Url::fromRequest()->without(array_keys($this->getElements())));
}
$this->created = true;
@ -292,12 +328,10 @@ class Form extends Zend_Form
* Intended to be implemented by concrete form classes.
*
* @param array $formData The data sent by the user
*
* @return self
*/
public function createElements(array $formData)
{
return $this;
}
/**
@ -336,7 +370,7 @@ class Form extends Zend_Form
*/
public function addSubmitButton()
{
if ($this->submitLabel !== null) {
if ($this->submitLabel) {
$this->addElement(
'submit',
'btn_submit',
@ -354,6 +388,31 @@ class Form extends Zend_Form
return $this;
}
/**
* Add a subform
*
* @param Zend_Form $form The subform to add
* @param string $name The name of the subform or null to use the name of $form
* @param int $order The location where to insert the form
*
* @return Zend_Form
*/
public function addSubForm(Zend_Form $form, $name = null, $order = null)
{
if ($form instanceof self) {
$form->removeDecorator('Form');
$form->setSubmitLabel('');
$form->setTokenDisabled();
$form->setUidDisabled();
}
if ($name === null) {
$name = $form->getName();
}
return parent::addSubForm($form, $name, $order);
}
/**
* Create a new element
*
@ -398,14 +457,17 @@ class Form extends Zend_Form
*/
public function addFormIdentification()
{
$this->addElement(
'hidden',
$this->uidElementName,
array(
'ignore' => true,
'value' => $this->getName()
)
);
if (false === $this->uidDisabled && $this->getElement($this->uidElementName) === null) {
$this->addElement(
'hidden',
$this->uidElementName,
array(
'ignore' => true,
'value' => $this->getName(),
'decorators' => array('ViewHelper')
)
);
}
return $this;
}
@ -431,7 +493,7 @@ class Form extends Zend_Form
*
* @param array $defaults The values to populate the elements with
*/
public function setDefaults(array $defaults)
public function setDefaults($defaults)
{
$this->create($defaults);
return parent::setDefaults($defaults);
@ -454,7 +516,7 @@ class Form extends Zend_Form
}
$formData = $this->getRequestData($request);
if ($this->wasSent($formData)) {
if ($this->getUidDisabled() || $this->wasSent($formData)) {
$this->populate($formData); // Necessary to get isSubmitted() to work
if (! $this->getSubmitLabel() || $this->isSubmitted()) {
if ($this->isValid($formData)

@ -22,7 +22,8 @@ class UnhandledHostMenuItemRenderer implements MenuItemRenderer {
$badge = '';
if ($statusSummary->hosts_down_unhandled) {
$badge = sprintf(
'<div class="badge-container"><span class="badge badge-critical">%s</span></div>',
'<div title="%s" class="badge-container"><span class="badge badge-critical">%s</span></div>',
t(sprintf('%d unhandled host problems', $statusSummary->hosts_down_unhandled)),
$statusSummary->hosts_down_unhandled
);
}

@ -22,7 +22,8 @@ class UnhandledServiceMenuItemRenderer implements MenuItemRenderer {
$badge = '';
if ($statusSummary->services_critical_unhandled) {
$badge = sprintf(
'<div class="badge-container"><span class="badge badge-critical">%s</span></div>',
'<div title="%s" class="badge-container"><span class="badge badge-critical">%s</span></div>',
t(sprintf('%d unhandled service problems', $statusSummary->services_critical_unhandled)),
$statusSummary->services_critical_unhandled
);
}

@ -25,6 +25,11 @@ class MenuRenderer extends RecursiveIteratorIterator
*/
protected $tags = array();
/**
* @var bool
*/
protected $useCustomRenderer = false;
/**
* Create a new MenuRenderer
*
@ -41,6 +46,15 @@ class MenuRenderer extends RecursiveIteratorIterator
parent::__construct($menu, RecursiveIteratorIterator::CHILD_FIRST);
}
/**
* @param bool $value
*/
public function useCustomRenderer($value = true)
{
$this->useCustomRenderer = $value;
return $this;
}
/**
* Register the outer ul opening html-tag
*/
@ -91,7 +105,7 @@ class MenuRenderer extends RecursiveIteratorIterator
*/
public function renderChild(Menu $child)
{
if ($child->getRenderer() !== null) {
if ($child->getRenderer() !== null && $this->useCustomRenderer) {
return $child->getRenderer()->render($child);
}
return sprintf(

@ -24,7 +24,6 @@ class StyleSheet
'css/icinga/monitoring-colors.less',
'css/icinga/selection-toolbar.less',
'css/icinga/login.less',
'css/icinga/charts.less',
'css/vendor/tipsy.css'
);

@ -119,15 +119,15 @@ class SortBox extends AbstractWidget
'label' => 'Sort By',
'multiOptions' => $this->sortFields,
'style' => 'width: 12em',
'class' => 'autosubmit',
'autosubmit' => true
));
$form->addElement('select', 'dir', array(
'multiOptions' => array(
'asc' => 'Asc',
'desc' => 'Desc',
),
'style' => 'width: 5em',
'class' => 'autosubmit'
'style' => 'width: 5em',
'autosubmit' => true
));
$sort = $form->getElement('sort')->setDecorators(array('ViewHelper'));
$dir = $form->getElement('dir')->setDecorators(array('ViewHelper'));

@ -1,324 +0,0 @@
<span style='color: #000'>1084 frames</span> <span style='color: #900'>64,000 KB</span> <span style='color: #090'>12,219.54 ms</span> <span style='color: #009' title='Quirksmode'><span style='color: #c00'>ON</span></span><br /><br />
<font size='1'><table class='xdebug-error' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line <i>396</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.0015</td><td bgcolor='#eeeeec' align='right'>634696</td><td bgcolor='#eeeeec'>{main}( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Icinga\Application\Web->dispatch( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>17</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Zend_Controller_Front->dispatch( )</td><td title='/vagrant/library/Icinga/Application/Web.php' bgcolor='#eeeeec'>../Web.php<b>:</b>177</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>4</td><td bgcolor='#eeeeec' align='center'>0.6718</td><td bgcolor='#eeeeec' align='right'>7339544</td><td bgcolor='#eeeeec'>Zend_Controller_Dispatcher_Standard->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Front.php' bgcolor='#eeeeec'>../Front.php<b>:</b>954</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>5</td><td bgcolor='#eeeeec' align='center'>0.7544</td><td bgcolor='#eeeeec' align='right'>9789672</td><td bgcolor='#eeeeec'>Zend_Controller_Action->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Dispatcher/Standard.php' bgcolor='#eeeeec'>../Standard.php<b>:</b>308</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>6</td><td bgcolor='#eeeeec' align='center'>0.8547</td><td bgcolor='#eeeeec' align='right'>11070736</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->postDispatch( )</td><td title='/usr/share/php/Zend/Controller/Action.php' bgcolor='#eeeeec'>../Action.php<b>:</b>521</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>7</td><td bgcolor='#eeeeec' align='center'>0.8550</td><td bgcolor='#eeeeec' align='right'>11071712</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->sendAsPdfAndDie( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>244</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>8</td><td bgcolor='#eeeeec' align='center'>1.9930</td><td bgcolor='#eeeeec' align='right'>23228752</td><td bgcolor='#eeeeec'>Icinga\File\Pdf->renderPage( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>279</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>9</td><td bgcolor='#eeeeec' align='center'>2.0668</td><td bgcolor='#eeeeec' align='right'>23495800</td><td bgcolor='#eeeeec'>DOMPDF->render( )</td><td title='/vagrant/library/Icinga/File/Pdf.php' bgcolor='#eeeeec'>../Pdf.php<b>:</b>62</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>10</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/dompdf.cls.php' bgcolor='#eeeeec'>../dompdf.cls.php<b>:</b>817</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>11</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430520</td><td bgcolor='#eeeeec'>Page_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>12</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432912</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/page_frame_reflower.cls.php' bgcolor='#eeeeec'>../page_frame_reflower.cls.php<b>:</b>138</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>13</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432960</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>14</td><td bgcolor='#eeeeec' align='center'>9.0962</td><td bgcolor='#eeeeec' align='right'>49449768</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>15</td><td bgcolor='#eeeeec' align='center'>9.0962</td><td bgcolor='#eeeeec' align='right'>49449768</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>16</td><td bgcolor='#eeeeec' align='center'>9.0987</td><td bgcolor='#eeeeec' align='right'>49466560</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>17</td><td bgcolor='#eeeeec' align='center'>9.0987</td><td bgcolor='#eeeeec' align='right'>49466560</td><td bgcolor='#eeeeec'>Table_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
</table></font>
<br />
<font size='1'><table class='xdebug-error' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line <i>396</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.0015</td><td bgcolor='#eeeeec' align='right'>634696</td><td bgcolor='#eeeeec'>{main}( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Icinga\Application\Web->dispatch( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>17</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Zend_Controller_Front->dispatch( )</td><td title='/vagrant/library/Icinga/Application/Web.php' bgcolor='#eeeeec'>../Web.php<b>:</b>177</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>4</td><td bgcolor='#eeeeec' align='center'>0.6718</td><td bgcolor='#eeeeec' align='right'>7339544</td><td bgcolor='#eeeeec'>Zend_Controller_Dispatcher_Standard->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Front.php' bgcolor='#eeeeec'>../Front.php<b>:</b>954</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>5</td><td bgcolor='#eeeeec' align='center'>0.7544</td><td bgcolor='#eeeeec' align='right'>9789672</td><td bgcolor='#eeeeec'>Zend_Controller_Action->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Dispatcher/Standard.php' bgcolor='#eeeeec'>../Standard.php<b>:</b>308</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>6</td><td bgcolor='#eeeeec' align='center'>0.8547</td><td bgcolor='#eeeeec' align='right'>11070736</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->postDispatch( )</td><td title='/usr/share/php/Zend/Controller/Action.php' bgcolor='#eeeeec'>../Action.php<b>:</b>521</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>7</td><td bgcolor='#eeeeec' align='center'>0.8550</td><td bgcolor='#eeeeec' align='right'>11071712</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->sendAsPdfAndDie( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>244</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>8</td><td bgcolor='#eeeeec' align='center'>1.9930</td><td bgcolor='#eeeeec' align='right'>23228752</td><td bgcolor='#eeeeec'>Icinga\File\Pdf->renderPage( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>279</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>9</td><td bgcolor='#eeeeec' align='center'>2.0668</td><td bgcolor='#eeeeec' align='right'>23495800</td><td bgcolor='#eeeeec'>DOMPDF->render( )</td><td title='/vagrant/library/Icinga/File/Pdf.php' bgcolor='#eeeeec'>../Pdf.php<b>:</b>62</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>10</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/dompdf.cls.php' bgcolor='#eeeeec'>../dompdf.cls.php<b>:</b>817</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>11</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430520</td><td bgcolor='#eeeeec'>Page_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>12</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432912</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/page_frame_reflower.cls.php' bgcolor='#eeeeec'>../page_frame_reflower.cls.php<b>:</b>138</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>13</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432960</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>14</td><td bgcolor='#eeeeec' align='center'>9.0962</td><td bgcolor='#eeeeec' align='right'>49449768</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>15</td><td bgcolor='#eeeeec' align='center'>9.0962</td><td bgcolor='#eeeeec' align='right'>49449768</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>16</td><td bgcolor='#eeeeec' align='center'>9.2135</td><td bgcolor='#eeeeec' align='right'>49818768</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>17</td><td bgcolor='#eeeeec' align='center'>9.2136</td><td bgcolor='#eeeeec' align='right'>49818768</td><td bgcolor='#eeeeec'>Table_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
</table></font>
<br />
<font size='1'><table class='xdebug-error' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line <i>396</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.0015</td><td bgcolor='#eeeeec' align='right'>634696</td><td bgcolor='#eeeeec'>{main}( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Icinga\Application\Web->dispatch( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>17</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Zend_Controller_Front->dispatch( )</td><td title='/vagrant/library/Icinga/Application/Web.php' bgcolor='#eeeeec'>../Web.php<b>:</b>177</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>4</td><td bgcolor='#eeeeec' align='center'>0.6718</td><td bgcolor='#eeeeec' align='right'>7339544</td><td bgcolor='#eeeeec'>Zend_Controller_Dispatcher_Standard->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Front.php' bgcolor='#eeeeec'>../Front.php<b>:</b>954</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>5</td><td bgcolor='#eeeeec' align='center'>0.7544</td><td bgcolor='#eeeeec' align='right'>9789672</td><td bgcolor='#eeeeec'>Zend_Controller_Action->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Dispatcher/Standard.php' bgcolor='#eeeeec'>../Standard.php<b>:</b>308</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>6</td><td bgcolor='#eeeeec' align='center'>0.8547</td><td bgcolor='#eeeeec' align='right'>11070736</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->postDispatch( )</td><td title='/usr/share/php/Zend/Controller/Action.php' bgcolor='#eeeeec'>../Action.php<b>:</b>521</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>7</td><td bgcolor='#eeeeec' align='center'>0.8550</td><td bgcolor='#eeeeec' align='right'>11071712</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->sendAsPdfAndDie( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>244</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>8</td><td bgcolor='#eeeeec' align='center'>1.9930</td><td bgcolor='#eeeeec' align='right'>23228752</td><td bgcolor='#eeeeec'>Icinga\File\Pdf->renderPage( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>279</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>9</td><td bgcolor='#eeeeec' align='center'>2.0668</td><td bgcolor='#eeeeec' align='right'>23495800</td><td bgcolor='#eeeeec'>DOMPDF->render( )</td><td title='/vagrant/library/Icinga/File/Pdf.php' bgcolor='#eeeeec'>../Pdf.php<b>:</b>62</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>10</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/dompdf.cls.php' bgcolor='#eeeeec'>../dompdf.cls.php<b>:</b>817</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>11</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430520</td><td bgcolor='#eeeeec'>Page_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>12</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432912</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/page_frame_reflower.cls.php' bgcolor='#eeeeec'>../page_frame_reflower.cls.php<b>:</b>138</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>13</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432960</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>14</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>15</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>16</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>17</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>18</td><td bgcolor='#eeeeec' align='center'>9.2355</td><td bgcolor='#eeeeec' align='right'>49886736</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>19</td><td bgcolor='#eeeeec' align='center'>9.2356</td><td bgcolor='#eeeeec' align='right'>49886736</td><td bgcolor='#eeeeec'>Table_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
</table></font>
<br />
<font size='1'><table class='xdebug-error' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line <i>396</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.0015</td><td bgcolor='#eeeeec' align='right'>634696</td><td bgcolor='#eeeeec'>{main}( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Icinga\Application\Web->dispatch( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>17</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Zend_Controller_Front->dispatch( )</td><td title='/vagrant/library/Icinga/Application/Web.php' bgcolor='#eeeeec'>../Web.php<b>:</b>177</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>4</td><td bgcolor='#eeeeec' align='center'>0.6718</td><td bgcolor='#eeeeec' align='right'>7339544</td><td bgcolor='#eeeeec'>Zend_Controller_Dispatcher_Standard->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Front.php' bgcolor='#eeeeec'>../Front.php<b>:</b>954</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>5</td><td bgcolor='#eeeeec' align='center'>0.7544</td><td bgcolor='#eeeeec' align='right'>9789672</td><td bgcolor='#eeeeec'>Zend_Controller_Action->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Dispatcher/Standard.php' bgcolor='#eeeeec'>../Standard.php<b>:</b>308</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>6</td><td bgcolor='#eeeeec' align='center'>0.8547</td><td bgcolor='#eeeeec' align='right'>11070736</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->postDispatch( )</td><td title='/usr/share/php/Zend/Controller/Action.php' bgcolor='#eeeeec'>../Action.php<b>:</b>521</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>7</td><td bgcolor='#eeeeec' align='center'>0.8550</td><td bgcolor='#eeeeec' align='right'>11071712</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->sendAsPdfAndDie( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>244</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>8</td><td bgcolor='#eeeeec' align='center'>1.9930</td><td bgcolor='#eeeeec' align='right'>23228752</td><td bgcolor='#eeeeec'>Icinga\File\Pdf->renderPage( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>279</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>9</td><td bgcolor='#eeeeec' align='center'>2.0668</td><td bgcolor='#eeeeec' align='right'>23495800</td><td bgcolor='#eeeeec'>DOMPDF->render( )</td><td title='/vagrant/library/Icinga/File/Pdf.php' bgcolor='#eeeeec'>../Pdf.php<b>:</b>62</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>10</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/dompdf.cls.php' bgcolor='#eeeeec'>../dompdf.cls.php<b>:</b>817</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>11</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430520</td><td bgcolor='#eeeeec'>Page_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>12</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432912</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/page_frame_reflower.cls.php' bgcolor='#eeeeec'>../page_frame_reflower.cls.php<b>:</b>138</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>13</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432960</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>14</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>15</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>16</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>17</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>18</td><td bgcolor='#eeeeec' align='center'>9.2431</td><td bgcolor='#eeeeec' align='right'>49918440</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>19</td><td bgcolor='#eeeeec' align='center'>9.2431</td><td bgcolor='#eeeeec' align='right'>49918440</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>20</td><td bgcolor='#eeeeec' align='center'>9.2459</td><td bgcolor='#eeeeec' align='right'>49935336</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>21</td><td bgcolor='#eeeeec' align='center'>9.2459</td><td bgcolor='#eeeeec' align='right'>49935336</td><td bgcolor='#eeeeec'>Table_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
</table></font>
<br />
<font size='1'><table class='xdebug-error' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line <i>396</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.0015</td><td bgcolor='#eeeeec' align='right'>634696</td><td bgcolor='#eeeeec'>{main}( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Icinga\Application\Web->dispatch( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>17</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Zend_Controller_Front->dispatch( )</td><td title='/vagrant/library/Icinga/Application/Web.php' bgcolor='#eeeeec'>../Web.php<b>:</b>177</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>4</td><td bgcolor='#eeeeec' align='center'>0.6718</td><td bgcolor='#eeeeec' align='right'>7339544</td><td bgcolor='#eeeeec'>Zend_Controller_Dispatcher_Standard->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Front.php' bgcolor='#eeeeec'>../Front.php<b>:</b>954</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>5</td><td bgcolor='#eeeeec' align='center'>0.7544</td><td bgcolor='#eeeeec' align='right'>9789672</td><td bgcolor='#eeeeec'>Zend_Controller_Action->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Dispatcher/Standard.php' bgcolor='#eeeeec'>../Standard.php<b>:</b>308</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>6</td><td bgcolor='#eeeeec' align='center'>0.8547</td><td bgcolor='#eeeeec' align='right'>11070736</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->postDispatch( )</td><td title='/usr/share/php/Zend/Controller/Action.php' bgcolor='#eeeeec'>../Action.php<b>:</b>521</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>7</td><td bgcolor='#eeeeec' align='center'>0.8550</td><td bgcolor='#eeeeec' align='right'>11071712</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->sendAsPdfAndDie( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>244</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>8</td><td bgcolor='#eeeeec' align='center'>1.9930</td><td bgcolor='#eeeeec' align='right'>23228752</td><td bgcolor='#eeeeec'>Icinga\File\Pdf->renderPage( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>279</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>9</td><td bgcolor='#eeeeec' align='center'>2.0668</td><td bgcolor='#eeeeec' align='right'>23495800</td><td bgcolor='#eeeeec'>DOMPDF->render( )</td><td title='/vagrant/library/Icinga/File/Pdf.php' bgcolor='#eeeeec'>../Pdf.php<b>:</b>62</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>10</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/dompdf.cls.php' bgcolor='#eeeeec'>../dompdf.cls.php<b>:</b>817</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>11</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430520</td><td bgcolor='#eeeeec'>Page_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>12</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432912</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/page_frame_reflower.cls.php' bgcolor='#eeeeec'>../page_frame_reflower.cls.php<b>:</b>138</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>13</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432960</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>14</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>15</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>16</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>17</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>18</td><td bgcolor='#eeeeec' align='center'>9.2431</td><td bgcolor='#eeeeec' align='right'>49918440</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>19</td><td bgcolor='#eeeeec' align='center'>9.2431</td><td bgcolor='#eeeeec' align='right'>49918440</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>20</td><td bgcolor='#eeeeec' align='center'>9.2519</td><td bgcolor='#eeeeec' align='right'>49965624</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>21</td><td bgcolor='#eeeeec' align='center'>9.2519</td><td bgcolor='#eeeeec' align='right'>49965624</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>22</td><td bgcolor='#eeeeec' align='center'>9.2575</td><td bgcolor='#eeeeec' align='right'>49989664</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>23</td><td bgcolor='#eeeeec' align='center'>9.2575</td><td bgcolor='#eeeeec' align='right'>49989664</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>24</td><td bgcolor='#eeeeec' align='center'>9.2593</td><td bgcolor='#eeeeec' align='right'>50005472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>25</td><td bgcolor='#eeeeec' align='center'>9.2594</td><td bgcolor='#eeeeec' align='right'>50005472</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>26</td><td bgcolor='#eeeeec' align='center'>9.2611</td><td bgcolor='#eeeeec' align='right'>50020048</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>27</td><td bgcolor='#eeeeec' align='center'>9.2611</td><td bgcolor='#eeeeec' align='right'>50020048</td><td bgcolor='#eeeeec'>Table_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
</table></font>
<br />
<font size='1'><table class='xdebug-error' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line <i>396</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.0015</td><td bgcolor='#eeeeec' align='right'>634696</td><td bgcolor='#eeeeec'>{main}( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Icinga\Application\Web->dispatch( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>17</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Zend_Controller_Front->dispatch( )</td><td title='/vagrant/library/Icinga/Application/Web.php' bgcolor='#eeeeec'>../Web.php<b>:</b>177</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>4</td><td bgcolor='#eeeeec' align='center'>0.6718</td><td bgcolor='#eeeeec' align='right'>7339544</td><td bgcolor='#eeeeec'>Zend_Controller_Dispatcher_Standard->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Front.php' bgcolor='#eeeeec'>../Front.php<b>:</b>954</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>5</td><td bgcolor='#eeeeec' align='center'>0.7544</td><td bgcolor='#eeeeec' align='right'>9789672</td><td bgcolor='#eeeeec'>Zend_Controller_Action->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Dispatcher/Standard.php' bgcolor='#eeeeec'>../Standard.php<b>:</b>308</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>6</td><td bgcolor='#eeeeec' align='center'>0.8547</td><td bgcolor='#eeeeec' align='right'>11070736</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->postDispatch( )</td><td title='/usr/share/php/Zend/Controller/Action.php' bgcolor='#eeeeec'>../Action.php<b>:</b>521</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>7</td><td bgcolor='#eeeeec' align='center'>0.8550</td><td bgcolor='#eeeeec' align='right'>11071712</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->sendAsPdfAndDie( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>244</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>8</td><td bgcolor='#eeeeec' align='center'>1.9930</td><td bgcolor='#eeeeec' align='right'>23228752</td><td bgcolor='#eeeeec'>Icinga\File\Pdf->renderPage( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>279</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>9</td><td bgcolor='#eeeeec' align='center'>2.0668</td><td bgcolor='#eeeeec' align='right'>23495800</td><td bgcolor='#eeeeec'>DOMPDF->render( )</td><td title='/vagrant/library/Icinga/File/Pdf.php' bgcolor='#eeeeec'>../Pdf.php<b>:</b>62</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>10</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/dompdf.cls.php' bgcolor='#eeeeec'>../dompdf.cls.php<b>:</b>817</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>11</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430520</td><td bgcolor='#eeeeec'>Page_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>12</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432912</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/page_frame_reflower.cls.php' bgcolor='#eeeeec'>../page_frame_reflower.cls.php<b>:</b>138</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>13</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432960</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>14</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>15</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>16</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>17</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>18</td><td bgcolor='#eeeeec' align='center'>9.2431</td><td bgcolor='#eeeeec' align='right'>49918440</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>19</td><td bgcolor='#eeeeec' align='center'>9.2431</td><td bgcolor='#eeeeec' align='right'>49918440</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>20</td><td bgcolor='#eeeeec' align='center'>9.2519</td><td bgcolor='#eeeeec' align='right'>49965624</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>21</td><td bgcolor='#eeeeec' align='center'>9.2519</td><td bgcolor='#eeeeec' align='right'>49965624</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>22</td><td bgcolor='#eeeeec' align='center'>9.2575</td><td bgcolor='#eeeeec' align='right'>49989664</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>23</td><td bgcolor='#eeeeec' align='center'>9.2575</td><td bgcolor='#eeeeec' align='right'>49989664</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>24</td><td bgcolor='#eeeeec' align='center'>9.2593</td><td bgcolor='#eeeeec' align='right'>50005472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>25</td><td bgcolor='#eeeeec' align='center'>9.2594</td><td bgcolor='#eeeeec' align='right'>50005472</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>26</td><td bgcolor='#eeeeec' align='center'>9.2722</td><td bgcolor='#eeeeec' align='right'>50061408</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>27</td><td bgcolor='#eeeeec' align='center'>9.2722</td><td bgcolor='#eeeeec' align='right'>50061408</td><td bgcolor='#eeeeec'>Table_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
</table></font>
<br />
<font size='1'><table class='xdebug-error' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line <i>396</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.0015</td><td bgcolor='#eeeeec' align='right'>634696</td><td bgcolor='#eeeeec'>{main}( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Icinga\Application\Web->dispatch( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>17</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Zend_Controller_Front->dispatch( )</td><td title='/vagrant/library/Icinga/Application/Web.php' bgcolor='#eeeeec'>../Web.php<b>:</b>177</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>4</td><td bgcolor='#eeeeec' align='center'>0.6718</td><td bgcolor='#eeeeec' align='right'>7339544</td><td bgcolor='#eeeeec'>Zend_Controller_Dispatcher_Standard->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Front.php' bgcolor='#eeeeec'>../Front.php<b>:</b>954</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>5</td><td bgcolor='#eeeeec' align='center'>0.7544</td><td bgcolor='#eeeeec' align='right'>9789672</td><td bgcolor='#eeeeec'>Zend_Controller_Action->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Dispatcher/Standard.php' bgcolor='#eeeeec'>../Standard.php<b>:</b>308</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>6</td><td bgcolor='#eeeeec' align='center'>0.8547</td><td bgcolor='#eeeeec' align='right'>11070736</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->postDispatch( )</td><td title='/usr/share/php/Zend/Controller/Action.php' bgcolor='#eeeeec'>../Action.php<b>:</b>521</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>7</td><td bgcolor='#eeeeec' align='center'>0.8550</td><td bgcolor='#eeeeec' align='right'>11071712</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->sendAsPdfAndDie( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>244</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>8</td><td bgcolor='#eeeeec' align='center'>1.9930</td><td bgcolor='#eeeeec' align='right'>23228752</td><td bgcolor='#eeeeec'>Icinga\File\Pdf->renderPage( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>279</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>9</td><td bgcolor='#eeeeec' align='center'>2.0668</td><td bgcolor='#eeeeec' align='right'>23495800</td><td bgcolor='#eeeeec'>DOMPDF->render( )</td><td title='/vagrant/library/Icinga/File/Pdf.php' bgcolor='#eeeeec'>../Pdf.php<b>:</b>62</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>10</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/dompdf.cls.php' bgcolor='#eeeeec'>../dompdf.cls.php<b>:</b>817</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>11</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430520</td><td bgcolor='#eeeeec'>Page_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>12</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432912</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/page_frame_reflower.cls.php' bgcolor='#eeeeec'>../page_frame_reflower.cls.php<b>:</b>138</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>13</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432960</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>14</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>15</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>16</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>17</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>18</td><td bgcolor='#eeeeec' align='center'>9.2431</td><td bgcolor='#eeeeec' align='right'>49918440</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>19</td><td bgcolor='#eeeeec' align='center'>9.2431</td><td bgcolor='#eeeeec' align='right'>49918440</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>20</td><td bgcolor='#eeeeec' align='center'>9.2999</td><td bgcolor='#eeeeec' align='right'>50176560</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>21</td><td bgcolor='#eeeeec' align='center'>9.2999</td><td bgcolor='#eeeeec' align='right'>50176560</td><td bgcolor='#eeeeec'>Table_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
</table></font>
<br />
<font size='1'><table class='xdebug-error' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line <i>396</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.0015</td><td bgcolor='#eeeeec' align='right'>634696</td><td bgcolor='#eeeeec'>{main}( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Icinga\Application\Web->dispatch( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>17</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Zend_Controller_Front->dispatch( )</td><td title='/vagrant/library/Icinga/Application/Web.php' bgcolor='#eeeeec'>../Web.php<b>:</b>177</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>4</td><td bgcolor='#eeeeec' align='center'>0.6718</td><td bgcolor='#eeeeec' align='right'>7339544</td><td bgcolor='#eeeeec'>Zend_Controller_Dispatcher_Standard->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Front.php' bgcolor='#eeeeec'>../Front.php<b>:</b>954</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>5</td><td bgcolor='#eeeeec' align='center'>0.7544</td><td bgcolor='#eeeeec' align='right'>9789672</td><td bgcolor='#eeeeec'>Zend_Controller_Action->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Dispatcher/Standard.php' bgcolor='#eeeeec'>../Standard.php<b>:</b>308</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>6</td><td bgcolor='#eeeeec' align='center'>0.8547</td><td bgcolor='#eeeeec' align='right'>11070736</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->postDispatch( )</td><td title='/usr/share/php/Zend/Controller/Action.php' bgcolor='#eeeeec'>../Action.php<b>:</b>521</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>7</td><td bgcolor='#eeeeec' align='center'>0.8550</td><td bgcolor='#eeeeec' align='right'>11071712</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->sendAsPdfAndDie( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>244</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>8</td><td bgcolor='#eeeeec' align='center'>1.9930</td><td bgcolor='#eeeeec' align='right'>23228752</td><td bgcolor='#eeeeec'>Icinga\File\Pdf->renderPage( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>279</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>9</td><td bgcolor='#eeeeec' align='center'>2.0668</td><td bgcolor='#eeeeec' align='right'>23495800</td><td bgcolor='#eeeeec'>DOMPDF->render( )</td><td title='/vagrant/library/Icinga/File/Pdf.php' bgcolor='#eeeeec'>../Pdf.php<b>:</b>62</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>10</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/dompdf.cls.php' bgcolor='#eeeeec'>../dompdf.cls.php<b>:</b>817</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>11</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430520</td><td bgcolor='#eeeeec'>Page_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>12</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432912</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/page_frame_reflower.cls.php' bgcolor='#eeeeec'>../page_frame_reflower.cls.php<b>:</b>138</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>13</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432960</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>14</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>15</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>16</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>17</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>18</td><td bgcolor='#eeeeec' align='center'>9.3083</td><td bgcolor='#eeeeec' align='right'>50220200</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>19</td><td bgcolor='#eeeeec' align='center'>9.3083</td><td bgcolor='#eeeeec' align='right'>50220200</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>20</td><td bgcolor='#eeeeec' align='center'>9.3103</td><td bgcolor='#eeeeec' align='right'>50235768</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>21</td><td bgcolor='#eeeeec' align='center'>9.3103</td><td bgcolor='#eeeeec' align='right'>50235768</td><td bgcolor='#eeeeec'>Table_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
</table></font>
<br />
<font size='1'><table class='xdebug-error' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line <i>396</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.0015</td><td bgcolor='#eeeeec' align='right'>634696</td><td bgcolor='#eeeeec'>{main}( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Icinga\Application\Web->dispatch( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>17</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Zend_Controller_Front->dispatch( )</td><td title='/vagrant/library/Icinga/Application/Web.php' bgcolor='#eeeeec'>../Web.php<b>:</b>177</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>4</td><td bgcolor='#eeeeec' align='center'>0.6718</td><td bgcolor='#eeeeec' align='right'>7339544</td><td bgcolor='#eeeeec'>Zend_Controller_Dispatcher_Standard->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Front.php' bgcolor='#eeeeec'>../Front.php<b>:</b>954</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>5</td><td bgcolor='#eeeeec' align='center'>0.7544</td><td bgcolor='#eeeeec' align='right'>9789672</td><td bgcolor='#eeeeec'>Zend_Controller_Action->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Dispatcher/Standard.php' bgcolor='#eeeeec'>../Standard.php<b>:</b>308</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>6</td><td bgcolor='#eeeeec' align='center'>0.8547</td><td bgcolor='#eeeeec' align='right'>11070736</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->postDispatch( )</td><td title='/usr/share/php/Zend/Controller/Action.php' bgcolor='#eeeeec'>../Action.php<b>:</b>521</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>7</td><td bgcolor='#eeeeec' align='center'>0.8550</td><td bgcolor='#eeeeec' align='right'>11071712</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->sendAsPdfAndDie( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>244</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>8</td><td bgcolor='#eeeeec' align='center'>1.9930</td><td bgcolor='#eeeeec' align='right'>23228752</td><td bgcolor='#eeeeec'>Icinga\File\Pdf->renderPage( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>279</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>9</td><td bgcolor='#eeeeec' align='center'>2.0668</td><td bgcolor='#eeeeec' align='right'>23495800</td><td bgcolor='#eeeeec'>DOMPDF->render( )</td><td title='/vagrant/library/Icinga/File/Pdf.php' bgcolor='#eeeeec'>../Pdf.php<b>:</b>62</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>10</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/dompdf.cls.php' bgcolor='#eeeeec'>../dompdf.cls.php<b>:</b>817</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>11</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430520</td><td bgcolor='#eeeeec'>Page_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>12</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432912</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/page_frame_reflower.cls.php' bgcolor='#eeeeec'>../page_frame_reflower.cls.php<b>:</b>138</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>13</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432960</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>14</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>15</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>16</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>17</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>18</td><td bgcolor='#eeeeec' align='center'>9.3083</td><td bgcolor='#eeeeec' align='right'>50220200</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>19</td><td bgcolor='#eeeeec' align='center'>9.3083</td><td bgcolor='#eeeeec' align='right'>50220200</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>20</td><td bgcolor='#eeeeec' align='center'>9.3170</td><td bgcolor='#eeeeec' align='right'>50278592</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>21</td><td bgcolor='#eeeeec' align='center'>9.3170</td><td bgcolor='#eeeeec' align='right'>50278592</td><td bgcolor='#eeeeec'>Table_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
</table></font>
<br />
<font size='1'><table class='xdebug-error' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line <i>396</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.0015</td><td bgcolor='#eeeeec' align='right'>634696</td><td bgcolor='#eeeeec'>{main}( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Icinga\Application\Web->dispatch( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>17</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Zend_Controller_Front->dispatch( )</td><td title='/vagrant/library/Icinga/Application/Web.php' bgcolor='#eeeeec'>../Web.php<b>:</b>177</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>4</td><td bgcolor='#eeeeec' align='center'>0.6718</td><td bgcolor='#eeeeec' align='right'>7339544</td><td bgcolor='#eeeeec'>Zend_Controller_Dispatcher_Standard->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Front.php' bgcolor='#eeeeec'>../Front.php<b>:</b>954</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>5</td><td bgcolor='#eeeeec' align='center'>0.7544</td><td bgcolor='#eeeeec' align='right'>9789672</td><td bgcolor='#eeeeec'>Zend_Controller_Action->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Dispatcher/Standard.php' bgcolor='#eeeeec'>../Standard.php<b>:</b>308</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>6</td><td bgcolor='#eeeeec' align='center'>0.8547</td><td bgcolor='#eeeeec' align='right'>11070736</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->postDispatch( )</td><td title='/usr/share/php/Zend/Controller/Action.php' bgcolor='#eeeeec'>../Action.php<b>:</b>521</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>7</td><td bgcolor='#eeeeec' align='center'>0.8550</td><td bgcolor='#eeeeec' align='right'>11071712</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->sendAsPdfAndDie( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>244</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>8</td><td bgcolor='#eeeeec' align='center'>1.9930</td><td bgcolor='#eeeeec' align='right'>23228752</td><td bgcolor='#eeeeec'>Icinga\File\Pdf->renderPage( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>279</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>9</td><td bgcolor='#eeeeec' align='center'>2.0668</td><td bgcolor='#eeeeec' align='right'>23495800</td><td bgcolor='#eeeeec'>DOMPDF->render( )</td><td title='/vagrant/library/Icinga/File/Pdf.php' bgcolor='#eeeeec'>../Pdf.php<b>:</b>62</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>10</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/dompdf.cls.php' bgcolor='#eeeeec'>../dompdf.cls.php<b>:</b>817</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>11</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430520</td><td bgcolor='#eeeeec'>Page_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>12</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432912</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/page_frame_reflower.cls.php' bgcolor='#eeeeec'>../page_frame_reflower.cls.php<b>:</b>138</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>13</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432960</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>14</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>15</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>16</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>17</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>18</td><td bgcolor='#eeeeec' align='center'>9.3246</td><td bgcolor='#eeeeec' align='right'>50312056</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>19</td><td bgcolor='#eeeeec' align='center'>9.3247</td><td bgcolor='#eeeeec' align='right'>50312056</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>20</td><td bgcolor='#eeeeec' align='center'>9.3266</td><td bgcolor='#eeeeec' align='right'>50326968</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>21</td><td bgcolor='#eeeeec' align='center'>9.3266</td><td bgcolor='#eeeeec' align='right'>50326968</td><td bgcolor='#eeeeec'>Table_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
</table></font>
<br />
<font size='1'><table class='xdebug-error' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line <i>396</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.0015</td><td bgcolor='#eeeeec' align='right'>634696</td><td bgcolor='#eeeeec'>{main}( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Icinga\Application\Web->dispatch( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>17</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Zend_Controller_Front->dispatch( )</td><td title='/vagrant/library/Icinga/Application/Web.php' bgcolor='#eeeeec'>../Web.php<b>:</b>177</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>4</td><td bgcolor='#eeeeec' align='center'>0.6718</td><td bgcolor='#eeeeec' align='right'>7339544</td><td bgcolor='#eeeeec'>Zend_Controller_Dispatcher_Standard->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Front.php' bgcolor='#eeeeec'>../Front.php<b>:</b>954</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>5</td><td bgcolor='#eeeeec' align='center'>0.7544</td><td bgcolor='#eeeeec' align='right'>9789672</td><td bgcolor='#eeeeec'>Zend_Controller_Action->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Dispatcher/Standard.php' bgcolor='#eeeeec'>../Standard.php<b>:</b>308</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>6</td><td bgcolor='#eeeeec' align='center'>0.8547</td><td bgcolor='#eeeeec' align='right'>11070736</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->postDispatch( )</td><td title='/usr/share/php/Zend/Controller/Action.php' bgcolor='#eeeeec'>../Action.php<b>:</b>521</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>7</td><td bgcolor='#eeeeec' align='center'>0.8550</td><td bgcolor='#eeeeec' align='right'>11071712</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->sendAsPdfAndDie( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>244</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>8</td><td bgcolor='#eeeeec' align='center'>1.9930</td><td bgcolor='#eeeeec' align='right'>23228752</td><td bgcolor='#eeeeec'>Icinga\File\Pdf->renderPage( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>279</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>9</td><td bgcolor='#eeeeec' align='center'>2.0668</td><td bgcolor='#eeeeec' align='right'>23495800</td><td bgcolor='#eeeeec'>DOMPDF->render( )</td><td title='/vagrant/library/Icinga/File/Pdf.php' bgcolor='#eeeeec'>../Pdf.php<b>:</b>62</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>10</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/dompdf.cls.php' bgcolor='#eeeeec'>../dompdf.cls.php<b>:</b>817</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>11</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430520</td><td bgcolor='#eeeeec'>Page_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>12</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432912</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/page_frame_reflower.cls.php' bgcolor='#eeeeec'>../page_frame_reflower.cls.php<b>:</b>138</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>13</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432960</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>14</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>15</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>16</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>17</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>18</td><td bgcolor='#eeeeec' align='center'>9.3246</td><td bgcolor='#eeeeec' align='right'>50312056</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>19</td><td bgcolor='#eeeeec' align='center'>9.3247</td><td bgcolor='#eeeeec' align='right'>50312056</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>20</td><td bgcolor='#eeeeec' align='center'>9.3367</td><td bgcolor='#eeeeec' align='right'>50378088</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>21</td><td bgcolor='#eeeeec' align='center'>9.3367</td><td bgcolor='#eeeeec' align='right'>50378088</td><td bgcolor='#eeeeec'>Table_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
</table></font>
<br />
<font size='1'><table class='xdebug-error' dir='ltr' border='1' cellspacing='0' cellpadding='1'>
<tr><th align='left' bgcolor='#f57900' colspan="5"><span style='background-color: #cc0000; color: #fce94f; font-size: x-large;'>( ! )</span> Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line <i>396</i></th></tr>
<tr><th align='left' bgcolor='#e9b96e' colspan='5'>Call Stack</th></tr>
<tr><th align='center' bgcolor='#eeeeec'>#</th><th align='left' bgcolor='#eeeeec'>Time</th><th align='left' bgcolor='#eeeeec'>Memory</th><th align='left' bgcolor='#eeeeec'>Function</th><th align='left' bgcolor='#eeeeec'>Location</th></tr>
<tr><td bgcolor='#eeeeec' align='center'>1</td><td bgcolor='#eeeeec' align='center'>0.0015</td><td bgcolor='#eeeeec' align='right'>634696</td><td bgcolor='#eeeeec'>{main}( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>0</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>2</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Icinga\Application\Web->dispatch( )</td><td title='/vagrant/public/index.php' bgcolor='#eeeeec'>../index.php<b>:</b>17</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>3</td><td bgcolor='#eeeeec' align='center'>0.6663</td><td bgcolor='#eeeeec' align='right'>7155080</td><td bgcolor='#eeeeec'>Zend_Controller_Front->dispatch( )</td><td title='/vagrant/library/Icinga/Application/Web.php' bgcolor='#eeeeec'>../Web.php<b>:</b>177</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>4</td><td bgcolor='#eeeeec' align='center'>0.6718</td><td bgcolor='#eeeeec' align='right'>7339544</td><td bgcolor='#eeeeec'>Zend_Controller_Dispatcher_Standard->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Front.php' bgcolor='#eeeeec'>../Front.php<b>:</b>954</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>5</td><td bgcolor='#eeeeec' align='center'>0.7544</td><td bgcolor='#eeeeec' align='right'>9789672</td><td bgcolor='#eeeeec'>Zend_Controller_Action->dispatch( )</td><td title='/usr/share/php/Zend/Controller/Dispatcher/Standard.php' bgcolor='#eeeeec'>../Standard.php<b>:</b>308</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>6</td><td bgcolor='#eeeeec' align='center'>0.8547</td><td bgcolor='#eeeeec' align='right'>11070736</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->postDispatch( )</td><td title='/usr/share/php/Zend/Controller/Action.php' bgcolor='#eeeeec'>../Action.php<b>:</b>521</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>7</td><td bgcolor='#eeeeec' align='center'>0.8550</td><td bgcolor='#eeeeec' align='right'>11071712</td><td bgcolor='#eeeeec'>Icinga\Web\Controller\ActionController->sendAsPdfAndDie( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>244</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>8</td><td bgcolor='#eeeeec' align='center'>1.9930</td><td bgcolor='#eeeeec' align='right'>23228752</td><td bgcolor='#eeeeec'>Icinga\File\Pdf->renderPage( )</td><td title='/vagrant/library/Icinga/Web/Controller/ActionController.php' bgcolor='#eeeeec'>../ActionController.php<b>:</b>279</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>9</td><td bgcolor='#eeeeec' align='center'>2.0668</td><td bgcolor='#eeeeec' align='right'>23495800</td><td bgcolor='#eeeeec'>DOMPDF->render( )</td><td title='/vagrant/library/Icinga/File/Pdf.php' bgcolor='#eeeeec'>../Pdf.php<b>:</b>62</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>10</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430472</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/dompdf.cls.php' bgcolor='#eeeeec'>../dompdf.cls.php<b>:</b>817</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>11</td><td bgcolor='#eeeeec' align='center'>9.0902</td><td bgcolor='#eeeeec' align='right'>49430520</td><td bgcolor='#eeeeec'>Page_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>12</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432912</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/page_frame_reflower.cls.php' bgcolor='#eeeeec'>../page_frame_reflower.cls.php<b>:</b>138</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>13</td><td bgcolor='#eeeeec' align='center'>9.0910</td><td bgcolor='#eeeeec' align='right'>49432960</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>14</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>15</td><td bgcolor='#eeeeec' align='center'>9.2291</td><td bgcolor='#eeeeec' align='right'>49850600</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>16</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>17</td><td bgcolor='#eeeeec' align='center'>9.2338</td><td bgcolor='#eeeeec' align='right'>49873816</td><td bgcolor='#eeeeec'>Block_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>18</td><td bgcolor='#eeeeec' align='center'>9.3442</td><td bgcolor='#eeeeec' align='right'>50422280</td><td bgcolor='#eeeeec'>Frame_Decorator->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/block_frame_reflower.cls.php' bgcolor='#eeeeec'>../block_frame_reflower.cls.php<b>:</b>722</td></tr>
<tr><td bgcolor='#eeeeec' align='center'>19</td><td bgcolor='#eeeeec' align='center'>9.3442</td><td bgcolor='#eeeeec' align='right'>50422280</td><td bgcolor='#eeeeec'>Table_Frame_Reflower->reflow( )</td><td title='/vagrant/library/vendor/dompdf/include/frame_decorator.cls.php' bgcolor='#eeeeec'>../frame_decorator.cls.php<b>:</b>556</td></tr>
</table></font>

@ -147,7 +147,7 @@ class Monitoring_ChartController extends Controller
->setXAxis(new StaticAxis())
->setAxisMin(null, 0);
$tooltip = t('<b>{title}:</b><br />{value} of {sum} services are {label}');
$tooltip = t('<b>{title}:</b><br>{value} of {sum} services are {label}');
$this->view->chart->drawBars(
array(
'label' => t('Ok'),
@ -199,7 +199,7 @@ class Monitoring_ChartController extends Controller
$hostgroup->hosts_unreachable_unhandled
);
}
$tooltip = t('<b>{title}:</b><br /> {value} of {sum} hosts are {label}');
$tooltip = t('<b>{title}:</b><br> {value} of {sum} hosts are {label}');
$this->view->chart = new GridChart();
$this->view->chart->alignTopLeft();
$this->view->chart->setAxisLabel('', t('Hosts'))

@ -2,14 +2,13 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
use Icinga\Config\PreservingIniWriter;
use Icinga\Web\Controller\ModuleActionController;
use Icinga\Web\Notification;
use Icinga\Data\ResourceFactory;
use Icinga\Form\ConfirmRemovalForm;
use Icinga\Module\Monitoring\Form\Config\BackendForm;
use Icinga\Module\Monitoring\Form\Config\InstanceForm;
use Icinga\Module\Monitoring\Form\Config\SecurityForm;
use Icinga\Exception\NotReadableError;
use Icinga\Web\Controller\ModuleActionController;
use Icinga\Module\Monitoring\Form\Config\BackendConfigForm;
use Icinga\Module\Monitoring\Form\Config\InstanceConfigForm;
use Icinga\Module\Monitoring\Form\Config\SecurityConfigForm;
/**
* Configuration controller for editing monitoring resources
@ -21,19 +20,9 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function indexAction()
{
$this->view->backendsConfig = $this->Config('backends');
$this->view->instancesConfig = $this->Config('instances');
$this->view->tabs = $this->Module()->getConfigTabs()->activate('backends');
foreach (array('backends', 'instances') as $element) {
try {
$elementConfig = $this->Config($element);
if ($elementConfig === null) {
$this->view->{$element} = array();
} else {
$this->view->{$element} = $elementConfig->toArray();
}
} catch (NotReadableError $e) {
$this->view->{$element} = $e;
}
}
}
/**
@ -41,38 +30,11 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function editbackendAction()
{
// Fetch the backend to be edited
$backend = $this->getParam('backend');
$backendsConfig = $this->Config('backends')->toArray();
if (false === array_key_exists($backend, $backendsConfig)) {
// TODO: Should behave as in the app's config controller (Specific redirect to an error action)
Notification::error(sprintf($this->translate('Cannot edit "%s". Backend not found.'), $backend));
$this->redirectNow('monitoring/config');
}
$form = new BackendForm();
$request = $this->getRequest();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
list($newName, $config) = $form->getBackendConfig();
if ($newName !== $backend) {
// Backend name has changed
unset($backendsConfig[$backend]); // We can safely use unset as all values are part of the form
}
$backendsConfig[$newName] = $config;
if ($this->writeConfiguration($backendsConfig, 'backends')) {
Notification::success(sprintf($this->translate('Backend "%s" successfully modified.'), $backend));
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
return;
}
}
} else {
$form->setBackendConfig($backend, $backendsConfig[$backend]);
}
$form = new BackendConfigForm();
$form->setIniConfig($this->Config('backends'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
$this->view->form = $form;
}
@ -82,20 +44,11 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function createbackendAction()
{
$form = new BackendForm();
$request = $this->getRequest();
if ($request->isPost() && $form->isValid($request->getPost())) {
list($name, $config) = $form->getBackendConfig();
$backendsConfig = $this->Config('backends')->toArray();
$backendsConfig[$name] = $config;
if ($this->writeConfiguration($backendsConfig, 'backends')) {
Notification::success(sprintf($this->translate('Backend "%s" created successfully.'), $name));
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
return;
}
}
$form = new BackendConfigForm();
$form->setIniConfig($this->Config('backends'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
$this->view->form = $form;
}
@ -105,26 +58,29 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function removebackendAction()
{
$backend = $this->getParam('backend');
$backendsConfig = $this->Config('backends')->toArray();
if (false === array_key_exists($backend, $backendsConfig)) {
// TODO: Should behave as in the app's config controller (Specific redirect to an error action)
Notification::error(sprintf($this->translate('Cannot remove "%s". Backend not found.'), $backend));
$this->redirectNow('monitoring/config');
}
$config = $this->Config('backends');
$form = new ConfirmRemovalForm(array(
'onSuccess' => function ($request) use ($config) {
$backendName = $request->getQuery('backend');
$configForm = new BackendConfigForm();
$configForm->setIniConfig($config);
$form = new ConfirmRemovalForm();
$request = $this->getRequest();
if ($request->isPost() && $form->isValid($request->getPost())) {
unset($backendsConfig[$backend]);
if ($this->writeConfiguration($backendsConfig, 'backends')) {
Notification::success(sprintf($this->translate('Backend "%s" successfully removed.'), $backend));
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
return;
try {
$configForm->remove($backendName);
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
return;
}
if ($configForm->save()) {
Notification::success(sprintf(t('Backend "%s" successfully removed.'), $backendName));
} else {
return false;
}
}
}
));
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
$this->view->form = $form;
}
@ -134,29 +90,31 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function removeinstanceAction()
{
$instance = $this->getParam('instance');
$instancesConfig = $this->Config('instances')->toArray();
if (false === array_key_exists($instance, $instancesConfig)) {
// TODO: Should behave as in the app's config controller (Specific redirect to an error action)
Notification::error(sprintf($this->translate('Cannot remove "%s". Instance not found.'), $instance));
$this->redirectNow('monitoring/config');
}
$config = $this->Config('instances');
$form = new ConfirmRemovalForm(array(
'onSuccess' => function ($request) use ($config) {
$instanceName = $request->getQuery('instance');
$configForm = new InstanceConfigForm();
$configForm->setIniConfig($config);
$form = new ConfirmRemovalForm();
$request = $this->getRequest();
if ($request->isPost() && $form->isValid($request->getPost())) {
unset($instancesConfig[$instance]);
if ($this->writeConfiguration($instancesConfig, 'instances')) {
Notification::success(sprintf($this->translate('Instance "%s" successfully removed.'), $instance));
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
return;
try {
$configForm->remove($instanceName);
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
return;
}
if ($configForm->save()) {
Notification::success(sprintf(t('Instance "%s" successfully removed.'), $instanceName));
} else {
return false;
}
}
}
));
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
$this->view->form = $form;
$this->view->name = $instance;
}
/**
@ -164,36 +122,10 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function editinstanceAction()
{
$instance = $this->getParam('instance');
$instancesConfig = $this->Config('instances')->toArray();
if (false === array_key_exists($instance, $instancesConfig)) {
// TODO: Should behave as in the app's config controller (Specific redirect to an error action)
Notification::error(sprintf($this->translate('Cannot edit "%s". Instance not found.'), $instance));
$this->redirectNow('monitoring/config');
}
$form = new InstanceForm();
$request = $this->getRequest();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
list($newName, $config) = $form->getInstanceConfig();
if ($newName !== $instance) {
unset($instancesConfig[$instance]); // We can safely use unset as all values are part of the form
}
$instancesConfig[$newName] = $config;
if ($this->writeConfiguration($instancesConfig, 'instances')) {
Notification::success(sprintf($this->translate('Instance "%s" successfully modified.'), $instance));
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
return;
}
}
} else {
$form->setInstanceConfig($instance, $instancesConfig[$instance]);
}
$form = new InstanceConfigForm();
$form->setIniConfig($this->Config('instances'));
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
$this->view->form = $form;
}
@ -203,77 +135,24 @@ class Monitoring_ConfigController extends ModuleActionController
*/
public function createinstanceAction()
{
$form = new InstanceForm();
$request = $this->getRequest();
if ($request->isPost() && $form->isValid($request->getPost())) {
list($name, $config) = $form->getInstanceConfig();
$instancesConfig = $this->Config('instances')->toArray();
$instancesConfig[$name] = $config;
if ($this->writeConfiguration($instancesConfig, 'instances')) {
Notification::success(sprintf($this->translate('Instance "%s" created successfully.'), $name));
$this->redirectNow('monitoring/config');
} else {
$this->render('show-configuration');
return;
}
}
$form = new InstanceConfigForm();
$form->setIniConfig($this->Config('instances'));
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
$this->view->form = $form;
}
/**
* Write configuration to an ini file
*
* @param Zend_Config $config The configuration to write
* @param string $file The config file to write to
*
* @return bool Whether the configuration was written or not
*/
protected function writeConfiguration($config, $file = null)
{
if (is_array($config)) {
$config = new Zend_Config($config);
}
$target = $this->Config($file)->getConfigFile();
$writer = new PreservingIniWriter(array('filename' => $target, 'config' => $config));
try {
$writer->write();
} catch (Exception $exc) {
$this->view->exceptionMessage = $exc->getMessage();
$this->view->iniConfigurationString = $writer->render();
$this->view->file = $target;
return false;
}
return true;
}
/**
* Display a form to adjust security relevant settings
*/
public function securityAction()
{
$this->view->tabs = $this->Module()->getConfigTabs()->activate('security');
$form = new SecurityForm();
$request = $this->getRequest();
$config = $this->Config()->toArray();
if ($request->isPost()) {
if ($form->isValid($request->getPost())) {
$config['security'] = $form->getValues();
if ($this->writeConfiguration(new Zend_Config($config))) {
Notification::success('Configuration modified successfully');
$this->redirectNow('monitoring/config/security');
} else {
$this->render('show-configuration');
return;
}
}
} elseif (isset($config['security'])) {
$form->populate($config['security']);
}
$form = new SecurityConfigForm();
$form->setIniConfig($this->Config());
$form->handleRequest();
$this->view->form = $form;
$this->view->tabs = $this->Module()->getConfigTabs()->activate('security');
}
}

@ -13,7 +13,6 @@ use Icinga\Module\Monitoring\Controller;
use Icinga\Module\Monitoring\Timeline\TimeLine;
use Icinga\Module\Monitoring\Timeline\TimeRange;
use Icinga\Module\Monitoring\Web\Widget\TimelineIntervalBox;
use Icinga\Module\Monitoring\DataView\EventHistory as EventHistoryView;
class Monitoring_TimelineController extends Controller
{

@ -0,0 +1,242 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\Form\Config;
use InvalidArgumentException;
use Icinga\Web\Request;
use Icinga\Web\Notification;
use Icinga\Form\ConfigForm;
use Icinga\Application\Config;
use Icinga\Exception\ConfigurationError;
/**
* Form class for creating/modifying monitoring backends
*/
class BackendConfigForm extends ConfigForm
{
/**
* The available monitoring backend resources split by type
*
* @var array
*/
protected $resources;
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_monitoring_backends');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* Set the resource configuration to use
*
* @param Config $resources The resource configuration
*
* @return self
*
* @throws ConfigurationError In case there are no valid monitoring backend resources
*/
public function setResourceConfig(Config $resourceConfig)
{
$resources = array();
foreach ($resourceConfig as $name => $resource) {
if ($resource->type === 'db' || $resource->type === 'statusdat' || $resource->type === 'livestatus') {
$resources[$resource->type === 'db' ? 'ido' : strtolower($resource->type)][] = $name;
}
}
if (empty($resources)) {
throw new ConfigurationError(t('Could not find any valid monitoring backend resources'));
}
$this->resources = $resources;
return $this;
}
/**
* Add a particular monitoring backend
*
* The backend to add is identified by the array-key `name'.
*
* @param array $values The values to extend the configuration with
*
* @return self
*
* @throws InvalidArgumentException In case the backend does already exist
*/
public function add(array $values)
{
$name = isset($values['name']) ? $values['name'] : '';
if (! $name) {
throw new InvalidArgumentException(t('Monitoring backend name missing'));
} elseif ($this->config->get($name) !== null) {
throw new InvalidArgumentException(t('Monitoring backend already exists'));
}
unset($values['name']);
$this->config->{$name} = $values;
return $this;
}
/**
* Edit a particular monitoring backend
*
* @param string $name The name of the backend to edit
* @param array $values The values to edit the configuration with
*
* @return array The edited backend configuration
*
* @throws InvalidArgumentException In case the backend does not exist
*/
public function edit($name, array $values)
{
if (! $name) {
throw new InvalidArgumentException(t('Old monitoring backend name missing'));
} elseif (! ($newName = isset($values['name']) ? $values['name'] : '')) {
throw new InvalidArgumentException(t('New monitoring backend name missing'));
} elseif (($backendConfig = $this->config->get($name)) === null) {
throw new InvalidArgumentException(t('Unknown monitoring backend provided'));
}
unset($values['name']);
unset($this->config->{$name});
$this->config->{$newName} = $values;
return $this->config->{$newName};
}
/**
* Remove the given monitoring backend
*
* @param string $name The name of the backend to remove
*
* @return array The removed backend configuration
*
* @throws InvalidArgumentException In case the backend does not exist
*/
public function remove($name)
{
if (! $name) {
throw new InvalidArgumentException(t('Monitoring backend name missing'));
} elseif (($backendConfig = $this->config->get($name)) === null) {
throw new InvalidArgumentException(t('Unknown monitoring backend provided'));
}
unset($this->config->{$name});
return $backendConfig;
}
/**
* Add or edit a monitoring backend and save the configuration
*
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
$monitoringBackend = $request->getQuery('backend');
try {
if ($monitoringBackend === null) { // create new backend
$this->add($this->getValues());
$message = t('Monitoring backend "%s" has been successfully created');
} else { // edit existing backend
$this->edit($monitoringBackend, $this->getValues());
$message = t('Monitoring backend "%s" has been successfully changed');
}
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
return;
}
if ($this->save()) {
Notification::success(sprintf($message, $this->getElement('name')->getValue()));
} else {
return false;
}
}
/**
* Populate the form in case a monitoring backend is being edited
*
* @see Form::onRequest()
*
* @throws ConfigurationError In case the backend name is missing in the request or is invalid
*/
public function onRequest(Request $request)
{
$monitoringBackend = $request->getQuery('backend');
if ($monitoringBackend !== null) {
if ($monitoringBackend === '') {
throw new ConfigurationError(t('Monitoring backend name missing'));
} elseif (false === isset($this->config->{$monitoringBackend})) {
throw new ConfigurationError(t('Unknown monitoring backend provided'));
}
$backendConfig = $this->config->{$monitoringBackend}->toArray();
$backendConfig['name'] = $monitoringBackend;
$this->populate($backendConfig);
}
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$resourceType = isset($formData['type']) ? $formData['type'] : key($this->resources);
$resourceTypes = array();
if ($resourceType === 'ido' || array_key_exists('ido', $this->resources)) {
$resourceTypes['ido'] = 'IDO Backend';
}
if ($resourceType === 'statusdat' || array_key_exists('statusdat', $this->resources)) {
$resourceTypes['statusdat'] = 'Status.dat';
}
if ($resourceType === 'livestatus' || array_key_exists('livestatus', $this->resources)) {
$resourceTypes['livestatus'] = 'Livestatus';
}
$this->addElement(
'checkbox',
'disabled',
array(
'required' => true,
'label' => t('Disable This Backend')
)
);
$this->addElement(
'text',
'name',
array(
'required' => true,
'label' => t('Backend Name'),
'description' => t('The identifier of this backend')
)
);
$this->addElement(
'select',
'type',
array(
'required' => true,
'autosubmit' => true,
'label' => t('Backend Type'),
'description' => t('The data source used for retrieving monitoring information'),
'multiOptions' => $resourceTypes,
'value' => $resourceType
)
);
$this->addElement(
'select',
'resource',
array(
'required' => true,
'label' => t('Resource'),
'description' => t('The resource to use'),
'multiOptions' => $this->resources[$resourceType]
)
);
}
}

@ -1,125 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\Form\Config;
use Icinga\Web\Form;
use Icinga\Data\ResourceFactory;
/**
* Form for modifying a monitoring backend
*/
class BackendForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_monitoring_backends');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
return array(
$this->createElement(
'text',
'name',
array(
'required' => true,
'label' => t('Backend Name'),
'helptext' => t('The identifier of this backend')
)
),
$this->createElement(
'select',
'type',
array(
'required' => true,
'class' => 'autosubmit',
'label' => t('Backend Type'),
'helptext' => t('The data source used for retrieving monitoring information'),
'multiOptions' => array(
'ido' => 'IDO Backend',
'statusdat' => 'Status.dat',
'livestatus' => 'Livestatus'
)
)
),
$this->createElement(
'select',
'resource',
array(
'required' => true,
'label' => t('Resource'),
'helptext' => t('The resource to use'),
'multiOptions' => $this->getResourcesByType(
false === isset($formData['type']) || $formData['type'] === 'ido' ? 'db' : $formData['type']
)
)
),
$this->createElement(
'checkbox',
'disabled',
array(
'required' => true,
'label' => t('Disable This Backend')
)
)
);
}
/**
* Return the backend configuration values and its name
*
* The first value is the name and the second one the values as array.
*
* @return array
*/
public function getBackendConfig()
{
$values = $this->getValues();
$name = $values['name'];
if ($values['disabled'] == '0') {
unset($values['disabled']);
}
unset($values['name']);
return array($name, $values);
}
/**
* Populate the form with the given configuration values
*
* @param string $name The name of the backend
* @param array $config The configuration values
*/
public function setBackendConfig($name, array $config)
{
$config['name'] = $name;
$this->populate($config);
}
/**
* Return a list of all resources of the given type ready to be used as content for a select input
*
* @param string $type The type of resources to return
*
* @return array
*/
protected function getResourcesByType($type)
{
$backends = array();
foreach (array_keys(ResourceFactory::getResourceConfigs($type)->toArray()) as $name) {
$backends[$name] = $name;
}
return $backends;
}
}

@ -0,0 +1,37 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\Form\Config\Instance;
use Icinga\Web\Form;
class LocalInstanceForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_monitoring_instance_local');
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'path',
array(
'required' => true,
'label' => t('Local Filepath'),
'value' => '/usr/local/icinga/var/rw/icinga.cmd',
'description' => t('The file path where the icinga commandpipe can be found')
)
);
return $this;
}
}

@ -0,0 +1,68 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\Form\Config\Instance;
use Icinga\Web\Form;
use Icinga\Web\Form\Element\Number;
class RemoteInstanceForm extends Form
{
public function init()
{
$this->setName('form_config_monitoring_instance_remote');
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'host',
array(
'required' => true,
'label' => t('Remote Host'),
'description' => t(
'Enter the hostname or address of the machine on which the icinga instance is running'
)
)
);
$this->addElement(
new Number(
array(
'required' => true,
'name' => 'port',
'label' => t('Remote SSH Port'),
'description' => t('Enter the ssh port to use for connecting to the remote icinga instance'),
'value' => 22
)
)
);
$this->addElement(
'text',
'user',
array(
'required' => true,
'label' => t('Remote SSH User'),
'description' => t(
'Enter the username to use for connecting to the remote machine or leave blank for default'
)
)
);
$this->addElement(
'text',
'path',
array(
'required' => true,
'label' => t('Remote Filepath'),
'value' => '/usr/local/icinga/var/rw/icinga.cmd',
'description' => t('The file path where the icinga commandpipe can be found')
)
);
return $this;
}
}

@ -0,0 +1,209 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\Form\Config;
use InvalidArgumentException;
use Icinga\Web\Request;
use Icinga\Form\ConfigForm;
use Icinga\Web\Notification;
use Icinga\Exception\ConfigurationError;
use Icinga\Module\Monitoring\Form\Config\Instance\LocalInstanceForm;
use Icinga\Module\Monitoring\Form\Config\Instance\RemoteInstanceForm;
/**
* Form for modifying/creating monitoring instances
*/
class InstanceConfigForm extends ConfigForm
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_monitoring_instance');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* Return a form object for the given instance type
*
* @param string $type The instance type for which to return a form
*
* @return Form
*
* @throws InvalidArgumentException In case the given instance type is invalid
*/
public function getInstanceForm($type)
{
if ($type === 'local') {
return new LocalInstanceForm();
} elseif ($type === 'remote') {
return new RemoteInstanceForm();
} else {
throw new InvalidArgumentException(sprintf(t('Invalid instance type "%s" provided'), $type));
}
}
/**
* Add a new instance
*
* The resource to add is identified by the array-key `name'.
*
* @param array $values The values to extend the configuration with
*
* @return self
*
* @throws InvalidArgumentException In case the resource already exists
*/
public function add(array $values)
{
$name = isset($values['name']) ? $values['name'] : '';
if (! $name) {
throw new InvalidArgumentException(t('Instance name missing'));
} elseif ($this->config->get($name) !== null) {
throw new InvalidArgumentException(t('Instance already exists'));
}
unset($values['name']);
$this->config->{$name} = $values;
return $this;
}
/**
* Edit an existing instance
*
* @param string $name The name of the resource to edit
* @param array $values The values to edit the configuration with
*
* @return array The edited resource configuration
*
* @throws InvalidArgumentException In case the resource name is missing or invalid
*/
public function edit($name, array $values)
{
if (! $name) {
throw new InvalidArgumentException(t('Old instance name missing'));
} elseif (! ($newName = isset($values['name']) ? $values['name'] : '')) {
throw new InvalidArgumentException(t('New instance name missing'));
} elseif (! ($instanceConfig = $this->config->get($name))) {
throw new InvalidArgumentException(t('Unknown instance name provided'));
}
unset($values['name']);
unset($this->config->{$name});
$this->config->{$newName} = array_merge($instanceConfig->toArray(), $values);
return $this->config->{$newName};
}
/**
* Remove a instance
*
* @param string $name The name of the resource to remove
*
* @return array The removed resource confguration
*
* @throws InvalidArgumentException In case the resource name is missing or invalid
*/
public function remove($name)
{
if (! $name) {
throw new InvalidArgumentException(t('Instance name missing'));
} elseif (! ($instanceConfig = $this->config->get($name))) {
throw new InvalidArgumentException(t('Unknown instance name provided'));
}
unset($this->config->{$name});
return $instanceConfig;
}
/**
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
$instanceName = $request->getQuery('instance');
try {
if ($instanceName === null) { // create new instance
$this->add($this->getValues());
$message = t('Instance "%s" created successfully.');
} else { // edit existing instance
$this->edit($instanceName, $this->getValues());
$message = t('Instance "%s" edited successfully.');
}
} catch (InvalidArgumentException $e) {
Notification::error($e->getMessage());
return;
}
if ($this->save()) {
Notification::success(sprintf($message, $this->getElement('name')->getValue()));
} else {
return false;
}
}
/**
* @see Form::onRequest()
*
* @throws ConfigurationError In case the instance name is missing or invalid
*/
public function onRequest(Request $request)
{
$instanceName = $request->getQuery('instance');
if ($instanceName !== null) {
if (! $instanceName) {
throw new ConfigurationError(t('Instance name missing'));
} elseif (false === isset($this->config->{$instanceName})) {
throw new ConfigurationError(t('Unknown instance name provided'));
}
$instanceConfig = $this->config->{$instanceName}->toArray();
$instanceConfig['name'] = $instanceName;
if (isset($instanceConfig['host'])) {
// Necessary as we have no config directive for setting the instance's type
$instanceConfig['type'] = 'remote';
}
$this->populate($instanceConfig);
}
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$instanceType = isset($formData['type']) ? $formData['type'] : 'local';
$this->addElement(
'text',
'name',
array(
'required' => true,
'label' => t('Instance Name')
)
);
$this->addElement(
'select',
'type',
array(
'required' => true,
'ignore' => true,
'autosubmit' => true,
'label' => t('Instance Type'),
'description' => t(
'When configuring a remote host, you need to setup passwordless key authentication'
),
'multiOptions' => array(
'local' => t('Local Command Pipe'),
'remote' => t('Remote Command Pipe')
),
'value' => $instanceType
)
);
$this->addElements($this->getInstanceForm($instanceType)->createElements($formData)->getElements());
}
}

@ -1,156 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\Form\Config;
use Icinga\Web\Form;
use Icinga\Web\Form\Element\Number;
use Icinga\Web\Form\Decorator\HelpText;
use Icinga\Web\Form\Decorator\ElementWrapper;
/**
* Form for modifying/creating monitoring instances
*/
class InstanceForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_monitoring_instances');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$elements = array(
$this->createElement(
'text',
'name',
array(
'required' => true,
'label' => t('Instance Name')
)
),
$this->createElement(
'select',
'type',
array(
'required' => true,
'ignore' => true,
'label' => t('Instance Type'),
'class' => 'autosubmit',
'helptext' => t(
'When configuring a remote host, you need to setup passwordless key authentication'
),
'multiOptions' => array(
'local' => t('Local Command Pipe'),
'remote' => t('Remote Command Pipe')
)
)
)
);
if (isset($formData['type']) && $formData['type'] === 'remote') {
$elements[] = $this->createElement(
'text',
'host',
array(
'required' => true,
'label' => t('Remote Host'),
'helptext' => t(
'Enter the hostname or address of the machine on which the icinga instance is running'
)
)
);
$elements[] = new Number(
array(
'required' => true,
'name' => 'port',
'label' => t('Remote SSH Port'),
'helptext' => t('Enter the ssh port to use for connecting to the remote icinga instance'),
'value' => 22,
'decorators' => array( // The order is important!
'ViewHelper',
'Errors',
new ElementWrapper(),
new HelpText()
)
)
);
$elements[] = $this->createElement(
'text',
'user',
array(
'required' => true,
'label' => t('Remote SSH User'),
'helptext' => t(
'Enter the username to use for connecting to the remote machine or leave blank for default'
)
)
);
} else {
// TODO(5967,5525): Without this element, switching the type to "local" causes
// the form to be processed as it's complete in that case.
$elements[] = $this->createElement(
'hidden',
'hitchhiker',
array(
'required' => true,
'ignore' => true,
'value' => 'Arthur'
)
);
}
$elements[] = $this->createElement(
'text',
'path',
array(
'required' => true,
'label' => t('Pipe Filepath'),
'value' => '/usr/local/icinga/var/rw/icinga.cmd',
'helptext' => t('The file path where the icinga commandpipe can be found')
)
);
return $elements;
}
/**
* Return the instance configuration values and its name
*
* The first value is the name and the second one the values as array.
*
* @return array
*/
public function getInstanceConfig()
{
$values = $this->getValues();
$name = $values['name'];
unset($values['name']);
return array($name, $values);
}
/**
* Populate the form with the given configuration values
*
* @param string $name The name of the instance
* @param array $config The configuration values
*/
public function setInstanceConfig($name, array $config)
{
$config['name'] = $name;
if (isset($config['host'])) {
// Necessary as we have no config directive for setting the instance's type
$config['type'] = 'remote';
}
$this->populate($config);
}
}

@ -0,0 +1,66 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\Form\Config;
use Icinga\Web\Request;
use Icinga\Web\Notification;
use Icinga\Form\ConfigForm;
/**
* Form for modifying security relevant settings
*/
class SecurityConfigForm extends ConfigForm
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_monitoring_security');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* @see Form::onSuccess()
*/
public function onSuccess(Request $request)
{
$this->config->security = $this->getValues();
if ($this->save()) {
Notification::success(t('New security configuration has successfully been stored'));
} else {
return false;
}
}
/**
* @see Form::onRequest()
*/
public function onRequest(Request $request)
{
if (isset($this->config->security)) {
$this->populate($this->config->security->toArray());
}
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
$this->addElement(
'text',
'protected_customvars',
array(
'required' => true,
'label' => 'Protected Custom Variables',
'description' => 'Comma separated case insensitive list of protected custom variables.'
. ' Use * as a placeholder for zero or more wildcard characters.'
. ' Existance of those custom variables will be shown, but their values will be masked.'
)
);
}
}

@ -1,42 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Icinga\Module\Monitoring\Form\Config;
use Icinga\Web\Form;
/**
* Form for modifying security relevant settings
*/
class SecurityForm extends Form
{
/**
* Initialize this form
*/
public function init()
{
$this->setName('form_config_monitoring_security');
$this->setSubmitLabel(t('Save Changes'));
}
/**
* @see Form::createElements()
*/
public function createElements(array $formData)
{
return array(
$this->createElement(
'text',
'protected_customvars',
array(
'label' => 'Protected Custom Variables',
'required' => true,
'helptext' => 'Comma separated case insensitive list of protected custom variables.'
. ' Use * as a placeholder for zero or more wildcard characters.'
. ' Existance of those custom variables will be shown, but their values will be masked.'
)
)
);
}
}

@ -1,99 +1,70 @@
<?php
use Icinga\Web\Url;
$fileNotReadable = array();
foreach (array('backends', 'instances') as $element) {
if (is_object($this->{$element}) &&
get_class($this->{$element}) === 'Icinga\Exception\NotReadableError') {
$fileNotReadable[$element] = $this->{$element}->getMessage();
} else {
$fileNotReadable[$element] = false;
}
}
?>
<div class="controls">
<?= $this->tabs->render($this); ?>
<?= $tabs; ?>
</div>
<div class="content" data-base-target="_next">
<?php if ($fileNotReadable['backends'] === false): ?>
<h1>Monitoring Backends</h1>
<?php if (isset($this->messageBox)): ?>
<?= $this->messageBox->render() ?>
<?php endif ?>
<p>
<a href="<?= Url::fromPath('/monitoring/config/createbackend')->getAbsoluteUrl();?>">
<?= $this->icon('create.png'); ?> Create New Monitoring Backend
</a>
</p>
<table class="action">
<thead>
<th>Monitoring Backend</th>
<th style="width: 5em">Remove</th>
</thead>
<tbody>
<?php foreach ($this->backends as $backendName => $config): ?>
<?php
$removeUrl = Url::fromPath('/monitoring/config/removebackend', array('backend' => $backendName));
$editUrl = Url::fromPath('/monitoring/config/editbackend', array('backend' => $backendName));
?>
<tr>
<td>
<a href="<?= $editUrl; ?>"><?= $this->icon('edit.png'); ?> <?= $this->escape($backendName); ?></a>
<small>(Type: <?= $this->escape($config['type'] === 'ido' ? 'IDO' : ucfirst($config['type'])); ?>)</small>
</td>
<td>
<a href="<?= $removeUrl; ?>"><?= $this->icon('remove.png'); ?></a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p class="fileNotReadable">
<?= $this->escape($fileNotReadable['backends']) ?>
</p>
<?php endif ?>
<?php if ($fileNotReadable['instances'] === false): ?>
<h1>Monitoring Instances</h1>
<p>
<a href="<?= Url::fromPath('/monitoring/config/createinstance')->getAbsoluteUrl();?>">
<?= $this->icon('create.png'); ?> Create New Instance
</a>
</p>
<table class="action">
<thead>
<th>Instance</th>
<th style="width: 5em">Remove</th>
</thead>
<tbody>
<?php foreach ($this->instances as $instanceName => $config): ?>
<?php
$removeUrl = Url::fromPath('/monitoring/config/removeinstance', array('instance' => $instanceName));
$editUrl = Url::fromPath('/monitoring/config/editinstance', array('instance' => $instanceName));
?>
<tr>
<td>
<a href="<?= $editUrl; ?>"><?= $this->icon('edit.png'); ?> <?= $this->escape($instanceName); ?></a>
<small>(Type: <?= isset($config['host']) ? 'Remote' : 'Local'; ?>)</small>
</td>
<td>
<a href="<?= $removeUrl; ?>"><?= $this->icon('remove.png'); ?></a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p class="fileNotReadable">
<?= $this->escape($fileNotReadable['instances']) ?>
</p>
<?php endif ?>
</div>
<h1>Monitoring Backends</h1>
<p>
<a href="<?= $this->href('/monitoring/config/createbackend'); ?>">
<?= $this->icon('create.png'); ?> <?= $this->translate('Create New Monitoring Backend'); ?>
</a>
</p>
<table class="action">
<thead>
<th><?= $this->translate('Monitoring Backend'); ?></th>
<th style="width: 5em"><?= $this->translate('Remove'); ?></th>
</thead>
<tbody>
<?php foreach ($this->backendsConfig as $backendName => $config): ?>
<tr>
<td>
<a href="<?= $this->href('/monitoring/config/editbackend', array('backend' => $backendName)); ?>">
<?= $this->icon('edit.png'); ?> <?= $this->escape($backendName); ?>
</a>
<small>(<?= sprintf(
$this->translate('Type: %s'),
$this->escape($config->type === 'ido' ? 'IDO' : ucfirst($config->type))
); ?>)</small>
</td>
<td>
<a href="<?= $this->href('/monitoring/config/removebackend', array('backend' => $backendName)); ?>">
<?= $this->icon('remove.png'); ?>
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<h1>Monitoring Instances</h1>
<p>
<a href="<?= $this->href('/monitoring/config/createinstance'); ?>">
<?= $this->icon('create.png'); ?> <?= $this->translate('Create New Instance'); ?>
</a>
</p>
<table class="action">
<thead>
<th><?= $this->translate('Instance'); ?></th>
<th style="width: 5em"><?= $this->translate('Remove'); ?></th>
</thead>
<tbody>
<?php foreach ($this->instancesConfig as $instanceName => $config): ?>
<tr>
<td>
<a href="<?= $this->href('/monitoring/config/editinstance', array('instance' => $instanceName)); ?>">
<?= $this->icon('edit.png'); ?> <?= $this->escape($instanceName); ?>
</a>
<small>(<?= sprintf(
$this->translate('Type: %s'),
$config->host !== null ? $this->translate('Remote') : $this->translate('Local')
); ?>)</small>
</td>
<td>
<a href="<?= $this->href('/monitoring/config/removeinstance', array('instance' => $instanceName)); ?>">
<?= $this->icon('remove.png'); ?>
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>

@ -1,4 +1,4 @@
<h4><?= $this->translate('Remove Existing Instance'); ?></h4>
<p>Are you sure you want to remove the instance <?= $this->escape($name); ?>?</p>
<p><i class="icinga-icon-warning"></i> If you have still any environments or views referring to this instance, you won't be able to send commands anymore after deletion.</p>
<p><?= $this->translate('Are you sure you want to remove this instance?'); ?></p>
<p><?= $this->translate('If you have still any environments or views referring to this instance, you won\'t be able to send commands anymore after deletion.'); ?></p>
<?= $form; ?>

@ -11,7 +11,6 @@ use Icinga\Exception\IcingaException;
use IteratorAggregate;
use Icinga\Data\Filter\Filter;
use Icinga\Web\Hook;
use Icinga\Web\Session;
use Icinga\Web\Session\SessionNamespace;
use Icinga\Module\Monitoring\DataView\DataView;

@ -84,6 +84,7 @@ class TimelineIntervalBox extends AbstractWidget
$form = new Form();
$form->setAttrib('class', 'inline');
$form->setMethod('GET');
$form->setUidDisabled();
$form->setTokenDisabled();
$form->setName($this->name);
$form->addElement(
@ -92,7 +93,7 @@ class TimelineIntervalBox extends AbstractWidget
array(
'label' => 'Timeline Interval',
'multiOptions' => $this->values,
'class' => 'autosubmit'
'autosubmit' => true
)
);

@ -1,111 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Module\Monitoring\Application\Forms\Command;
use Icinga\Test\BaseTestCase;
class AcknowledgeFormTest extends BaseTestCase
{
const FORM_CLASS = 'Icinga\Module\Monitoring\Form\Command\AcknowledgeForm';
public function testFormValid()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'Author',
'comment' => 'Comment',
'persistent' => '0',
'expire' => '0',
'sticky' => '0',
'notify' => '0',
'btn_submit' => 'Submit'
)
);
$this->assertTrue(
$form->isSubmittedAndValid(),
'Legal request data without expire time must be considered valid'
);
$formWithExpireTime = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'Author',
'comment' => 'Comment',
'persistent' => '0',
'expire' => '1',
'expiretime' => '10/07/2013 5:32 PM',
'sticky' => '0',
'notify' => '0',
'btn_submit' => 'Submit'
)
);
$this->assertTrue(
$formWithExpireTime->isSubmittedAndValid(),
'Legal request data with expire time must be considered valid'
);
}
public function testFormInvalidWhenCommentMissing()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'Author',
'comment' => '',
'persistent' => '0',
'expire' => '0',
'sticky' => '0',
'notify' => '0',
'btn_submit' => 'Submit'
)
);
$this->assertFalse(
$form->isSubmittedAndValid(),
'Missing comment must be considered not valid'
);
}
public function testFormInvalidWhenExpireTimeMissingAndExpireSet()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'Author',
'comment' => 'Comment',
'persistent' => '0',
'expire' => '1',
'sticky' => '0',
'notify' => '0',
'btn_submit' => 'Submit'
)
);
$this->assertFalse(
$form->isSubmittedAndValid(),
'If expire is set and expire time is missing, the form must not be valid'
);
}
public function testFormInvalidWhenExpireTimeIsIncorrectAndExpireSet()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'Author',
'comment' => 'Comment',
'persistent' => '0',
'expire' => '1',
'expiretime' => 'Not a date',
'sticky' => '0',
'notify' => '0',
'btn_submit' => 'Submit'
)
);
$this->assertFalse(
$form->isSubmittedAndValid(),
'If expire is set and expire time is incorrect, the form must not be valid'
);
}
}

@ -1,64 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Module\Monitoring\Application\Forms\Command;
use Icinga\Test\BaseTestCase;
class CommentFormTest extends BaseTestCase
{
const FORM_CLASS = 'Icinga\Module\Monitoring\Form\Command\CommentForm';
public function testCorrectCommentValidation()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'Author',
'comment' => 'Comment',
'sticky' => '0',
'btn_submit' => 'Submit'
)
);
$this->assertTrue(
$form->isSubmittedAndValid(),
'Legal request data must be considered valid'
);
}
public function testFormInvalidWhenCommentMissing()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'Author',
'comment' => '',
'sticky' => '0',
'btn_submit' => 'Submit'
)
);
$this->assertFalse(
$form->isSubmittedAndValid(),
'Missing comment must be considered not valid'
);
}
public function testFormInvalidWhenAuthorMissing()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => '',
'comment' => 'Comment',
'sticky' => '0',
'btn_submit' => 'Submit'
)
);
$this->assertFalse(
$form->isSubmittedAndValid(),
'Missing author must be considered not valid'
);
}
}

@ -1,28 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Module\Monitoring\Application\Forms\Command;
use Icinga\Test\BaseTestCase;
class CustomNotificationFormTest extends BaseTestCase
{
const FORM_CLASS = 'Icinga\Module\Monitoring\Form\Command\CustomNotificationForm';
public function testFormInvalidWhenCommentMissing()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'Author',
'comment' => '',
'btn_submit' => 'Submit'
)
);
$this->assertFalse(
$form->isSubmittedAndValid(),
'Missing comment must be considered not valid'
);
}
}

@ -1,58 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Module\Monitoring\Application\Forms\Command;
use Icinga\Test\BaseTestCase;
use Icinga\Module\Monitoring\Form\Command\DelayNotificationForm;
class DelayNotificationFormTest extends BaseTestCase
{
const FORM_CLASS = 'Icinga\Module\Monitoring\Form\Command\DelayNotificationForm';
public function testFormInvalidWhenNotificationDelayMissing()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'minutes' => '',
'btn_submit' => 'Submit'
)
);
$this->assertFalse(
$form->isSubmittedAndValid(),
'Missing notification delay must be considered invalid'
);
}
public function testFormInvalidWhenNotificationDelayNaN()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'minutes' => 'A String',
'btn_submit' => 'Submit'
)
);
$this->assertFalse(
$form->isSubmittedAndValid(),
'Incorrect notification delay, i.e. NaN must be considered invalid'
);
}
public function testFormInvalidWhenNotificationDelayOverflows()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'minutes' => DelayNotificationForm::MAX_DELAY + 1,
'btn_submit' => 'Submit'
)
);
$this->assertFalse(
$form->isSubmittedAndValid(),
'Notification delay bigger than constant "DelayNotificationForm::MAX_DELAY" must be considered invalid'
);
}
}

@ -1,54 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Module\Monitoring\Application\Forms\Command;
use Icinga\Test\BaseTestCase;
class RescheduleNextCheckFormTest extends BaseTestCase
{
const FORM_CLASS = 'Icinga\Module\Monitoring\Form\Command\RescheduleNextCheckForm';
public function testFormInvalidWhenChecktimeIsIncorrect()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'checktime' => '2013-24-12 17:30:00',
'forcecheck' => 0,
'btn_submit' => 'Submit'
)
);
$this->assertFalse(
$form->isSubmittedAndValid(),
'Asserting a logically incorrect checktime as invalid'
);
$form2 = $this->createForm(
self::FORM_CLASS,
array(
'checktime' => 'Captain Morgan',
'forcecheck' => 1,
'btn_submit' => 'Submit'
)
);
$this->assertFalse(
$form2->isSubmittedAndValid(),
'Providing arbitrary strings as checktime must be considered invalid'
);
$form3 = $this->createForm(
self::FORM_CLASS,
array(
'checktime' => '',
'forcecheck' => 0,
'btn_submit' => 'Submit'
)
);
$this->assertFalse(
$form3->isSubmittedAndValid(),
'Missing checktime must be considered invalid'
);
}
}

@ -1,356 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Module\Monitoring\Application\Forms\Command;
use Icinga\Test\BaseTestCase;
use Icinga\Module\Monitoring\Form\Command\ScheduleDowntimeForm;
class ScheduleDowntimeFormTest extends BaseTestCase
{
const FORM_CLASS = 'Icinga\Module\Monitoring\Form\Command\ScheduleDowntimeForm';
public function testCorrectFormElementCreation()
{
$formFixed = $this->createForm(self::FORM_CLASS);
$formFixed->setCurrentDowntimes(array('foo'));
$formFixed->buildForm();
$formFlexible = $this->createForm(
self::FORM_CLASS,
array(
'type' => 'flexible'
)
);
$formFlexible->setCurrentDowntimes(array('foo'));
$formFlexible->buildForm();
$form = $this->createForm(self::FORM_CLASS);
$form->setCurrentDowntimes(array('foo'));
$form->setWithChildren(true);
$form->buildForm();
}
public function testCorrectValidationWithChildrend()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'TEST_AUTHOR',
'comment' => 'DING DING',
'triggered' => '0',
'starttime' => '17/07/2013 10:30 AM',
'endtime' => '18/07/2013 10:30 AM',
'type' => ScheduleDowntimeForm::TYPE_FIXED,
'hours' => '',
'minutes' => '',
'btn_submit' => 'foo',
)
);
$form->setWithChildren(true);
$form->setCurrentDowntimes(array('foo'));
$this->assertTrue(
$form->isSubmittedAndValid(),
'Asserting a correct fixed downtime form to be considered valid'
);
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'TEST_AUTHOR',
'comment' => 'DING DING',
'triggered' => '0',
'starttime' => '17/07/2013 10:30 AM',
'endtime' => '18/07/2013 10:30 AM',
'type' => ScheduleDowntimeForm::TYPE_FLEXIBLE,
'hours' => '10',
'minutes' => '10',
'btn_submit' => 'foo'
)
);
$form->setWithChildren(true);
$form->setCurrentDowntimes(array('foo'));
$this->assertTrue(
$form->isSubmittedAndValid(),
'Asserting a correct flexible downtime form to be considered valid'
);
}
public function testMissingFlexibleDurationRecognition()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'TEST_AUTHOR',
'comment' => 'DING DING',
'triggered' => '0',
'starttime' => '17/07/2013 10:30 AM',
'endtime' => '18/07/2013 10:30 AM',
'type' => ScheduleDowntimeForm::TYPE_FLEXIBLE,
'hours' => '',
'minutes' => '',
)
);
$form->setWithChildren(true);
$form->setCurrentDowntimes(array('foo'));
$this->assertFalse(
$form->isSubmittedAndValid(),
'Assert missing hours and minutes in downtime form to cause failing validation'
);
}
public function testMissingAuthorRecognition()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => '',
'comment' => 'DING DING',
'triggered' => '0',
'starttime' => '17/07/2013 10:30 AM',
'endtime' => '18/07/2013 10:30 AM',
'type' => ScheduleDowntimeForm::TYPE_FIXED,
'hours' => '',
'minutes' => '',
)
);
$form->setWithChildren(true);
$form->setCurrentDowntimes(array('foo'));
$this->assertFalse(
$form->isSubmittedAndValid(),
'Assert missing author to cause validation errors in fixed downtime'
);
}
public function testMissingCommentRecognition()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'OK',
'comment' => '',
'triggered' => '0',
'starttime' => '17/07/2013 10:30 AM',
'endtime' => '18/07/2013 10:30 AM',
'type' => ScheduleDowntimeForm::TYPE_FIXED,
'hours' => '',
'minutes' => '',
)
);
$form->setWithChildren(true);
$form->setCurrentDowntimes(array('foo'));
$this->assertFalse(
$form->isSubmittedAndValid(),
'Assert missing comment to cause validation errors in fixed downtime'
);
}
public function testInvalidTriggeredFieldValueRecognition()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'OK',
'comment' => 'OK',
'triggered' => 'HAHA',
'starttime' => '17/07/2013 10:30 AM',
'endtime' => '18/07/2013 10:30 AM',
'type' => ScheduleDowntimeForm::TYPE_FIXED,
'hours' => '',
'minutes' => '',
)
);
$form->setWithChildren(true);
$form->setCurrentDowntimes(array('foo'));
$this->assertFalse(
$form->isSubmittedAndValid(),
'Assert invalid trigger field to cause validation to fail'
);
}
public function testInvalidStartTimeRecognition()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'OK',
'comment' => 'OK',
'triggered' => '0',
'starttime' => '17/07/2013',
'endtime' => '18/07/2013 10:30 AM',
'type' => ScheduleDowntimeForm::TYPE_FIXED,
'hours' => '',
'minutes' => '',
)
);
$form->setWithChildren(true);
$form->setCurrentDowntimes(array('foo'));
$this->assertFalse(
$form->isSubmittedAndValid(),
'Assert incorrect start time to cause validation errors in fixed downtime'
);
}
public function testInvalidEndTimeRecognition()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'OK',
'comment' => 'OK',
'triggered' => '0',
'starttime' => '17/07/2013 10:30 AM',
'endtime' => 'DING',
'type' => ScheduleDowntimeForm::TYPE_FIXED,
'hours' => '',
'minutes' => '',
)
);
$form->setWithChildren(true);
$form->setCurrentDowntimes(array('foo'));
$this->assertFalse(
$form->isSubmittedAndValid(),
'Assert invalid endtime to cause validation errors in fixed downtime'
);
}
public function testInvalidHoursValueRecognitionInFlexibleDowntime()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'OK',
'comment' => 'OK',
'triggered' => '0',
'starttime' => '17/07/2013 10:30 AM',
'endtime' => '18/07/2013 10:30 AM',
'type' => ScheduleDowntimeForm::TYPE_FLEXIBLE,
'hours' => '-1',
'minutes' => '12',
)
);
$form->setWithChildren(true);
$form->setCurrentDowntimes(array('foo'));
$this->assertFalse(
$form->isSubmittedAndValid(),
'Assert negative hours to cause validation errors in flexible downtime'
);
}
public function testInvalidMinutesValueRecognitionInFlexibleDowntime()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'OK',
'comment' => 'OK',
'triggered' => '0',
'starttime' => '17/07/2013 10:30 AM',
'endtime' => '18/07/2013 10:30 AM',
'type' => ScheduleDowntimeForm::TYPE_FLEXIBLE,
'hours' => '12',
'minutes' => 'DING',
)
);
$form->setWithChildren(true);
$form->setCurrentDowntimes(array('foo'));
$this->assertFalse(
$form->isSubmittedAndValid(),
'Assert non numeric valud to cause validation errors in flexible downtime '
);
}
public function testCorrectScheduleDowntimeWithoutChildrenForm()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'TEST_AUTHOR',
'comment' => 'DING DING',
'triggered' => '0',
'starttime' => '17/07/2013 10:30 AM',
'endtime' => '18/07/2013 10:30 AM',
'type' => ScheduleDowntimeForm::TYPE_FIXED,
'hours' => '',
'minutes' => '',
'btn_submit' => 'foo',
'childobjects' => '0',
)
);
$form->setWithChildren(false);
$form->setCurrentDowntimes(array('foo'));
$this->assertTrue(
$form->isSubmittedAndValid(),
'Assert a correct schedule downtime without children form to be considered valid'
);
}
public function testIncorrectChildObjectsRecognition() {
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'TEST_AUTHOR',
'comment' => 'DING DING',
'triggered' => '0',
'starttime' => '17/07/2013 10:30 AM',
'endtime' => '18/07/2013 10:30 AM',
'type' => ScheduleDowntimeForm::TYPE_FIXED,
'hours' => '',
'minutes' => '',
'childobjects' => 'AHA',
)
);
$form->setWithChildren(false);
$form->setCurrentDowntimes(array('foo'));
$this->assertFalse(
$form->isSubmittedAndValid(),
'Assert and incorrect (non-numeric) childobjects value to cause validation errors'
);
$form = $this->createForm(
self::FORM_CLASS,
array(
'author' => 'TEST_AUTHOR',
'comment' => 'DING DING',
'triggered' => '0',
'starttime' => '17/07/2013 10:30 AM',
'endtime' => '18/07/2013 10:30 AM',
'type' => ScheduleDowntimeForm::TYPE_FIXED,
'hours' => '',
'minutes' => '',
'childobjects' => '4',
)
);
$form->setWithChildren(false);
$form->setCurrentDowntimes(array('foo'));
$this->assertFalse(
$form->isSubmittedAndValid(),
'Assert and incorrect (numeric) childobjects value to cause validation errors'
);
}
public function testTimeRange()
{
$form = $this->createForm(self::FORM_CLASS);
$form->setCurrentDowntimes(array('foo'));
$form->buildForm();
$time1 = $form->getElement('starttime')->getValue();
$time2 = $form->getElement('endtime')->getValue();
$this->assertEquals(3600, ($time2 - $time1));
}
}

@ -1,117 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Module\Monitoring\Application\Forms\Command;
use Icinga\Test\BaseTestCase;
use Icinga\Module\Monitoring\Form\Command\SubmitPassiveCheckResultForm;
class SubmitPassiveCheckResultFormTest extends BaseTestCase
{
const FORM_CLASS = 'Icinga\Module\Monitoring\Form\Command\SubmitPassiveCheckResultForm';
public function testStateTypes()
{
$form = $this->createForm(self::FORM_CLASS, array());
$form->setType(SubmitPassiveCheckResultForm::TYPE_SERVICE);
$options = $form->getOptions();
$this->assertCount(4, $options, 'Assert correct number of states in service passive checks form');
$this->assertEquals('OK', $options[0], 'Assert OK state to be available in service passive check form');
$this->assertEquals(
'WARNING',
$options[1],
'Assert WARNING state to be available in service passive check form'
);
$this->assertEquals(
'CRITICAL',
$options[2],
'Assert CRITICAL state to be available in service passive check form'
);
$this->assertEquals(
'UNKNOWN',
$options[3],
'Assert UNKNOWN state to be available in service passive check form'
);
$form->setType(SubmitPassiveCheckResultForm::TYPE_HOST);
$options = $form->getOptions();
$this->assertCount(3, $options, 'Assert correct number of states in host passive checks form');
$this->assertEquals('UP', $options[0], 'Assert UP state to be available in host passive check form');
$this->assertEquals('DOWN', $options[1], 'Assert DOWN state to be available in host passive check form');
$this->assertEquals(
'UNREACHABLE',
$options[2],
'Assert UNREACHABLE state to be available in host passive check form'
);
}
/**
* @expectedException Icinga\Exception\ProgrammingError
* @expectedExceptionMessage Type is not valid
*/
public function testMissingTypeThrowingException()
{
$form = $this->createForm(self::FORM_CLASS, array());
$form->buildForm();
}
public function testCorrectFormCreation()
{
$form = $this->createForm(self::FORM_CLASS, array());
$form->setType(SubmitPassiveCheckResultForm::TYPE_SERVICE);
$form->buildForm();
}
public function testCorrectServicePassiveCheckSubmission()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'pluginstate' => 0,
'checkoutput' => 'DING',
'performancedata' => '',
'btn_submit' => 'foo'
)
);
$form->setType(SubmitPassiveCheckResultForm::TYPE_SERVICE);
$this->assertTrue(
$form->isSubmittedAndValid(),
'Assert a correct passive service check form to pass form validation'
);
}
public function testIncorrectCheckoutputRecognition()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'pluginstate' => 0,
'checkoutput' => '',
'performancedata' => ''
)
);
$form->setType(SubmitPassiveCheckResultForm::TYPE_SERVICE);
$this->assertFalse(
$form->isSubmittedAndValid(),
'Assert empty checkoutput to cause validation errors in passive service check '
);
}
public function testIncorrectStateRecognition()
{
$form = $this->createForm(
self::FORM_CLASS,
array(
'pluginstate' => 'LA',
'checkoutput' => 'DING',
'performancedata' => ''
)
);
$form->setType(SubmitPassiveCheckResultForm::TYPE_SERVICE);
$this->assertFalse(
$form->isSubmittedAndValid(),
'Assert invalid (non-numeric) state to cause validation errors in passive service check'
);
}
}

@ -271,6 +271,7 @@ class GettextTranslationHelper
'po_revision_date' => 'YEAR-MO-DA HO:MI+ZONE',
'translator_name' => 'FULL NAME',
'translator_mail' => 'EMAIL@ADDRESS',
'language' => $this->locale,
'language_team_name' => 'LANGUAGE',
'language_team_url' => 'LL@li.org',
'charset' => self::FILE_ENCODING
@ -298,6 +299,9 @@ class GettextTranslationHelper
$headerInfo['language_team_name'] = $languageInfo[1];
$headerInfo['language_team_url'] = $languageInfo[2];
}
if (preg_match('@Language: ([a-z]{2}_[A-Z]{2})@', $content, $languageInfo)) {
$headerInfo['language'] = $languageInfo[1];
}
}
file_put_contents(
@ -321,6 +325,7 @@ class GettextTranslationHelper
'"PO-Revision-Date: ' . $headerInfo['po_revision_date'] . '\n"',
'"Last-Translator: ' . $headerInfo['translator_name'] . ' <'
. $headerInfo['translator_mail'] . '>\n"',
'"Language: ' . $headerInfo['language'] . '\n"',
'"Language-Team: ' . $headerInfo['language_team_name'] . ' <'
. $headerInfo['language_team_url'] . '>\n"',
'"MIME-Version: 1.0\n"',

@ -1,11 +0,0 @@
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
/* Add hover effects to chart data */
.chart-data:hover {
opacity: 0.85;
}
.pie-data:hover {
opacity: 0.6;
}

@ -174,6 +174,15 @@ ul.tree li a.error:hover {
color: @colorCritical;
}
/* Add hover effect to chart data */
.chart-data:hover {
opacity: 0.85;
}
.pie-data:hover {
opacity: 0.6;
}
/* charts should grow as much as possible but never beyond the current viewport's size */
.svg-container-responsive {
padding: 1.5em;

@ -10,6 +10,8 @@
'use strict';
var activeMenuId;
var mouseX, mouseY;
Icinga.Events = function (icinga) {
@ -133,22 +135,37 @@
if (!icinga.utils.elementsOverlap(arrow, el)) {
return;
}
var title = $(this).find('.tipsy-inner').html();
var atMouse = document.elementFromPoint(mouseX, mouseY);
var nearestTip = $(atMouse)
.closest('[original-title="' + title + '"]')[0];
if (nearestTip) {
console.log ('migrating orphan...');
var tipsy = $.data(nearestTip, 'tipsy');
tipsy.$tip = $(this);
$.data(this, 'tipsy-pointee', nearestTip);
} else {
// doesn't match delete
console.log ('deleting orphan...');
$(this).remove();
}
});
// restore menu state
if (activeMenuId) {
$('li.active', el).removeClass('active');
var $selectedMenu = $('#' + activeMenuId, el);
var $outerMenu = $selectedMenu.parent().closest('li');
if ($outerMenu.size()) {
$selectedMenu = $outerMenu;
}
$selectedMenu.addClass('active');
} else {
// store menu state
var $menus = $('[role="navigation"] li.active', el);
if ($menus.size()) {
activeMenuId = $menus[0].id;
}
}
},
/**
@ -569,6 +586,7 @@
$li = $a.closest('li');
$('#menu .active').removeClass('active');
$li.addClass('active');
activeMenuId = $($li).attr('id');
if ($li.hasClass('hover')) {
$li.removeClass('hover');
}
@ -594,14 +612,22 @@
return false;
}
} else {
if (isMenuLink) {
activeMenuId = $(event.target).closest('li').attr('id');
}
$target = self.getLinkTargetFor($a);
}
// Load link URL
icinga.loader.loadUrl(href, $target);
// Menu links should remove all but the first layout column
if (isMenuLink) {
// update target url of the menu container to the clicked link
var menuDataUrl = icinga.utils.parseUrl($('#menu').data('icinga-url'));
menuDataUrl = icinga.utils.addUrlParams(menuDataUrl.path, { url: href });
$('#menu').data('icinga-url', menuDataUrl);
// Menu links should remove all but the first layout column
icinga.ui.layout1col();
}
@ -687,6 +713,7 @@
$(document).off('mouseenter', 'li.dropdown', this.dropdownHover);
$(document).off('mouseleave', 'li.dropdown', this.dropdownLeave);
$(document).off('click', 'div.tristate .tristate-dummy', this.clickTriState);
$(document).off('mousemove');
},
destroy: function() {

@ -673,8 +673,12 @@
}
var origFocus = document.activeElement;
if (typeof containerId !== 'undefined' && autorefresh && origFocus && $(origFocus).closest('form').length && $container.has($(origFocus)) && $(origFocus).closest('#' + containerId).length && ! $(origFocus).hasClass('autosubmit')) {
this.icinga.logger.debug('Not changing content, form has focus');
if (
// Do not reload menu when search field has content
(containerId === 'menu' && $(origFocus).length && $(origFocus).val().length)
// TODO: remove once #7146 is solved
|| (containerId !== 'menu' && typeof containerId !== 'undefined' && autorefresh && origFocus && $(origFocus).closest('form').length && $container.has($(origFocus)) && $(origFocus).closest('#' + containerId).length && ! $(origFocus).hasClass('autosubmit'))) {
this.icinga.logger.debug('Not changing content for ', containerId, ' form has focus');
return;
}

@ -10,9 +10,6 @@
'use strict';
// The currently hovered tooltip
var tooltip = null;
// Stores the icinga-data-url of the last focused table.
var focusedTableDataUrl = null;

@ -217,9 +217,9 @@
return false;
}
var at = aoff.top;
var ah = a.offsetHeight;
var ah = a.offsetHeight || (a.getBBox && a.getBBox().height);
var al = aoff.left;
var aw = a.offsetWidth;
var aw = a.offsetWidth || (a.getBBox && a.getBBox().width);
// b bounds
var boff = $(b).offset();
@ -227,9 +227,9 @@
return false;
}
var bt = boff.top;
var bh = b.offsetHeight;
var bh = b.offsetHeight || (b.getBBox && b.getBBox().height);
var bl = boff.left;
var bw = b.offsetWidth;
var bw = b.offsetWidth || (b.getBBox && b.getBBox().width);
return !(at > (bt + bh) || bt > (at + ah)) && !(bl > (al + aw) || al > (bl + bw));
},

@ -1,61 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Form\Config\Authentication;
use Icinga\Test\BaseTestCase;
use Icinga\Form\Config\Authentication\BaseBackendForm;
class BackendForm extends BaseBackendForm
{
public $is_valid;
public function getConfig()
{
// Need to be declared as being abstract otherwise
}
public function isValidAuthenticationBackend()
{
return $this->is_valid;
}
}
class BaseBackendFormTest extends BaseTestCase
{
public function testIsForceCreationCheckboxBeingAdded()
{
$form = new BackendForm();
$form->is_valid = false;
$this->assertFalse($form->isValid(array()));
$this->assertNotNull(
$form->getElement('backend_force_creation'),
'Checkbox to force a backend\'s creation is not being added though the backend is invalid'
);
}
public function testIsForceCreationCheckboxNotBeingAdded()
{
$form = new BackendForm();
$form->is_valid = true;
$this->assertTrue($form->isValid(array()));
$this->assertNull(
$form->getElement('backend_force_creation'),
'Checkbox to force a backend\'s creation is being added though the backend is valid'
);
}
public function testIsTheFormValidIfForceCreationTrue()
{
$form = new BackendForm();
$form->is_valid = false;
$this->assertTrue(
$form->isValid(array('backend_force_creation' => 1)),
'BaseBackendForm with invalid backend is not valid though force creation is set'
);
}
}

@ -32,13 +32,12 @@ class DbBackendFormTest extends BaseTestCase
->andReturn(2);
$form = new DbBackendForm();
$form->setBackendName('test');
$form->setResources(array('test_db_backend' => null));
$form->create();
$form->populate(array('backend_test_resource' => 'test_db_backend'));
$form->setTokenDisabled();
$form->setResources(array('test_db_backend'));
$form->populate(array('resource' => 'test_db_backend'));
$this->assertTrue(
$form->isValidAuthenticationBackend(),
$form->isValidAuthenticationBackend($form),
'DbBackendForm claims that a valid authentication backend with users is not valid'
);
}
@ -55,13 +54,12 @@ class DbBackendFormTest extends BaseTestCase
->andReturn(0);
$form = new DbBackendForm();
$form->setBackendName('test');
$form->setResources(array('test_db_backend' => null));
$form->create();
$form->populate(array('backend_test_resource' => 'test_db_backend'));
$form->setTokenDisabled();
$form->setResources(array('test_db_backend'));
$form->populate(array('resource' => 'test_db_backend'));
$this->assertFalse(
$form->isValidAuthenticationBackend(),
$form->isValidAuthenticationBackend($form),
'DbBackendForm claims that an invalid authentication backend without users is valid'
);
}

@ -29,16 +29,15 @@ class LdapBackendFormTest extends BaseTestCase
{
$this->setUpResourceFactoryMock();
Mockery::mock('overload:Icinga\Authentication\Backend\LdapUserBackend')
->shouldReceive('assertAuthenticationPossible')->andReturn(null);
->shouldReceive('assertAuthenticationPossible')->andReturnNull();
$form = new LdapBackendForm();
$form->setBackendName('test');
$form->setResources(array('test_ldap_backend' => null));
$form->create();
$form->populate(array('backend_test_resource' => 'test_ldap_backend'));
$form->setTokenDisabled();
$form->setResources(array('test_ldap_backend'));
$form->populate(array('resource' => 'test_ldap_backend'));
$this->assertTrue(
$form->isValidAuthenticationBackend(),
$form->isValidAuthenticationBackend($form),
'LdapBackendForm claims that a valid authentication backend with users is not valid'
);
}
@ -54,13 +53,12 @@ class LdapBackendFormTest extends BaseTestCase
->shouldReceive('assertAuthenticationPossible')->andThrow(new AuthenticationException);
$form = new LdapBackendForm();
$form->setBackendName('test');
$form->setResources(array('test_ldap_backend' => null));
$form->create();
$form->populate(array('backend_test_resource' => 'test_ldap_backend'));
$form->setTokenDisabled();
$form->setResources(array('test_ldap_backend'));
$form->populate(array('resource' => 'test_ldap_backend'));
$this->assertFalse(
$form->isValidAuthenticationBackend(),
$form->isValidAuthenticationBackend($form),
'LdapBackendForm claims that an invalid authentication backend without users is valid'
);
}

@ -1,80 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Form\Config\Authentication;
use Mockery;
use Zend_Config;
use Icinga\Test\BaseTestCase;
use Icinga\Form\Config\Authentication\ReorderForm;
class RequestLessReorderForm extends ReorderForm
{
public $order;
public function getValues($suppressArrayNotation = false)
{
return array('form_backend_order' => $this->order);
}
}
class ReorderFormTest extends BaseTestCase
{
public function setUp()
{
parent::setUp();
$this->viewMock = Mockery::mock('\Zend_View');
$this->viewMock->shouldReceive('icon')->andReturn('');
}
public function testMoveBackendUp()
{
$config = new Zend_Config(
array(
'test1' => '',
'test2' => '',
'test3' => ''
)
);
$oldOrder = array_keys($config->toArray());
$form = new RequestLessReorderForm();
$form->setCurrentOrder($oldOrder);
$form->setBackendName('test3');
$form->setView($this->viewMock);
$form->create();
$form->order = $form->getSubForm('btn_reorder_up')->getElement('form_backend_order')->getValue();
$this->assertSame(
$form->getReorderedConfig($config),
array('test1' => '', 'test3' => '', 'test2' => ''),
'Moving elements up with ReorderForm does not seem to properly work'
);
}
public function testMoveBackendDown()
{
$config = new Zend_Config(
array(
'test1' => '',
'test2' => '',
'test3' => ''
)
);
$oldOrder = array_keys($config->toArray());
$form = new RequestLessReorderForm();
$form->setCurrentOrder($oldOrder);
$form->setBackendName('test1');
$form->setView($this->viewMock);
$form->create();
$form->order = $form->getSubForm('btn_reorder_down')->getElement('form_backend_order')->getValue();
$this->assertSame(
$form->getReorderedConfig($config),
array('test2' => '', 'test1' => '', 'test3' => ''),
'Moving elements down with ReorderForm does not seem to properly work'
);
}
}

@ -0,0 +1,61 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Form\Config;
use Icinga\Test\BaseTestCase;
use Icinga\Application\Config;
use Icinga\Form\Config\AuthenticationBackendConfigForm;
use Icinga\Form\Config\AuthenticationBackendReorderForm;
class AuthenticationBackendConfigFormWithoutSave extends AuthenticationBackendConfigForm
{
public static $newConfig;
public function save()
{
self::$newConfig = $this->config;
return false;
}
}
class AuthenticationBackendReorderFormProvidingConfigFormWithoutSave extends AuthenticationBackendReorderForm
{
public function getConfigForm()
{
$form = new AuthenticationBackendConfigFormWithoutSave();
$form->setIniConfig($this->config);
return $form;
}
}
class AuthenticationBackendReorderFormTest extends BaseTestCase
{
public function testMoveBackend()
{
$config = new Config(
array(
'test1' => '',
'test2' => '',
'test3' => ''
)
);
$this->getRequestMock()->shouldReceive('getMethod')->andReturn('POST')
->shouldReceive('isPost')->andReturn(true)
->shouldReceive('getPost')->andReturn(array('backend_newpos' => 'test3|1'));
$form = new AuthenticationBackendReorderFormProvidingConfigFormWithoutSave();
$form->setIniConfig($config);
$form->setTokenDisabled();
$form->setUidDisabled();
$form->handleRequest();
$this->assertEquals(
array('test1', 'test3', 'test2'),
AuthenticationBackendConfigFormWithoutSave::$newConfig->keys(),
'Moving elements with AuthenticationBackendReorderForm does not seem to properly work'
);
}
}

@ -0,0 +1,66 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Form\Config\Resource;
// Necessary as some of these tests disable phpunit's preservation
// of the global state (e.g. autoloaders are in the global state)
require_once realpath(dirname(__FILE__) . '/../../../../bootstrap.php');
use Mockery;
use Icinga\Test\BaseTestCase;
use Icinga\Form\Config\Resource\DbResourceForm;
class DbResourceFormTest extends BaseTestCase
{
public function tearDown()
{
parent::tearDown();
Mockery::close(); // Necessary because some tests run in a separate process
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testValidDbResourceIsValid()
{
$this->setUpResourceFactoryMock(
Mockery::mock()->shouldReceive('getConnection')->atMost()->twice()->andReturn(Mockery::self())->getMock()
);
$form = new DbResourceForm();
$this->assertTrue(
$form->isValidResource($form),
'ResourceForm claims that a valid db resource is not valid'
);
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testInvalidDbResourceIsNotValid()
{
$this->setUpResourceFactoryMock(
Mockery::mock()->shouldReceive('getConnection')->once()->andThrow('\Exception')->getMock()
);
$form = new DbResourceForm();
$this->assertFalse(
$form->isValidResource($form),
'ResourceForm claims that an invalid db resource is valid'
);
}
protected function setUpResourceFactoryMock($resourceMock)
{
Mockery::mock('alias:Icinga\Data\ResourceFactory')
->shouldReceive('createResource')
->with(Mockery::type('\Zend_Config'))
->andReturn($resourceMock);
}
}

@ -0,0 +1,66 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Form\Config\Resource;
// Necessary as some of these tests disable phpunit's preservation
// of the global state (e.g. autoloaders are in the global state)
require_once realpath(dirname(__FILE__) . '/../../../../bootstrap.php');
use Mockery;
use Icinga\Test\BaseTestCase;
use Icinga\Form\Config\Resource\LdapResourceForm;
class LdapResourceFormTest extends BaseTestCase
{
public function tearDown()
{
parent::tearDown();
Mockery::close(); // Necessary because some tests run in a separate process
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testValidLdapResourceIsValid()
{
$this->setUpResourceFactoryMock(
Mockery::mock()->shouldReceive('connect')->getMock()
);
$form = new LdapResourceForm();
$this->assertTrue(
$form->isValidResource($form),
'ResourceForm claims that a valid ldap resource is not valid'
);
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testInvalidLdapResourceIsNotValid()
{
$this->setUpResourceFactoryMock(
Mockery::mock()->shouldReceive('connect')->once()->andThrow('\Exception')->getMock()
);
$form = new LdapResourceForm();
$this->assertFalse(
$form->isValidResource($form),
'ResourceForm claims that an invalid ldap resource is valid'
);
}
protected function setUpResourceFactoryMock($resourceMock)
{
Mockery::mock('alias:Icinga\Data\ResourceFactory')
->shouldReceive('createResource')
->with(Mockery::type('\Zend_Config'))
->andReturn($resourceMock);
}
}

@ -0,0 +1,67 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Form\Config\Resource;
// Necessary as some of these tests disable phpunit's preservation
// of the global state (e.g. autoloaders are in the global state)
require_once realpath(dirname(__FILE__) . '/../../../../bootstrap.php');
use Mockery;
use Icinga\Test\BaseTestCase;
use Icinga\Form\Config\Resource\LivestatusResourceForm;
class LivestatusResourceFormTest extends BaseTestCase
{
public function tearDown()
{
parent::tearDown();
Mockery::close(); // Necessary because some tests run in a separate process
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testValidLivestatusResourceIsValid()
{
$this->setUpResourceFactoryMock(
Mockery::mock()->shouldReceive('connect')->andReturn(Mockery::self())
->shouldReceive('disconnect')->getMock()
);
$form = new LivestatusResourceForm();
$this->assertTrue(
$form->isValidResource($form),
'ResourceForm claims that a valid livestatus resource is not valid'
);
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testInvalidLivestatusResourceIsNotValid()
{
$this->setUpResourceFactoryMock(
Mockery::mock()->shouldReceive('connect')->once()->andThrow('\Exception')->getMock()
);
$form = new LivestatusResourceForm();
$this->assertFalse(
$form->isValidResource($form),
'ResourceForm claims that an invalid livestatus resource is valid'
);
}
protected function setUpResourceFactoryMock($resourceMock)
{
Mockery::mock('alias:Icinga\Data\ResourceFactory')
->shouldReceive('createResource')
->with(Mockery::type('\Zend_Config'))
->andReturn($resourceMock);
}
}

@ -1,268 +0,0 @@
<?php
// {{{ICINGA_LICENSE_HEADER}}}
// {{{ICINGA_LICENSE_HEADER}}}
namespace Tests\Icinga\Form\Config\Resource;
// Necessary as some of these tests disable phpunit's preservation
// of the global state (e.g. autoloaders are in the global state)
require_once realpath(dirname(__FILE__) . '/../../../../bootstrap.php');
use Mockery;
use Zend_Config;
use Icinga\Test\BaseTestCase;
use Icinga\Form\Config\ResourceForm;
class TestResourceForm extends ResourceForm
{
public $is_valid;
public function isValidResource()
{
return $this->is_valid;
}
}
class ResourceFormTest extends BaseTestCase
{
public function tearDown()
{
parent::tearDown();
Mockery::close(); // Necessary because some tests run in a separate process
}
public function testIsForceCreationCheckboxBeingAdded()
{
$form = new TestResourceForm();
$form->is_valid = false;
$this->assertFalse($form->isValid(array()));
$this->assertNotNull(
$form->getElement('resource_force_creation'),
'Checkbox to force the creation of a resource is not being added though the resource is invalid'
);
}
public function testIsForceCreationCheckboxNotBeingAdded()
{
$form = new TestResourceForm();
$form->is_valid = true;
$this->assertTrue($form->isValid(array()));
$this->assertNull(
$form->getElement('resource_force_creation'),
'Checkbox to force the creation of a resource is being added though the resource is valid'
);
}
public function testIsTheFormValidIfForceCreationTrue()
{
$form = new TestResourceForm();
$form->is_valid = false;
$this->assertTrue(
$form->isValid(array('resource_force_creation' => 1)),
'ResourceForm with invalid resource is not valid though force creation is set'
);
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testValidDbResourceIsValid()
{
$this->setUpResourceFactoryMock(
Mockery::mock()->shouldReceive('getConnection')->atMost()->twice()->andReturn(Mockery::self())->getMock()
);
$form = $this->buildResourceForm(new Zend_Config(array('type' => 'db')));
$this->assertTrue(
$form->isValidResource(),
'ResourceForm claims that a valid db resource is not valid'
);
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testInvalidDbResourceIsNotValid()
{
$this->setUpResourceFactoryMock(
Mockery::mock()->shouldReceive('getConnection')->once()->andThrow('\Exception')->getMock()
);
$form = $this->buildResourceForm(new Zend_Config(array('type' => 'db')));
$this->assertFalse(
$form->isValidResource(),
'ResourceForm claims that an invalid db resource is valid'
);
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testValidLdapResourceIsValid()
{
$this->setUpResourceFactoryMock(
Mockery::mock()->shouldReceive('connect')->getMock()
);
$form = $this->buildResourceForm(new Zend_Config(array('type' => 'ldap')));
$this->assertTrue(
$form->isValidResource(),
'ResourceForm claims that a valid ldap resource is not valid'
);
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testInvalidLdapResourceIsNotValid()
{
$this->setUpResourceFactoryMock(
Mockery::mock()->shouldReceive('connect')->once()->andThrow('\Exception')->getMock()
);
$form = $this->buildResourceForm(new Zend_Config(array('type' => 'ldap')));
$this->assertFalse(
$form->isValidResource(),
'ResourceForm claims that an invalid ldap resource is valid'
);
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testValidLivestatusResourceIsValid()
{
$this->setUpResourceFactoryMock(
Mockery::mock()->shouldReceive('connect')->andReturn(Mockery::self())
->shouldReceive('disconnect')->getMock()
);
$form = $this->buildResourceForm(new Zend_Config(array('type' => 'livestatus')));
$this->assertTrue(
$form->isValidResource(),
'ResourceForm claims that a valid livestatus resource is not valid'
);
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testInvalidLivestatusResourceIsNotValid()
{
$this->setUpResourceFactoryMock(
Mockery::mock()->shouldReceive('connect')->once()->andThrow('\Exception')->getMock()
);
$form = $this->buildResourceForm(new Zend_Config(array('type' => 'livestatus')));
$this->assertFalse(
$form->isValidResource(),
'ResourceForm claims that an invalid livestatus resource is valid'
);
}
public function testValidFileResourceIsValid()
{
$form = $this->buildResourceForm(
new Zend_Config(
array(
'type' => 'file',
'filename' => BaseTestCase::$testDir . '/res/status/icinga.status.dat'
)
)
);
$this->assertTrue(
$form->isValidResource(),
'ResourceForm claims that a valid file resource is not valid'
);
}
public function testInvalidFileResourceIsNotValid()
{
$form = $this->buildResourceForm(
new Zend_Config(
array(
'type' => 'file',
'filename' => 'not_existing'
)
)
);
$this->assertFalse(
$form->isValidResource(),
'ResourceForm claims that an invalid file resource is valid'
);
}
public function testValidStatusdatResourceIsValid()
{
$form = $this->buildResourceForm(
new Zend_Config(
array(
'type' => 'statusdat',
'status_file' => BaseTestCase::$testDir . '/res/status/icinga.status.dat',
'object_file' => BaseTestCase::$testDir . '/res/status/icinga.objects.cache',
)
)
);
$this->assertTrue(
$form->isValidResource(),
'ResourceForm claims that a valid statusdat resource is not valid'
);
}
public function testInvalidStatusdatResourceIsNotValid()
{
$form = $this->buildResourceForm(
new Zend_Config(
array(
'type' => 'statusdat',
'status_file' => 'not_existing',
'object_file' => 'not_existing'
)
)
);
$this->assertFalse(
$form->isValidResource(),
'ResourceForm claims that an invalid statusdat resource is valid'
);
}
protected function buildResourceForm($resourceConfig)
{
$form = new ResourceForm();
$form->setRequest($this->getRequestMock());
$form->setResource($resourceConfig);
$form->create();
return $form;
}
protected function getRequestMock()
{
return Mockery::mock('\Zend_Controller_Request_Abstract')
->shouldReceive('getParam')
->with(Mockery::type('string'), Mockery::type('string'))
->andReturnUsing(function ($name, $default) { return $default; })
->getMock();
}
protected function setUpResourceFactoryMock($resourceMock)
{
Mockery::mock('alias:Icinga\Data\ResourceFactory')
->shouldReceive('createResource')
->with(Mockery::type('\Zend_Config'))
->andReturn($resourceMock);
}
}

@ -4,58 +4,285 @@
namespace Tests\Icinga\Web;
use Mockery;
use Icinga\Web\Form;
use Icinga\Web\Request;
use Icinga\Test\BaseTestCase;
class SuccessfulForm extends Form
{
public function onSuccess(Request $request)
{
return true;
}
}
class FormTest extends BaseTestCase
{
public function testWhetherAddElementDoesNotAddSpecificDecorators()
public function tearDown()
{
Mockery::close(); // Necessary as some tests are running isolated
}
public function testWhetherASubmitButtonIsAddedWithASubmitLabelBeingSet()
{
$form = new Form();
$form->addElement('text', 'someText');
$element = $form->getElement('someText');
$form->setTokenDisabled();
$form->setSubmitLabel('test');
$form->create();
$this->assertFalse(
$element->getDecorator('HtmlTag'),
'Form::addElement does not remove the HtmlTag-Decorator'
);
$this->assertFalse(
$element->getDecorator('Label'),
'Form::addElement does not remove the Label-Decorator'
);
$this->assertFalse(
$element->getDecorator('DtDdWrapper'),
'Form::addElement does not remove the DtDdWrapper-Decorator'
$this->assertInstanceOf(
'\Zend_Form_Element',
$form->getElement('btn_submit'),
'Form::create() does not add a submit button in case a submit label is set'
);
}
public function testWhetherAddElementDoesNotAddAnyOptionalDecoratorsToHiddenElements()
public function testWhetherNoSubmitButtonIsAddedWithoutASubmitLabelBeingSet()
{
$form = new Form();
$form->addElement('hidden', 'somethingHidden');
$element = $form->getElement('somethingHidden');
$form->setTokenDisabled();
$form->create();
$this->assertNull(
$form->getElement('btn_submit'),
'Form::create() adds a submit button in case no submit label is set'
);
}
/**
* @depends testWhetherASubmitButtonIsAddedWithASubmitLabelBeingSet
*/
public function testWhetherIsSubmittedReturnsTrueWithASubmitLabelBeingSet()
{
$form = new Form();
$form->setTokenDisabled();
$form->setSubmitLabel('test');
$form->populate(array('btn_submit' => true));
$this->assertTrue(
$form->isSubmitted(),
'Form::isSubmitted() does not return true in case a submit label is set'
);
}
/**
* @depends testWhetherNoSubmitButtonIsAddedWithoutASubmitLabelBeingSet
*/
public function testWhetherIsSubmittedReturnsFalseWithoutASubmitLabelBeingSet()
{
$form = new Form();
$this->assertFalse(
$form->isSubmitted(),
'Form::isSubmitted() does not return false in case no submit label is set'
);
}
public function testWhetherTheCurrentLocationIsUsedAsDefaultRedirection()
{
$this->getRequestMock()->shouldReceive('getPathInfo')->andReturn('default/route');
$this->getResponseMock()->shouldReceive('redirectAndExit')->atLeast()->once()
->with(Mockery::on(function ($url) { return $url->getRelativeUrl() === 'default/route'; }));
$form = new SuccessfulForm();
$form->setTokenDisabled();
$form->setUidDisabled();
$form->handleRequest();
}
public function testWhetherAnExplicitlySetRedirectUrlIsUsedForRedirection()
{
$this->getResponseMock()->shouldReceive('redirectAndExit')->atLeast()->once()->with('special/route');
$form = new SuccessfulForm();
$form->setTokenDisabled();
$form->setUidDisabled();
$form->setRedirectUrl('special/route');
$form->handleRequest();
}
/**
* @runInSeparateProcess
*/
public function testWhetherACsrfCounterMeasureIsBeingAdded()
{
Mockery::mock('alias:Icinga\Web\Session')->shouldReceive('getSession->getId')->andReturn('1234567890');
$form = new Form();
$form->create();
$this->assertInstanceOf(
'\Zend_Form_Element',
$form->getElement($form->getTokenElementName()),
'Form::create() does not add a csrf counter measure element'
);
}
public function testWhetherACsrfCounterMeasureIsNotBeingAdded()
{
$form = new Form();
$form->setTokenDisabled();
$form->create();
$this->assertNull(
$form->getElement($form->getTokenElementName()),
'Form::create() adds a csrf counter measure element in case it\'s disabled'
);
}
public function testWhetherAUniqueFormIdIsBeingAdded()
{
$form = new Form();
$form->setTokenDisabled();
$form->create();
$this->assertInstanceOf(
'\Zend_Form_Element',
$form->getElement($form->getUidElementName()),
'Form::create() does not add a form identification element'
);
}
public function testWhetherAUniqueFormIdIsNotBeingAdded()
{
$form = new Form();
$form->setTokenDisabled();
$form->setUidDisabled();
$form->create();
$this->assertNull(
$form->getElement($form->getUidElementName()),
'Form::create() adds a form identification element in case it\'s disabled'
);
}
/**
* @depends testWhetherAUniqueFormIdIsBeingAdded
*/
public function testWhetherAFormIsSentWithAUniqueFormIdBeingAdded()
{
$form = new Form();
$form->setTokenDisabled();
$form->create();
$this->assertTrue(
$form->wasSent(
array(
$form->getUidElementName() => $form->getElement($form->getUidElementName())->getValue()
)
),
'Form::wasSent() does not return true in case a the form identification value is being sent'
);
}
/**
* @depends testWhetherAUniqueFormIdIsNotBeingAdded
*/
public function testWhetherAFormIsNotSentWithoutAUniqueFormIdBeingAdded()
{
$form = new Form();
$form->setTokenDisabled();
$form->setUidDisabled();
$form->create();
$this->assertFalse(
$form->wasSent(array()),
'Form::wasSent() does not return false in case no form identification element was added'
);
}
public function testWhetherADefaultActionIsBeingSetOnFormCreation()
{
$this->getRequestMock()->shouldReceive('getPathInfo')->andReturn('some/route');
$form = new Form();
$form->setTokenDisabled();
$form->create();
$this->assertEquals(
'/some/route',
$form->getAction(),
'Form::create() does not set a default action if none was set explicitly'
);
}
/**
* @depends testWhetherAUniqueFormIdIsBeingAdded
* @depends testWhetherASubmitButtonIsAddedWithASubmitLabelBeingSet
*/
public function testWhetherItIsPossibleToRecreateAForm()
{
$form = new Form();
$form->setTokenDisabled();
$form->setSubmitLabel('test');
$form->create(); // sets the flag $this->created to true
$form->clearElements(); // should reset the flag..
$form->create(); // ..so that we can recreate the form
$this->assertCount(
1,
$element->getDecorators(),
'Form::addElement adds more decorators than necessary to hidden elements'
);
$this->assertInstanceOf(
'\Zend_Form_Decorator_ViewHelper',
$element->getDecorator('ViewHelper'),
'Form::addElement does not add the ViewHelper-Decorator to hidden elements'
2,
$form->getElements(),
'Form::clearElements() does not fully reset the form'
);
}
public function testWhetherLoadDefaultDecoratorsDoesNotAddTheHtmlTagDecorator()
public function testWhetherGetNameReturnsTheEscapedClassNameByDefault()
{
$form = new Form();
$form->loadDefaultDecorators();
$this->assertArrayNotHasKey(
'HtmlTag',
$form->getDecorators(),
'Form::loadDefaultDecorators adds the HtmlTag-Decorator'
$this->assertEquals(
$form->filterName(get_class($form)),
$form->getName(),
'Form::getName() does not return the escaped class name in case no name was explicitly set'
);
}
public function testWhetherGetRequestDataOnlyReturnsFormRelevantData()
{
$form = new Form();
$form->setMethod('POST');
$expectedResult = array('expected_key' => 'expected_value');
$request = $this->getRequestMock();
$request->shouldReceive('getMethod')->andReturn('POST')
->shouldReceive('isPost')->andReturn(true)
->shouldReceive('getPost')->andReturn($expectedResult);
$this->assertEquals(
$expectedResult,
$form->getRequestData($request),
'Form::getRequestData() does not (only) return form relevant data'
);
}
/**
* @expectedException LogicException
*/
public function testWhetherTheOnSuccessOptionMustBeCallable()
{
new Form(array('onSuccess' => '_invalid_'));
}
/**
* @depends testWhetherACsrfCounterMeasureIsNotBeingAdded
* @depends testWhetherAUniqueFormIdIsNotBeingAdded
* @depends testWhetherNoSubmitButtonIsAddedWithoutASubmitLabelBeingSet
*/
public function testWhetherAClosureCanBePassedAsOnSuccessCallback()
{
$request = new Request();
$form = new Form(array(
'onSuccess' => function ($req) { $req->setParam('test', 'tset'); return false; }
));
$form->setTokenDisabled();
$form->setUidDisabled();
$form->handleRequest($request);
$this->assertEquals(
'tset',
$request->getParam('test'),
'Form does not utilize the onSuccess callback set with form options on instantiation'
);
}
}

@ -12,11 +12,9 @@ class UrlTest extends BaseTestCase
{
public function testWhetherFromRequestWorksWithoutARequest()
{
$request = Mockery::mock('Icinga\Web\Request');
$request->shouldReceive('getPathInfo')->andReturn('my/test/url.html')
->shouldReceive('getBaseUrl')->andReturn('/path/to')
$this->getRequestMock()->shouldReceive('getBaseUrl')->andReturn('/path/to')
->shouldReceive('getPathInfo')->andReturn('my/test/url.html')
->shouldReceive('getQuery')->andReturn(array('param1' => 'value1', 'param2' => 'value2'));
$this->setupIcingaMock($request);
$url = Url::fromRequest();
$this->assertEquals(

@ -47,7 +47,7 @@ class DashboardTest extends BaseTestCase
Mockery::close(); // Necessary because some tests run in a separate process
}
protected function setupIcingaMock(\Zend_Controller_Request_Abstract $request)
public function setUp()
{
$moduleMock = Mockery::mock('Icinga\Application\Modules\Module');
$moduleMock->shouldReceive('getPaneItems')->andReturn(array(
@ -59,14 +59,8 @@ class DashboardTest extends BaseTestCase
'test-module' => $moduleMock
));
$bootstrapMock = Mockery::mock('Icinga\Application\ApplicationBootstrap')->shouldDeferMissing();
$bootstrapMock->shouldReceive('getFrontController->getRequest')->andReturnUsing(
function () use ($request) { return $request; }
)->shouldReceive('getApplicationDir')->andReturn(self::$appDir);
$bootstrapMock = $this->setupIcingaMock();
$bootstrapMock->shouldReceive('getModuleManager')->andReturn($moduleManagerMock);
Icinga::setApp($bootstrapMock, true);
}
public function testWhetherCreatePaneCreatesAPane()

@ -5,19 +5,12 @@
namespace Tests\Icinga\Web;
use Mockery;
use Icinga\Application\Icinga;
use Icinga\Web\Widget\SearchDashboard;
use Icinga\Test\BaseTestCase;
use Icinga\Web\Widget\SearchDashboard;
class SearchDashboardTest extends BaseTestCase
{
public function tearDown()
{
parent::tearDown();
Mockery::close();
}
protected function setupIcingaMock(\Zend_Controller_Request_Abstract $request)
public function setUp()
{
$moduleMock = Mockery::mock('Icinga\Application\Modules\Module');
$searchUrl = (object) array(
@ -33,14 +26,8 @@ class SearchDashboardTest extends BaseTestCase
'test-module' => $moduleMock
));
$bootstrapMock = Mockery::mock('Icinga\Application\ApplicationBootstrap')->shouldDeferMissing();
$bootstrapMock->shouldReceive('getFrontController->getRequest')->andReturnUsing(
function () use ($request) { return $request; }
)->shouldReceive('getApplicationDir')->andReturn(self::$appDir);
$bootstrapMock = $this->setupIcingaMock();
$bootstrapMock->shouldReceive('getModuleManager')->andReturn($moduleManagerMock);
Icinga::setApp($bootstrapMock, true);
}
/**