Merge branch 'master' into feature/conditional-requirements-8508

This commit is contained in:
Johannes Meyer 2015-03-09 08:51:03 +01:00
commit 4badbc660b
145 changed files with 1960 additions and 1097 deletions

View File

@ -90,7 +90,7 @@ class icingaweb2_dev (
source => $name,
}
icingaweb2::config::general { [ 'config', 'resources' ]:
icingaweb2::config::general { [ 'config', 'resources', 'roles' ]:
source => $name,
replace => false,
}

View File

@ -0,0 +1,3 @@
[admins]
users = icingaadmin
permissions = *

View File

@ -1,5 +1,6 @@
Alexander Fuhr <alexander.fuhr@netways.de>
Alexander Klimov <alexander.klimov@netways.de>
ayoubabid <ayoubabid@users.noreply.github.com>
baufrecht <baufrecht@users.noreply.github.com>
Bernd Erk <bernd.erk@icinga.org>
Boden Garman <boden.garman@spintel.net.au>
@ -11,8 +12,9 @@ Goran Rakic <grakic@devbase.net>
Gunnar Beutner <gunnar.beutner@netways.de>
Jannis Moßhammer <jannis.mosshammer@netways.de>
Johannes Meyer <johannes.meyer@netways.de>
Marius Hein <marius.hein@netways.de>
Louis Sautier <sautier.louis@gmail.com>
Marcus Cobden <marcus@marcuscobden.co.uk>
Marius Hein <marius.hein@netways.de>
Markus Frosch <markus@lazyfrosch.de>
Matthias Jentsch <matthias.jentsch@netways.de>
Michael Friedrich <michael.friedrich@netways.de>
@ -22,4 +24,3 @@ Sylph Lin <sylph.lin@gmail.com>
Thomas Gelf <thomas.gelf@netways.de>
Tom Ford <exptom@users.noreply.github.com>
Ulf Lange <mopp@gmx.net>
ayoubabid <ayoubabid@users.noreply.github.com>

View File

@ -121,7 +121,8 @@ class ConfigController extends ActionController
// @TODO(el): This seems not natural to me. Module configuration should have its own controller.
$this->view->tabs = Widget::create('tabs')
->add('modules', array(
'title' => $this->translate('Modules'),
'label' => $this->translate('Modules'),
'title' => $this->translate('List intalled modules'),
'url' => 'config/modules'
))
->activate('modules');
@ -134,22 +135,23 @@ class ConfigController extends ActionController
public function moduleAction()
{
$name = $this->getParam('name');
$app = Icinga::app();
$manager = $app->getModuleManager();
$name = $this->getParam('name');
if ($manager->hasInstalled($name)) {
$this->view->moduleData = Icinga::app()
->getModuleManager()
->select()
->from('modules')
->where('name', $name)
->fetchRow();
$module = new Module($app, $name, $manager->getModuleDir($name));
$this->view->moduleData = $manager->select()->from('modules')->where('name', $name)->fetchRow();
if ($manager->hasLoaded($name)) {
$module = $manager->getModule($name);
} else {
$module = new Module($app, $name, $manager->getModuleDir($name));
}
$this->view->module = $module;
$this->view->tabs = $module->getConfigTabs()->activate('info');
} else {
$this->view->module = false;
$this->view->tabs = null;
}
$this->view->tabs = $module->getConfigTabs()->activate('info');
}
/**
@ -162,7 +164,6 @@ class ConfigController extends ActionController
$manager = Icinga::app()->getModuleManager();
try {
$manager->enableModule($module);
$manager->loadModule($module);
Notification::success(sprintf($this->translate('Module "%s" enabled'), $module));
$this->rerenderLayout()->reloadCss()->redirectNow('config/modules');
} catch (Exception $e) {
@ -215,6 +216,11 @@ class ConfigController extends ActionController
{
$this->assertPermission('system/config/authentication');
$form = new AuthenticationBackendConfigForm();
$form->setTitle($this->translate('Create New Authentication Backend'));
$form->addDescription($this->translate(
'Create a new backend for authenticating your users. This backend'
. ' will be added at the end of your authentication order.'
));
$form->setIniConfig(Config::app('authentication'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('config/authentication');
@ -232,6 +238,7 @@ class ConfigController extends ActionController
{
$this->assertPermission('system/config/authentication');
$form = new AuthenticationBackendConfigForm();
$form->setTitle($this->translate('Edit Backend'));
$form->setIniConfig(Config::app('authentication'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('config/authentication');
@ -271,6 +278,7 @@ class ConfigController extends ActionController
}
}
));
$form->setTitle($this->translate('Remove Backend'));
$form->setRedirectUrl('config/authentication');
$form->handleRequest();
@ -296,6 +304,8 @@ class ConfigController extends ActionController
{
$this->assertPermission('system/config/resources');
$form = new ResourceConfigForm();
$form->setTitle($this->translate('Create A New Resource'));
$form->addDescription($this->translate('Resources are entities that provide data to Icinga Web 2.'));
$form->setIniConfig(Config::app('resources'));
$form->setRedirectUrl('config/resource');
$form->handleRequest();
@ -311,6 +321,7 @@ class ConfigController extends ActionController
{
$this->assertPermission('system/config/resources');
$form = new ResourceConfigForm();
$form->setTitle($this->translate('Edit Existing Resource'));
$form->setIniConfig(Config::app('resources'));
$form->setRedirectUrl('config/resource');
$form->handleRequest();
@ -345,6 +356,7 @@ class ConfigController extends ActionController
}
}
));
$form->setTitle($this->translate('Remove Existing Resource'));
$form->setRedirectUrl('config/resource');
$form->handleRequest();
@ -353,7 +365,7 @@ class ConfigController extends ActionController
$authConfig = Config::app('authentication');
foreach ($authConfig as $backendName => $config) {
if ($config->get('resource') === $resource) {
$form->addError(sprintf(
$form->addDescription(sprintf(
$this->translate(
'The resource "%s" is currently in use by the authentication backend "%s". ' .
'Removing the resource can result in noone being able to log in any longer.'

View File

@ -66,6 +66,7 @@ class DashboardController extends ActionController
Notification::success(t('Dashlet created'));
return true;
});
$form->setTitle($this->translate('Add Dashlet To Dashboard'));
$form->setRedirectUrl('dashboard');
$form->handleRequest();
$this->view->form = $form;
@ -128,6 +129,7 @@ class DashboardController extends ActionController
Notification::success(t('Dashlet updated'));
return true;
});
$form->setTitle($this->translate('Edit Dashlet'));
$form->setRedirectUrl('dashboard/settings');
$form->handleRequest();
$pane = $dashboard->getPane($this->getParam('pane'));
@ -176,6 +178,7 @@ class DashboardController extends ActionController
}
return false;
});
$form->setTitle($this->translate('Remove Dashlet From Dashboard'));
$form->setRedirectUrl('dashboard/settings');
$form->handleRequest();
$this->view->pane = $pane;
@ -215,6 +218,7 @@ class DashboardController extends ActionController
}
return false;
});
$form->setTitle($this->translate('Remove Dashboard'));
$form->setRedirectUrl('dashboard/settings');
$form->handleRequest();
$this->view->pane = $pane;
@ -249,8 +253,9 @@ class DashboardController extends ActionController
$this->view->tabs->add(
'Add',
array(
'title' => '+',
'url' => Url::fromPath('dashboard/new-dashlet')
'label' => '+',
'title' => 'Add a dashlet to an existing or new dashboard',
'url' => Url::fromPath('dashboard/new-dashlet')
)
);
$this->view->dashboard = $this->dashboard;

View File

@ -86,6 +86,7 @@ class RolesController extends ActionController
}
));
$role
->setTitle($this->translate('New Role'))
->setSubmitLabel($this->translate('Create Role'))
->setIniConfig(Config::app('roles', true))
->setRedirectUrl('roles')
@ -108,6 +109,7 @@ class RolesController extends ActionController
);
}
$role = new RoleForm();
$role->setTitle(sprintf($this->translate('Update Role %s'), $name));
$role->setSubmitLabel($this->translate('Update Role'));
try {
$role
@ -138,7 +140,6 @@ class RolesController extends ActionController
})
->setRedirectUrl('roles')
->handleRequest();
$this->view->name = $name;
$this->view->form = $role;
}
@ -183,10 +184,10 @@ class RolesController extends ActionController
}
));
$confirmation
->setTitle(sprintf($this->translate('Remove Role %s'), $name))
->setSubmitLabel($this->translate('Remove Role'))
->setRedirectUrl('roles')
->handleRequest();
$this->view->name = $name;
$this->view->form = $confirmation;
}
}

View File

@ -37,3 +37,12 @@ Font license info
Homepage: http://www.entypo.com
## Fontelico
Copyright (C) 2012 by Fontello project
Author: Crowdsourced, for Fontello project
License: SIL (http://scripts.sil.org/OFL)
Homepage: http://fontello.com

View File

@ -6,6 +6,12 @@
"units_per_em": 1000,
"ascent": 850,
"glyphs": [
{
"uid": "9bc2902722abb366a213a052ade360bc",
"css": "spin6",
"code": 59508,
"src": "fontelico"
},
{
"uid": "9dd9e835aebe1060ba7190ad2b2ed951",
"css": "search",

View File

@ -114,4 +114,5 @@
.icon-chart-area:before { content: '\e870'; } /* '' */
.icon-chart-bar:before { content: '\e871'; } /* '' */
.icon-beaker:before { content: '\e872'; } /* '' */
.icon-magic:before { content: '\e873'; } /* '' */
.icon-magic:before { content: '\e873'; } /* '' */
.icon-spin6:before { content: '\e874'; } /* '' */

File diff suppressed because one or more lines are too long

View File

@ -114,4 +114,5 @@
.icon-chart-area { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe870;&nbsp;'); }
.icon-chart-bar { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe871;&nbsp;'); }
.icon-beaker { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe872;&nbsp;'); }
.icon-magic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe873;&nbsp;'); }
.icon-magic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe873;&nbsp;'); }
.icon-spin6 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe874;&nbsp;'); }

View File

@ -125,4 +125,5 @@
.icon-chart-area { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe870;&nbsp;'); }
.icon-chart-bar { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe871;&nbsp;'); }
.icon-beaker { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe872;&nbsp;'); }
.icon-magic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe873;&nbsp;'); }
.icon-magic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe873;&nbsp;'); }
.icon-spin6 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = '&#xe874;&nbsp;'); }

View File

@ -1,10 +1,10 @@
@font-face {
font-family: 'ifont';
src: url('../font/ifont.eot?81587324');
src: url('../font/ifont.eot?81587324#iefix') format('embedded-opentype'),
url('../font/ifont.woff?81587324') format('woff'),
url('../font/ifont.ttf?81587324') format('truetype'),
url('../font/ifont.svg?81587324#ifont') format('svg');
src: url('../font/ifont.eot?6491776');
src: url('../font/ifont.eot?6491776#iefix') format('embedded-opentype'),
url('../font/ifont.woff?6491776') format('woff'),
url('../font/ifont.ttf?6491776') format('truetype'),
url('../font/ifont.svg?6491776#ifont') format('svg');
font-weight: normal;
font-style: normal;
}
@ -14,7 +14,7 @@
@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: 'ifont';
src: url('../font/ifont.svg?81587324#ifont') format('svg');
src: url('../font/ifont.svg?6491776#ifont') format('svg');
}
}
*/
@ -165,4 +165,5 @@
.icon-chart-area:before { content: '\e870'; } /* '' */
.icon-chart-bar:before { content: '\e871'; } /* '' */
.icon-beaker:before { content: '\e872'; } /* '' */
.icon-magic:before { content: '\e873'; } /* '' */
.icon-magic:before { content: '\e873'; } /* '' */
.icon-spin6:before { content: '\e874'; } /* '' */

View File

@ -428,6 +428,9 @@ body {
<div title="Code: 0xe872" class="the-icons span3"><i class="icon-beaker"></i> <span class="i-name">icon-beaker</span><span class="i-code">0xe872</span></div>
<div title="Code: 0xe873" class="the-icons span3"><i class="icon-magic"></i> <span class="i-name">icon-magic</span><span class="i-code">0xe873</span></div>
</div>
<div class="row">
<div title="Code: 0xe874" class="the-icons span3"><i class="icon-spin6 animate-spin"></i> <span class="i-name">icon-spin6</span><span class="i-code">0xe874</span></div>
</div>
</div>
<div class="container footer">Generated by <a href="http://fontello.com">fontello.com</a></div>
</body>

View File

@ -16,6 +16,7 @@ class LoginForm extends Form
*/
public function init()
{
$this->setRequiredCue(null);
$this->setName('form_login');
$this->setSubmitLabel($this->translate('Login'));
}

View File

@ -53,7 +53,7 @@ class ExternalBackendForm extends Form
return @preg_match($value, '') !== false;
});
$callbackValidator->setMessage(
$this->translate('"%value%" is not a valid regular expression'),
$this->translate('"%value%" is not a valid regular expression.'),
Zend_Validate_Callback::INVALID_VALUE
);
$this->addElement(
@ -62,9 +62,10 @@ class ExternalBackendForm extends Form
array(
'label' => $this->translate('Filter Pattern'),
'description' => $this->translate(
'The regular expression to use to strip specific parts off from usernames.'
. ' Leave empty if you do not want to strip off anything'
'The filter to use to strip specific parts off from usernames.'
. ' Leave empty if you do not want to strip off anything.'
),
'requirement' => $this->translate('The filter pattern must be a valid regular expression.'),
'validators' => array($callbackValidator)
)
);

View File

@ -66,6 +66,7 @@ class LoggingConfigForm extends Form
'description' => $this->translate(
'The name of the application by which to prefix syslog messages.'
),
'requirement' => $this->translate('The application prefix must not contain whitespace.'),
'value' => 'icingaweb2',
'validators' => array(
array(

View File

@ -20,6 +20,7 @@ class GeneralConfigForm extends ConfigForm
{
$this->setName('form_config_general');
$this->setSubmitLabel($this->translate('Save Changes'));
$this->setTitle($this->translate('General Configuration'));
}
/**

View File

@ -3,6 +3,7 @@
namespace Icinga\Forms\Config\Resource;
use Zend_Validate_Callback;
use Icinga\Web\Form;
/**
@ -42,13 +43,22 @@ class FileResourceForm extends Form
'validators' => array('ReadablePathValidator')
)
);
$callbackValidator = new Zend_Validate_Callback(function ($value) {
return @preg_match($value, '') !== false;
});
$callbackValidator->setMessage(
$this->translate('"%value%" is not a valid regular expression.'),
Zend_Validate_Callback::INVALID_VALUE
);
$this->addElement(
'text',
'fields',
array(
'required' => true,
'label' => $this->translate('Pattern'),
'description' => $this->translate('The regular expression by which to identify columns')
'description' => $this->translate('The pattern by which to identify columns.'),
'requirement' => $this->translate('The column pattern must be a valid regular expression.'),
'validators' => array($callbackValidator)
)
);

View File

@ -116,9 +116,9 @@ class DashletForm extends Form
'checkbox',
'create_new_pane',
array(
'autosubmit' => true,
'required' => false,
'label' => $this->translate('New dashboard'),
'class' => 'autosubmit',
'description' => $this->translate('Check this box if you want to add the dashlet to a new dashboard')
)
);

View File

@ -24,51 +24,11 @@ class LdapDiscoveryForm extends Form
'text',
'domain',
array(
'required' => true,
'label' => $this->translate('Search Domain'),
'description' => $this->translate('Search this domain for records of available servers.'),
)
);
if (false) {
$this->addElement(
'note',
'additional_description',
array(
'value' => $this->translate('No Ldap servers found on this domain.'
. ' You can try to specify host and port and try again, or just skip this step and '
. 'configure the server manually.'
)
)
);
$this->addElement(
'text',
'hostname',
array(
'required' => false,
'label' => $this->translate('Host'),
'description' => $this->translate('IP or hostname to search.'),
)
);
$this->addElement(
'text',
'port',
array(
'required' => false,
'label' => $this->translate('Port'),
'description' => $this->translate('Port', 389),
)
);
}
return $this;
}
public function isValid($data)
{
if (false === parent::isValid($data)) {
return false;
}
return true;
}
}

View File

@ -40,6 +40,7 @@ class PreferenceForm extends Form
public function init()
{
$this->setName('form_config_preferences');
$this->setTitle($this->translate('Preferences'));
}
/**

View File

@ -29,7 +29,16 @@ if ($notifications->hasMessages()) {
}
?></ul>
<div id="logo" data-base-target="_main">
<img aria-hidden="true" src="<?= $this->href('img/logo_icinga-inv.png') ?>" class="logo" alt="<?= t('Dashboard') ?>" />
<?= $this->qlink(
'',
'/dashboard',
null,
array(
'icon' => '../logo_icinga-inv.png',
'aria-hidden' => 'true',
'tabindex' => -1
)
); ?>
</div>
</div>

View File

@ -0,0 +1,12 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
/**
* Class Zend_View_Helper_Util
*/
class Zend_View_Helper_ProtectId extends Zend_View_Helper_Abstract
{
public function protectId($id) {
return Zend_Controller_Front::getInstance()->getRequest()->protectId($id);
}
}

View File

@ -18,7 +18,7 @@
'</a>'
); ?></p>
<?php elseif ($requiresExternalAuth): ?>
<p class="info-box"><?= $this->icon('icon-info'); ?><?= $this->translate(
<p class="info-box"><?= $this->icon('info'); ?><?= $this->translate(
'You\'re currently not authenticated using any of the web server\'s authentication mechanisms.'
. ' Make sure you\'ll configure such, otherwise you\'ll not be able to login.'
); ?></p>

View File

@ -2,9 +2,6 @@
<?= $this->tabs->render($this); ?>
</div>
<div class="content">
<h1 tabindex="-1" id="application-configuration">
<?= $this->translate('General Configuration'); ?>
</h1>
<?php if (isset($this->messageBox)): ?>
<?= $this->messageBox->render() ?>
<?php endif ?>

View File

@ -2,15 +2,5 @@
<?= $this->tabs->showOnlyCloseButton() ?>
</div>
<div class="content">
<h1 tabindex="-1" id="authentication-create">
<?= $this->translate('Create New Authentication Backend'); ?>
</h1>
<p>
<?= $this->translate(
'Create a new backend for authenticating your users. This backend will be added at the end of your authentication order.'
); ?>
</p>
<div>
<?= $form; ?>
</div>
</div>
<?= $form; ?>
</div>

View File

@ -2,10 +2,5 @@
<?= $this->tabs->showOnlyCloseButton() ?>
</div>
<div class="content">
<h1 tabindex="-1" id="authentication-modify">
<?= $this->translate('Edit Backend'); ?>
</h1>
<div>
<?= $form; ?>
</div>
<?= $form; ?>
</div>

View File

@ -2,10 +2,5 @@
<?= $this->tabs->showOnlyCloseButton() ?>
</div>
<div class="content">
<h1 tabindex="-1" id="authentication-remove">
<?= $this->translate('Remove Backend'); ?>
</h1>
<div>
<?= $form; ?>
</div>
<?= $form; ?>
</div>

View File

@ -2,7 +2,7 @@
<?= $tabs; ?>
</div>
<div class="content" data-base-target="_next">
<h1 tabindex="-1" id="authentication-reorder">
<h1 tabindex="-1" id="authentication-configuration">
<?= $this->translate('Authentication Configuration'); ?>
</h1>
<h2 tabindex="-1" id="authentication-new-backend" class="sr-only">

View File

@ -2,9 +2,6 @@
<?= $this->tabs ?>
</div>
<div class="content">
<h1 tabindex="-1">
<?= $this->escape($module->getTitle()) ?>
</h1>
<?php if (! $module): ?>
<?= $this->translate('There is no such module installed.') ?>
<?php return; endif ?>
@ -14,6 +11,9 @@
$permissions = $module->getProvidedPermissions();
$state = $moduleData->enabled ? ($moduleData->loaded ? 'enabled' : 'failed') : 'disabled'
?>
<h1 tabindex="-1">
<?= $this->escape($module->getTitle()) ?>
</h1>
<table class="avp">
<tr>
<th><?= $this->escape($this->translate('Name')) ?></th>

View File

@ -42,7 +42,7 @@
'config/removeresource',
array('resource' => $name),
array(
'icon' => 'cancel',
'icon' => 'trash',
'title' => sprintf($this->translate('Remove resource %s'), $name)
)
); ?>

View File

@ -2,11 +2,5 @@
<?= $this->tabs->showOnlyCloseButton() ?>
</div>
<div class="content">
<h1 tabindex="-1" id="resource-create">
<?= $this->translate('Create A New Resource'); ?>
</h1>
<p><?= $this->translate('Resources are entities that provide data to Icinga Web 2.'); ?></p>
<div>
<?= $form; ?>
</div>
<?= $form; ?>
</div>

View File

@ -2,10 +2,5 @@
<?= $this->tabs->showOnlyCloseButton() ?>
</div>
<div class="content">
<h1 tabindex="-1" id="resource-edit">
<?= $this->translate('Edit Existing Resource'); ?>
</h1>
<div>
<?= $form; ?>
</div>
<?= $form; ?>
</div>

View File

@ -2,10 +2,5 @@
<?= $this->tabs->showOnlyCloseButton() ?>
</div>
<div class="content">
<h1 tabindex="-1" id="resource-remove">
<?= $this->translate('Remove Existing Resource'); ?>
</h1>
<div>
<?= $form; ?>
</div>
<?= $form; ?>
</div>

View File

@ -2,6 +2,5 @@
<?= $this->tabs ?>
</div>
<div class="content">
<h1><?= t('Add Dashlet To Dashboard'); ?></h1>
<?= $this->form; ?>
</div>

View File

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

View File

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

View File

@ -28,7 +28,7 @@
'dashboard/remove-pane',
array('pane' => $pane->getName()),
array(
'icon' => 'cancel',
'icon' => 'trash',
'title' => sprintf($this->translate('Remove pane %s'), $pane->getName())
)
); ?>
@ -67,7 +67,7 @@
'dashboard/remove-dashlet',
array('pane' => $pane->getName(), 'dashlet' => $dashlet->getTitle()),
array(
'icon' => 'cancel',
'icon' => 'trash',
'title' => sprintf($this->translate('Remove dashlet %s from pane %s'), $dashlet->getTitle(), $pane->getName())
)
); ?>

View File

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

View File

@ -1,4 +1,4 @@
<form data-base-target="_self" id="<?= $form->getName(); ?>" name="<?= $form->getName(); ?>" enctype="<?= $form->getEncType(); ?>" method="<?= $form->getMethod(); ?>" action="<?= $form->getAction(); ?>">
<form id="<?= $form->getId(); ?>" name="<?= $form->getName(); ?>" enctype="<?= $form->getEncType(); ?>" method="<?= $form->getMethod(); ?>" action="<?= $form->getAction(); ?>">
<table class="action">
<thead>
<th>Backend</th>
@ -26,12 +26,12 @@
'config/removeAuthenticationBackend',
array('auth_backend' => $backendNames[$i]),
array(
'icon' => 'cancel',
'icon' => 'trash',
'title' => sprintf($this->translate('Remove authentication backend %s'), $backendNames[$i])
)
); ?>
</td>
<td>
<td data-base-target="_self">
<?php if ($i > 0): ?>
<button type="submit" name="backend_newpos" value="<?= sprintf(
'%s|%s',

