diff --git a/application/controllers/ConfigController.php b/application/controllers/ConfigController.php
index 39051011c..559d8f3f9 100644
--- a/application/controllers/ConfigController.php
+++ b/application/controllers/ConfigController.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 {
diff --git a/application/controllers/DashboardController.php b/application/controllers/DashboardController.php
index e8629f865..4942f5cdb 100644
--- a/application/controllers/DashboardController.php
+++ b/application/controllers/DashboardController.php
@@ -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;
}
diff --git a/application/controllers/LayoutController.php b/application/controllers/LayoutController.php
index 6c1355fc1..b2a260884 100644
--- a/application/controllers/LayoutController.php
+++ b/application/controllers/LayoutController.php
@@ -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();
}
/**
diff --git a/application/controllers/PreferenceController.php b/application/controllers/PreferenceController.php
index 0eb45dca0..bd76b2466 100644
--- a/application/controllers/PreferenceController.php
+++ b/application/controllers/PreferenceController.php
@@ -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');
}
}
diff --git a/application/controllers/StaticController.php b/application/controllers/StaticController.php
index fec60a624..c8b1d9b73 100644
--- a/application/controllers/StaticController.php
+++ b/application/controllers/StaticController.php
@@ -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
diff --git a/application/forms/Authentication/LoginForm.php b/application/forms/Authentication/LoginForm.php
index 0d9b8dedc..d878475f2 100644
--- a/application/forms/Authentication/LoginForm.php
+++ b/application/forms/Authentication/LoginForm.php
@@ -53,7 +53,5 @@ class LoginForm extends Form
'value' => Url::fromRequest()->getParam('redirect')
)
);
-
- return $this;
}
}
diff --git a/application/forms/Config/Authentication/LdapBackendForm.php b/application/forms/Config/Authentication/LdapBackendForm.php
index 9db773708..6056b0911 100644
--- a/application/forms/Config/Authentication/LdapBackendForm.php
+++ b/application/forms/Config/Authentication/LdapBackendForm.php
@@ -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;
diff --git a/application/forms/Config/AuthenticationBackendConfigForm.php b/application/forms/Config/AuthenticationBackendConfigForm.php
index 9068ed25a..e81382cd4 100644
--- a/application/forms/Config/AuthenticationBackendConfigForm.php
+++ b/application/forms/Config/AuthenticationBackendConfigForm.php
@@ -318,7 +318,5 @@ class AuthenticationBackendConfigForm extends ConfigForm
}
$this->addElements($this->getBackendForm($backendType)->createElements($formData)->getElements());
-
- return $this;
}
}
diff --git a/application/forms/Config/AuthenticationBackendReorderForm.php b/application/forms/Config/AuthenticationBackendReorderForm.php
index d4be16c30..3b5e70866 100644
--- a/application/forms/Config/AuthenticationBackendReorderForm.php
+++ b/application/forms/Config/AuthenticationBackendReorderForm.php
@@ -62,7 +62,7 @@ class AuthenticationBackendReorderForm extends ConfigForm
protected function getConfigForm()
{
$form = new AuthenticationBackendConfigForm();
- $form->setConfig($this->config);
+ $form->setIniConfig($this->config);
return $form;
}
}
diff --git a/application/forms/Config/GeneralConfigForm.php b/application/forms/Config/GeneralConfigForm.php
index ffb0a7d1c..550fe4cfb 100644
--- a/application/forms/Config/GeneralConfigForm.php
+++ b/application/forms/Config/GeneralConfigForm.php
@@ -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;
}
/**
diff --git a/application/forms/Config/ResourceConfigForm.php b/application/forms/Config/ResourceConfigForm.php
index d9ec4dad3..8e677cf8b 100644
--- a/application/forms/Config/ResourceConfigForm.php
+++ b/application/forms/Config/ResourceConfigForm.php
@@ -252,7 +252,5 @@ class ResourceConfigForm extends ConfigForm
}
$this->addElements($this->getResourceForm($resourceType)->createElements($formData)->getElements());
-
- return $this;
}
}
diff --git a/application/forms/ConfigForm.php b/application/forms/ConfigForm.php
index 1f3692473..86790d618 100644
--- a/application/forms/ConfigForm.php
+++ b/application/forms/ConfigForm.php
@@ -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(),
diff --git a/application/forms/Dashboard/AddUrlForm.php b/application/forms/Dashboard/AddUrlForm.php
index 67452a84f..88195654d 100644
--- a/application/forms/Dashboard/AddUrlForm.php
+++ b/application/forms/Dashboard/AddUrlForm.php
@@ -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;
}
/**
diff --git a/application/forms/Preference/GeneralForm.php b/application/forms/Preference/GeneralForm.php
deleted file mode 100644
index b9ce5e9e2..000000000
--- a/application/forms/Preference/GeneralForm.php
+++ /dev/null
@@ -1,171 +0,0 @@
-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
- )
- );
- }
-}
diff --git a/application/forms/PreferenceForm.php b/application/forms/PreferenceForm.php
new file mode 100644
index 000000000..cdb6ff288
--- /dev/null
+++ b/application/forms/PreferenceForm.php
@@ -0,0 +1,225 @@
+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();
+ }
+ }
+}
diff --git a/application/layouts/scripts/parts/navigation.phtml b/application/layouts/scripts/parts/navigation.phtml
index 5dedc75aa..da02a02de 100644
--- a/application/layouts/scripts/parts/navigation.phtml
+++ b/application/layouts/scripts/parts/navigation.phtml
@@ -11,11 +11,15 @@ if (! $this->auth()->isAuthenticated()) {
}
?>
-
\ No newline at end of file
diff --git a/doc/components.md b/doc/components.md
deleted file mode 100644
index a46afc2eb..000000000
--- a/doc/components.md
+++ /dev/null
@@ -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*.
-
- /
-
-
-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('' +
- '')
- .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.
-
-
-
-
-### 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-<ID>" 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
diff --git a/library/Icinga/Application/Modules/Module.php b/library/Icinga/Application/Modules/Module.php
index c0c6b1f6f..6d66412e6 100644
--- a/library/Icinga/Application/Modules/Module.php
+++ b/library/Icinga/Application/Modules/Module.php
@@ -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'
)
)
);
diff --git a/library/Icinga/Chart/Graph/Tooltip.php b/library/Icinga/Chart/Graph/Tooltip.php
index b630c7c61..4457e04e2 100644
--- a/library/Icinga/Chart/Graph/Tooltip.php
+++ b/library/Icinga/Chart/Graph/Tooltip.php
@@ -67,7 +67,7 @@ class Tooltip
*/
public function __construct (
$data = array(),
- $format = '{title}
{value} of {sum} {label}'
+ $format = '{title}
{value} of {sum} {label}'
) {
$this->data = array_merge($this->data, $data);
$this->defaultFormat = $format;
diff --git a/library/Icinga/Test/BaseTestCase.php b/library/Icinga/Test/BaseTestCase.php
index 9cc8ba519..a735550cb 100644
--- a/library/Icinga/Test/BaseTestCase.php
+++ b/library/Icinga/Test/BaseTestCase.php
@@ -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();
diff --git a/library/Icinga/Test/FormTest.php b/library/Icinga/Test/FormTest.php
deleted file mode 100644
index e8b070483..000000000
--- a/library/Icinga/Test/FormTest.php
+++ /dev/null
@@ -1,23 +0,0 @@
-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);
- }
}
diff --git a/library/Icinga/Web/Form.php b/library/Icinga/Web/Form.php
index 13ed535e3..f0695242e 100644
--- a/library/Icinga/Web/Form.php
+++ b/library/Icinga/Web/Form.php
@@ -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)
diff --git a/library/Icinga/Web/Menu/UnhandledHostMenuItemRenderer.php b/library/Icinga/Web/Menu/UnhandledHostMenuItemRenderer.php
index b66709422..c7e6036fb 100644
--- a/library/Icinga/Web/Menu/UnhandledHostMenuItemRenderer.php
+++ b/library/Icinga/Web/Menu/UnhandledHostMenuItemRenderer.php
@@ -22,7 +22,8 @@ class UnhandledHostMenuItemRenderer implements MenuItemRenderer {
$badge = '';
if ($statusSummary->hosts_down_unhandled) {
$badge = sprintf(
- '%s
',
+ '%s
',
+ t(sprintf('%d unhandled host problems', $statusSummary->hosts_down_unhandled)),
$statusSummary->hosts_down_unhandled
);
}
diff --git a/library/Icinga/Web/Menu/UnhandledServiceMenuItemRenderer.php b/library/Icinga/Web/Menu/UnhandledServiceMenuItemRenderer.php
index cdac34c04..b677a4935 100644
--- a/library/Icinga/Web/Menu/UnhandledServiceMenuItemRenderer.php
+++ b/library/Icinga/Web/Menu/UnhandledServiceMenuItemRenderer.php
@@ -22,7 +22,8 @@ class UnhandledServiceMenuItemRenderer implements MenuItemRenderer {
$badge = '';
if ($statusSummary->services_critical_unhandled) {
$badge = sprintf(
- '%s
',
+ '%s
',
+ t(sprintf('%d unhandled service problems', $statusSummary->services_critical_unhandled)),
$statusSummary->services_critical_unhandled
);
}
diff --git a/library/Icinga/Web/MenuRenderer.php b/library/Icinga/Web/MenuRenderer.php
index 1bba54239..c026e5553 100644
--- a/library/Icinga/Web/MenuRenderer.php
+++ b/library/Icinga/Web/MenuRenderer.php
@@ -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(
diff --git a/library/Icinga/Web/StyleSheet.php b/library/Icinga/Web/StyleSheet.php
index 90fb314a8..3c4baf943 100644
--- a/library/Icinga/Web/StyleSheet.php
+++ b/library/Icinga/Web/StyleSheet.php
@@ -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'
);
diff --git a/library/Icinga/Web/Widget/SortBox.php b/library/Icinga/Web/Widget/SortBox.php
index 557469966..42e7110cc 100644
--- a/library/Icinga/Web/Widget/SortBox.php
+++ b/library/Icinga/Web/Widget/SortBox.php
@@ -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'));
diff --git a/library/IcingaVendor/dompdf/lib/fonts/log.htm b/library/IcingaVendor/dompdf/lib/fonts/log.htm
deleted file mode 100644
index b1c46f075..000000000
--- a/library/IcingaVendor/dompdf/lib/fonts/log.htm
+++ /dev/null
@@ -1,324 +0,0 @@
-1084 frames 64,000 KB 12,219.54 ms ON
-
-( ! ) Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line 396 |
-Call Stack |
-# | Time | Memory | Function | Location |
-1 | 0.0015 | 634696 | {main}( ) | ../index.php:0 |
-2 | 0.6663 | 7155080 | Icinga\Application\Web->dispatch( ) | ../index.php:17 |
-3 | 0.6663 | 7155080 | Zend_Controller_Front->dispatch( ) | ../Web.php:177 |
-4 | 0.6718 | 7339544 | Zend_Controller_Dispatcher_Standard->dispatch( ) | ../Front.php:954 |
-5 | 0.7544 | 9789672 | Zend_Controller_Action->dispatch( ) | ../Standard.php:308 |
-6 | 0.8547 | 11070736 | Icinga\Web\Controller\ActionController->postDispatch( ) | ../Action.php:521 |
-7 | 0.8550 | 11071712 | Icinga\Web\Controller\ActionController->sendAsPdfAndDie( ) | ../ActionController.php:244 |
-8 | 1.9930 | 23228752 | Icinga\File\Pdf->renderPage( ) | ../ActionController.php:279 |
-9 | 2.0668 | 23495800 | DOMPDF->render( ) | ../Pdf.php:62 |
-10 | 9.0902 | 49430472 | Frame_Decorator->reflow( ) | ../dompdf.cls.php:817 |
-11 | 9.0902 | 49430520 | Page_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-12 | 9.0910 | 49432912 | Frame_Decorator->reflow( ) | ../page_frame_reflower.cls.php:138 |
-13 | 9.0910 | 49432960 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-14 | 9.0962 | 49449768 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-15 | 9.0962 | 49449768 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-16 | 9.0987 | 49466560 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-17 | 9.0987 | 49466560 | Table_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-
-
-
-( ! ) Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line 396 |
-Call Stack |
-# | Time | Memory | Function | Location |
-1 | 0.0015 | 634696 | {main}( ) | ../index.php:0 |
-2 | 0.6663 | 7155080 | Icinga\Application\Web->dispatch( ) | ../index.php:17 |
-3 | 0.6663 | 7155080 | Zend_Controller_Front->dispatch( ) | ../Web.php:177 |
-4 | 0.6718 | 7339544 | Zend_Controller_Dispatcher_Standard->dispatch( ) | ../Front.php:954 |
-5 | 0.7544 | 9789672 | Zend_Controller_Action->dispatch( ) | ../Standard.php:308 |
-6 | 0.8547 | 11070736 | Icinga\Web\Controller\ActionController->postDispatch( ) | ../Action.php:521 |
-7 | 0.8550 | 11071712 | Icinga\Web\Controller\ActionController->sendAsPdfAndDie( ) | ../ActionController.php:244 |
-8 | 1.9930 | 23228752 | Icinga\File\Pdf->renderPage( ) | ../ActionController.php:279 |
-9 | 2.0668 | 23495800 | DOMPDF->render( ) | ../Pdf.php:62 |
-10 | 9.0902 | 49430472 | Frame_Decorator->reflow( ) | ../dompdf.cls.php:817 |
-11 | 9.0902 | 49430520 | Page_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-12 | 9.0910 | 49432912 | Frame_Decorator->reflow( ) | ../page_frame_reflower.cls.php:138 |
-13 | 9.0910 | 49432960 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-14 | 9.0962 | 49449768 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-15 | 9.0962 | 49449768 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-16 | 9.2135 | 49818768 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-17 | 9.2136 | 49818768 | Table_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-
-
-
-( ! ) Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line 396 |
-Call Stack |
-# | Time | Memory | Function | Location |
-1 | 0.0015 | 634696 | {main}( ) | ../index.php:0 |
-2 | 0.6663 | 7155080 | Icinga\Application\Web->dispatch( ) | ../index.php:17 |
-3 | 0.6663 | 7155080 | Zend_Controller_Front->dispatch( ) | ../Web.php:177 |
-4 | 0.6718 | 7339544 | Zend_Controller_Dispatcher_Standard->dispatch( ) | ../Front.php:954 |
-5 | 0.7544 | 9789672 | Zend_Controller_Action->dispatch( ) | ../Standard.php:308 |
-6 | 0.8547 | 11070736 | Icinga\Web\Controller\ActionController->postDispatch( ) | ../Action.php:521 |
-7 | 0.8550 | 11071712 | Icinga\Web\Controller\ActionController->sendAsPdfAndDie( ) | ../ActionController.php:244 |
-8 | 1.9930 | 23228752 | Icinga\File\Pdf->renderPage( ) | ../ActionController.php:279 |
-9 | 2.0668 | 23495800 | DOMPDF->render( ) | ../Pdf.php:62 |
-10 | 9.0902 | 49430472 | Frame_Decorator->reflow( ) | ../dompdf.cls.php:817 |
-11 | 9.0902 | 49430520 | Page_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-12 | 9.0910 | 49432912 | Frame_Decorator->reflow( ) | ../page_frame_reflower.cls.php:138 |
-13 | 9.0910 | 49432960 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-14 | 9.2291 | 49850600 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-15 | 9.2291 | 49850600 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-16 | 9.2338 | 49873816 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-17 | 9.2338 | 49873816 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-18 | 9.2355 | 49886736 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-19 | 9.2356 | 49886736 | Table_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-
-
-
-( ! ) Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line 396 |
-Call Stack |
-# | Time | Memory | Function | Location |
-1 | 0.0015 | 634696 | {main}( ) | ../index.php:0 |
-2 | 0.6663 | 7155080 | Icinga\Application\Web->dispatch( ) | ../index.php:17 |
-3 | 0.6663 | 7155080 | Zend_Controller_Front->dispatch( ) | ../Web.php:177 |
-4 | 0.6718 | 7339544 | Zend_Controller_Dispatcher_Standard->dispatch( ) | ../Front.php:954 |
-5 | 0.7544 | 9789672 | Zend_Controller_Action->dispatch( ) | ../Standard.php:308 |
-6 | 0.8547 | 11070736 | Icinga\Web\Controller\ActionController->postDispatch( ) | ../Action.php:521 |
-7 | 0.8550 | 11071712 | Icinga\Web\Controller\ActionController->sendAsPdfAndDie( ) | ../ActionController.php:244 |
-8 | 1.9930 | 23228752 | Icinga\File\Pdf->renderPage( ) | ../ActionController.php:279 |
-9 | 2.0668 | 23495800 | DOMPDF->render( ) | ../Pdf.php:62 |
-10 | 9.0902 | 49430472 | Frame_Decorator->reflow( ) | ../dompdf.cls.php:817 |
-11 | 9.0902 | 49430520 | Page_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-12 | 9.0910 | 49432912 | Frame_Decorator->reflow( ) | ../page_frame_reflower.cls.php:138 |
-13 | 9.0910 | 49432960 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-14 | 9.2291 | 49850600 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-15 | 9.2291 | 49850600 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-16 | 9.2338 | 49873816 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-17 | 9.2338 | 49873816 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-18 | 9.2431 | 49918440 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-19 | 9.2431 | 49918440 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-20 | 9.2459 | 49935336 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-21 | 9.2459 | 49935336 | Table_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-
-
-
-( ! ) Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line 396 |
-Call Stack |
-# | Time | Memory | Function | Location |
-1 | 0.0015 | 634696 | {main}( ) | ../index.php:0 |
-2 | 0.6663 | 7155080 | Icinga\Application\Web->dispatch( ) | ../index.php:17 |
-3 | 0.6663 | 7155080 | Zend_Controller_Front->dispatch( ) | ../Web.php:177 |
-4 | 0.6718 | 7339544 | Zend_Controller_Dispatcher_Standard->dispatch( ) | ../Front.php:954 |
-5 | 0.7544 | 9789672 | Zend_Controller_Action->dispatch( ) | ../Standard.php:308 |
-6 | 0.8547 | 11070736 | Icinga\Web\Controller\ActionController->postDispatch( ) | ../Action.php:521 |
-7 | 0.8550 | 11071712 | Icinga\Web\Controller\ActionController->sendAsPdfAndDie( ) | ../ActionController.php:244 |
-8 | 1.9930 | 23228752 | Icinga\File\Pdf->renderPage( ) | ../ActionController.php:279 |
-9 | 2.0668 | 23495800 | DOMPDF->render( ) | ../Pdf.php:62 |
-10 | 9.0902 | 49430472 | Frame_Decorator->reflow( ) | ../dompdf.cls.php:817 |
-11 | 9.0902 | 49430520 | Page_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-12 | 9.0910 | 49432912 | Frame_Decorator->reflow( ) | ../page_frame_reflower.cls.php:138 |
-13 | 9.0910 | 49432960 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-14 | 9.2291 | 49850600 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-15 | 9.2291 | 49850600 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-16 | 9.2338 | 49873816 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-17 | 9.2338 | 49873816 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-18 | 9.2431 | 49918440 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-19 | 9.2431 | 49918440 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-20 | 9.2519 | 49965624 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-21 | 9.2519 | 49965624 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-22 | 9.2575 | 49989664 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-23 | 9.2575 | 49989664 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-24 | 9.2593 | 50005472 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-25 | 9.2594 | 50005472 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-26 | 9.2611 | 50020048 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-27 | 9.2611 | 50020048 | Table_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-
-
-
-( ! ) Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line 396 |
-Call Stack |
-# | Time | Memory | Function | Location |
-1 | 0.0015 | 634696 | {main}( ) | ../index.php:0 |
-2 | 0.6663 | 7155080 | Icinga\Application\Web->dispatch( ) | ../index.php:17 |
-3 | 0.6663 | 7155080 | Zend_Controller_Front->dispatch( ) | ../Web.php:177 |
-4 | 0.6718 | 7339544 | Zend_Controller_Dispatcher_Standard->dispatch( ) | ../Front.php:954 |
-5 | 0.7544 | 9789672 | Zend_Controller_Action->dispatch( ) | ../Standard.php:308 |
-6 | 0.8547 | 11070736 | Icinga\Web\Controller\ActionController->postDispatch( ) | ../Action.php:521 |
-7 | 0.8550 | 11071712 | Icinga\Web\Controller\ActionController->sendAsPdfAndDie( ) | ../ActionController.php:244 |
-8 | 1.9930 | 23228752 | Icinga\File\Pdf->renderPage( ) | ../ActionController.php:279 |
-9 | 2.0668 | 23495800 | DOMPDF->render( ) | ../Pdf.php:62 |
-10 | 9.0902 | 49430472 | Frame_Decorator->reflow( ) | ../dompdf.cls.php:817 |
-11 | 9.0902 | 49430520 | Page_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-12 | 9.0910 | 49432912 | Frame_Decorator->reflow( ) | ../page_frame_reflower.cls.php:138 |
-13 | 9.0910 | 49432960 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-14 | 9.2291 | 49850600 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-15 | 9.2291 | 49850600 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-16 | 9.2338 | 49873816 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-17 | 9.2338 | 49873816 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-18 | 9.2431 | 49918440 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-19 | 9.2431 | 49918440 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-20 | 9.2519 | 49965624 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-21 | 9.2519 | 49965624 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-22 | 9.2575 | 49989664 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-23 | 9.2575 | 49989664 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-24 | 9.2593 | 50005472 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-25 | 9.2594 | 50005472 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-26 | 9.2722 | 50061408 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-27 | 9.2722 | 50061408 | Table_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-
-
-
-( ! ) Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line 396 |
-Call Stack |
-# | Time | Memory | Function | Location |
-1 | 0.0015 | 634696 | {main}( ) | ../index.php:0 |
-2 | 0.6663 | 7155080 | Icinga\Application\Web->dispatch( ) | ../index.php:17 |
-3 | 0.6663 | 7155080 | Zend_Controller_Front->dispatch( ) | ../Web.php:177 |
-4 | 0.6718 | 7339544 | Zend_Controller_Dispatcher_Standard->dispatch( ) | ../Front.php:954 |
-5 | 0.7544 | 9789672 | Zend_Controller_Action->dispatch( ) | ../Standard.php:308 |
-6 | 0.8547 | 11070736 | Icinga\Web\Controller\ActionController->postDispatch( ) | ../Action.php:521 |
-7 | 0.8550 | 11071712 | Icinga\Web\Controller\ActionController->sendAsPdfAndDie( ) | ../ActionController.php:244 |
-8 | 1.9930 | 23228752 | Icinga\File\Pdf->renderPage( ) | ../ActionController.php:279 |
-9 | 2.0668 | 23495800 | DOMPDF->render( ) | ../Pdf.php:62 |
-10 | 9.0902 | 49430472 | Frame_Decorator->reflow( ) | ../dompdf.cls.php:817 |
-11 | 9.0902 | 49430520 | Page_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-12 | 9.0910 | 49432912 | Frame_Decorator->reflow( ) | ../page_frame_reflower.cls.php:138 |
-13 | 9.0910 | 49432960 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-14 | 9.2291 | 49850600 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-15 | 9.2291 | 49850600 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-16 | 9.2338 | 49873816 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-17 | 9.2338 | 49873816 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-18 | 9.2431 | 49918440 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-19 | 9.2431 | 49918440 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-20 | 9.2999 | 50176560 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-21 | 9.2999 | 50176560 | Table_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-
-
-
-( ! ) Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line 396 |
-Call Stack |
-# | Time | Memory | Function | Location |
-1 | 0.0015 | 634696 | {main}( ) | ../index.php:0 |
-2 | 0.6663 | 7155080 | Icinga\Application\Web->dispatch( ) | ../index.php:17 |
-3 | 0.6663 | 7155080 | Zend_Controller_Front->dispatch( ) | ../Web.php:177 |
-4 | 0.6718 | 7339544 | Zend_Controller_Dispatcher_Standard->dispatch( ) | ../Front.php:954 |
-5 | 0.7544 | 9789672 | Zend_Controller_Action->dispatch( ) | ../Standard.php:308 |
-6 | 0.8547 | 11070736 | Icinga\Web\Controller\ActionController->postDispatch( ) | ../Action.php:521 |
-7 | 0.8550 | 11071712 | Icinga\Web\Controller\ActionController->sendAsPdfAndDie( ) | ../ActionController.php:244 |
-8 | 1.9930 | 23228752 | Icinga\File\Pdf->renderPage( ) | ../ActionController.php:279 |
-9 | 2.0668 | 23495800 | DOMPDF->render( ) | ../Pdf.php:62 |
-10 | 9.0902 | 49430472 | Frame_Decorator->reflow( ) | ../dompdf.cls.php:817 |
-11 | 9.0902 | 49430520 | Page_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-12 | 9.0910 | 49432912 | Frame_Decorator->reflow( ) | ../page_frame_reflower.cls.php:138 |
-13 | 9.0910 | 49432960 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-14 | 9.2291 | 49850600 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-15 | 9.2291 | 49850600 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-16 | 9.2338 | 49873816 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-17 | 9.2338 | 49873816 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-18 | 9.3083 | 50220200 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-19 | 9.3083 | 50220200 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-20 | 9.3103 | 50235768 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-21 | 9.3103 | 50235768 | Table_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-
-
-
-( ! ) Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line 396 |
-Call Stack |
-# | Time | Memory | Function | Location |
-1 | 0.0015 | 634696 | {main}( ) | ../index.php:0 |
-2 | 0.6663 | 7155080 | Icinga\Application\Web->dispatch( ) | ../index.php:17 |
-3 | 0.6663 | 7155080 | Zend_Controller_Front->dispatch( ) | ../Web.php:177 |
-4 | 0.6718 | 7339544 | Zend_Controller_Dispatcher_Standard->dispatch( ) | ../Front.php:954 |
-5 | 0.7544 | 9789672 | Zend_Controller_Action->dispatch( ) | ../Standard.php:308 |
-6 | 0.8547 | 11070736 | Icinga\Web\Controller\ActionController->postDispatch( ) | ../Action.php:521 |
-7 | 0.8550 | 11071712 | Icinga\Web\Controller\ActionController->sendAsPdfAndDie( ) | ../ActionController.php:244 |
-8 | 1.9930 | 23228752 | Icinga\File\Pdf->renderPage( ) | ../ActionController.php:279 |
-9 | 2.0668 | 23495800 | DOMPDF->render( ) | ../Pdf.php:62 |
-10 | 9.0902 | 49430472 | Frame_Decorator->reflow( ) | ../dompdf.cls.php:817 |
-11 | 9.0902 | 49430520 | Page_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-12 | 9.0910 | 49432912 | Frame_Decorator->reflow( ) | ../page_frame_reflower.cls.php:138 |
-13 | 9.0910 | 49432960 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-14 | 9.2291 | 49850600 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-15 | 9.2291 | 49850600 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-16 | 9.2338 | 49873816 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-17 | 9.2338 | 49873816 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-18 | 9.3083 | 50220200 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-19 | 9.3083 | 50220200 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-20 | 9.3170 | 50278592 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-21 | 9.3170 | 50278592 | Table_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-
-
-
-( ! ) Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line 396 |
-Call Stack |
-# | Time | Memory | Function | Location |
-1 | 0.0015 | 634696 | {main}( ) | ../index.php:0 |
-2 | 0.6663 | 7155080 | Icinga\Application\Web->dispatch( ) | ../index.php:17 |
-3 | 0.6663 | 7155080 | Zend_Controller_Front->dispatch( ) | ../Web.php:177 |
-4 | 0.6718 | 7339544 | Zend_Controller_Dispatcher_Standard->dispatch( ) | ../Front.php:954 |
-5 | 0.7544 | 9789672 | Zend_Controller_Action->dispatch( ) | ../Standard.php:308 |
-6 | 0.8547 | 11070736 | Icinga\Web\Controller\ActionController->postDispatch( ) | ../Action.php:521 |
-7 | 0.8550 | 11071712 | Icinga\Web\Controller\ActionController->sendAsPdfAndDie( ) | ../ActionController.php:244 |
-8 | 1.9930 | 23228752 | Icinga\File\Pdf->renderPage( ) | ../ActionController.php:279 |
-9 | 2.0668 | 23495800 | DOMPDF->render( ) | ../Pdf.php:62 |
-10 | 9.0902 | 49430472 | Frame_Decorator->reflow( ) | ../dompdf.cls.php:817 |
-11 | 9.0902 | 49430520 | Page_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-12 | 9.0910 | 49432912 | Frame_Decorator->reflow( ) | ../page_frame_reflower.cls.php:138 |
-13 | 9.0910 | 49432960 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-14 | 9.2291 | 49850600 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-15 | 9.2291 | 49850600 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-16 | 9.2338 | 49873816 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-17 | 9.2338 | 49873816 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-18 | 9.3246 | 50312056 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-19 | 9.3247 | 50312056 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-20 | 9.3266 | 50326968 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-21 | 9.3266 | 50326968 | Table_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-
-
-
-( ! ) Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line 396 |
-Call Stack |
-# | Time | Memory | Function | Location |
-1 | 0.0015 | 634696 | {main}( ) | ../index.php:0 |
-2 | 0.6663 | 7155080 | Icinga\Application\Web->dispatch( ) | ../index.php:17 |
-3 | 0.6663 | 7155080 | Zend_Controller_Front->dispatch( ) | ../Web.php:177 |
-4 | 0.6718 | 7339544 | Zend_Controller_Dispatcher_Standard->dispatch( ) | ../Front.php:954 |
-5 | 0.7544 | 9789672 | Zend_Controller_Action->dispatch( ) | ../Standard.php:308 |
-6 | 0.8547 | 11070736 | Icinga\Web\Controller\ActionController->postDispatch( ) | ../Action.php:521 |
-7 | 0.8550 | 11071712 | Icinga\Web\Controller\ActionController->sendAsPdfAndDie( ) | ../ActionController.php:244 |
-8 | 1.9930 | 23228752 | Icinga\File\Pdf->renderPage( ) | ../ActionController.php:279 |
-9 | 2.0668 | 23495800 | DOMPDF->render( ) | ../Pdf.php:62 |
-10 | 9.0902 | 49430472 | Frame_Decorator->reflow( ) | ../dompdf.cls.php:817 |
-11 | 9.0902 | 49430520 | Page_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-12 | 9.0910 | 49432912 | Frame_Decorator->reflow( ) | ../page_frame_reflower.cls.php:138 |
-13 | 9.0910 | 49432960 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-14 | 9.2291 | 49850600 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-15 | 9.2291 | 49850600 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-16 | 9.2338 | 49873816 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-17 | 9.2338 | 49873816 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-18 | 9.3246 | 50312056 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-19 | 9.3247 | 50312056 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-20 | 9.3367 | 50378088 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-21 | 9.3367 | 50378088 | Table_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-
-
-
-( ! ) Notice: Undefined offset: 1 in /vagrant/library/vendor/dompdf/include/table_frame_reflower.cls.php on line 396 |
-Call Stack |
-# | Time | Memory | Function | Location |
-1 | 0.0015 | 634696 | {main}( ) | ../index.php:0 |
-2 | 0.6663 | 7155080 | Icinga\Application\Web->dispatch( ) | ../index.php:17 |
-3 | 0.6663 | 7155080 | Zend_Controller_Front->dispatch( ) | ../Web.php:177 |
-4 | 0.6718 | 7339544 | Zend_Controller_Dispatcher_Standard->dispatch( ) | ../Front.php:954 |
-5 | 0.7544 | 9789672 | Zend_Controller_Action->dispatch( ) | ../Standard.php:308 |
-6 | 0.8547 | 11070736 | Icinga\Web\Controller\ActionController->postDispatch( ) | ../Action.php:521 |
-7 | 0.8550 | 11071712 | Icinga\Web\Controller\ActionController->sendAsPdfAndDie( ) | ../ActionController.php:244 |
-8 | 1.9930 | 23228752 | Icinga\File\Pdf->renderPage( ) | ../ActionController.php:279 |
-9 | 2.0668 | 23495800 | DOMPDF->render( ) | ../Pdf.php:62 |
-10 | 9.0902 | 49430472 | Frame_Decorator->reflow( ) | ../dompdf.cls.php:817 |
-11 | 9.0902 | 49430520 | Page_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-12 | 9.0910 | 49432912 | Frame_Decorator->reflow( ) | ../page_frame_reflower.cls.php:138 |
-13 | 9.0910 | 49432960 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-14 | 9.2291 | 49850600 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-15 | 9.2291 | 49850600 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-16 | 9.2338 | 49873816 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-17 | 9.2338 | 49873816 | Block_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-18 | 9.3442 | 50422280 | Frame_Decorator->reflow( ) | ../block_frame_reflower.cls.php:722 |
-19 | 9.3442 | 50422280 | Table_Frame_Reflower->reflow( ) | ../frame_decorator.cls.php:556 |
-
diff --git a/modules/monitoring/application/controllers/ChartController.php b/modules/monitoring/application/controllers/ChartController.php
index c3d80b59f..bf41ab5eb 100644
--- a/modules/monitoring/application/controllers/ChartController.php
+++ b/modules/monitoring/application/controllers/ChartController.php
@@ -147,7 +147,7 @@ class Monitoring_ChartController extends Controller
->setXAxis(new StaticAxis())
->setAxisMin(null, 0);
- $tooltip = t('{title}:
{value} of {sum} services are {label}');
+ $tooltip = t('{title}:
{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('{title}:
{value} of {sum} hosts are {label}');
+ $tooltip = t('{title}:
{value} of {sum} hosts are {label}');
$this->view->chart = new GridChart();
$this->view->chart->alignTopLeft();
$this->view->chart->setAxisLabel('', t('Hosts'))
diff --git a/modules/monitoring/application/controllers/ConfigController.php b/modules/monitoring/application/controllers/ConfigController.php
index ce22d73df..de9c65b04 100644
--- a/modules/monitoring/application/controllers/ConfigController.php
+++ b/modules/monitoring/application/controllers/ConfigController.php
@@ -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');
}
}
diff --git a/modules/monitoring/application/controllers/TimelineController.php b/modules/monitoring/application/controllers/TimelineController.php
index 2da29a0b9..a67615b1c 100644
--- a/modules/monitoring/application/controllers/TimelineController.php
+++ b/modules/monitoring/application/controllers/TimelineController.php
@@ -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
{
diff --git a/modules/monitoring/application/forms/Config/BackendConfigForm.php b/modules/monitoring/application/forms/Config/BackendConfigForm.php
new file mode 100644
index 000000000..e2cdf210c
--- /dev/null
+++ b/modules/monitoring/application/forms/Config/BackendConfigForm.php
@@ -0,0 +1,242 @@
+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]
+ )
+ );
+ }
+}
diff --git a/modules/monitoring/application/forms/Config/BackendForm.php b/modules/monitoring/application/forms/Config/BackendForm.php
deleted file mode 100644
index f74c9bbaf..000000000
--- a/modules/monitoring/application/forms/Config/BackendForm.php
+++ /dev/null
@@ -1,125 +0,0 @@
-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;
- }
-}
diff --git a/modules/monitoring/application/forms/Config/Instance/LocalInstanceForm.php b/modules/monitoring/application/forms/Config/Instance/LocalInstanceForm.php
new file mode 100644
index 000000000..513ba2433
--- /dev/null
+++ b/modules/monitoring/application/forms/Config/Instance/LocalInstanceForm.php
@@ -0,0 +1,37 @@
+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;
+ }
+}
diff --git a/modules/monitoring/application/forms/Config/Instance/RemoteInstanceForm.php b/modules/monitoring/application/forms/Config/Instance/RemoteInstanceForm.php
new file mode 100644
index 000000000..0e78a0aec
--- /dev/null
+++ b/modules/monitoring/application/forms/Config/Instance/RemoteInstanceForm.php
@@ -0,0 +1,68 @@
+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;
+ }
+}
diff --git a/modules/monitoring/application/forms/Config/InstanceConfigForm.php b/modules/monitoring/application/forms/Config/InstanceConfigForm.php
new file mode 100644
index 000000000..6f8d04764
--- /dev/null
+++ b/modules/monitoring/application/forms/Config/InstanceConfigForm.php
@@ -0,0 +1,209 @@
+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());
+ }
+}
diff --git a/modules/monitoring/application/forms/Config/InstanceForm.php b/modules/monitoring/application/forms/Config/InstanceForm.php
deleted file mode 100644
index 3794e3c54..000000000
--- a/modules/monitoring/application/forms/Config/InstanceForm.php
+++ /dev/null
@@ -1,156 +0,0 @@
-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);
- }
-}
diff --git a/modules/monitoring/application/forms/Config/SecurityConfigForm.php b/modules/monitoring/application/forms/Config/SecurityConfigForm.php
new file mode 100644
index 000000000..a164766cc
--- /dev/null
+++ b/modules/monitoring/application/forms/Config/SecurityConfigForm.php
@@ -0,0 +1,66 @@
+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.'
+ )
+ );
+ }
+}
diff --git a/modules/monitoring/application/forms/Config/SecurityForm.php b/modules/monitoring/application/forms/Config/SecurityForm.php
deleted file mode 100644
index 48368d0f1..000000000
--- a/modules/monitoring/application/forms/Config/SecurityForm.php
+++ /dev/null
@@ -1,42 +0,0 @@
-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.'
- )
- )
- );
- }
-}
diff --git a/modules/monitoring/application/views/scripts/config/index.phtml b/modules/monitoring/application/views/scripts/config/index.phtml
index 41d2748d5..34f47a0b4 100644
--- a/modules/monitoring/application/views/scripts/config/index.phtml
+++ b/modules/monitoring/application/views/scripts/config/index.phtml
@@ -1,99 +1,70 @@
-{$element}) &&
- get_class($this->{$element}) === 'Icinga\Exception\NotReadableError') {
- $fileNotReadable[$element] = $this->{$element}->getMessage();
- } else {
- $fileNotReadable[$element] = false;
- }
-}
-?>
-
- = $this->tabs->render($this); ?>
+ = $tabs; ?>
-
-
Monitoring Backends
-
- messageBox)): ?>
- = $this->messageBox->render() ?>
-
-
-
-
- = $this->icon('create.png'); ?> Create New Monitoring Backend
-
-
-
-
-
-
- = $this->escape($fileNotReadable['backends']) ?>
-
-
-
-
-
Monitoring Instances
-
-
-
- = $this->icon('create.png'); ?> Create New Instance
-
-
-
-
-
-
- = $this->escape($fileNotReadable['instances']) ?>
-
-
-
+ Monitoring Backends
+
+
+ = $this->icon('create.png'); ?> = $this->translate('Create New Monitoring Backend'); ?>
+
+
+
+ Monitoring Instances
+
+
+ = $this->icon('create.png'); ?> = $this->translate('Create New Instance'); ?>
+
+
+
+
\ No newline at end of file
diff --git a/modules/monitoring/application/views/scripts/config/removeinstance.phtml b/modules/monitoring/application/views/scripts/config/removeinstance.phtml
index 586452173..306d41815 100644
--- a/modules/monitoring/application/views/scripts/config/removeinstance.phtml
+++ b/modules/monitoring/application/views/scripts/config/removeinstance.phtml
@@ -1,4 +1,4 @@
= $this->translate('Remove Existing Instance'); ?>
-Are you sure you want to remove the instance = $this->escape($name); ?>?
- If you have still any environments or views referring to this instance, you won't be able to send commands anymore after deletion.
+= $this->translate('Are you sure you want to remove this instance?'); ?>
+= $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.'); ?>
= $form; ?>
\ No newline at end of file
diff --git a/modules/monitoring/library/Monitoring/Timeline/TimeLine.php b/modules/monitoring/library/Monitoring/Timeline/TimeLine.php
index be3820e19..3a795df32 100644
--- a/modules/monitoring/library/Monitoring/Timeline/TimeLine.php
+++ b/modules/monitoring/library/Monitoring/Timeline/TimeLine.php
@@ -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;
diff --git a/modules/monitoring/library/Monitoring/Web/Widget/TimelineIntervalBox.php b/modules/monitoring/library/Monitoring/Web/Widget/TimelineIntervalBox.php
index 4cab3517d..4d6dbdad5 100644
--- a/modules/monitoring/library/Monitoring/Web/Widget/TimelineIntervalBox.php
+++ b/modules/monitoring/library/Monitoring/Web/Widget/TimelineIntervalBox.php
@@ -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
)
);
diff --git a/modules/monitoring/test/php/application/forms/Command/AcknowledgeFormTest.php b/modules/monitoring/test/php/application/forms/Command/AcknowledgeFormTest.php
deleted file mode 100644
index 32d8e35d3..000000000
--- a/modules/monitoring/test/php/application/forms/Command/AcknowledgeFormTest.php
+++ /dev/null
@@ -1,111 +0,0 @@
-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'
- );
- }
-}
diff --git a/modules/monitoring/test/php/application/forms/Command/CommentFormTest.php b/modules/monitoring/test/php/application/forms/Command/CommentFormTest.php
deleted file mode 100644
index 3228af399..000000000
--- a/modules/monitoring/test/php/application/forms/Command/CommentFormTest.php
+++ /dev/null
@@ -1,64 +0,0 @@
-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'
- );
- }
-}
diff --git a/modules/monitoring/test/php/application/forms/Command/CustomNotificationFormTest.php b/modules/monitoring/test/php/application/forms/Command/CustomNotificationFormTest.php
deleted file mode 100644
index 9c03ff3ec..000000000
--- a/modules/monitoring/test/php/application/forms/Command/CustomNotificationFormTest.php
+++ /dev/null
@@ -1,28 +0,0 @@
-createForm(
- self::FORM_CLASS,
- array(
- 'author' => 'Author',
- 'comment' => '',
- 'btn_submit' => 'Submit'
- )
- );
- $this->assertFalse(
- $form->isSubmittedAndValid(),
- 'Missing comment must be considered not valid'
- );
- }
-}
diff --git a/modules/monitoring/test/php/application/forms/Command/DelayNotificationFormTest.php b/modules/monitoring/test/php/application/forms/Command/DelayNotificationFormTest.php
deleted file mode 100644
index 3a955f191..000000000
--- a/modules/monitoring/test/php/application/forms/Command/DelayNotificationFormTest.php
+++ /dev/null
@@ -1,58 +0,0 @@
-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'
- );
- }
-}
diff --git a/modules/monitoring/test/php/application/forms/Command/RescheduleNextCheckFormTest.php b/modules/monitoring/test/php/application/forms/Command/RescheduleNextCheckFormTest.php
deleted file mode 100644
index 72a4914f5..000000000
--- a/modules/monitoring/test/php/application/forms/Command/RescheduleNextCheckFormTest.php
+++ /dev/null
@@ -1,54 +0,0 @@
-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'
- );
- }
-}
diff --git a/modules/monitoring/test/php/application/forms/Command/ScheduleDowntimeFormTest.php b/modules/monitoring/test/php/application/forms/Command/ScheduleDowntimeFormTest.php
deleted file mode 100644
index 5c7138b17..000000000
--- a/modules/monitoring/test/php/application/forms/Command/ScheduleDowntimeFormTest.php
+++ /dev/null
@@ -1,356 +0,0 @@
-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));
- }
-}
diff --git a/modules/monitoring/test/php/application/forms/Command/SubmitPassiveCheckResultTest.php b/modules/monitoring/test/php/application/forms/Command/SubmitPassiveCheckResultTest.php
deleted file mode 100644
index 4c83294df..000000000
--- a/modules/monitoring/test/php/application/forms/Command/SubmitPassiveCheckResultTest.php
+++ /dev/null
@@ -1,117 +0,0 @@
-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'
- );
- }
-}
diff --git a/modules/translation/library/Translation/Util/GettextTranslationHelper.php b/modules/translation/library/Translation/Util/GettextTranslationHelper.php
index 68e07fbcd..be0497a31 100644
--- a/modules/translation/library/Translation/Util/GettextTranslationHelper.php
+++ b/modules/translation/library/Translation/Util/GettextTranslationHelper.php
@@ -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"',
diff --git a/public/css/icinga/charts.less b/public/css/icinga/charts.less
deleted file mode 100644
index 6164921df..000000000
--- a/public/css/icinga/charts.less
+++ /dev/null
@@ -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;
-}
\ No newline at end of file
diff --git a/public/css/icinga/widgets.less b/public/css/icinga/widgets.less
index 761c2ca0e..f546443c4 100644
--- a/public/css/icinga/widgets.less
+++ b/public/css/icinga/widgets.less
@@ -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;
diff --git a/public/js/icinga/events.js b/public/js/icinga/events.js
index 685b50423..a48336147 100644
--- a/public/js/icinga/events.js
+++ b/public/js/icinga/events.js
@@ -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() {
diff --git a/public/js/icinga/loader.js b/public/js/icinga/loader.js
index f70bc0522..9d14ebb7f 100644
--- a/public/js/icinga/loader.js
+++ b/public/js/icinga/loader.js
@@ -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;
}
diff --git a/public/js/icinga/ui.js b/public/js/icinga/ui.js
index d933844c9..f6ae29b35 100644
--- a/public/js/icinga/ui.js
+++ b/public/js/icinga/ui.js
@@ -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;
diff --git a/public/js/icinga/utils.js b/public/js/icinga/utils.js
index 1a6759d87..ba4d7a040 100644
--- a/public/js/icinga/utils.js
+++ b/public/js/icinga/utils.js
@@ -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));
},
diff --git a/test/php/application/forms/Config/Authentication/BaseBackendFormTest.php b/test/php/application/forms/Config/Authentication/BaseBackendFormTest.php
deleted file mode 100644
index ca32a1dae..000000000
--- a/test/php/application/forms/Config/Authentication/BaseBackendFormTest.php
+++ /dev/null
@@ -1,61 +0,0 @@
-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'
- );
- }
-}
diff --git a/test/php/application/forms/Config/Authentication/DbBackendFormTest.php b/test/php/application/forms/Config/Authentication/DbBackendFormTest.php
index 51bec896f..3364dff60 100644
--- a/test/php/application/forms/Config/Authentication/DbBackendFormTest.php
+++ b/test/php/application/forms/Config/Authentication/DbBackendFormTest.php
@@ -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'
);
}
diff --git a/test/php/application/forms/Config/Authentication/LdapBackendFormTest.php b/test/php/application/forms/Config/Authentication/LdapBackendFormTest.php
index 209b7a675..0335d1f82 100644
--- a/test/php/application/forms/Config/Authentication/LdapBackendFormTest.php
+++ b/test/php/application/forms/Config/Authentication/LdapBackendFormTest.php
@@ -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'
);
}
diff --git a/test/php/application/forms/Config/Authentication/ReorderFormTest.php b/test/php/application/forms/Config/Authentication/ReorderFormTest.php
deleted file mode 100644
index 808806f1a..000000000
--- a/test/php/application/forms/Config/Authentication/ReorderFormTest.php
+++ /dev/null
@@ -1,80 +0,0 @@
- $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'
- );
- }
-}
diff --git a/test/php/application/forms/Config/AuthenticationBackendReorderFormTest.php b/test/php/application/forms/Config/AuthenticationBackendReorderFormTest.php
new file mode 100644
index 000000000..c79b12fd9
--- /dev/null
+++ b/test/php/application/forms/Config/AuthenticationBackendReorderFormTest.php
@@ -0,0 +1,61 @@
+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'
+ );
+ }
+}
diff --git a/test/php/application/forms/Config/Resource/DbResourceFormTest.php b/test/php/application/forms/Config/Resource/DbResourceFormTest.php
new file mode 100644
index 000000000..1b624c49f
--- /dev/null
+++ b/test/php/application/forms/Config/Resource/DbResourceFormTest.php
@@ -0,0 +1,66 @@
+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);
+ }
+}
diff --git a/test/php/application/forms/Config/Resource/LdapResourceFormTest.php b/test/php/application/forms/Config/Resource/LdapResourceFormTest.php
new file mode 100644
index 000000000..078a11146
--- /dev/null
+++ b/test/php/application/forms/Config/Resource/LdapResourceFormTest.php
@@ -0,0 +1,66 @@
+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);
+ }
+}
diff --git a/test/php/application/forms/Config/Resource/LivestatusResourceFormTest.php b/test/php/application/forms/Config/Resource/LivestatusResourceFormTest.php
new file mode 100644
index 000000000..300adebed
--- /dev/null
+++ b/test/php/application/forms/Config/Resource/LivestatusResourceFormTest.php
@@ -0,0 +1,67 @@
+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);
+ }
+}
diff --git a/test/php/application/forms/Config/Resource/ResourceFormTestBroken.php b/test/php/application/forms/Config/Resource/ResourceFormTestBroken.php
deleted file mode 100644
index 6dba6ce54..000000000
--- a/test/php/application/forms/Config/Resource/ResourceFormTestBroken.php
+++ /dev/null
@@ -1,268 +0,0 @@
-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);
- }
-}
diff --git a/test/php/library/Icinga/Web/FormTest.php b/test/php/library/Icinga/Web/FormTest.php
index 4e6ec5d92..a2fc9c8b1 100644
--- a/test/php/library/Icinga/Web/FormTest.php
+++ b/test/php/library/Icinga/Web/FormTest.php
@@ -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'
);
}
}
diff --git a/test/php/library/Icinga/Web/UrlTest.php b/test/php/library/Icinga/Web/UrlTest.php
index 5da50c3f8..68206beee 100644
--- a/test/php/library/Icinga/Web/UrlTest.php
+++ b/test/php/library/Icinga/Web/UrlTest.php
@@ -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(
diff --git a/test/php/library/Icinga/Web/Widget/DashboardTest.php b/test/php/library/Icinga/Web/Widget/DashboardTest.php
index 9114a8f90..be11c42fe 100644
--- a/test/php/library/Icinga/Web/Widget/DashboardTest.php
+++ b/test/php/library/Icinga/Web/Widget/DashboardTest.php
@@ -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()
diff --git a/test/php/library/Icinga/Web/Widget/SearchDashboardTest.php b/test/php/library/Icinga/Web/Widget/SearchDashboardTest.php
index d42862ff6..d9323c00a 100644
--- a/test/php/library/Icinga/Web/Widget/SearchDashboardTest.php
+++ b/test/php/library/Icinga/Web/Widget/SearchDashboardTest.php
@@ -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);
}
/**