View File

@ -9,8 +9,8 @@ use Icinga\Web\Url;
if ($this->pageCount <= 1) return;
?><p id="paginationlabel" class="audible"><?= t('Pagination') ?></p>
<ul class="pagination" aria-labelledby="paginationlabel" role="navigation"
?><p id="<?= $this->protectId('paginationlabel'); ?>" class="audible"><?= t('Pagination') ?></p>
<ul class="pagination" aria-labelledby="<?= $this->protectId('paginationlabel'); ?>" role="navigation"
<?php
$fromto = t('Show rows %u to %u out of %u');

View File

@ -2,6 +2,5 @@
<?= $tabs; ?>
</div>
<div class="content">
<h1 tabindex="-1" id="preferences"><?= $this->translate('Preferences'); ?></h1>
<?= $form; ?>
</div>

View File

@ -60,7 +60,7 @@
'roles/remove',
array('role' => $name),
array(
'icon' => 'cancel',
'icon' => 'trash',
'title' => sprintf($this->translate('Remove role %s'), $name)
)
); ?>

View File

@ -2,8 +2,5 @@
<?= $tabs->showOnlyCloseButton() ?>
</div>
<div class="content">
<h1 tabindex="-1" id="roles-new">
<?= $this->translate('New Role') ?>
</h1>
<?= $form ?>
</div>
</div>

View File

@ -2,8 +2,5 @@
<?= $tabs->showOnlyCloseButton() ?>
</div>
<div class="content">
<h1 tabindex="-1" id="roles-remove">
<?= sprintf($this->translate('Remove Role %s'), $name) ?>
</h1>
<?= $form ?>
</div>
</div>

View File

@ -2,8 +2,5 @@
<?= $tabs->showOnlyCloseButton() ?>
</div>
<div class="content">
<h1 tabindex="-1" id="roles-update">
<?= sprintf($this->translate('Update Role %s'), $name) ?>
</h1>
<?= $form ?>
</div>
</div>

View File

@ -252,7 +252,7 @@ class Manager
}
/**
* Disable the given module and remove it's enabled state
* Disable the given module and remove its enabled state
*
* @param string $name The name of the module to disable
*

View File

@ -113,6 +113,13 @@ class Module
*/
private $triedToLaunchConfigScript = false;
/**
* Whether this module has been registered
*
* @var bool
*/
private $registered = false;
/**
* Provided permissions
*
@ -279,6 +286,10 @@ class Module
*/
public function register()
{
if ($this->registered) {
return true;
}
$this->registerAutoloader();
try {
$this->launchRunScript();
@ -291,10 +302,22 @@ class Module
);
return false;
}
$this->registerWebIntegration();
$this->registered = true;
return true;
}
/**
* Return whether this module has been registered
*
* @return bool
*/
public function isRegistered()
{
return $this->registered;
}
/**
* Test for an enabled module by name
*
@ -913,7 +936,7 @@ class Module
*/
protected function launchConfigScript()
{
if ($this->triedToLaunchConfigScript) {
if ($this->triedToLaunchConfigScript || !$this->registered) {
return;
}
$this->triedToLaunchConfigScript = true;

View File

@ -314,12 +314,12 @@ class Web extends ApplicationBootstrap
protected function detectLocale()
{
$auth = Manager::getInstance();
if (! $auth->isAuthenticated()
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) && !$auth->isAuthenticated()
|| ($locale = $auth->getUser()->getPreferences()->getValue('icingaweb', 'language')) === null
&& isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])
) {
$locale = Translator::getPreferredLocaleCode($_SERVER['HTTP_ACCEPT_LANGUAGE']);
}
return $locale;
}

View File

@ -96,10 +96,15 @@ class DbUserBackend extends UserBackend
'SELECT password_hash FROM icingaweb_user WHERE name = :name AND active = 1'
);
}
$stmt->execute(array(':name' => $username));
$stmt->bindColumn(1, $lob, PDO::PARAM_LOB);
$stmt->fetch(PDO::FETCH_BOUND);
return is_resource($lob) ? stream_get_contents($lob) : $lob;
if (is_resource($lob)) {
$lob = stream_get_contents($lob);
}
return $this->conn->getDbType() === 'pgsql' ? pg_unescape_bytea($lob) : $lob;
}
/**

View File

@ -16,7 +16,7 @@ use Icinga\Chart\Unit\LinearUnit;
/**
* Axis class for the GridChart class.
*
* Implements drawing functions for the axis and it's labels but delegates tick and label calculations
* Implements drawing functions for the axis and its labels but delegates tick and label calculations
* to the AxisUnit implementations
*
* @see GridChart

View File

@ -0,0 +1,210 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Protocol\Ldap;
/**
* The properties and capabilities of an LDAP server
*
* Provides information about the available encryption mechanisms (StartTLS), the supported
* LDAP protocol (v2/v3), vendor-specific extensions or protocols controls and extensions.
*/
class Capability {
const LDAP_SERVER_START_TLS_OID = '1.3.6.1.4.1.1466.20037';
const LDAP_PAGED_RESULT_OID_STRING = '1.2.840.113556.1.4.319';
const LDAP_SERVER_SHOW_DELETED_OID = '1.2.840.113556.1.4.417';
const LDAP_SERVER_SORT_OID = '1.2.840.113556.1.4.473';
const LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID = '1.2.840.113556.1.4.521';
const LDAP_SERVER_NOTIFICATION_OID = '1.2.840.113556.1.4.528';
const LDAP_SERVER_EXTENDED_DN_OID = '1.2.840.113556.1.4.529';
const LDAP_SERVER_LAZY_COMMIT_OID = '1.2.840.113556.1.4.619';
const LDAP_SERVER_SD_FLAGS_OID = '1.2.840.113556.1.4.801';
const LDAP_SERVER_TREE_DELETE_OID = '1.2.840.113556.1.4.805';
const LDAP_SERVER_DIRSYNC_OID = '1.2.840.113556.1.4.841';
const LDAP_SERVER_VERIFY_NAME_OID = '1.2.840.113556.1.4.1338';
const LDAP_SERVER_DOMAIN_SCOPE_OID = '1.2.840.113556.1.4.1339';
const LDAP_SERVER_SEARCH_OPTIONS_OID = '1.2.840.113556.1.4.1340';
const LDAP_SERVER_PERMISSIVE_MODIFY_OID = '1.2.840.113556.1.4.1413';
const LDAP_SERVER_ASQ_OID = '1.2.840.113556.1.4.1504';
const LDAP_SERVER_FAST_BIND_OID = '1.2.840.113556.1.4.1781';
const LDAP_CONTROL_VLVREQUEST = '2.16.840.1.113730.3.4.9';
// MS Capabilities, Source: http://msdn.microsoft.com/en-us/library/cc223359.aspx
// Running Active Directory as AD DS
const LDAP_CAP_ACTIVE_DIRECTORY_OID = '1.2.840.113556.1.4.800';
// Capable of signing and sealing on an NTLM authenticated connection
// and of performing subsequent binds on a signed or sealed connection
const LDAP_CAP_ACTIVE_DIRECTORY_LDAP_INTEG_OID = '1.2.840.113556.1.4.1791';
// If AD DS: running at least W2K3, if AD LDS running at least W2K8
const LDAP_CAP_ACTIVE_DIRECTORY_V51_OID = '1.2.840.113556.1.4.1670';
// If AD LDS: accepts DIGEST-MD5 binds for AD LDSsecurity principals
const LDAP_CAP_ACTIVE_DIRECTORY_ADAM_DIGEST = '1.2.840.113556.1.4.1880';
// Running Active Directory as AD LDS
const LDAP_CAP_ACTIVE_DIRECTORY_ADAM_OID = '1.2.840.113556.1.4.1851';
// If AD DS: it's a Read Only DC (RODC)
const LDAP_CAP_ACTIVE_DIRECTORY_PARTIAL_SECRETS_OID = '1.2.840.113556.1.4.1920';
// Running at least W2K8
const LDAP_CAP_ACTIVE_DIRECTORY_V60_OID = '1.2.840.113556.1.4.1935';
// Running at least W2K8r2
const LDAP_CAP_ACTIVE_DIRECTORY_V61_R2_OID = '1.2.840.113556.1.4.2080';
// Running at least W2K12
const LDAP_CAP_ACTIVE_DIRECTORY_W8_OID = '1.2.840.113556.1.4.2237';
/**
* Attributes of the LDAP Server returned by the discovery query
*
* @var StdClass
*/
private $attributes;
/**
* Map of supported available OIDS
*
* @var array
*/
private $oids = array();
/**
* Construct a new capability
*
* @param $attributes StdClass The attributes returned, may be null for guessing default capabilities
*/
public function __construct($attributes = null)
{
$this->attributes = $attributes;
$keys = array('supportedControl', 'supportedExtension', 'supportedFeatures', 'supportedCapabilities');
foreach ($keys as $key) {
if (isset($attributes->$key)) {
if (is_array($attributes->$key)) {
foreach ($attributes->$key as $oid) {
$this->oids[$oid] = true;
}
} else {
$this->oids[$attributes->$key] = true;
}
}
}
}
/**
* Return if the capability object contains support for StartTLS
*
* @return bool Whether StartTLS is supported
*/
public function hasStartTLS()
{
return isset($this->oids[self::LDAP_SERVER_START_TLS_OID]);
}
/**
* Return if the capability object contains support for StartTLS
*
* @return bool Whether StartTLS is supported
*/
public function hasPagedResult()
{
return isset($this->oids[self::LDAP_PAGED_RESULT_OID_STRING]);
}
/**
* Whether the ldap server is an ActiveDirectory server
*
* @return boolean
*/
public function hasAdOid()
{
return isset($this->oids[self::LDAP_CAP_ACTIVE_DIRECTORY_OID]);
}
/**
* Return if the capability objects contains support for LdapV3, defaults to true if discovery failed
*
* @return bool
*/
public function hasLdapV3()
{
if (! isset($this->attributes) || ! isset($this->attributes->supportedLDAPVersion)) {
// Default to true, if unknown
return true;
}
return (is_string($this->attributes->supportedLDAPVersion)
&& (int) $this->attributes->supportedLDAPVersion === 3)
|| (is_array($this->attributes->supportedLDAPVersion)
&& in_array(3, $this->attributes->supportedLDAPVersion));
}
/**
* Whether the capability with the given OID is supported
*
* @param $oid string The OID of the capability
*
* @return bool
*/
public function hasOid($oid)
{
return isset($this->oids[$oid]);
}
/**
* Get the default naming context
*
* @return string|null the default naming context, or null when no contexts are available
*/
public function getDefaultNamingContext()
{
// defaultNamingContext entry has higher priority
if (isset($this->attributes->defaultNamingContext)) {
return $this->attributes->defaultNamingContext;
}
// if its missing use namingContext
$namingContexts = $this->namingContexts();
return empty($namingContexts) ? null : $namingContexts[0];
}
/**
* Fetch the namingContexts
*
* @return array the available naming contexts
*/
public function namingContexts()
{
if (!isset($this->attributes->namingContexts)) {
return array();
}
if (!is_array($this->attributes->namingContexts)) {
return array($this->attributes->namingContexts);
}
return$this->attributes->namingContexts;
}
}

View File

@ -44,47 +44,6 @@ class Connection
protected $root_dn;
protected $count;
protected $ldap_extension = array(
'1.3.6.1.4.1.1466.20037' => 'STARTTLS',
// '1.3.6.1.4.1.4203.1.11.1' => '11.1', // PASSWORD_MODIFY
// '1.3.6.1.4.1.4203.1.11.3' => '11.3', // Whoami
// '1.3.6.1.1.8' => '8', // Cancel Extended Request
);
protected $ms_capability = array(
// Prefix LDAP_CAP_
// Source: http://msdn.microsoft.com/en-us/library/cc223359.aspx
// Running Active Directory as AD DS:
'1.2.840.113556.1.4.800' => 'ACTIVE_DIRECTORY_OID',
// Capable of signing and sealing on an NTLM authenticated connection
// and of performing subsequent binds on a signed or sealed connection.
'1.2.840.113556.1.4.1791' => 'ACTIVE_DIRECTORY_LDAP_INTEG_OID',
// If AD DS: running at least W2K3, if AD LDS running at least W2K8
'1.2.840.113556.1.4.1670' => 'ACTIVE_DIRECTORY_V51_OID',
// If AD LDS: accepts DIGEST-MD5 binds for AD LDSsecurity principals
'1.2.840.113556.1.4.1880' => 'ACTIVE_DIRECTORY_ADAM_DIGEST',
// Running Active Directory as AD LDS
'1.2.840.113556.1.4.1851' => 'ACTIVE_DIRECTORY_ADAM_OID',
// If AD DS: it's a Read Only DC (RODC)
'1.2.840.113556.1.4.1920' => 'ACTIVE_DIRECTORY_PARTIAL_SECRETS_OID',
// Running at least W2K8
'1.2.840.113556.1.4.1935' => 'ACTIVE_DIRECTORY_V60_OID',
// Running at least W2K8r2
'1.2.840.113556.1.4.2080' => 'ACTIVE_DIRECTORY_V61_R2_OID',
// Running at least W2K12
'1.2.840.113556.1.4.2237' => 'ACTIVE_DIRECTORY_W8_OID',
);
/**
* Whether the bind on this connection was already performed
*
@ -94,11 +53,14 @@ class Connection
protected $root;
protected $supports_v3 = false;
protected $supports_tls = false;
/**
* @var Capability
*/
protected $capabilities;
protected $namingContexts;
/**
* @var bool
*/
protected $discoverySuccess = false;
/**
@ -337,7 +299,9 @@ class Connection
*/
protected function pageControlAvailable(Query $query)
{
return $query->getUsePagedResults() && version_compare(PHP_VERSION, '5.4.0') >= 0;
return $this->capabilities->hasPagedResult() &&
$query->getUsePagedResults() &&
version_compare(PHP_VERSION, '5.4.0') >= 0;
}
/**
@ -375,7 +339,7 @@ class Connection
$entries = array();
do {
// do not set controlPageResult as a critical extension, since we still want the
// server to return an answer in case the pagination extension is missing.
// possibillity server to return an answer in case the pagination extension is missing.
ldap_control_paged_result($this->ds, $pageSize, false, $cookie);
$results = @ldap_search($this->ds, $base, $queryString, $fields, 0, $limit ? $offset + $limit : 0);
@ -415,7 +379,7 @@ class Connection
}
} while (($limit === 0 || $limit !== count($entries)) && ($entry = ldap_next_entry($this->ds, $entry)));
if (false === ldap_control_paged_result_response($this->ds, $results, $cookie)) {
if (false === @ldap_control_paged_result_response($this->ds, $results, $cookie)) {
// If the page size is greater than or equal to the sizeLimit value, the server should ignore the
// control as the request can be satisfied in a single page: https://www.ietf.org/rfc/rfc2696.txt
// This applies no matter whether paged search requests are permitted or not. You're done once you
@ -507,7 +471,6 @@ class Connection
protected function prepareNewConnection()
{
$use_tls = false;
$force_tls = true;
$force_tls = false;
if ($use_tls) {
@ -516,24 +479,18 @@ class Connection
$ds = ldap_connect($this->hostname, $this->port);
try {
$capabilities = $this->discoverCapabilities($ds);
list($cap, $namingContexts) = $capabilities;
$this->capabilities = $this->discoverCapabilities($ds);
$this->discoverySuccess = true;
} catch (LdapException $e) {
// discovery failed, guess defaults
$cap = (object) array(
'supports_ldapv3' => true,
'supports_starttls' => false,
'msCapabilities' => array()
);
$namingContexts = null;
// create empty default capabilities
Logger::warning('LADP discovery failed, assuming default LDAP settings.');
$this->capabilities = new Capability();
}
$this->capabilities = $cap;
$this->namingContexts = $namingContexts;
if ($use_tls) {
if ($cap->supports_starttls) {
if ($this->capabilities->hasStartTLS()) {
if (@ldap_start_tls($ds)) {
Logger::debug('LDAP STARTTLS succeeded');
} else {
@ -549,11 +506,11 @@ class Connection
$this->hostname
);
} else {
// TODO: Log noticy -> TLS enabled but not announced
Logger::warning('LDAP TLS enabled but not announced');
}
}
// ldap_rename requires LDAPv3:
if ($cap->supports_ldapv3) {
if ($this->capabilities->hasLdapV3()) {
if (! ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3)) {
throw new LdapException('LDAPv3 is required');
}
@ -591,141 +548,15 @@ class Connection
}
/**
* Return if the capability object contains support for StartTLS
* Get the capabilities of the connected server
*
* @param $cap The object containing the capabilities
*
* @return bool Whether StartTLS is supported
*/
protected function hasCapabilityStartTLS($cap)
{
$cap = $this->getExtensionCapabilities($cap);
return isset($cap['1.3.6.1.4.1.1466.20037']);
}
/**
* Return if the capability objects contains support for LdapV3
*
* @param $cap
*
* @return bool
*/
protected function hasCapabilityLdapV3($cap)
{
if ((is_string($cap->supportedLDAPVersion)
&& (int) $cap->supportedLDAPVersion === 3)
|| (is_array($cap->supportedLDAPVersion)
&& in_array(3, $cap->supportedLDAPVersion)
)) {
return true;
}
return false;
}
/**
* Extract an array of all extension capabilities from the given ldap response
*
* @param $cap object The response returned by a ldap_search discovery query
*
* @return object The extracted capabilities.
*/
protected function getExtensionCapabilities($cap)
{
$extensions = array();
if (isset($cap->supportedExtension)) {
foreach ($cap->supportedExtension as $oid) {
if (array_key_exists($oid, $this->ldap_extension)) {
if ($this->ldap_extension[$oid] === 'STARTTLS') {
$extensions['1.3.6.1.4.1.1466.20037'] = $this->ldap_extension['1.3.6.1.4.1.1466.20037'];
}
}
}
}
return $extensions;
}
/**
* Extract an array of all MSAD capabilities from the given ldap response
*
* @param $cap object The response returned by a ldap_search discovery query
*
* @return object The extracted capabilities.
*/
protected function getMsCapabilities($cap)
{
$ms = array();
foreach ($this->ms_capability as $name) {
$ms[$this->convName($name)] = false;
}
if (isset($cap->supportedCapabilities)) {
foreach ($cap->supportedCapabilities as $oid) {
if (array_key_exists($oid, $this->ms_capability)) {
$ms[$this->convName($this->ms_capability[$oid])] = true;
}
}
}
return (object)$ms;
}
/**
* Convert a single capability name entry into camel-case
*
* @param $name string The name to convert
*
* @return string The name in camel-case
*/
private function convName($name)
{
$parts = explode('_', $name);
foreach ($parts as $i => $part) {
$parts[$i] = ucfirst(strtolower($part));
}
return implode('', $parts);
}
/**
* Get the capabilities of this ldap server
*
* @return stdClass An object, providing the flags 'ldapv3' and 'starttls' to indicate LdapV3 and StartTLS
* support and an additional property 'msCapabilities', containing all supported active directory capabilities.
* @return Capability The capability object
*/
public function getCapabilities()
{
return $this->capabilities;
}
/**
* Get the default naming context of this ldap connection
*
* @return string|null the default naming context, or null when no contexts are available
*/
public function getDefaultNamingContext()
{
$cap = $this->capabilities;
if (isset($cap->defaultNamingContext)) {
return $cap->defaultNamingContext;
}
$namingContexts = $this->namingContexts($cap);
return empty($namingContexts) ? null : $namingContexts[0];
}
/**
* Fetch the namingContexts for this Ldap-Connection
*
* @return array the available naming contexts
*/
public function namingContexts()
{
if (!isset($this->namingContexts)) {
return array();
}
if (!is_array($this->namingContexts)) {
return array($this->namingContexts);
}
return $this->namingContexts;
}
/**
* Whether service discovery was successful
*
@ -742,7 +573,7 @@ class Connection
*
* @param resource $ds The link identifier of the current ldap connection
*
* @return array The capabilities and naming-contexts
* @return Capability The capabilities
* @throws LdapException When the capability query fails
*/
protected function discoverCapabilities($ds)
@ -759,6 +590,7 @@ class Connection
'schemaNamingContext',
'supportedLDAPVersion', // => array(3, 2)
'supportedCapabilities',
'supportedControl',
'supportedExtension',
'+'
)
@ -789,19 +621,9 @@ class Connection
);
}
$cap = (object) array(
'supports_ldapv3' => false,
'supports_starttls' => false,
'msCapabilities' => array()
);
$ldapAttributes = ldap_get_attributes($ds, $entry);
$result = $this->cleanupAttributes($ldapAttributes);
$cap->supports_ldapv3 = $this->hasCapabilityLdapV3($result);
$cap->supports_starttls = $this->hasCapabilityStartTLS($result);
$cap->msCapabilities = $this->getMsCapabilities($result);
return array($cap, $result->namingContexts);
return new Capability($result);
}
/**

View File

@ -54,7 +54,7 @@ class Discovery {
return array(
'hostname' => $this->connection->getHostname(),
'port' => $this->connection->getPort(),
'root_dn' => $this->connection->getDefaultNamingContext()
'root_dn' => $this->connection->getCapabilities()->getDefaultNamingContext()
);
}
@ -69,14 +69,14 @@ class Discovery {
$this->execDiscovery();
if ($this->isAd()) {
return array(
'base_dn' => $this->connection->getDefaultNamingContext(),
'base_dn' => $this->connection->getCapabilities()->getDefaultNamingContext(),
'user_class' => 'user',
'user_name_attribute' => 'sAMAccountName'
);
} else {
return array(
'base_dn' => $this->connection->getDefaultNamingContext(),
'user_class' => 'getDefaultNamingContext',
'base_dn' => $this->connection->getCapabilities()->getDefaultNamingContext(),
'user_class' => 'inetOrgPerson',
'user_name_attribute' => 'uid'
);
}
@ -90,8 +90,7 @@ class Discovery {
public function isAd()
{
$this->execDiscovery();
$caps = $this->connection->getCapabilities();
return isset($caps->msCapabilities->ActiveDirectoryOid) && $caps->msCapabilities->ActiveDirectoryOid;
return $this->connection->getCapabilities()->hasAdOid();
}
/**

View File

@ -203,12 +203,14 @@ class DbStore extends PreferencesStore
foreach ($preferences as $key => $value) {
$db->update(
$this->table,
array(self::COLUMN_VALUE => $value),
array(
self::COLUMN_VALUE => $value,
self::COLUMN_MODIFIED_TIME => new Zend_Db_Expr('NOW()')
),
array(
self::COLUMN_USERNAME . '=?' => $this->getUser()->getUsername(),
$db->quoteIdentifier(self::COLUMN_SECTION) . '=?' => $section,
$db->quoteIdentifier(self::COLUMN_PREFERENCE) . '=?' => $key,
self::COLUMN_MODIFIED_TIME => new Zend_Db_Expr('NOW()')
$db->quoteIdentifier(self::COLUMN_PREFERENCE) . '=?' => $key
)
);
}

View File

@ -27,7 +27,7 @@ class BasePreferenceController extends ActionController
}
/**
* Initialize the controller and collect all tabs for it from the application and it's modules
* Initialize the controller and collect all tabs for it from the application and its modules
*
* @see ActionController::init()
*/

View File

@ -13,7 +13,7 @@ use Icinga\Authentication\Manager;
use Icinga\Security\SecurityException;
use Icinga\Util\Translator;
use Icinga\Web\Form\ErrorLabeller;
use Icinga\Web\Form\Decorator\NoScriptApply;
use Icinga\Web\Form\Decorator\Autosubmit;
use Icinga\Web\Form\Element\CsrfCounterMeasure;
/**
@ -112,6 +112,36 @@ class Form extends Zend_Form
*/
protected $validatePartial = false;
/**
* Whether element ids will be protected against collisions by appending a request-specific unique identifier
*
* @var bool
*/
protected $protectIds = true;
/**
* The cue that is appended to each element's label if it's required
*
* @var string
*/
protected $requiredCue = '*';
/**
* The descriptions of this form
*
* @var array
*/
protected $descriptions;
/**
* Whether the Autosubmit decorator should be applied to this form
*
* If this is true, the Autosubmit decorator is being applied to this form instead of to each of its elements.
*
* @var bool
*/
protected $useFormAutosubmit = false;
/**
* Authentication manager
*
@ -127,6 +157,7 @@ class Form extends Zend_Form
public static $defaultElementDecorators = array(
array('ViewHelper', array('separator' => '')),
array('Errors', array('separator' => '')),
array('Help', array('placement' => 'PREPEND')),
array('Label', array('separator' => '')),
array('HtmlTag', array('tag' => 'div', 'class' => 'element'))
);
@ -375,6 +406,120 @@ class Form extends Zend_Form
return $this->validatePartial;
}
/**
* Set whether each element's id should be altered to avoid duplicates
*
* @param bool $value
*
* @return Form
*/
public function setProtectIds($value = true)
{
$this->protectIds = (bool) $value;
return $this;
}
/**
* Return whether each element's id is being altered to avoid duplicates
*
* @return bool
*/
public function getProtectIds()
{
return $this->protectIds;
}
/**
* Set the cue to append to each element's label if it's required
*
* @param string $cue
*
* @return Form
*/
public function setRequiredCue($cue)
{
$this->requiredCue = $cue;
return $this;
}
/**
* Return the cue being appended to each element's label if it's required
*
* @return string
*/
public function getRequiredCue()
{
return $this->requiredCue;
}
/**
* Set the descriptions for this form
*
* @param array $descriptions
*
* @return Form
*/
public function setDescriptions(array $descriptions)
{
$this->descriptions = $descriptions;
return $this;
}
/**
* Add a description for this form
*
* If $description is an array the second value should be
* an array as well containing additional HTML properties.
*
* @param string|array $description
*
* @return Form
*/
public function addDescription($description)
{
$this->descriptions[] = $description;
return $this;
}
/**
* Return the descriptions of this form
*
* @return array
*/
public function getDescriptions()
{
if ($this->descriptions === null) {
return array();
}
return $this->descriptions;
}
/**
* Set whether the Autosubmit decorator should be applied to this form
*
* If true, the Autosubmit decorator is being applied to this form instead of to each of its elements.
*
* @param bool $state
*
* @return Form
*/
public function setUseFormAutosubmit($state = true)
{
$this->useFormAutosubmit = (bool) $state;
return $this;
}
/**
* Return whether the Autosubmit decorator is being applied to this form
*
* @return bool
*/
public function getUseFormAutosubmit()
{
return $this->useFormAutosubmit;
}
/**
* Create this form
*
@ -477,7 +622,7 @@ class Form extends Zend_Form
public function addSubForm(Zend_Form $form, $name = null, $order = null)
{
if ($form instanceof self) {
$form->removeDecorator('Form');
$form->setDecorators(array('FormElements')); // TODO: Makes it difficult to customise subform decorators..
$form->setSubmitLabel('');
$form->setTokenDisabled();
$form->setUidDisabled();
@ -531,23 +676,42 @@ class Form extends Zend_Form
)
));
if (($description = $el->getDescription()) !== null && ($label = $el->getDecorator('label')) !== false) {
$label->setOptions(array(
'title' => $description,
'class' => 'has-feedback'
));
if ($this->protectIds) {
$el->setAttrib('id', $this->getRequest()->protectId($this->getId(false) . '_' . $el->getId()));
}
if ($el->getAttrib('autosubmit')) {
$noScript = new NoScriptApply(); // Non-JS environments
if ($this->getUseFormAutosubmit()) {
$warningId = 'autosubmit_warning_' . $el->getId();
$warningText = $this->getView()->escape($this->translate(
'Upon its value has changed, this field issues an automatic update of this page.'
));
$autosubmitDecorator = $this->_getDecorator('Callback', array(
'placement' => 'PREPEND',
'callback' => function ($content) use ($warningId, $warningText) {
return '<span class="sr-only" id="' . $warningId . '">' . $warningText . '</span>';
}
));
} else {
$autosubmitDecorator = new Autosubmit();
$autosubmitDecorator->setAccessible();
$warningId = $autosubmitDecorator->getWarningId($el);
}
$decorators = $el->getDecorators();
$pos = array_search('Zend_Form_Decorator_ViewHelper', array_keys($decorators)) + 1;
$el->setDecorators(
array_slice($decorators, 0, $pos, true)
+ array(get_class($noScript) => $noScript)
+ array('autosubmit' => $autosubmitDecorator)
+ array_slice($decorators, $pos, count($decorators) - $pos, true)
);
if (($describedBy = $el->getAttrib('aria-describedby')) !== null) {
$el->setAttrib('aria-describedby', $describedBy . ' ' . $warningId);
} else {
$el->setAttrib('aria-describedby', $warningId);
}
$class = $el->getAttrib('class');
if (is_array($class)) {
$class[] = 'autosubmit';
@ -556,7 +720,7 @@ class Form extends Zend_Form
} else {
$class .= ' autosubmit';
}
$el->setAttrib('class', $class); // JS environments
$el->setAttrib('class', $class);
unset($el->autosubmit);
}
@ -576,6 +740,25 @@ class Form extends Zend_Form
if ($element->isRequired() && strpos(strtolower($element->getType()), 'checkbox') === false) {
$element->setAttrib('aria-required', 'true'); // ARIA
$element->setAttrib('required', ''); // HTML5
if (($cue = $this->getRequiredCue()) !== null && ($label = $element->getDecorator('label')) !== false) {
$element->setLabel($this->getView()->escape($element->getLabel()));
$label->setOption('escape', false);
$label->setRequiredSuffix(sprintf(' <span aria-hidden="true">%s</span>', $cue));
}
}
if ($element->getDescription() !== null && ($help = $element->getDecorator('help')) !== false) {
if (($describedBy = $element->getAttrib('aria-describedby')) !== null) {
// Assume that it's because of the element being of type autosubmit or
// that one who did set the property manually removes the help decorator
// in case it has already an aria-describedby property set
$element->setAttrib(
'aria-describedby',
$help->setAccessible()->getDescriptionId($element) . ' ' . $describedBy
);
} else {
$element->setAttrib('aria-describedby', $help->setAccessible()->getDescriptionId($element));
}
}
return $element;
@ -775,7 +958,14 @@ class Form extends Zend_Form
'form' => $this
));
} else {
$this->addDecorator('Description', array('tag' => 'h1'));
if ($this->getUseFormAutosubmit()) {
$this->addDecorator('Autosubmit', array('accessible' => true))
->addDecorator('HtmlTag', array('tag' => 'div', 'class' => 'header'));
}
$this->addDecorator('FormErrors', array('onlyCustomFormErrors' => true))
->addDecorator('FormDescriptions')
->addDecorator('FormElements')
//->addDecorator('HtmlTag', array('tag' => 'dl', 'class' => 'zend_form'))
->addDecorator('Form');
@ -785,6 +975,21 @@ class Form extends Zend_Form
return $this;
}
/**
* Get element id
*
* Returns the protected id, in case id protection is enabled.
*
* @param bool $protect
*
* @return string
*/
public function getId($protect = true)
{
$id = parent::getId();
return $protect && $this->protectIds ? $this->getRequest()->protectId($id) : $id;
}
/**
* Return the name of this form
*
@ -801,6 +1006,20 @@ class Form extends Zend_Form
return $name;
}
/**
* Set form description
*
* Alias for Zend_Form::setDescription().
*
* @param string $value
*
* @return Form
*/
public function setTitle($value)
{
return $this->setDescription($value);
}
/**
* Return the request associated with this form
*
@ -852,10 +1071,11 @@ class Form extends Zend_Form
protected function getTranslationDomain()
{
$parts = explode('\\', get_called_class());
if ($parts[1] === 'Module') {
if (count($parts) > 1 && $parts[1] === 'Module') {
// Assume format Icinga\Module\ModuleName\Forms\...
return strtolower($parts[2]);
}
return 'icinga';
}

View File

@ -0,0 +1,128 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Web\Form\Decorator;
use Zend_Form_Decorator_Abstract;
use Icinga\Application\Icinga;
use Icinga\Web\View;
use Icinga\Web\Form;
/**
* Decorator to add an icon and a submit button encapsulated in noscript-tags
*
* The icon is shown in JS environments to indicate that a specific form field does automatically request an update
* of its form upon it has changed. The button allows users in non-JS environments to trigger the update manually.
*/
class Autosubmit extends Zend_Form_Decorator_Abstract
{
/**
* Whether a hidden <span> should be created with the same warning as in the icon label
*
* @var bool
*/
protected $accessible;
/**
* The id used to identify the auto-submit warning associated with the decorated form element
*
* @var string
*/
protected $warningId;
/**
* Set whether a hidden <span> should be created with the same warning as in the icon label
*
* @param bool $state
*
* @return Autosubmit
*/
public function setAccessible($state = true)
{
$this->accessible = (bool) $state;
return $this;
}
/**
* Return whether a hidden <span> is being created with the same warning as in the icon label
*
* @return bool
*/
public function getAccessible()
{
if ($this->accessible === null) {
$this->accessible = $this->getOption('accessible') ?: false;
}
return $this->accessible;
}
/**
* Return the id used to identify the auto-submit warning associated with the decorated element
*
* @param mixed $element The element for which to generate a id
*
* @return string
*/
public function getWarningId($element = null)
{
if ($this->warningId === null) {
$element = $element ?: $this->getElement();
$this->warningId = 'autosubmit_warning_' . $element->getId();
}
return $this->warningId;
}
/**
* Return the current view
*
* @return View
*/
protected function getView()
{
return Icinga::app()->getViewRenderer()->view;
}
/**
* Add a auto-submit icon and submit button encapsulated in noscript-tags to the element
*
* @param string $content The html rendered so far
*
* @return string The updated html
*/
public function render($content = '')
{
if ($content) {
$isForm = $this->getElement() instanceof Form;
$warning = $isForm
? t('Upon any of this form\'s fields were changed, this page is being updated automatically.')
: t('Upon its value has changed, this field issues an automatic update of this page.');
$content .= $this->getView()->icon('cw', $warning, array(
'aria-hidden' => $isForm ? 'false' : 'true',
'class' => 'autosubmit-warning'
));
if (! $isForm && $this->getAccessible()) {
$content = '<span id="' . $this->getWarningId() . '" class="sr-only">' . $warning . '</span>' . $content;
}
$content .= sprintf(
'<noscript><button'
. ' name="noscript_apply"'
. ' class="noscript-apply"'
. ' type="submit"'
. ' value="1"'
. ($this->getAccessible() ? ' aria-label="%1$s"' : '')
. ' title="%1$s"'
. '>%2$s</button></noscript>',
$isForm
? t('Push this button to update the form to reflect the changes that were made below')
: t('Push this button to update the form to reflect the change'
. ' that was made in the field on the left'),
$this->getView()->icon('cw') . t('Apply')
);
}
return $content;
}
}

View File

@ -0,0 +1,146 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Web\Form\Decorator;
use Zend_Form_Decorator_Abstract;
use Icinga\Web\Form;
/**
* Decorator to add a list of descriptions at the top of a form
*
* The description for required form elements is automatically being handled.
*/
class FormDescriptions extends Zend_Form_Decorator_Abstract
{
/**
* A list of element class names to be ignored when detecting which message to use to describe required elements
*
* @var array
*/
protected $blacklist;
/**
* {@inheritdoc}
*/
public function __construct($options = null)
{
parent::__construct($options);
$this->blacklist = array(
'Zend_Form_Element_Hidden',
'Zend_Form_Element_Submit',
'Zend_Form_Element_Button',
'Icinga\Web\Form\Element\Note',
'Icinga\Web\Form\Element\Button',
'Icinga\Web\Form\Element\CsrfCounterMeasure'
);
}
/**
* Render form descriptions
*
* @param string $content The html rendered so far
*
* @return string The updated html
*/
public function render($content = '')
{
$form = $this->getElement();
if (! $form instanceof Form) {
return $content;
}
$view = $form->getView();
if ($view === null) {
return $content;
}
$descriptions = $this->recurseForm($form, $entirelyRequired);
if ($entirelyRequired) {
$descriptions[] = $form->getView()->translate(
'All fields are required and must be filled in to complete the form.'
);
} elseif ($entirelyRequired === false) {
$descriptions[] = $form->getView()->translate(sprintf(
'Required fields are marked with %s and must be filled in to complete the form.',
$form->getRequiredCue()
));
}
if (empty($descriptions)) {
return $content;
}
$html = '<ul class="descriptions">';
foreach ($descriptions as $description) {
if (is_array($description)) {
list($description, $properties) = $description;
$html .= '<li' . $view->propertiesToString($properties) . '>' . $view->escape($description) . '</li>';
} else {
$html .= '<li>' . $view->escape($description) . '</li>';
}
}
switch ($this->getPlacement()) {
case self::APPEND:
return $content . $html . '</ul>';
case self::PREPEND:
return $html . '</ul>' . $content;
}
}
/**
* Recurse the given form and return the descriptions for it and all of its subforms
*
* @param Form $form The form to recurse
* @param mixed $entirelyRequired Set by reference, true means all elements in the hierarchy are
* required, false only a partial subset and null none at all
* @param bool $elementsPassed Whether there were any elements passed during the recursion until now
*
* @return array
*/
protected function recurseForm(Form $form, & $entirelyRequired = null, $elementsPassed = false)
{
$requiredLabels = array();
if ($form->getRequiredCue() !== null) {
$partiallyRequired = $partiallyOptional = false;
foreach ($form->getElements() as $element) {
if (! in_array($element->getType(), $this->blacklist)) {
if (! $element->isRequired()) {
$partiallyOptional = true;
if ($entirelyRequired) {
$entirelyRequired = false;
}
} else {
$partiallyRequired = true;
if (($label = $element->getDecorator('label')) !== false) {
$requiredLabels[] = $label;
}
}
}
}
if (! $elementsPassed) {
$elementsPassed = $partiallyRequired || $partiallyOptional;
if ($entirelyRequired === null && $partiallyRequired) {
$entirelyRequired = ! $partiallyOptional;
}
} elseif ($entirelyRequired === null && $partiallyRequired) {
$entirelyRequired = false;
}
}
$descriptions = array($form->getDescriptions());
foreach ($form->getSubForms() as $subForm) {
$descriptions[] = $this->recurseForm($subForm, $entirelyRequired, $elementsPassed);
}
if ($entirelyRequired) {
foreach ($requiredLabels as $label) {
$label->setRequiredSuffix('');
}
}
return call_user_func_array('array_merge', $descriptions);
}
}

View File

@ -0,0 +1,110 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Web\Form\Decorator;
use Zend_Form_Element;
use Zend_Form_Decorator_Abstract;
use Icinga\Application\Icinga;
use Icinga\Web\View;
/**
* Decorator to add helptext to a form element
*/
class Help extends Zend_Form_Decorator_Abstract
{
/**
* Whether a hidden <span> should be created to describe the decorated form element
*
* @var bool
*/
protected $accessible = false;
/**
* The id used to identify the description associated with the decorated form element
*
* @var string
*/
protected $descriptionId;
/**
* Set whether a hidden <span> should be created to describe the decorated form element
*
* @param bool $state
*
* @return Help
*/
public function setAccessible($state = true)
{
$this->accessible = (bool) $state;
return $this;
}
/**
* Return the id used to identify the description associated with the decorated element
*
* @param Zend_Form_Element $element The element for which to generate a id
*
* @return string
*/
public function getDescriptionId(Zend_Form_Element $element = null)
{
if ($this->descriptionId === null) {
$element = $element ?: $this->getElement();
$this->descriptionId = 'desc_' . $element->getId();
}
return $this->descriptionId;
}
/**
* Return the current view
*
* @return View
*/
protected function getView()
{
return Icinga::app()->getViewRenderer()->view;
}
/**
* Add a help icon to the left of an element
*
* @param string $content The html rendered so far
*
* @return string The updated html
*/
public function render($content = '')
{
$element = $this->getElement();
$description = $element->getDescription();
$requirement = $element->getAttrib('requirement');
unset($element->requirement);
$helpContent = '';
if ($description || $requirement) {
if ($this->accessible) {
$helpContent = '<span id="'
. $this->getDescriptionId()
. '" class="sr-only">'
. $description
. ($description && $requirement ? ' ' : '')
. $requirement
. '</span>';
}
$helpContent = $this->getView()->icon(
'help',
$description . ($description && $requirement ? ' ' : '') . $requirement,
array('aria-hidden' => $this->accessible ? 'true' : 'false')
) . $helpContent;
}
switch ($this->getPlacement()) {
case self::APPEND:
return $content . $helpContent;
case self::PREPEND:
return $helpContent . $content;
}
}
}

View File

@ -1,34 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
namespace Icinga\Web\Form\Decorator;
use Zend_Form_Decorator_Abstract;
use Icinga\Application\Icinga;
/**
* Decorator to add a submit button encapsulated in noscript-tags
*
* This enables users in non-JS environments to update the contents
* of a form without the use of the main submit button.
*/
class NoScriptApply extends Zend_Form_Decorator_Abstract
{
/**
* Add a submit button encapsulated in noscript-tags to the element
*
* @param string $content The html rendered so far
*
* @return string The updated html
*/
public function render($content = '')
{
if ($content) {
$content .= '<noscript><button name="noscript_apply" style="margin-left: 0.5em;" type="submit" value="1">'
. Icinga::app()->getViewRenderer()->view->icon('refresh.png') . '&nbsp;' . t('Apply')
. '</button></noscript>';
}
return $content;
}
}

View File

@ -18,6 +18,11 @@ class Request extends Zend_Controller_Request_Http
*/
private $user;
/**
* @var string
*/
private $uniqueId;
private $url;
public function getUrl()
@ -47,4 +52,19 @@ class Request extends Zend_Controller_Request_Http
{
return $this->user;
}
/**
* Makes an ID unique to this request, to prevent id collisions in different containers
*
* Call this whenever an ID might show up multiple times in different containers. This function is useful
* for ensuring unique ids on sites, even if we combine the HTML of different requests into one site,
* while still being able to reference elements uniquely in the same request.
*/
public function protectId($id)
{
if (! isset($this->uniqueId)) {
$this->uniqueId = Window::generateId();
}
return $id . '-' . $this->uniqueId;
}
}

View File

@ -13,6 +13,7 @@ class StyleSheet
'../application/fonts/fontello-ifont/css/ifont-embedded.css',
'css/vendor/tipsy.css',
'css/icinga/defaults.less',
'css/icinga/animation.less',
'css/icinga/layout-colors.less',
'css/icinga/layout-structure.less',
'css/icinga/menu.less',

View File

@ -53,11 +53,12 @@ $this->addHelperFunction('img', function ($url, $params = null, array $propertie
$properties['alt'] = '';
}
$ariaHidden = array_key_exists('aria-hidden', $properties) ? $properties['aria-hidden'] : null;
if (array_key_exists('title', $properties)) {
if (! array_key_exists('aria-label', $properties)) {
if (! array_key_exists('aria-label', $properties) && $ariaHidden !== 'true') {
$properties['aria-label'] = $properties['title'];
}
} elseif (! array_key_exists('aria-hidden', $properties)) {
} elseif ($ariaHidden === null) {
$properties['aria-hidden'] = 'true';
}
@ -79,14 +80,15 @@ $this->addHelperFunction('icon', function ($img, $title = null, array $propertie
return $view->img('img/icons/' . $img, $properties);
}
$ariaHidden = array_key_exists('aria-hidden', $properties) ? $properties['aria-hidden'] : null;
if ($title !== null) {
$properties['role'] = 'img';
$properties['title'] = $title;
if (! array_key_exists('aria-label', $properties)) {
if (! array_key_exists('aria-label', $properties) && $ariaHidden !== 'true') {
$properties['aria-label'] = $title;
}
} elseif (! array_key_exists('aria-hidden', $properties)) {
} elseif ($ariaHidden === null) {
$properties['aria-hidden'] = 'true';
}

View File

@ -26,7 +26,7 @@ abstract class AbstractWidget
{
/**
* If you are going to access the current view with the view() function,
* it's instance is stored here for performance reasons.
* its instance is stored here for performance reasons.
*
* @var Zend_View_Abstract
*/

View File

@ -18,7 +18,7 @@ use Icinga\Web\Url;
*
* The terminology is as follows:
* - Dashlet: A single view showing a specific url
* - Pane: Aggregates one or more dashlets on one page, displays it's title as a tab
* - Pane: Aggregates one or more dashlets on one page, displays its title as a tab
* - Dashboard: Shows all panes
*
*/
@ -347,7 +347,7 @@ class Dashboard extends AbstractWidget
}
/**
* Activates the default pane of this dashboard and returns it's name
* Activates the default pane of this dashboard and returns its name
*
* @return mixed
*/

View File

@ -310,7 +310,7 @@ class FilterEditor extends AbstractWidget
$this->preservedUrl()->with('removeFilter', $filter->getId()),
null,
array(
'icon' => 'icon-cancel',
'icon' => 'trash',
'title' => t('Remove this part of your filter')
)
);
@ -323,7 +323,7 @@ class FilterEditor extends AbstractWidget
$this->preservedUrl()->with('addFilter', $filter->getId()),
null,
array(
'icon' => 'icon-plus',
'icon' => 'plus',
'title' => t('Add another filter')
)
);
@ -336,7 +336,7 @@ class FilterEditor extends AbstractWidget
$this->preservedUrl()->with('stripFilter', $filter->getId()),
null,
array(
'icon' => 'icon-minus',
'icon' => 'minus',
'title' => t('Strip this filter')
)
);
@ -349,7 +349,7 @@ class FilterEditor extends AbstractWidget
$this->preservedUrl()->without('addFilter'),
null,
array(
'icon' => 'icon-cancel',
'icon' => 'cancel',
'title' => t('Cancel this operation')
)
);

View File

@ -42,6 +42,11 @@ class Tab extends AbstractWidget
*/
private $title = '';
/**
* The label displayed for this tab
*
* @var string
*/
private $label = '';
/**
@ -118,11 +123,26 @@ class Tab extends AbstractWidget
return $this->name;
}
/**
* Set the tab label
*
* @param string $label
*/
public function setLabel($label)
{
$this->label = $label;
}
/**
* Get the tab label
*
* @return string
*/
public function getLabel()
{
return $this->label;
}
/**
* @param mixed $title
*/

View File

@ -4,6 +4,7 @@
namespace Icinga\Web\Widget;
use Icinga\Exception\ProgrammingError;
use Icinga\Web\Url;
use Icinga\Web\Widget\Tabextension\Tabextension;
use Icinga\Application\Icinga;
use Countable;
@ -23,6 +24,7 @@ class Tabs extends AbstractWidget implements Countable
<ul class="tabs">
{TABS}
{DROPDOWN}
{REFRESH}
{CLOSE}
</ul>
EOT;
@ -59,6 +61,18 @@ EOT;
</li>
EOT;
/**
* Template used for the refresh icon
*
* @var string
*/
private $refreshTpl = <<< 'EOT'
<li>
<a class="spinner" href="{URL}" title="{TITLE}" aria-label="{LABEL}">
<i aria-hidden="true" class="icon-cw"></i>
</a>
</li>
EOT;
/**
* This is where single tabs added to this container will be stored
@ -193,7 +207,7 @@ EOT;
* with tab properties or an instance of an existing Tab
*
* @param string $name The new tab name
* @param array|Tab $tab The tab itself of it's properties
* @param array|Tab $tab The tab itself of its properties
*
* @return self
*
@ -218,7 +232,7 @@ EOT;
* of an existing Tab
*
* @param string $name The new tab name
* @param array|Tab $tab The tab itself of it's properties
* @param array|Tab $tab The tab itself of its properties
*
* @return self
*/
@ -265,7 +279,7 @@ EOT;
}
/**
* Render the dropdown area with it's tabs and return the resulting HTML
* Render the dropdown area with its tabs and return the resulting HTML
*
* @return mixed|string
*/
@ -308,6 +322,43 @@ EOT;
return $this->closeTpl;
}
private function renderRefreshTab()
{
$url = Url::fromRequest()->without('renderLayout');
$tab = $this->get($this->getActiveName());
if ($tab !== null) {
$label = $this->view()->escape(
$tab->getLabel()
);
}
if (! empty($label)) {
$caption = $label;
} else {
$caption = t('Content');
}
$label = t(sprintf('Refresh the %s', $caption));
$title = $label;
$tpl = str_replace(
array(
'{URL}',
'{TITLE}',
'{LABEL}'
),
array(
$url,
$title,
$label
),
$this->refreshTpl
);
return $tpl;
}
/**
* Render to HTML
*
@ -323,11 +374,13 @@ EOT;
$drop = $this->renderDropdownTabs();
}
$close = $this->closeTab ? $this->renderCloseTab() : '';
$refresh = $this->renderRefreshTab();
return str_replace(
array(
'{TABS}',
'{DROPDOWN}',
'{REFRESH}',
'{CLOSE}',
'{HEADER}'
),
@ -335,6 +388,7 @@ EOT;
$tabs,
$drop,
$close,
$refresh,
$this->renderHeader()
),
$this->baseTpl

View File

@ -24,14 +24,15 @@ class Doc_StyleController extends Controller
return Widget::create('tabs')->add(
'guide',
array(
'title' => $this->translate('Style Guide'),
'url' => 'doc/style/guide'
'label' => $this->translate('Style Guide'),
'url' => 'doc/style/guide'
)
)->add(
'font',
array(
'title' => $this->translate('Icons'),
'url' => 'doc/style/font'
'label' => $this->translate('Icons'),
'title' => $this->translate('List all available icons'),
'url' => 'doc/style/font'
)
);
}

View File

@ -1,4 +1,4 @@
Module: doc
Version: 2.0.0
Description: Documentation module
Extracts, shows and exports documentation for Icinga Web 2 and it's modules.
Extracts, shows and exports documentation for Icinga Web 2 and its modules.

View File

@ -30,6 +30,7 @@ class Monitoring_ConfigController extends ModuleActionController
public function editbackendAction()
{
$form = new BackendConfigForm();
$form->setTitle($this->translate('Edit Existing Backend'));
$form->setIniConfig($this->Config('backends'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('monitoring/config');
@ -44,6 +45,7 @@ class Monitoring_ConfigController extends ModuleActionController
public function createbackendAction()
{
$form = new BackendConfigForm();
$form->setTitle($this->translate('Add New Backend'));
$form->setIniConfig($this->Config('backends'));
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
$form->setRedirectUrl('monitoring/config');
@ -72,12 +74,16 @@ class Monitoring_ConfigController extends ModuleActionController
}
if ($configForm->save()) {
Notification::success(sprintf(mt('monitoring', 'Backend "%s" successfully removed.'), $backendName));
Notification::success(sprintf(
$this->translate('Backend "%s" successfully removed.'),
$backendName
));
} else {
return false;
}
}
));
$form->setTitle($this->translate('Remove Existing Backend'));
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
@ -104,12 +110,31 @@ class Monitoring_ConfigController extends ModuleActionController
}
if ($configForm->save()) {
Notification::success(sprintf(mt('monitoring', 'Instance "%s" successfully removed.'), $instanceName));
Notification::success(sprintf(
$this->translate('Instance "%s" successfully removed.'),
$instanceName
));
} else {
return false;
}
}
));
$form->setTitle($this->translate('Remove Existing Instance'));
$form->addDescription($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->addElement(
'note',
'question',
array(
'value' => $this->translate('Are you sure you want to remove this instance?'),
'decorators' => array(
'ViewHelper',
array('HtmlTag', array('tag' => 'p'))
)
)
);
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
@ -122,6 +147,7 @@ class Monitoring_ConfigController extends ModuleActionController
public function editinstanceAction()
{
$form = new InstanceConfigForm();
$form->setTitle($this->translate('Edit Existing Instance'));
$form->setIniConfig($this->Config('instances'));
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();
@ -135,6 +161,7 @@ class Monitoring_ConfigController extends ModuleActionController
public function createinstanceAction()
{
$form = new InstanceConfigForm();
$form->setTitle($this->translate('Add New Instance'));
$form->setIniConfig($this->Config('instances'));
$form->setRedirectUrl('monitoring/config');
$form->handleRequest();

View File

@ -66,8 +66,9 @@ class Monitoring_HostController extends MonitoredObjectController
{
$this->assertPermission('monitoring/command/acknowledge-problem');
$this->view->title = $this->translate('Acknowledge Host Problem');
$this->handleCommandForm(new AcknowledgeProblemCommandForm());
$form = new AcknowledgeProblemCommandForm();
$form->setTitle($this->translate('Acknowledge Host Problem'));
$this->handleCommandForm($form);
}
/**
@ -77,8 +78,9 @@ class Monitoring_HostController extends MonitoredObjectController
{
$this->assertPermission('monitoring/command/comment/add');
$this->view->title = $this->translate('Add Host Comment');
$this->handleCommandForm(new AddCommentCommandForm());
$form = new AddCommentCommandForm();
$form->setTitle($this->translate('Add Host Comment'));
$this->handleCommandForm($form);
}
/**
@ -88,8 +90,9 @@ class Monitoring_HostController extends MonitoredObjectController
{
$this->assertPermission('monitoring/command/schedule-check');
$this->view->title = $this->translate('Reschedule Host Check');
$this->handleCommandForm(new ScheduleHostCheckCommandForm());
$form = new ScheduleHostCheckCommandForm();
$form->setTitle($this->translate('Reschedule Host Check'));
$this->handleCommandForm($form);
}
/**
@ -99,8 +102,9 @@ class Monitoring_HostController extends MonitoredObjectController
{
$this->assertPermission('monitoring/command/downtime/schedule');
$this->view->title = $this->translate('Schedule Host Downtime');
$this->handleCommandForm(new ScheduleHostDowntimeCommandForm());
$form = new ScheduleHostDowntimeCommandForm();
$form->setTitle($this->translate('Schedule Host Downtime'));
$this->handleCommandForm($form);
}
/**
@ -110,7 +114,8 @@ class Monitoring_HostController extends MonitoredObjectController
{
$this->assertPermission('monitoring/command/process-check-result');
$this->view->title = $this->translate('Submit Passive Host Check Result');
$this->handleCommandForm(new ProcessCheckResultCommandForm());
$form = new ProcessCheckResultCommandForm();
$form->setTitle($this->translate('Submit Passive Host Check Result'));
$this->handleCommandForm($form);
}
}

View File

@ -175,8 +175,9 @@ class Monitoring_HostsController extends Controller
{
$this->assertPermission('monitoring/command/acknowledge-problem');
$this->view->title = $this->translate('Acknowledge Host Problems');
$this->handleCommandForm(new AcknowledgeProblemCommandForm());
$form = new AcknowledgeProblemCommandForm();
$form->setTitle($this->translate('Acknowledge Host Problems'));
$this->handleCommandForm($form);
}
/**
@ -186,8 +187,9 @@ class Monitoring_HostsController extends Controller
{
$this->assertPermission('monitoring/command/schedule-check');
$this->view->title = $this->translate('Reschedule Host Checks');
$this->handleCommandForm(new ScheduleHostCheckCommandForm());
$form = new ScheduleHostCheckCommandForm();
$form->setTitle($this->translate('Reschedule Host Checks'));
$this->handleCommandForm($form);
}
/**
@ -197,8 +199,9 @@ class Monitoring_HostsController extends Controller
{
$this->assertPermission('monitoring/command/downtime/schedule');
$this->view->title = $this->translate('Schedule Host Downtimes');
$this->handleCommandForm(new ScheduleHostDowntimeCommandForm());
$form = new ScheduleHostDowntimeCommandForm();
$form->setTitle($this->translate('Schedule Host Downtimes'));
$this->handleCommandForm($form);
}
/**
@ -208,7 +211,8 @@ class Monitoring_HostsController extends Controller
{
$this->assertPermission('monitoring/command/process-check-result');
$this->view->title = $this->translate('Submit Passive Host Check Results');
$this->handleCommandForm(new ProcessCheckResultCommandForm());
$form = new ProcessCheckResultCommandForm();
$form->setTitle($this->translate('Submit Passive Host Check Results'));
$this->handleCommandForm($form);
}
}

View File

@ -397,6 +397,7 @@ class Monitoring_ListController extends Controller
$form->render();
$this->view->form = $form;
$this->params->remove('view');
$orientation = $this->params->shift('vertical', 0) ? 'vertical' : 'horizontal';
/*
$orientationBox = new SelectBox(
@ -702,7 +703,7 @@ class Monitoring_ListController extends Controller
private function setupSortControl(array $columns)
{
$this->view->sortControl = new SortBox(
$this->getRequest()->getActionName(),
'sortbox-' . $this->getRequest()->getActionName(),
$columns
);
$this->view->sortControl->applyRequest($this->getRequest());

View File

@ -43,8 +43,9 @@ class Monitoring_ServiceController extends MonitoredObjectController
{
$this->assertPermission('monitoring/command/acknowledge-problem');
$this->view->title = $this->translate('Acknowledge Service Problem');
$this->handleCommandForm(new AcknowledgeProblemCommandForm());
$form = new AcknowledgeProblemCommandForm();
$form->setTitle($this->translate('Acknowledge Service Problem'));
$this->handleCommandForm($form);
}
/**
@ -54,8 +55,9 @@ class Monitoring_ServiceController extends MonitoredObjectController
{
$this->assertPermission('monitoring/command/comment/add');
$this->view->title = $this->translate('Add Service Comment');
$this->handleCommandForm(new AddCommentCommandForm());
$form = new AddCommentCommandForm();
$form->setTitle($this->translate('Add Service Comment'));
$this->handleCommandForm($form);
}
/**
@ -65,8 +67,9 @@ class Monitoring_ServiceController extends MonitoredObjectController
{
$this->assertPermission('monitoring/command/schedule-check');
$this->view->title = $this->translate('Reschedule Service Check');
$this->handleCommandForm(new ScheduleServiceCheckCommandForm());
$form = new ScheduleServiceCheckCommandForm();
$form->setTitle($this->translate('Reschedule Service Check'));
$this->handleCommandForm($form);
}
/**
@ -76,8 +79,9 @@ class Monitoring_ServiceController extends MonitoredObjectController
{
$this->assertPermission('monitoring/command/downtime/schedule');
$this->view->title = $this->translate('Schedule Service Downtime');
$this->handleCommandForm(new ScheduleServiceDowntimeCommandForm());
$form = new ScheduleServiceDowntimeCommandForm();
$form->setTitle($this->translate('Schedule Service Downtime'));
$this->handleCommandForm($form);
}
/**
@ -87,7 +91,8 @@ class Monitoring_ServiceController extends MonitoredObjectController
{
$this->assertPermission('monitoring/command/process-check-result');
$this->view->title = $this->translate('Submit Passive Service Check Result');
$this->handleCommandForm(new ProcessCheckResultCommandForm());
$form = new ProcessCheckResultCommandForm();
$form->setTitle($this->translate('Submit Passive Service Check Result'));
$this->handleCommandForm($form);
}
}

View File

@ -224,8 +224,9 @@ class Monitoring_ServicesController extends Controller
{
$this->assertPermission('monitoring/command/acknowledge-problem');
$this->view->title = $this->translate('Acknowledge Service Problems');
$this->handleCommandForm(new AcknowledgeProblemCommandForm());
$form = new AcknowledgeProblemCommandForm();
$form->setTitle($this->translate('Acknowledge Service Problems'));
$this->handleCommandForm($form);
}
/**
@ -235,8 +236,9 @@ class Monitoring_ServicesController extends Controller
{
$this->assertPermission('monitoring/command/schedule-check');
$this->view->title = $this->translate('Reschedule Service Checks');
$this->handleCommandForm(new ScheduleServiceCheckCommandForm());
$form = new ScheduleServiceCheckCommandForm();
$form->setTitle($this->translate('Reschedule Service Checks'));
$this->handleCommandForm($form);
}
/**
@ -246,8 +248,9 @@ class Monitoring_ServicesController extends Controller
{
$this->assertPermission('monitoring/command/downtime/schedule');
$this->view->title = $this->translate('Schedule Service Downtimes');
$this->handleCommandForm(new ScheduleServiceDowntimeCommandForm());
$form = new ScheduleServiceDowntimeCommandForm();
$form->setTitle($this->translate('Schedule Service Downtimes'));
$this->handleCommandForm($form);
}
/**
@ -257,7 +260,8 @@ class Monitoring_ServicesController extends Controller
{
$this->assertPermission('monitoring/command/process-check-result');
$this->view->title = $this->translate('Submit Passive Service Check Results');
$this->handleCommandForm(new ProcessCheckResultCommandForm());
$form = new ProcessCheckResultCommandForm();
$form->setTitle($this->translate('Submit Passive Service Check Results'));
$this->handleCommandForm($form);
}
}

View File

@ -43,16 +43,6 @@ abstract class CommandForm extends Form
return $this->backend;
}
/**
* Get the command help description
*
* @return string|null
*/
public function getHelp()
{
return null;
}
/**
* Get the transport used to send commands
*

View File

@ -20,18 +20,11 @@ class DisableNotificationsExpireCommandForm extends CommandForm
*/
public function init()
{
$this->setRequiredCue(null);
$this->setSubmitLabel($this->translate('Disable Notifications'));
}
/**
* (non-PHPDoc)
* @see \Icinga\Module\Monitoring\Forms\Command\CommandForm::getHelp() For the method documentation.
*/
public function getHelp()
{
return $this->translate(
$this->addDescription($this->translate(
'This command is used to disable host and service notifications for a specific time.'
);
));
}
/**

View File

@ -25,7 +25,10 @@ class ToggleInstanceFeaturesCommandForm extends CommandForm
*/
public function init()
{
$this->setUseFormAutosubmit();
$this->setTitle($this->translate('Feature Commands'));
$this->setAttrib('class', 'inline instance-features');
$this->loadDefaultDecorators()->getDecorator('description')->setTag('h2');
}
/**

View File

@ -13,28 +13,25 @@ use Icinga\Web\Notification;
*/
class AcknowledgeProblemCommandForm extends ObjectsCommandForm
{
/**
* Initialize this form
*/
public function init()
{
$this->addDescription($this->translate(
'This command is used to acknowledge host or service problems. When a problem is acknowledged,'
. ' future notifications about problems are temporarily disabled until the host or service'
. ' recovers.'
));
}
/**
* (non-PHPDoc)
* @see \Icinga\Web\Form::getSubmitLabel() For the method documentation.
*/
public function getSubmitLabel()
{
return mtp(
'monitoring', 'Acknowledge problem', 'Acknowledge problems', count($this->objects)
);
}
/**
* (non-PHPDoc)
* @see \Icinga\Module\Monitoring\Forms\Command\CommandForm::getHelp() For the method documentation.
*/
public function getHelp()
{
return $this->translate(
'This command is used to acknowledge host or service problems. When a problem is acknowledged,'
. ' future notifications about problems are temporarily disabled until the host or service'
. ' recovers.'
);
return $this->translatePlural('Acknowledge problem', 'Acknowledge problems', count($this->objects));
}
/**
@ -156,8 +153,7 @@ class AcknowledgeProblemCommandForm extends ObjectsCommandForm
}
$this->getTransport($this->request)->send($ack);
}
Notification::success(mtp(
'monitoring',
Notification::success($this->translatePlural(
'Acknowledging problem..',
'Acknowledging problems..',
count($this->objects)

View File

@ -11,26 +11,21 @@ use Icinga\Web\Notification;
*/
class AddCommentCommandForm extends ObjectsCommandForm
{
/**
* Initialize this form
*/
public function init()
{
$this->addDescription($this->translate('This command is used to add host or service comments.'));
}
/**
* (non-PHPDoc)
* @see \Icinga\Web\Form::getSubmitLabel() For the method documentation.
*/
public function getSubmitLabel()
{
return mtp(
'monitoring', 'Add comment', 'Add comments', count($this->objects)
);
}
/**
* (non-PHPDoc)
* @see \Icinga\Module\Monitoring\Forms\Command\CommandForm::getHelp() For the method documentation.
*/
public function getHelp()
{
return $this->translate(
'This command is used to add host or service comments.'
);
return $this->translatePlural('Add comment', 'Add comments', count($this->objects));
}
/**
@ -84,8 +79,7 @@ class AddCommentCommandForm extends ObjectsCommandForm
$comment->setPersistent($this->getElement('persistent')->isChecked());
$this->getTransport($this->request)->send($comment);
}
Notification::success(mtp(
'monitoring',
Notification::success($this->translatePlural(
'Adding comment..',
'Adding comments..',
count($this->objects)

View File

@ -39,7 +39,7 @@ class CheckNowCommandForm extends ObjectsCommandForm
. $this->translate('Check now'),
'decorators' => array('ViewHelper'),
'escape' => false,
'class' => 'link-like',
'class' => 'link-like spinner',
'title' => $this->translate('Schedule the next active check to run immediately')
)
)

View File

@ -11,25 +11,24 @@ use Icinga\Module\Monitoring\Command\Object\ProcessCheckResultCommand;
*/
class ProcessCheckResultCommandForm extends ObjectsCommandForm
{
/**
* Initialize this form
*/
public function init()
{
$this->addDescription($this->translate(
'This command is used to submit passive host or service check results.'
));
}
/**
* (non-PHPDoc)
* @see \Icinga\Web\Form::getSubmitLabel() For the method documentation.
*/
public function getSubmitLabel()
{
return mtp(
'monitoring', 'Submit Passive Check Result', 'Submit Passive Check Results', count($this->objects)
);
}
/**
* (non-PHPDoc)
* @see \Icinga\Module\Monitoring\Forms\Command\CommandForm::getHelp() For the method documentation.
*/
public function getHelp()
{
return $this->translate(
'This command is used to submit passive host or service check results.'
return $this->translatePlural(
'Submit Passive Check Result', 'Submit Passive Check Results', count($this->objects)
);
}
@ -108,8 +107,7 @@ class ProcessCheckResultCommandForm extends ObjectsCommandForm
$this->getTransport($this->request)->send($command);
}
Notification::success(mtp(
'monitoring',
Notification::success($this->translatePlural(
'Processing check result..',
'Processing check results..',
count($this->objects)

View File

@ -47,8 +47,7 @@ class ScheduleHostCheckCommandForm extends ScheduleServiceCheckCommandForm
->setOfAllServices($this->getElement('all_services')->isChecked());
$this->scheduleCheck($check, $this->request);
}
Notification::success(mtp(
'monitoring',
Notification::success($this->translatePlural(
'Scheduling host check..',
'Scheduling host checks..',
count($this->objects)

View File

@ -7,7 +7,6 @@ use Icinga\Module\Monitoring\Command\Object\PropagateHostDowntimeCommand;
use Icinga\Module\Monitoring\Command\Object\ScheduleHostDowntimeCommand;
use Icinga\Module\Monitoring\Command\Object\ScheduleServiceDowntimeCommand;
use Icinga\Web\Notification;
use Icinga\Web\Request;
/**
* Form for scheduling host downtimes
@ -83,8 +82,7 @@ class ScheduleHostDowntimeCommandForm extends ScheduleServiceDowntimeCommandForm
$hostDowntime->setObject($object);
$this->scheduleDowntime($hostDowntime, $this->request);
}
Notification::success(mtp(
'monitoring',
Notification::success($this->translatePlural(
'Scheduling host downtime..',
'Scheduling host downtimes..',
count($this->objects)

View File

@ -14,27 +14,24 @@ use Icinga\Web\Request;
*/
class ScheduleServiceCheckCommandForm extends ObjectsCommandForm
{
/**
* Initialize this form
*/
public function init()
{
$this->addDescription($this->translate(
'This command is used to schedule the next check of hosts or services. Icinga will re-queue the'
. ' hosts or services to be checked at the time you specify.'
));
}
/**
* (non-PHPDoc)
* @see \Icinga\Web\Form::getSubmitLabel() For the method documentation.
*/
public function getSubmitLabel()
{
return mtp(
'monitoring', 'Schedule check', 'Schedule checks', count($this->objects)
);
}
/**
* (non-PHPDoc)
* @see \Icinga\Module\Monitoring\Forms\Command\CommandForm::getHelp() For the method documentation.
*/
public function getHelp()
{
return $this->translate(
'This command is used to schedule the next check of hosts or services. Icinga will re-queue the'
. ' hosts or services to be checked at the time you specify.'
);
return $this->translatePlural('Schedule check', 'Schedule checks', count($this->objects));
}
/**
@ -99,8 +96,7 @@ class ScheduleServiceCheckCommandForm extends ObjectsCommandForm
$check->setObject($object);
$this->scheduleCheck($check, $this->request);
}
Notification::success(mtp(
'monitoring',
Notification::success($this->translatePlural(
'Scheduling service check..',
'Scheduling service checks..',
count($this->objects)

View File

@ -25,29 +25,26 @@ class ScheduleServiceDowntimeCommandForm extends ObjectsCommandForm
const FLEXIBLE = 'flexible';
/**
* (non-PHPDoc)
* @see \Icinga\Web\Form::getSubmitLabel() For the method documentation.
* Initialize this form
*/
public function getSubmitLabel()
public function init()
{
return mtp(
'monitoring', 'Schedule downtime', 'Schedule downtimes', count($this->objects)
);
}
/**
* (non-PHPDoc)
* @see \Icinga\Module\Monitoring\Forms\Command\CommandForm::getHelp() For the method documentation.
*/
public function getHelp()
{
return $this->translate(
$this->addDescription($this->translate(
'This command is used to schedule host and service downtimes. During the specified downtime,'
. ' Icinga will not send notifications out about the hosts and services. When the scheduled'
. ' downtime expires, Icinga will send out notifications for the hosts and services as it'
. ' normally would. Scheduled downtimes are preserved across program shutdowns and'
. ' restarts.'
);
));
}
/**
* (non-PHPDoc)
* @see \Icinga\Web\Form::getSubmitLabel() For the method documentation.
*/
public function getSubmitLabel()
{
return $this->translatePlural('Schedule downtime', 'Schedule downtimes', count($this->objects));
}
/**
@ -206,8 +203,7 @@ class ScheduleServiceDowntimeCommandForm extends ObjectsCommandForm
$downtime->setObject($object);
$this->scheduleDowntime($downtime, $this->request);
}
Notification::success(mtp(
'monitoring',
Notification::success($this->translatePlural(
'Scheduling service downtime..',
'Scheduling service downtimes..',
count($this->objects)

View File

@ -18,7 +18,10 @@ class ToggleObjectFeaturesCommandForm extends ObjectsCommandForm
*/
public function init()
{
$this->setUseFormAutosubmit();
$this->setTitle('Feature Commands');
$this->setAttrib('class', 'inline object-features');
$this->loadDefaultDecorators()->getDecorator('description')->setTag('h4');
}
/**

View File

@ -11,31 +11,14 @@ class BackendPage extends Form
public function init()
{
$this->setName('setup_monitoring_backend');
$this->setTitle($this->translate('Monitoring Backend', 'setup.page.title'));
$this->addDescription($this->translate(
'Please configure below how Icinga Web 2 should retrieve monitoring information.'
));
}
public function createElements(array $formData)
{
$this->addElement(
'note',
'title',
array(
'value' => $this->translate('Monitoring Backend', 'setup.page.title'),
'decorators' => array(
'ViewHelper',
array('HtmlTag', array('tag' => 'h2'))
)
)
);
$this->addElement(
'note',
'description',
array(
'value' => $this->translate(
'Please configure below how Icinga Web 2 should retrieve monitoring information.'
)
)
);
$this->addElement(
'text',
'name',

View File

@ -11,6 +11,10 @@ class IdoResourcePage extends Form
public function init()
{
$this->setName('setup_monitoring_ido');
$this->setTitle($this->translate('Monitoring IDO Resource', 'setup.page.title'));
$this->addDescription($this->translate(
'Please fill out the connection details below to access the IDO database of your monitoring environment.'
));
}
public function createElements(array $formData)
@ -23,27 +27,6 @@ class IdoResourcePage extends Form
'value' => 'db'
)
);
$this->addElement(
'note',
'title',
array(
'value' => $this->translate('Monitoring IDO Resource', 'setup.page.title'),
'decorators' => array(
'ViewHelper',
array('HtmlTag', array('tag' => 'h2'))
)
)
);
$this->addElement(
'note',
'description',
array(
'value' => $this->translate(
'Please fill out the connection details below to access'
. ' the IDO database of your monitoring environment.'
)
)
);
if (isset($formData['skip_validation']) && $formData['skip_validation']) {
$this->addSkipValidationCheckbox();

View File

@ -11,31 +11,14 @@ class InstancePage extends Form
public function init()
{
$this->setName('setup_monitoring_instance');
$this->setTitle($this->translate('Monitoring Instance', 'setup.page.title'));
$this->addDescription($this->translate(
'Please define the settings specific to your monitoring instance below.'
));
}
public function createElements(array $formData)
{
$this->addElement(
'note',
'title',
array(
'value' => $this->translate('Monitoring Instance', 'setup.page.title'),
'decorators' => array(
'ViewHelper',
array('HtmlTag', array('tag' => 'h2'))
)
)
);
$this->addElement(
'note',
'description',
array(
'value' => $this->translate(
'Please define the settings specific to your monitoring instance below.'
)
)
);
if (isset($formData['host'])) {
$formData['type'] = 'remote'; // This is necessary as the type element gets ignored by Form::getValues()
}

View File

@ -11,6 +11,11 @@ class LivestatusResourcePage extends Form
public function init()
{
$this->setName('setup_monitoring_livestatus');
$this->setTitle($this->translate('Monitoring Livestatus Resource', 'setup.page.title'));
$this->addDescription($this->translate(
'Please fill out the connection details below to access the Livestatus'
. ' socket interface for your monitoring environment.'
));
}
public function createElements(array $formData)
@ -23,27 +28,6 @@ class LivestatusResourcePage extends Form
'value' => 'livestatus'
)
);
$this->addElement(
'note',
'title',
array(
'value' => $this->translate('Monitoring Livestatus Resource', 'setup.page.title'),
'decorators' => array(
'ViewHelper',
array('HtmlTag', array('tag' => 'h2'))
)
)
);
$this->addElement(
'note',
'description',
array(
'value' => $this->translate(
'Please fill out the connection details below to access the Livestatus'
. ' socket interface for your monitoring environment.'
)
)
);
if (isset($formData['skip_validation']) && $formData['skip_validation']) {
$this->addSkipValidationCheckbox();

View File

@ -11,31 +11,14 @@ class SecurityPage extends Form
public function init()
{
$this->setName('setup_monitoring_security');
$this->setTitle($this->translate('Monitoring Security', 'setup.page.title'));
$this->addDescription($this->translate(
'To protect your monitoring environment against prying eyes please fill out the settings below.'
));
}
public function createElements(array $formData)
{
$this->addElement(
'note',
'title',
array(
'value' => $this->translate('Monitoring Security', 'setup.page.title'),
'decorators' => array(
'ViewHelper',
array('HtmlTag', array('tag' => 'h2'))
)
)
);
$this->addElement(
'note',
'description',
array(
'value' => $this->translate(
'To protect your monitoring environment against prying eyes please fill out the settings below.'
)
)
);
$securityConfigForm = new SecurityConfigForm();
$securityConfigForm->createElements($formData);
$this->addElements($securityConfigForm->getElements());

View File

@ -1,5 +1,6 @@
<div class="controls">
<?= $tabs->showOnlyCloseButton() ?>
</div>
<h4><?= $this->translate('Add New Backend'); ?></h4>
<?= $form; ?>
<div class="content">
<?= $form; ?>
</div>

View File

@ -1,5 +1,6 @@
<div class="controls">
<?= $tabs->showOnlyCloseButton() ?>
</div>
<h4><?= $this->translate('Add New Instance') ?></h4>
<?= $form; ?>
<div class="content">
<?= $form; ?>
</div>

View File

@ -1,5 +1,6 @@
<div class="controls">
<?= $tabs->showOnlyCloseButton() ?>
</div>
<h4><?= $this->translate('Edit Existing Backend') ?></h4>
<?= $form; ?>
<div class="content">
<?= $form; ?>
</div>

View File

@ -1,5 +1,6 @@
<div class="controls">
<?= $tabs->showOnlyCloseButton() ?>
</div>
<h4><?= $this->translate('Edit Existing Instance'); ?></h4>
<?= $form; ?>
<div class="content">
<?= $form; ?>
</div>

View File

@ -38,7 +38,7 @@
'/monitoring/config/removebackend',
array('backend' => $backendName),
array(
'icon' => 'cancel',
'icon' => 'trash',
'title' => sprintf($this->translate('Remove monitoring backend %s'), $backendName)
)
); ?>
@ -82,7 +82,7 @@
'/monitoring/config/removeinstance',
array('instance' => $instanceName),
array(
'icon' => 'cancel',
'icon' => 'trash',
'title' => sprintf($this->translate('Remove monitoring instance %s'), $instanceName)
)
); ?>

Some files were not shown because too many files have changed in this diff Show More