mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-09-25 18:59:04 +02:00
Merge branch 'master' into feature/secure-modules-9644
Conflicts: library/Icinga/Exception/IcingaException.php
This commit is contained in:
commit
7cfc78558d
@ -20,7 +20,7 @@ esac
|
|||||||
|
|
||||||
echo "Adding puppet repository.."
|
echo "Adding puppet repository.."
|
||||||
rpm --import "https://yum.puppetlabs.com/RPM-GPG-KEY-puppetlabs"
|
rpm --import "https://yum.puppetlabs.com/RPM-GPG-KEY-puppetlabs"
|
||||||
rpm -ivh $PUPPET >/dev/null
|
rpm -Uvh $PUPPET >/dev/null
|
||||||
|
|
||||||
echo "Installing puppet.."
|
echo "Installing puppet.."
|
||||||
yum install -y puppet >/dev/null
|
yum install -y puppet >/dev/null
|
||||||
|
@ -15,10 +15,10 @@
|
|||||||
class epel {
|
class epel {
|
||||||
|
|
||||||
yumrepo { 'epel':
|
yumrepo { 'epel':
|
||||||
mirrorlist => "http://mirrors.fedoraproject.org/mirrorlist?repo=epel-6&arch=${::architecture}",
|
mirrorlist => "http://mirrors.fedoraproject.org/mirrorlist?repo=epel-${::operatingsystemmajrelease}&arch=${::architecture}",
|
||||||
enabled => '1',
|
enabled => '1',
|
||||||
gpgcheck => '0',
|
gpgcheck => '0',
|
||||||
descr => "Extra Packages for Enterprise Linux 6 - ${::architecture}"
|
descr => "Extra Packages for Enterprise Linux ${::operatingsystemmajrelease} - ${::architecture}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ class icinga2 {
|
|||||||
include icinga_packages
|
include icinga_packages
|
||||||
|
|
||||||
package { [
|
package { [
|
||||||
'icinga2', 'icinga2-doc', 'icinga2-debuginfo'
|
'icinga2', 'icinga2-doc'
|
||||||
]:
|
]:
|
||||||
ensure => latest,
|
ensure => latest,
|
||||||
require => Class['icinga_packages'],
|
require => Class['icinga_packages'],
|
||||||
@ -35,7 +35,7 @@ class icinga2 {
|
|||||||
links => follow,
|
links => follow,
|
||||||
owner => 'icinga',
|
owner => 'icinga',
|
||||||
group => 'icinga',
|
group => 'icinga',
|
||||||
mode => 6750,
|
mode => '6750',
|
||||||
}
|
}
|
||||||
|
|
||||||
icinga2::feature { [ 'statusdata', 'command', 'compatlog' ]: }
|
icinga2::feature { [ 'statusdata', 'command', 'compatlog' ]: }
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#
|
#
|
||||||
class icinga_packages {
|
class icinga_packages {
|
||||||
yumrepo { 'icinga_packages':
|
yumrepo { 'icinga_packages':
|
||||||
baseurl => 'http://packages.icinga.org/epel/6/snapshot/',
|
baseurl => "http://packages.icinga.org/epel/${::operatingsystemmajrelease}/snapshot/",
|
||||||
enabled => '1',
|
enabled => '1',
|
||||||
gpgcheck => '1',
|
gpgcheck => '1',
|
||||||
gpgkey => 'http://packages.icinga.org/icinga.key',
|
gpgkey => 'http://packages.icinga.org/icinga.key',
|
||||||
|
@ -10,7 +10,7 @@ define icingaweb2::config::general (
|
|||||||
content => template("${source}/${name}.ini.erb"),
|
content => template("${source}/${name}.ini.erb"),
|
||||||
owner => 'root',
|
owner => 'root',
|
||||||
group => $web_group,
|
group => $web_group,
|
||||||
mode => 0660,
|
mode => '0660',
|
||||||
replace => $replace,
|
replace => $replace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ define icingaweb2::config::module (
|
|||||||
source => "${source}/modules/${module}/${name}.ini",
|
source => "${source}/modules/${module}/${name}.ini",
|
||||||
owner => 'root',
|
owner => 'root',
|
||||||
group => $web_group,
|
group => $web_group,
|
||||||
mode => 0660,
|
mode => '0660',
|
||||||
replace => $replace,
|
replace => $replace,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Class: mysql
|
# Class: mysql
|
||||||
#
|
#
|
||||||
# This class installs the mysql server and client software.
|
# This class installs the MySQL server and client software on a RHEL or CentOS
|
||||||
#
|
#
|
||||||
# Parameters:
|
# Parameters:
|
||||||
#
|
#
|
||||||
@ -16,21 +16,39 @@ class mysql {
|
|||||||
|
|
||||||
Exec { path => '/usr/bin' }
|
Exec { path => '/usr/bin' }
|
||||||
|
|
||||||
|
if versioncmp($::operatingsystemmajrelease, '7') >= 0 {
|
||||||
|
$client_package_name = 'mariadb'
|
||||||
|
$server_package_name = 'mariadb-server'
|
||||||
|
$server_service_name = 'mariadb'
|
||||||
|
$cnf = '/etc/my.cnf.d/server.cnf'
|
||||||
|
$log_error = '/var/log/mariadb/mariadb.log'
|
||||||
|
$pid_file = '/var/run/mariadb/mariadb.pid'
|
||||||
|
} else {
|
||||||
|
$client_package_name = 'mysql'
|
||||||
|
$server_package_name = 'mysql-server'
|
||||||
|
$server_service_name = 'mysqld'
|
||||||
|
$cnf = '/etc/my.cnf'
|
||||||
|
$log_error = '/var/log/mysqld.log'
|
||||||
|
$pid_file = '/var/run/mysqld/mysqld.pid'
|
||||||
|
}
|
||||||
|
|
||||||
package { [
|
package { [
|
||||||
'mysql', 'mysql-server'
|
$client_package_name, $server_package_name,
|
||||||
]:
|
]:
|
||||||
ensure => latest,
|
ensure => latest,
|
||||||
}
|
}
|
||||||
|
|
||||||
service { 'mysqld':
|
service { $server_service_name:
|
||||||
ensure => running,
|
alias => 'mysqld',
|
||||||
enable => true,
|
enable => true,
|
||||||
require => Package['mysql-server']
|
ensure => running,
|
||||||
|
require => Package[$server_package_name],
|
||||||
}
|
}
|
||||||
|
|
||||||
file { '/etc/my.cnf':
|
file { $cnf:
|
||||||
content => template('mysql/my.cnf.erb'),
|
content => template('mysql/my.cnf.erb'),
|
||||||
require => Package['mysql-server'],
|
notify => Service['mysqld'],
|
||||||
notify => Service['mysqld']
|
recurse => true,
|
||||||
|
require => Package[$server_package_name],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,8 +104,8 @@ innodb_file_per_table
|
|||||||
innodb_log_file_size = 64M
|
innodb_log_file_size = 64M
|
||||||
|
|
||||||
[mysqld_safe]
|
[mysqld_safe]
|
||||||
log-error=/var/log/mysqld.log
|
log-error=<%= @log_error %>
|
||||||
pid-file=/var/run/mysqld/mysqld.pid
|
pid-file=<%= @pid_file %>
|
||||||
|
|
||||||
# Increase the amount of open files allowed per process. Warning: Make
|
# Increase the amount of open files allowed per process. Warning: Make
|
||||||
# sure you have set the global system limit high enough! The high value
|
# sure you have set the global system limit high enough! The high value
|
||||||
|
@ -20,6 +20,18 @@ class openldap {
|
|||||||
|
|
||||||
service { 'slapd':
|
service { 'slapd':
|
||||||
ensure => running,
|
ensure => running,
|
||||||
require => Package['openldap-servers']
|
require => Package['openldap-servers'],
|
||||||
|
}
|
||||||
|
|
||||||
|
if versioncmp($::operatingsystemmajrelease, '7') >= 0 {
|
||||||
|
['core', 'cosine', 'inetorgperson', 'nis', 'misc', 'openldap'].each |String $schema| {
|
||||||
|
exec { "slapd-schema-${schema}":
|
||||||
|
command => "ldapadd -Y EXTERNAL -H ldapi:// -f /etc/openldap/schema/${schema}.ldif",
|
||||||
|
group => 'root',
|
||||||
|
require => Package['openldap-servers'],
|
||||||
|
unless => "test -n \"$(find /etc/openldap/slapd.d/cn=config/cn=schema/ -name cn={*}${schema}.ldif -print -quit)\"",
|
||||||
|
user => 'root',
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ define pgsql::database::create ($username, $password) {
|
|||||||
unless => "psql -tAc \"SELECT 1 FROM pg_roles WHERE rolname='${username}'\" | grep -q 1",
|
unless => "psql -tAc \"SELECT 1 FROM pg_roles WHERE rolname='${username}'\" | grep -q 1",
|
||||||
command => "psql -c \"CREATE ROLE ${username} WITH LOGIN PASSWORD '${password}';\" && \
|
command => "psql -c \"CREATE ROLE ${username} WITH LOGIN PASSWORD '${password}';\" && \
|
||||||
createdb -O ${username} -E UTF8 -T template0 ${name} && \
|
createdb -O ${username} -E UTF8 -T template0 ${name} && \
|
||||||
createlang plpgsql ${name}",
|
(createlang plpgsql ${name} || true)",
|
||||||
user => 'postgres',
|
user => 'postgres',
|
||||||
require => Class['pgsql']
|
require => Class['pgsql']
|
||||||
}
|
}
|
||||||
|
@ -20,24 +20,11 @@ class php {
|
|||||||
|
|
||||||
package { 'php':
|
package { 'php':
|
||||||
ensure => latest,
|
ensure => latest,
|
||||||
require => Package['apache'],
|
|
||||||
notify => Service['apache']
|
|
||||||
}
|
|
||||||
# TODO(el): Always executed. Should be a resource
|
|
||||||
-> exec { 'php-timezone':
|
|
||||||
command => 'sed -re $\'s#^;?(date\\.timezone =).*$#\\1 "UTC"#\' -i /etc/php.ini',
|
|
||||||
notify => Service['apache'],
|
notify => Service['apache'],
|
||||||
|
require => Package['apache'],
|
||||||
}
|
}
|
||||||
|
|
||||||
file { '/etc/php.d/error_reporting.ini':
|
php::phpd { ['error_reporting', 'timezone', 'xdebug_settings' ]:
|
||||||
content => template('php/error_reporting.ini.erb'),
|
|
||||||
require => Package['php'],
|
require => Package['php'],
|
||||||
notify => Service['apache']
|
|
||||||
}
|
|
||||||
|
|
||||||
file { '/etc/php.d/xdebug_settings.ini':
|
|
||||||
content => template('php/xdebug_settings.ini.erb'),
|
|
||||||
require => Package['php'],
|
|
||||||
notify => Service['apache']
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
.puppet/modules/php/manifests/phpd.pp
Normal file
21
.puppet/modules/php/manifests/phpd.pp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# define: php::phpd
|
||||||
|
#
|
||||||
|
# Provision php.d config
|
||||||
|
#
|
||||||
|
# Parameters:
|
||||||
|
#
|
||||||
|
# Actions:
|
||||||
|
#
|
||||||
|
# Requires:
|
||||||
|
#
|
||||||
|
# Sample Usage:
|
||||||
|
#
|
||||||
|
define php::phpd {
|
||||||
|
|
||||||
|
include php
|
||||||
|
|
||||||
|
file { "/etc/php.d/$name.ini":
|
||||||
|
content => template("php/$name.ini.erb"),
|
||||||
|
notify => Service['apache'],
|
||||||
|
}
|
||||||
|
}
|
1
.puppet/modules/php/templates/timezone.ini.erb
Normal file
1
.puppet/modules/php/templates/timezone.ini.erb
Normal file
@ -0,0 +1 @@
|
|||||||
|
date.timezone = "UTC"
|
@ -1,6 +1,6 @@
|
|||||||
# Class: icinga2_dev
|
# Class: icinga2_dev
|
||||||
#
|
#
|
||||||
# This class installs Icinga 2 w/ MySQL and provides Icinga 2 test configuration.
|
# This class installs Icinga 2 w/ MySQL and PostgreSQL and provides Icinga 2 test configuration.
|
||||||
#
|
#
|
||||||
# Requires:
|
# Requires:
|
||||||
#
|
#
|
||||||
@ -19,10 +19,15 @@ class icinga2_dev {
|
|||||||
include monitoring_test_config
|
include monitoring_test_config
|
||||||
|
|
||||||
icinga2::config { [
|
icinga2::config { [
|
||||||
'conf.d/test-config', 'conf.d/commands', 'constants' ]:
|
'conf.d/test-config', 'conf.d/commands', 'constants'
|
||||||
|
]:
|
||||||
source => 'puppet:///modules/icinga2_dev',
|
source => 'puppet:///modules/icinga2_dev',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
icinga2::feature { 'api':
|
||||||
|
ensure => absent,
|
||||||
|
}
|
||||||
|
|
||||||
icinga2::feature { 'ido-pgsql':
|
icinga2::feature { 'ido-pgsql':
|
||||||
ensure => absent,
|
ensure => absent,
|
||||||
require => Class['icinga2_pgsql'],
|
require => Class['icinga2_pgsql'],
|
||||||
|
@ -6,7 +6,7 @@ olcRootPW: {SSHA}N/2WMqT8q7cElh7KUQz+p9TJbjmKv/u9
|
|||||||
replace: olcRootDN
|
replace: olcRootDN
|
||||||
olcRootDN: cn=admin,cn=config
|
olcRootDN: cn=admin,cn=config
|
||||||
|
|
||||||
dn: olcDatabase={2}bdb,cn=config
|
dn: olcDatabase={2}hdb,cn=config
|
||||||
changetype: modify
|
changetype: modify
|
||||||
replace: olcRootPW
|
replace: olcRootPW
|
||||||
olcRootPW: {SSHA}MxMpLBo2/TSymoIBf/Sb5iQac7Wwiur5
|
olcRootPW: {SSHA}MxMpLBo2/TSymoIBf/Sb5iQac7Wwiur5
|
||||||
|
@ -1,15 +1,27 @@
|
|||||||
Alias /<%= @web_path %> /vagrant/public
|
Alias /<%= @web_path %> "/vagrant/public"
|
||||||
|
|
||||||
<Directory "/vagrant/public/">
|
<Directory "/vagrant/public">
|
||||||
Options FollowSymLinks
|
Options SymLinksIfOwnerMatch
|
||||||
AllowOverride None
|
AllowOverride None
|
||||||
|
|
||||||
|
<IfModule mod_authz_core.c>
|
||||||
|
# Apache 2.4
|
||||||
|
<RequireAll>
|
||||||
|
Require all granted
|
||||||
|
</RequireAll>
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
<IfModule !mod_authz_core.c>
|
||||||
|
# Apache 2.2
|
||||||
Order allow,deny
|
Order allow,deny
|
||||||
Allow from all
|
Allow from all
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
# SetEnv ICINGAWEB_CONFIGDIR <%= @config %>
|
SetEnv ICINGAWEB_CONFIGDIR <%= @config %>
|
||||||
|
|
||||||
EnableSendfile Off
|
EnableSendfile Off
|
||||||
|
|
||||||
|
<IfModule mod_rewrite.c>
|
||||||
RewriteEngine on
|
RewriteEngine on
|
||||||
RewriteBase /<%= @web_path %>/
|
RewriteBase /<%= @web_path %>/
|
||||||
RewriteCond %{REQUEST_FILENAME} -s [OR]
|
RewriteCond %{REQUEST_FILENAME} -s [OR]
|
||||||
@ -17,7 +29,10 @@ Alias /<%= @web_path %> /vagrant/public
|
|||||||
RewriteCond %{REQUEST_FILENAME} -d
|
RewriteCond %{REQUEST_FILENAME} -d
|
||||||
RewriteRule ^.*$ - [NC,L]
|
RewriteRule ^.*$ - [NC,L]
|
||||||
RewriteRule ^.*$ index.php [NC,L]
|
RewriteRule ^.*$ index.php [NC,L]
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
php_value xdebug.idekey PHPSTORM
|
<IfModule !mod_rewrite.c>
|
||||||
|
DirectoryIndex error_norewrite.html
|
||||||
|
ErrorDocument 404 /error_norewrite.html
|
||||||
|
</IfModule>
|
||||||
</Directory>
|
</Directory>
|
||||||
|
|
||||||
|
5
Vagrantfile
vendored
5
Vagrantfile
vendored
@ -22,13 +22,13 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|||||||
config.vm.provision :shell, :path => ".puppet/manifests/puppet.sh"
|
config.vm.provision :shell, :path => ".puppet/manifests/puppet.sh"
|
||||||
|
|
||||||
config.vm.provider :virtualbox do |v, override|
|
config.vm.provider :virtualbox do |v, override|
|
||||||
override.vm.box = "puppetlabs/centos-6.6-64-puppet"
|
override.vm.box = "puppetlabs/centos-7.0-64-puppet"
|
||||||
|
|
||||||
v.customize ["modifyvm", :id, "--memory", "1024"]
|
v.customize ["modifyvm", :id, "--memory", "1024"]
|
||||||
end
|
end
|
||||||
|
|
||||||
config.vm.provider :parallels do |p, override|
|
config.vm.provider :parallels do |p, override|
|
||||||
override.vm.box = "parallels/centos-6.5"
|
override.vm.box = "parallels/centos-7.1"
|
||||||
|
|
||||||
p.name = "Icinga Web 2 Development"
|
p.name = "Icinga Web 2 Development"
|
||||||
|
|
||||||
@ -47,5 +47,6 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|||||||
puppet.module_path = [ ".puppet/modules", ".puppet/profiles" ]
|
puppet.module_path = [ ".puppet/modules", ".puppet/profiles" ]
|
||||||
puppet.manifests_path = ".puppet/manifests"
|
puppet.manifests_path = ".puppet/manifests"
|
||||||
puppet.manifest_file = "site.pp"
|
puppet.manifest_file = "site.pp"
|
||||||
|
puppet.options = "--parser=future"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -5,6 +5,8 @@ use Icinga\Application\Config;
|
|||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
use Icinga\Application\Modules\Module;
|
use Icinga\Application\Modules\Module;
|
||||||
use Icinga\Data\ResourceFactory;
|
use Icinga\Data\ResourceFactory;
|
||||||
|
use Icinga\Exception\ConfigurationError;
|
||||||
|
use Icinga\Exception\NotFoundError;
|
||||||
use Icinga\Forms\Config\UserBackendConfigForm;
|
use Icinga\Forms\Config\UserBackendConfigForm;
|
||||||
use Icinga\Forms\Config\UserBackendReorderForm;
|
use Icinga\Forms\Config\UserBackendReorderForm;
|
||||||
use Icinga\Forms\Config\GeneralConfigForm;
|
use Icinga\Forms\Config\GeneralConfigForm;
|
||||||
@ -195,80 +197,129 @@ class ConfigController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action for creating a new user backend
|
* Create a new user backend
|
||||||
*/
|
*/
|
||||||
public function createuserbackendAction()
|
public function createuserbackendAction()
|
||||||
{
|
{
|
||||||
$this->assertPermission('config/application/userbackend');
|
$this->assertPermission('config/application/userbackend');
|
||||||
$form = new UserBackendConfigForm();
|
$form = new UserBackendConfigForm();
|
||||||
|
$form->setRedirectUrl('config/userbackend');
|
||||||
$form->setTitle($this->translate('Create New User Backend'));
|
$form->setTitle($this->translate('Create New User Backend'));
|
||||||
$form->addDescription($this->translate(
|
$form->addDescription($this->translate(
|
||||||
'Create a new backend for authenticating your users. This backend'
|
'Create a new backend for authenticating your users. This backend'
|
||||||
. ' will be added at the end of your authentication order.'
|
. ' will be added at the end of your authentication order.'
|
||||||
));
|
));
|
||||||
$form->setIniConfig(Config::app('authentication'));
|
$form->setIniConfig(Config::app('authentication'));
|
||||||
|
|
||||||
|
try {
|
||||||
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
|
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
|
||||||
$form->setRedirectUrl('config/userbackend');
|
} catch (ConfigurationError $e) {
|
||||||
|
if ($this->hasPermission('config/application/resources')) {
|
||||||
|
Notification::error($e->getMessage());
|
||||||
|
$this->redirectNow('config/createresource');
|
||||||
|
}
|
||||||
|
|
||||||
|
throw $e; // No permission for resource configuration, show the error
|
||||||
|
}
|
||||||
|
|
||||||
|
$form->setOnSuccess(function (UserBackendConfigForm $form) {
|
||||||
|
try {
|
||||||
|
$form->add(array_filter($form->getValues()));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$form->error($e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($form->save()) {
|
||||||
|
Notification::success(t('User backend successfully created'));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
$form->handleRequest();
|
$form->handleRequest();
|
||||||
|
|
||||||
$this->view->form = $form;
|
$this->view->form = $form;
|
||||||
$this->render('userbackend/create');
|
$this->render('form');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action for editing user backends
|
* Edit a user backend
|
||||||
*/
|
*/
|
||||||
public function edituserbackendAction()
|
public function edituserbackendAction()
|
||||||
{
|
{
|
||||||
$this->assertPermission('config/application/userbackend');
|
$this->assertPermission('config/application/userbackend');
|
||||||
|
$backendName = $this->params->getRequired('backend');
|
||||||
|
|
||||||
$form = new UserBackendConfigForm();
|
$form = new UserBackendConfigForm();
|
||||||
$form->setTitle($this->translate('Edit User Backend'));
|
|
||||||
$form->setIniConfig(Config::app('authentication'));
|
|
||||||
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
|
|
||||||
$form->setRedirectUrl('config/userbackend');
|
$form->setRedirectUrl('config/userbackend');
|
||||||
$form->setAction(Url::fromRequest());
|
$form->setTitle(sprintf($this->translate('Edit User Backend %s'), $backendName));
|
||||||
|
$form->setIniConfig(Config::app('authentication'));
|
||||||
|
$form->setOnSuccess(function (UserBackendConfigForm $form) use ($backendName) {
|
||||||
|
try {
|
||||||
|
$form->edit($backendName, array_map(
|
||||||
|
function ($v) {
|
||||||
|
return $v !== '' ? $v : null;
|
||||||
|
},
|
||||||
|
$form->getValues()
|
||||||
|
));
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$form->error($e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($form->save()) {
|
||||||
|
Notification::success(sprintf(t('User backend "%s" successfully updated'), $backendName));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
$form->load($backendName);
|
||||||
|
$form->setResourceConfig(ResourceFactory::getResourceConfigs());
|
||||||
$form->handleRequest();
|
$form->handleRequest();
|
||||||
|
} catch (NotFoundError $_) {
|
||||||
|
$this->httpNotFound(sprintf($this->translate('User backend "%s" not found'), $backendName));
|
||||||
|
}
|
||||||
|
|
||||||
$this->view->form = $form;
|
$this->view->form = $form;
|
||||||
$this->render('userbackend/modify');
|
$this->render('form');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action for removing a user backend
|
* Display a confirmation form to remove the backend identified by the 'backend' parameter
|
||||||
*/
|
*/
|
||||||
public function removeuserbackendAction()
|
public function removeuserbackendAction()
|
||||||
{
|
{
|
||||||
$this->assertPermission('config/application/userbackend');
|
$this->assertPermission('config/application/userbackend');
|
||||||
$form = new ConfirmRemovalForm(array(
|
$backendName = $this->params->getRequired('backend');
|
||||||
'onSuccess' => function ($form) {
|
|
||||||
$configForm = new UserBackendConfigForm();
|
|
||||||
$configForm->setIniConfig(Config::app('authentication'));
|
|
||||||
$authBackend = $form->getRequest()->getQuery('backend');
|
|
||||||
|
|
||||||
try {
|
$backendForm = new UserBackendConfigForm();
|
||||||
$configForm->remove($authBackend);
|
$backendForm->setIniConfig(Config::app('authentication'));
|
||||||
} catch (InvalidArgumentException $e) {
|
$form = new ConfirmRemovalForm();
|
||||||
Notification::error($e->getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($configForm->save()) {
|
|
||||||
Notification::success(sprintf(
|
|
||||||
t('User backend "%s" has been successfully removed'),
|
|
||||||
$authBackend
|
|
||||||
));
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
));
|
|
||||||
$form->setTitle($this->translate('Remove User Backend'));
|
|
||||||
$form->setRedirectUrl('config/userbackend');
|
$form->setRedirectUrl('config/userbackend');
|
||||||
$form->setAction(Url::fromRequest());
|
$form->setTitle(sprintf($this->translate('Remove User Backend %s'), $backendName));
|
||||||
|
$form->setOnSuccess(function (ConfirmRemovalForm $form) use ($backendName, $backendForm) {
|
||||||
|
try {
|
||||||
|
$backendForm->delete($backendName);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$form->error($e->getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($backendForm->save()) {
|
||||||
|
Notification::success(sprintf(t('User backend "%s" successfully removed'), $backendName));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
$form->handleRequest();
|
$form->handleRequest();
|
||||||
|
|
||||||
$this->view->form = $form;
|
$this->view->form = $form;
|
||||||
$this->render('userbackend/remove');
|
$this->render('form');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||||
|
|
||||||
use Icinga\Web\Controller;
|
|
||||||
use Icinga\Web\Url;
|
|
||||||
use Icinga\Web\Widget\Tabextension\DashboardAction;
|
|
||||||
use Icinga\Web\Widget\Tabextension\OutputFormat;
|
|
||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
use Icinga\Application\Logger;
|
use Icinga\Application\Logger;
|
||||||
use Icinga\Data\ConfigObject;
|
use Icinga\Data\ConfigObject;
|
||||||
use Icinga\Protocol\File\FileReader;
|
use Icinga\Protocol\File\FileReader;
|
||||||
use \Zend_Controller_Action_Exception as ActionError;
|
use Icinga\Web\Controller;
|
||||||
|
use Icinga\Web\Url;
|
||||||
|
use Icinga\Web\Widget\Tabextension\DashboardAction;
|
||||||
|
use Icinga\Web\Widget\Tabextension\OutputFormat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class ListController
|
* Class ListController
|
||||||
@ -40,7 +39,7 @@ class ListController extends Controller
|
|||||||
public function applicationlogAction()
|
public function applicationlogAction()
|
||||||
{
|
{
|
||||||
if (! Logger::writesToFile()) {
|
if (! Logger::writesToFile()) {
|
||||||
throw new ActionError('Site not found', 404);
|
$this->httpNotFound('Page not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addTitleTab('application log');
|
$this->addTitleTab('application log');
|
||||||
|
@ -78,7 +78,6 @@ class UsergroupbackendController extends Controller
|
|||||||
$backendName = $this->params->getRequired('backend');
|
$backendName = $this->params->getRequired('backend');
|
||||||
|
|
||||||
$form = new UserGroupBackendForm();
|
$form = new UserGroupBackendForm();
|
||||||
$form->setAction(Url::fromRequest());
|
|
||||||
$form->setRedirectUrl('usergroupbackend/list');
|
$form->setRedirectUrl('usergroupbackend/list');
|
||||||
$form->setTitle(sprintf($this->translate('Edit User Group Backend %s'), $backendName));
|
$form->setTitle(sprintf($this->translate('Edit User Group Backend %s'), $backendName));
|
||||||
$form->setIniConfig(Config::app('groups'));
|
$form->setIniConfig(Config::app('groups'));
|
||||||
|
@ -46,3 +46,12 @@ Font license info
|
|||||||
Homepage: http://fontello.com
|
Homepage: http://fontello.com
|
||||||
|
|
||||||
|
|
||||||
|
## Typicons
|
||||||
|
|
||||||
|
(c) Stephen Hutchings 2012
|
||||||
|
|
||||||
|
Author: Stephen Hutchings
|
||||||
|
License: SIL (http://scripts.sil.org/OFL)
|
||||||
|
Homepage: http://typicons.com/
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ webfont pack. Details available in LICENSE.txt file.
|
|||||||
- If your project is open-source, usually, it will be ok to make LICENSE.txt
|
- If your project is open-source, usually, it will be ok to make LICENSE.txt
|
||||||
file publically available in your repository.
|
file publically available in your repository.
|
||||||
|
|
||||||
- Fonts, used in Fontello, don't require to make clickable links on your site.
|
- Fonts, used in Fontello, don't require a clickable link on your site.
|
||||||
But any kind of additional authors crediting is welcome.
|
But any kind of additional authors crediting is welcome.
|
||||||
================================================================================
|
================================================================================
|
||||||
|
|
||||||
@ -29,8 +29,8 @@ Comments on archive content
|
|||||||
|
|
||||||
- LICENSE.txt - license info about source fonts, used to build your one.
|
- LICENSE.txt - license info about source fonts, used to build your one.
|
||||||
|
|
||||||
- config.json - keeps your settings. You can import it back to fontello anytime,
|
- config.json - keeps your settings. You can import it back into fontello
|
||||||
to continue your work
|
anytime, to continue your work
|
||||||
|
|
||||||
|
|
||||||
Why so many CSS files ?
|
Why so many CSS files ?
|
||||||
@ -38,17 +38,17 @@ Why so many CSS files ?
|
|||||||
|
|
||||||
Because we like to fit all your needs :)
|
Because we like to fit all your needs :)
|
||||||
|
|
||||||
- basic file, <your_font_name>.css - is usually enougth, in contains @font-face
|
- basic file, <your_font_name>.css - is usually enough, it contains @font-face
|
||||||
and character codes definition
|
and character code definitions
|
||||||
|
|
||||||
- *-ie7.css - if you need IE7 support, but still don't wish to put char codes
|
- *-ie7.css - if you need IE7 support, but still don't wish to put char codes
|
||||||
directly into html
|
directly into html
|
||||||
|
|
||||||
- *-codes.css and *-ie7-codes.css - if you like to use your own @font-face
|
- *-codes.css and *-ie7-codes.css - if you like to use your own @font-face
|
||||||
rules, but still wish to benefit of css generation. That can be very
|
rules, but still wish to benefit from css generation. That can be very
|
||||||
convenient for automated assets build systems. When you need to update font -
|
convenient for automated asset build systems. When you need to update font -
|
||||||
no needs to manually edit files, just override old version with archive
|
no need to manually edit files, just override old version with archive
|
||||||
content. See fontello source codes for example.
|
content. See fontello source code for examples.
|
||||||
|
|
||||||
- *-embedded.css - basic css file, but with embedded WOFF font, to avoid
|
- *-embedded.css - basic css file, but with embedded WOFF font, to avoid
|
||||||
CORS issues in Firefox and IE9+, when fonts are hosted on the separate domain.
|
CORS issues in Firefox and IE9+, when fonts are hosted on the separate domain.
|
||||||
@ -63,11 +63,11 @@ Because we like to fit all your needs :)
|
|||||||
Attention for server setup
|
Attention for server setup
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
You MUST setup server to reply with proper `mime-types` for font files. In other
|
You MUST setup server to reply with proper `mime-types` for font files -
|
||||||
case, some browsers will fail to show fonts.
|
otherwise some browsers will fail to show fonts.
|
||||||
|
|
||||||
Usually, `apache` already has necessary settings, but `nginx` and other
|
Usually, `apache` already has necessary settings, but `nginx` and other
|
||||||
webservers should be tuned. Here is list of mime types for our file extentions:
|
webservers should be tuned. Here is list of mime types for our file extensions:
|
||||||
|
|
||||||
- `application/vnd.ms-fontobject` - eot
|
- `application/vnd.ms-fontobject` - eot
|
||||||
- `application/x-font-woff` - woff
|
- `application/x-font-woff` - woff
|
||||||
|
@ -672,6 +672,30 @@
|
|||||||
"code": 59492,
|
"code": 59492,
|
||||||
"src": "entypo"
|
"src": "entypo"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"uid": "c16a63e911bc47b46dc2a7129d2f0c46",
|
||||||
|
"css": "down-small",
|
||||||
|
"code": 59509,
|
||||||
|
"src": "typicons"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": "58b78b6ca784d5c3db5beefcd9e18061",
|
||||||
|
"css": "left-small",
|
||||||
|
"code": 59510,
|
||||||
|
"src": "typicons"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": "877a233d7fdca8a1d82615b96ed0d7a2",
|
||||||
|
"css": "right-small",
|
||||||
|
"code": 59511,
|
||||||
|
"src": "typicons"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": "62bc6fe2a82e4864e2b94d4c0985ee0c",
|
||||||
|
"css": "up-small",
|
||||||
|
"code": 59512,
|
||||||
|
"src": "typicons"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"uid": "b90d80c250a9bbdd6cd3fe00e6351710",
|
"uid": "b90d80c250a9bbdd6cd3fe00e6351710",
|
||||||
"css": "ok",
|
"css": "ok",
|
||||||
|
@ -116,3 +116,7 @@
|
|||||||
.icon-beaker:before { content: '\e872'; } /* '' */
|
.icon-beaker:before { content: '\e872'; } /* '' */
|
||||||
.icon-magic:before { content: '\e873'; } /* '' */
|
.icon-magic:before { content: '\e873'; } /* '' */
|
||||||
.icon-spin6:before { content: '\e874'; } /* '' */
|
.icon-spin6:before { content: '\e874'; } /* '' */
|
||||||
|
.icon-down-small:before { content: '\e875'; } /* '' */
|
||||||
|
.icon-left-small:before { content: '\e876'; } /* '' */
|
||||||
|
.icon-right-small:before { content: '\e877'; } /* '' */
|
||||||
|
.icon-up-small:before { content: '\e878'; } /* '' */
|
File diff suppressed because one or more lines are too long
@ -116,3 +116,7 @@
|
|||||||
.icon-beaker { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-beaker { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-magic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-magic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-spin6 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-spin6 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-down-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-left-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-right-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-up-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
@ -127,3 +127,7 @@
|
|||||||
.icon-beaker { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-beaker { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-magic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-magic { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
.icon-spin6 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
.icon-spin6 { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-down-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-left-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-right-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
||||||
|
.icon-up-small { *zoom: expression( this.runtimeStyle['zoom'] = '1', this.innerHTML = ' '); }
|
20
application/fonts/fontello-ifont/css/ifont.css
vendored
20
application/fonts/fontello-ifont/css/ifont.css
vendored
@ -1,10 +1,10 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'ifont';
|
font-family: 'ifont';
|
||||||
src: url('../font/ifont.eot?6491776');
|
src: url('../font/ifont.eot?54745533');
|
||||||
src: url('../font/ifont.eot?6491776#iefix') format('embedded-opentype'),
|
src: url('../font/ifont.eot?54745533#iefix') format('embedded-opentype'),
|
||||||
url('../font/ifont.woff?6491776') format('woff'),
|
url('../font/ifont.woff?54745533') format('woff'),
|
||||||
url('../font/ifont.ttf?6491776') format('truetype'),
|
url('../font/ifont.ttf?54745533') format('truetype'),
|
||||||
url('../font/ifont.svg?6491776#ifont') format('svg');
|
url('../font/ifont.svg?54745533#ifont') format('svg');
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
@ -14,7 +14,7 @@
|
|||||||
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
@media screen and (-webkit-min-device-pixel-ratio:0) {
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'ifont';
|
font-family: 'ifont';
|
||||||
src: url('../font/ifont.svg?6491776#ifont') format('svg');
|
src: url('../font/ifont.svg?54745533#ifont') format('svg');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@ -46,6 +46,10 @@
|
|||||||
/* you can be more comfortable with increased icons size */
|
/* you can be more comfortable with increased icons size */
|
||||||
/* font-size: 120%; */
|
/* font-size: 120%; */
|
||||||
|
|
||||||
|
/* Font smoothing. That was taken from TWBS */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
/* Uncomment for 3D effect */
|
/* Uncomment for 3D effect */
|
||||||
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
|
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
|
||||||
}
|
}
|
||||||
@ -167,3 +171,7 @@
|
|||||||
.icon-beaker:before { content: '\e872'; } /* '' */
|
.icon-beaker:before { content: '\e872'; } /* '' */
|
||||||
.icon-magic:before { content: '\e873'; } /* '' */
|
.icon-magic:before { content: '\e873'; } /* '' */
|
||||||
.icon-spin6:before { content: '\e874'; } /* '' */
|
.icon-spin6:before { content: '\e874'; } /* '' */
|
||||||
|
.icon-down-small:before { content: '\e875'; } /* '' */
|
||||||
|
.icon-left-small:before { content: '\e876'; } /* '' */
|
||||||
|
.icon-right-small:before { content: '\e877'; } /* '' */
|
||||||
|
.icon-up-small:before { content: '\e878'; } /* '' */
|
@ -226,9 +226,55 @@ body {
|
|||||||
}
|
}
|
||||||
.i-code {
|
.i-code {
|
||||||
display: none;
|
display: none;
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'ifont';
|
||||||
|
src: url('./font/ifont.eot?11424534');
|
||||||
|
src: url('./font/ifont.eot?11424534#iefix') format('embedded-opentype'),
|
||||||
|
url('./font/ifont.woff?11424534') format('woff'),
|
||||||
|
url('./font/ifont.ttf?11424534') format('truetype'),
|
||||||
|
url('./font/ifont.svg?11424534#ifont') format('svg');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.demo-icon
|
||||||
|
{
|
||||||
|
font-family: "ifont";
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: normal;
|
||||||
|
speak: none;
|
||||||
|
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: inherit;
|
||||||
|
width: 1em;
|
||||||
|
margin-right: .2em;
|
||||||
|
text-align: center;
|
||||||
|
/* opacity: .8; */
|
||||||
|
|
||||||
|
/* For safety - reset parent styles, that can break glyph codes*/
|
||||||
|
font-variant: normal;
|
||||||
|
text-transform: none;
|
||||||
|
|
||||||
|
/* fix buttons height, for twitter bootstrap */
|
||||||
|
line-height: 1em;
|
||||||
|
|
||||||
|
/* Animation center compensation - margins should be symmetric */
|
||||||
|
/* remove if not needed */
|
||||||
|
margin-left: .2em;
|
||||||
|
|
||||||
|
/* You can be more comfortable with increased icons size */
|
||||||
|
/* font-size: 120%; */
|
||||||
|
|
||||||
|
/* Font smoothing. That was taken from TWBS */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
|
/* Uncomment for 3D effect */
|
||||||
|
/* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<link rel="stylesheet" href="css/ifont.css">
|
|
||||||
<link rel="stylesheet" href="css/animation.css"><!--[if IE 7]><link rel="stylesheet" href="css/ifont-ie7.css"><![endif]-->
|
<link rel="stylesheet" href="css/animation.css"><!--[if IE 7]><link rel="stylesheet" href="css/ifont-ie7.css"><![endif]-->
|
||||||
<script>
|
<script>
|
||||||
function toggleCodes(on) {
|
function toggleCodes(on) {
|
||||||
@ -255,181 +301,187 @@ body {
|
|||||||
</div>
|
</div>
|
||||||
<div id="icons" class="container">
|
<div id="icons" class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe800" class="the-icons span3"><i class="icon-dashboard"></i> <span class="i-name">icon-dashboard</span><span class="i-code">0xe800</span></div>
|
<div title="Code: 0xe800" class="the-icons span3"><i class="demo-icon icon-dashboard"></i> <span class="i-name">icon-dashboard</span><span class="i-code">0xe800</span></div>
|
||||||
<div title="Code: 0xe801" class="the-icons span3"><i class="icon-user"></i> <span class="i-name">icon-user</span><span class="i-code">0xe801</span></div>
|
<div title="Code: 0xe801" class="the-icons span3"><i class="demo-icon icon-user"></i> <span class="i-name">icon-user</span><span class="i-code">0xe801</span></div>
|
||||||
<div title="Code: 0xe802" class="the-icons span3"><i class="icon-users"></i> <span class="i-name">icon-users</span><span class="i-code">0xe802</span></div>
|
<div title="Code: 0xe802" class="the-icons span3"><i class="demo-icon icon-users"></i> <span class="i-name">icon-users</span><span class="i-code">0xe802</span></div>
|
||||||
<div title="Code: 0xe803" class="the-icons span3"><i class="icon-ok"></i> <span class="i-name">icon-ok</span><span class="i-code">0xe803</span></div>
|
<div title="Code: 0xe803" class="the-icons span3"><i class="demo-icon icon-ok"></i> <span class="i-name">icon-ok</span><span class="i-code">0xe803</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe804" class="the-icons span3"><i class="icon-cancel"></i> <span class="i-name">icon-cancel</span><span class="i-code">0xe804</span></div>
|
<div title="Code: 0xe804" class="the-icons span3"><i class="demo-icon icon-cancel"></i> <span class="i-name">icon-cancel</span><span class="i-code">0xe804</span></div>
|
||||||
<div title="Code: 0xe805" class="the-icons span3"><i class="icon-plus"></i> <span class="i-name">icon-plus</span><span class="i-code">0xe805</span></div>
|
<div title="Code: 0xe805" class="the-icons span3"><i class="demo-icon icon-plus"></i> <span class="i-name">icon-plus</span><span class="i-code">0xe805</span></div>
|
||||||
<div title="Code: 0xe806" class="the-icons span3"><i class="icon-minus"></i> <span class="i-name">icon-minus</span><span class="i-code">0xe806</span></div>
|
<div title="Code: 0xe806" class="the-icons span3"><i class="demo-icon icon-minus"></i> <span class="i-name">icon-minus</span><span class="i-code">0xe806</span></div>
|
||||||
<div title="Code: 0xe807" class="the-icons span3"><i class="icon-folder-empty"></i> <span class="i-name">icon-folder-empty</span><span class="i-code">0xe807</span></div>
|
<div title="Code: 0xe807" class="the-icons span3"><i class="demo-icon icon-folder-empty"></i> <span class="i-name">icon-folder-empty</span><span class="i-code">0xe807</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe808" class="the-icons span3"><i class="icon-download"></i> <span class="i-name">icon-download</span><span class="i-code">0xe808</span></div>
|
<div title="Code: 0xe808" class="the-icons span3"><i class="demo-icon icon-download"></i> <span class="i-name">icon-download</span><span class="i-code">0xe808</span></div>
|
||||||
<div title="Code: 0xe809" class="the-icons span3"><i class="icon-upload"></i> <span class="i-name">icon-upload</span><span class="i-code">0xe809</span></div>
|
<div title="Code: 0xe809" class="the-icons span3"><i class="demo-icon icon-upload"></i> <span class="i-name">icon-upload</span><span class="i-code">0xe809</span></div>
|
||||||
<div title="Code: 0xe80a" class="the-icons span3"><i class="icon-git"></i> <span class="i-name">icon-git</span><span class="i-code">0xe80a</span></div>
|
<div title="Code: 0xe80a" class="the-icons span3"><i class="demo-icon icon-git"></i> <span class="i-name">icon-git</span><span class="i-code">0xe80a</span></div>
|
||||||
<div title="Code: 0xe80b" class="the-icons span3"><i class="icon-cubes"></i> <span class="i-name">icon-cubes</span><span class="i-code">0xe80b</span></div>
|
<div title="Code: 0xe80b" class="the-icons span3"><i class="demo-icon icon-cubes"></i> <span class="i-name">icon-cubes</span><span class="i-code">0xe80b</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe80c" class="the-icons span3"><i class="icon-database"></i> <span class="i-name">icon-database</span><span class="i-code">0xe80c</span></div>
|
<div title="Code: 0xe80c" class="the-icons span3"><i class="demo-icon icon-database"></i> <span class="i-name">icon-database</span><span class="i-code">0xe80c</span></div>
|
||||||
<div title="Code: 0xe80d" class="the-icons span3"><i class="icon-gauge"></i> <span class="i-name">icon-gauge</span><span class="i-code">0xe80d</span></div>
|
<div title="Code: 0xe80d" class="the-icons span3"><i class="demo-icon icon-gauge"></i> <span class="i-name">icon-gauge</span><span class="i-code">0xe80d</span></div>
|
||||||
<div title="Code: 0xe80e" class="the-icons span3"><i class="icon-sitemap"></i> <span class="i-name">icon-sitemap</span><span class="i-code">0xe80e</span></div>
|
<div title="Code: 0xe80e" class="the-icons span3"><i class="demo-icon icon-sitemap"></i> <span class="i-name">icon-sitemap</span><span class="i-code">0xe80e</span></div>
|
||||||
<div title="Code: 0xe80f" class="the-icons span3"><i class="icon-sort-name-up"></i> <span class="i-name">icon-sort-name-up</span><span class="i-code">0xe80f</span></div>
|
<div title="Code: 0xe80f" class="the-icons span3"><i class="demo-icon icon-sort-name-up"></i> <span class="i-name">icon-sort-name-up</span><span class="i-code">0xe80f</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe810" class="the-icons span3"><i class="icon-sort-name-down"></i> <span class="i-name">icon-sort-name-down</span><span class="i-code">0xe810</span></div>
|
<div title="Code: 0xe810" class="the-icons span3"><i class="demo-icon icon-sort-name-down"></i> <span class="i-name">icon-sort-name-down</span><span class="i-code">0xe810</span></div>
|
||||||
<div title="Code: 0xe811" class="the-icons span3"><i class="icon-megaphone"></i> <span class="i-name">icon-megaphone</span><span class="i-code">0xe811</span></div>
|
<div title="Code: 0xe811" class="the-icons span3"><i class="demo-icon icon-megaphone"></i> <span class="i-name">icon-megaphone</span><span class="i-code">0xe811</span></div>
|
||||||
<div title="Code: 0xe812" class="the-icons span3"><i class="icon-bug"></i> <span class="i-name">icon-bug</span><span class="i-code">0xe812</span></div>
|
<div title="Code: 0xe812" class="the-icons span3"><i class="demo-icon icon-bug"></i> <span class="i-name">icon-bug</span><span class="i-code">0xe812</span></div>
|
||||||
<div title="Code: 0xe813" class="the-icons span3"><i class="icon-tasks"></i> <span class="i-name">icon-tasks</span><span class="i-code">0xe813</span></div>
|
<div title="Code: 0xe813" class="the-icons span3"><i class="demo-icon icon-tasks"></i> <span class="i-name">icon-tasks</span><span class="i-code">0xe813</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe814" class="the-icons span3"><i class="icon-filter"></i> <span class="i-name">icon-filter</span><span class="i-code">0xe814</span></div>
|
<div title="Code: 0xe814" class="the-icons span3"><i class="demo-icon icon-filter"></i> <span class="i-name">icon-filter</span><span class="i-code">0xe814</span></div>
|
||||||
<div title="Code: 0xe815" class="the-icons span3"><i class="icon-off"></i> <span class="i-name">icon-off</span><span class="i-code">0xe815</span></div>
|
<div title="Code: 0xe815" class="the-icons span3"><i class="demo-icon icon-off"></i> <span class="i-name">icon-off</span><span class="i-code">0xe815</span></div>
|
||||||
<div title="Code: 0xe816" class="the-icons span3"><i class="icon-book"></i> <span class="i-name">icon-book</span><span class="i-code">0xe816</span></div>
|
<div title="Code: 0xe816" class="the-icons span3"><i class="demo-icon icon-book"></i> <span class="i-name">icon-book</span><span class="i-code">0xe816</span></div>
|
||||||
<div title="Code: 0xe817" class="the-icons span3"><i class="icon-paste"></i> <span class="i-name">icon-paste</span><span class="i-code">0xe817</span></div>
|
<div title="Code: 0xe817" class="the-icons span3"><i class="demo-icon icon-paste"></i> <span class="i-name">icon-paste</span><span class="i-code">0xe817</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe818" class="the-icons span3"><i class="icon-scissors"></i> <span class="i-name">icon-scissors</span><span class="i-code">0xe818</span></div>
|
<div title="Code: 0xe818" class="the-icons span3"><i class="demo-icon icon-scissors"></i> <span class="i-name">icon-scissors</span><span class="i-code">0xe818</span></div>
|
||||||
<div title="Code: 0xe819" class="the-icons span3"><i class="icon-globe"></i> <span class="i-name">icon-globe</span><span class="i-code">0xe819</span></div>
|
<div title="Code: 0xe819" class="the-icons span3"><i class="demo-icon icon-globe"></i> <span class="i-name">icon-globe</span><span class="i-code">0xe819</span></div>
|
||||||
<div title="Code: 0xe81a" class="the-icons span3"><i class="icon-cloud"></i> <span class="i-name">icon-cloud</span><span class="i-code">0xe81a</span></div>
|
<div title="Code: 0xe81a" class="the-icons span3"><i class="demo-icon icon-cloud"></i> <span class="i-name">icon-cloud</span><span class="i-code">0xe81a</span></div>
|
||||||
<div title="Code: 0xe81b" class="the-icons span3"><i class="icon-flash"></i> <span class="i-name">icon-flash</span><span class="i-code">0xe81b</span></div>
|
<div title="Code: 0xe81b" class="the-icons span3"><i class="demo-icon icon-flash"></i> <span class="i-name">icon-flash</span><span class="i-code">0xe81b</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe81c" class="the-icons span3"><i class="icon-barchart"></i> <span class="i-name">icon-barchart</span><span class="i-code">0xe81c</span></div>
|
<div title="Code: 0xe81c" class="the-icons span3"><i class="demo-icon icon-barchart"></i> <span class="i-name">icon-barchart</span><span class="i-code">0xe81c</span></div>
|
||||||
<div title="Code: 0xe81d" class="the-icons span3"><i class="icon-down-dir"></i> <span class="i-name">icon-down-dir</span><span class="i-code">0xe81d</span></div>
|
<div title="Code: 0xe81d" class="the-icons span3"><i class="demo-icon icon-down-dir"></i> <span class="i-name">icon-down-dir</span><span class="i-code">0xe81d</span></div>
|
||||||
<div title="Code: 0xe81e" class="the-icons span3"><i class="icon-up-dir"></i> <span class="i-name">icon-up-dir</span><span class="i-code">0xe81e</span></div>
|
<div title="Code: 0xe81e" class="the-icons span3"><i class="demo-icon icon-up-dir"></i> <span class="i-name">icon-up-dir</span><span class="i-code">0xe81e</span></div>
|
||||||
<div title="Code: 0xe81f" class="the-icons span3"><i class="icon-left-dir"></i> <span class="i-name">icon-left-dir</span><span class="i-code">0xe81f</span></div>
|
<div title="Code: 0xe81f" class="the-icons span3"><i class="demo-icon icon-left-dir"></i> <span class="i-name">icon-left-dir</span><span class="i-code">0xe81f</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe820" class="the-icons span3"><i class="icon-right-dir"></i> <span class="i-name">icon-right-dir</span><span class="i-code">0xe820</span></div>
|
<div title="Code: 0xe820" class="the-icons span3"><i class="demo-icon icon-right-dir"></i> <span class="i-name">icon-right-dir</span><span class="i-code">0xe820</span></div>
|
||||||
<div title="Code: 0xe821" class="the-icons span3"><i class="icon-down-open"></i> <span class="i-name">icon-down-open</span><span class="i-code">0xe821</span></div>
|
<div title="Code: 0xe821" class="the-icons span3"><i class="demo-icon icon-down-open"></i> <span class="i-name">icon-down-open</span><span class="i-code">0xe821</span></div>
|
||||||
<div title="Code: 0xe822" class="the-icons span3"><i class="icon-right-open"></i> <span class="i-name">icon-right-open</span><span class="i-code">0xe822</span></div>
|
<div title="Code: 0xe822" class="the-icons span3"><i class="demo-icon icon-right-open"></i> <span class="i-name">icon-right-open</span><span class="i-code">0xe822</span></div>
|
||||||
<div title="Code: 0xe823" class="the-icons span3"><i class="icon-up-open"></i> <span class="i-name">icon-up-open</span><span class="i-code">0xe823</span></div>
|
<div title="Code: 0xe823" class="the-icons span3"><i class="demo-icon icon-up-open"></i> <span class="i-name">icon-up-open</span><span class="i-code">0xe823</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe824" class="the-icons span3"><i class="icon-left-open"></i> <span class="i-name">icon-left-open</span><span class="i-code">0xe824</span></div>
|
<div title="Code: 0xe824" class="the-icons span3"><i class="demo-icon icon-left-open"></i> <span class="i-name">icon-left-open</span><span class="i-code">0xe824</span></div>
|
||||||
<div title="Code: 0xe825" class="the-icons span3"><i class="icon-up-big"></i> <span class="i-name">icon-up-big</span><span class="i-code">0xe825</span></div>
|
<div title="Code: 0xe825" class="the-icons span3"><i class="demo-icon icon-up-big"></i> <span class="i-name">icon-up-big</span><span class="i-code">0xe825</span></div>
|
||||||
<div title="Code: 0xe826" class="the-icons span3"><i class="icon-right-big"></i> <span class="i-name">icon-right-big</span><span class="i-code">0xe826</span></div>
|
<div title="Code: 0xe826" class="the-icons span3"><i class="demo-icon icon-right-big"></i> <span class="i-name">icon-right-big</span><span class="i-code">0xe826</span></div>
|
||||||
<div title="Code: 0xe827" class="the-icons span3"><i class="icon-left-big"></i> <span class="i-name">icon-left-big</span><span class="i-code">0xe827</span></div>
|
<div title="Code: 0xe827" class="the-icons span3"><i class="demo-icon icon-left-big"></i> <span class="i-name">icon-left-big</span><span class="i-code">0xe827</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe828" class="the-icons span3"><i class="icon-down-big"></i> <span class="i-name">icon-down-big</span><span class="i-code">0xe828</span></div>
|
<div title="Code: 0xe828" class="the-icons span3"><i class="demo-icon icon-down-big"></i> <span class="i-name">icon-down-big</span><span class="i-code">0xe828</span></div>
|
||||||
<div title="Code: 0xe829" class="the-icons span3"><i class="icon-resize-full-alt"></i> <span class="i-name">icon-resize-full-alt</span><span class="i-code">0xe829</span></div>
|
<div title="Code: 0xe829" class="the-icons span3"><i class="demo-icon icon-resize-full-alt"></i> <span class="i-name">icon-resize-full-alt</span><span class="i-code">0xe829</span></div>
|
||||||
<div title="Code: 0xe82a" class="the-icons span3"><i class="icon-resize-full"></i> <span class="i-name">icon-resize-full</span><span class="i-code">0xe82a</span></div>
|
<div title="Code: 0xe82a" class="the-icons span3"><i class="demo-icon icon-resize-full"></i> <span class="i-name">icon-resize-full</span><span class="i-code">0xe82a</span></div>
|
||||||
<div title="Code: 0xe82b" class="the-icons span3"><i class="icon-resize-small"></i> <span class="i-name">icon-resize-small</span><span class="i-code">0xe82b</span></div>
|
<div title="Code: 0xe82b" class="the-icons span3"><i class="demo-icon icon-resize-small"></i> <span class="i-name">icon-resize-small</span><span class="i-code">0xe82b</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe82c" class="the-icons span3"><i class="icon-move"></i> <span class="i-name">icon-move</span><span class="i-code">0xe82c</span></div>
|
<div title="Code: 0xe82c" class="the-icons span3"><i class="demo-icon icon-move"></i> <span class="i-name">icon-move</span><span class="i-code">0xe82c</span></div>
|
||||||
<div title="Code: 0xe82d" class="the-icons span3"><i class="icon-resize-horizontal"></i> <span class="i-name">icon-resize-horizontal</span><span class="i-code">0xe82d</span></div>
|
<div title="Code: 0xe82d" class="the-icons span3"><i class="demo-icon icon-resize-horizontal"></i> <span class="i-name">icon-resize-horizontal</span><span class="i-code">0xe82d</span></div>
|
||||||
<div title="Code: 0xe82e" class="the-icons span3"><i class="icon-resize-vertical"></i> <span class="i-name">icon-resize-vertical</span><span class="i-code">0xe82e</span></div>
|
<div title="Code: 0xe82e" class="the-icons span3"><i class="demo-icon icon-resize-vertical"></i> <span class="i-name">icon-resize-vertical</span><span class="i-code">0xe82e</span></div>
|
||||||
<div title="Code: 0xe82f" class="the-icons span3"><i class="icon-zoom-in"></i> <span class="i-name">icon-zoom-in</span><span class="i-code">0xe82f</span></div>
|
<div title="Code: 0xe82f" class="the-icons span3"><i class="demo-icon icon-zoom-in"></i> <span class="i-name">icon-zoom-in</span><span class="i-code">0xe82f</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe830" class="the-icons span3"><i class="icon-block"></i> <span class="i-name">icon-block</span><span class="i-code">0xe830</span></div>
|
<div title="Code: 0xe830" class="the-icons span3"><i class="demo-icon icon-block"></i> <span class="i-name">icon-block</span><span class="i-code">0xe830</span></div>
|
||||||
<div title="Code: 0xe831" class="the-icons span3"><i class="icon-zoom-out"></i> <span class="i-name">icon-zoom-out</span><span class="i-code">0xe831</span></div>
|
<div title="Code: 0xe831" class="the-icons span3"><i class="demo-icon icon-zoom-out"></i> <span class="i-name">icon-zoom-out</span><span class="i-code">0xe831</span></div>
|
||||||
<div title="Code: 0xe832" class="the-icons span3"><i class="icon-lightbulb"></i> <span class="i-name">icon-lightbulb</span><span class="i-code">0xe832</span></div>
|
<div title="Code: 0xe832" class="the-icons span3"><i class="demo-icon icon-lightbulb"></i> <span class="i-name">icon-lightbulb</span><span class="i-code">0xe832</span></div>
|
||||||
<div title="Code: 0xe833" class="the-icons span3"><i class="icon-clock"></i> <span class="i-name">icon-clock</span><span class="i-code">0xe833</span></div>
|
<div title="Code: 0xe833" class="the-icons span3"><i class="demo-icon icon-clock"></i> <span class="i-name">icon-clock</span><span class="i-code">0xe833</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe834" class="the-icons span3"><i class="icon-volume-up"></i> <span class="i-name">icon-volume-up</span><span class="i-code">0xe834</span></div>
|
<div title="Code: 0xe834" class="the-icons span3"><i class="demo-icon icon-volume-up"></i> <span class="i-name">icon-volume-up</span><span class="i-code">0xe834</span></div>
|
||||||
<div title="Code: 0xe835" class="the-icons span3"><i class="icon-volume-down"></i> <span class="i-name">icon-volume-down</span><span class="i-code">0xe835</span></div>
|
<div title="Code: 0xe835" class="the-icons span3"><i class="demo-icon icon-volume-down"></i> <span class="i-name">icon-volume-down</span><span class="i-code">0xe835</span></div>
|
||||||
<div title="Code: 0xe836" class="the-icons span3"><i class="icon-volume-off"></i> <span class="i-name">icon-volume-off</span><span class="i-code">0xe836</span></div>
|
<div title="Code: 0xe836" class="the-icons span3"><i class="demo-icon icon-volume-off"></i> <span class="i-name">icon-volume-off</span><span class="i-code">0xe836</span></div>
|
||||||
<div title="Code: 0xe837" class="the-icons span3"><i class="icon-mute"></i> <span class="i-name">icon-mute</span><span class="i-code">0xe837</span></div>
|
<div title="Code: 0xe837" class="the-icons span3"><i class="demo-icon icon-mute"></i> <span class="i-name">icon-mute</span><span class="i-code">0xe837</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe838" class="the-icons span3"><i class="icon-mic"></i> <span class="i-name">icon-mic</span><span class="i-code">0xe838</span></div>
|
<div title="Code: 0xe838" class="the-icons span3"><i class="demo-icon icon-mic"></i> <span class="i-name">icon-mic</span><span class="i-code">0xe838</span></div>
|
||||||
<div title="Code: 0xe839" class="the-icons span3"><i class="icon-endtime"></i> <span class="i-name">icon-endtime</span><span class="i-code">0xe839</span></div>
|
<div title="Code: 0xe839" class="the-icons span3"><i class="demo-icon icon-endtime"></i> <span class="i-name">icon-endtime</span><span class="i-code">0xe839</span></div>
|
||||||
<div title="Code: 0xe83a" class="the-icons span3"><i class="icon-starttime"></i> <span class="i-name">icon-starttime</span><span class="i-code">0xe83a</span></div>
|
<div title="Code: 0xe83a" class="the-icons span3"><i class="demo-icon icon-starttime"></i> <span class="i-name">icon-starttime</span><span class="i-code">0xe83a</span></div>
|
||||||
<div title="Code: 0xe83b" class="the-icons span3"><i class="icon-calendar-empty"></i> <span class="i-name">icon-calendar-empty</span><span class="i-code">0xe83b</span></div>
|
<div title="Code: 0xe83b" class="the-icons span3"><i class="demo-icon icon-calendar-empty"></i> <span class="i-name">icon-calendar-empty</span><span class="i-code">0xe83b</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe83c" class="the-icons span3"><i class="icon-calendar"></i> <span class="i-name">icon-calendar</span><span class="i-code">0xe83c</span></div>
|
<div title="Code: 0xe83c" class="the-icons span3"><i class="demo-icon icon-calendar"></i> <span class="i-name">icon-calendar</span><span class="i-code">0xe83c</span></div>
|
||||||
<div title="Code: 0xe83d" class="the-icons span3"><i class="icon-wrench"></i> <span class="i-name">icon-wrench</span><span class="i-code">0xe83d</span></div>
|
<div title="Code: 0xe83d" class="the-icons span3"><i class="demo-icon icon-wrench"></i> <span class="i-name">icon-wrench</span><span class="i-code">0xe83d</span></div>
|
||||||
<div title="Code: 0xe83e" class="the-icons span3"><i class="icon-sliders"></i> <span class="i-name">icon-sliders</span><span class="i-code">0xe83e</span></div>
|
<div title="Code: 0xe83e" class="the-icons span3"><i class="demo-icon icon-sliders"></i> <span class="i-name">icon-sliders</span><span class="i-code">0xe83e</span></div>
|
||||||
<div title="Code: 0xe83f" class="the-icons span3"><i class="icon-services"></i> <span class="i-name">icon-services</span><span class="i-code">0xe83f</span></div>
|
<div title="Code: 0xe83f" class="the-icons span3"><i class="demo-icon icon-services"></i> <span class="i-name">icon-services</span><span class="i-code">0xe83f</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe840" class="the-icons span3"><i class="icon-service"></i> <span class="i-name">icon-service</span><span class="i-code">0xe840</span></div>
|
<div title="Code: 0xe840" class="the-icons span3"><i class="demo-icon icon-service"></i> <span class="i-name">icon-service</span><span class="i-code">0xe840</span></div>
|
||||||
<div title="Code: 0xe841" class="the-icons span3"><i class="icon-phone"></i> <span class="i-name">icon-phone</span><span class="i-code">0xe841</span></div>
|
<div title="Code: 0xe841" class="the-icons span3"><i class="demo-icon icon-phone"></i> <span class="i-name">icon-phone</span><span class="i-code">0xe841</span></div>
|
||||||
<div title="Code: 0xe842" class="the-icons span3"><i class="icon-file-pdf"></i> <span class="i-name">icon-file-pdf</span><span class="i-code">0xe842</span></div>
|
<div title="Code: 0xe842" class="the-icons span3"><i class="demo-icon icon-file-pdf"></i> <span class="i-name">icon-file-pdf</span><span class="i-code">0xe842</span></div>
|
||||||
<div title="Code: 0xe843" class="the-icons span3"><i class="icon-file-word"></i> <span class="i-name">icon-file-word</span><span class="i-code">0xe843</span></div>
|
<div title="Code: 0xe843" class="the-icons span3"><i class="demo-icon icon-file-word"></i> <span class="i-name">icon-file-word</span><span class="i-code">0xe843</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe844" class="the-icons span3"><i class="icon-file-excel"></i> <span class="i-name">icon-file-excel</span><span class="i-code">0xe844</span></div>
|
<div title="Code: 0xe844" class="the-icons span3"><i class="demo-icon icon-file-excel"></i> <span class="i-name">icon-file-excel</span><span class="i-code">0xe844</span></div>
|
||||||
<div title="Code: 0xe845" class="the-icons span3"><i class="icon-doc-text"></i> <span class="i-name">icon-doc-text</span><span class="i-code">0xe845</span></div>
|
<div title="Code: 0xe845" class="the-icons span3"><i class="demo-icon icon-doc-text"></i> <span class="i-name">icon-doc-text</span><span class="i-code">0xe845</span></div>
|
||||||
<div title="Code: 0xe846" class="the-icons span3"><i class="icon-trash"></i> <span class="i-name">icon-trash</span><span class="i-code">0xe846</span></div>
|
<div title="Code: 0xe846" class="the-icons span3"><i class="demo-icon icon-trash"></i> <span class="i-name">icon-trash</span><span class="i-code">0xe846</span></div>
|
||||||
<div title="Code: 0xe847" class="the-icons span3"><i class="icon-comment-empty"></i> <span class="i-name">icon-comment-empty</span><span class="i-code">0xe847</span></div>
|
<div title="Code: 0xe847" class="the-icons span3"><i class="demo-icon icon-comment-empty"></i> <span class="i-name">icon-comment-empty</span><span class="i-code">0xe847</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe848" class="the-icons span3"><i class="icon-comment"></i> <span class="i-name">icon-comment</span><span class="i-code">0xe848</span></div>
|
<div title="Code: 0xe848" class="the-icons span3"><i class="demo-icon icon-comment"></i> <span class="i-name">icon-comment</span><span class="i-code">0xe848</span></div>
|
||||||
<div title="Code: 0xe849" class="the-icons span3"><i class="icon-chat"></i> <span class="i-name">icon-chat</span><span class="i-code">0xe849</span></div>
|
<div title="Code: 0xe849" class="the-icons span3"><i class="demo-icon icon-chat"></i> <span class="i-name">icon-chat</span><span class="i-code">0xe849</span></div>
|
||||||
<div title="Code: 0xe84a" class="the-icons span3"><i class="icon-chat-empty"></i> <span class="i-name">icon-chat-empty</span><span class="i-code">0xe84a</span></div>
|
<div title="Code: 0xe84a" class="the-icons span3"><i class="demo-icon icon-chat-empty"></i> <span class="i-name">icon-chat-empty</span><span class="i-code">0xe84a</span></div>
|
||||||
<div title="Code: 0xe84b" class="the-icons span3"><i class="icon-bell"></i> <span class="i-name">icon-bell</span><span class="i-code">0xe84b</span></div>
|
<div title="Code: 0xe84b" class="the-icons span3"><i class="demo-icon icon-bell"></i> <span class="i-name">icon-bell</span><span class="i-code">0xe84b</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe84c" class="the-icons span3"><i class="icon-bell-alt"></i> <span class="i-name">icon-bell-alt</span><span class="i-code">0xe84c</span></div>
|
<div title="Code: 0xe84c" class="the-icons span3"><i class="demo-icon icon-bell-alt"></i> <span class="i-name">icon-bell-alt</span><span class="i-code">0xe84c</span></div>
|
||||||
<div title="Code: 0xe84d" class="the-icons span3"><i class="icon-attention-alt"></i> <span class="i-name">icon-attention-alt</span><span class="i-code">0xe84d</span></div>
|
<div title="Code: 0xe84d" class="the-icons span3"><i class="demo-icon icon-attention-alt"></i> <span class="i-name">icon-attention-alt</span><span class="i-code">0xe84d</span></div>
|
||||||
<div title="Code: 0xe84e" class="the-icons span3"><i class="icon-print"></i> <span class="i-name">icon-print</span><span class="i-code">0xe84e</span></div>
|
<div title="Code: 0xe84e" class="the-icons span3"><i class="demo-icon icon-print"></i> <span class="i-name">icon-print</span><span class="i-code">0xe84e</span></div>
|
||||||
<div title="Code: 0xe84f" class="the-icons span3"><i class="icon-edit"></i> <span class="i-name">icon-edit</span><span class="i-code">0xe84f</span></div>
|
<div title="Code: 0xe84f" class="the-icons span3"><i class="demo-icon icon-edit"></i> <span class="i-name">icon-edit</span><span class="i-code">0xe84f</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe850" class="the-icons span3"><i class="icon-forward"></i> <span class="i-name">icon-forward</span><span class="i-code">0xe850</span></div>
|
<div title="Code: 0xe850" class="the-icons span3"><i class="demo-icon icon-forward"></i> <span class="i-name">icon-forward</span><span class="i-code">0xe850</span></div>
|
||||||
<div title="Code: 0xe851" class="the-icons span3"><i class="icon-reply"></i> <span class="i-name">icon-reply</span><span class="i-code">0xe851</span></div>
|
<div title="Code: 0xe851" class="the-icons span3"><i class="demo-icon icon-reply"></i> <span class="i-name">icon-reply</span><span class="i-code">0xe851</span></div>
|
||||||
<div title="Code: 0xe852" class="the-icons span3"><i class="icon-reply-all"></i> <span class="i-name">icon-reply-all</span><span class="i-code">0xe852</span></div>
|
<div title="Code: 0xe852" class="the-icons span3"><i class="demo-icon icon-reply-all"></i> <span class="i-name">icon-reply-all</span><span class="i-code">0xe852</span></div>
|
||||||
<div title="Code: 0xe853" class="the-icons span3"><i class="icon-eye"></i> <span class="i-name">icon-eye</span><span class="i-code">0xe853</span></div>
|
<div title="Code: 0xe853" class="the-icons span3"><i class="demo-icon icon-eye"></i> <span class="i-name">icon-eye</span><span class="i-code">0xe853</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe854" class="the-icons span3"><i class="icon-tag"></i> <span class="i-name">icon-tag</span><span class="i-code">0xe854</span></div>
|
<div title="Code: 0xe854" class="the-icons span3"><i class="demo-icon icon-tag"></i> <span class="i-name">icon-tag</span><span class="i-code">0xe854</span></div>
|
||||||
<div title="Code: 0xe855" class="the-icons span3"><i class="icon-tags"></i> <span class="i-name">icon-tags</span><span class="i-code">0xe855</span></div>
|
<div title="Code: 0xe855" class="the-icons span3"><i class="demo-icon icon-tags"></i> <span class="i-name">icon-tags</span><span class="i-code">0xe855</span></div>
|
||||||
<div title="Code: 0xe856" class="the-icons span3"><i class="icon-lock-open-alt"></i> <span class="i-name">icon-lock-open-alt</span><span class="i-code">0xe856</span></div>
|
<div title="Code: 0xe856" class="the-icons span3"><i class="demo-icon icon-lock-open-alt"></i> <span class="i-name">icon-lock-open-alt</span><span class="i-code">0xe856</span></div>
|
||||||
<div title="Code: 0xe857" class="the-icons span3"><i class="icon-lock-open"></i> <span class="i-name">icon-lock-open</span><span class="i-code">0xe857</span></div>
|
<div title="Code: 0xe857" class="the-icons span3"><i class="demo-icon icon-lock-open"></i> <span class="i-name">icon-lock-open</span><span class="i-code">0xe857</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe858" class="the-icons span3"><i class="icon-lock"></i> <span class="i-name">icon-lock</span><span class="i-code">0xe858</span></div>
|
<div title="Code: 0xe858" class="the-icons span3"><i class="demo-icon icon-lock"></i> <span class="i-name">icon-lock</span><span class="i-code">0xe858</span></div>
|
||||||
<div title="Code: 0xe859" class="the-icons span3"><i class="icon-home"></i> <span class="i-name">icon-home</span><span class="i-code">0xe859</span></div>
|
<div title="Code: 0xe859" class="the-icons span3"><i class="demo-icon icon-home"></i> <span class="i-name">icon-home</span><span class="i-code">0xe859</span></div>
|
||||||
<div title="Code: 0xe85a" class="the-icons span3"><i class="icon-info"></i> <span class="i-name">icon-info</span><span class="i-code">0xe85a</span></div>
|
<div title="Code: 0xe85a" class="the-icons span3"><i class="demo-icon icon-info"></i> <span class="i-name">icon-info</span><span class="i-code">0xe85a</span></div>
|
||||||
<div title="Code: 0xe85b" class="the-icons span3"><i class="icon-help"></i> <span class="i-name">icon-help</span><span class="i-code">0xe85b</span></div>
|
<div title="Code: 0xe85b" class="the-icons span3"><i class="demo-icon icon-help"></i> <span class="i-name">icon-help</span><span class="i-code">0xe85b</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe85c" class="the-icons span3"><i class="icon-search"></i> <span class="i-name">icon-search</span><span class="i-code">0xe85c</span></div>
|
<div title="Code: 0xe85c" class="the-icons span3"><i class="demo-icon icon-search"></i> <span class="i-name">icon-search</span><span class="i-code">0xe85c</span></div>
|
||||||
<div title="Code: 0xe85d" class="the-icons span3"><i class="icon-flapping"></i> <span class="i-name">icon-flapping</span><span class="i-code">0xe85d</span></div>
|
<div title="Code: 0xe85d" class="the-icons span3"><i class="demo-icon icon-flapping"></i> <span class="i-name">icon-flapping</span><span class="i-code">0xe85d</span></div>
|
||||||
<div title="Code: 0xe85e" class="the-icons span3"><i class="icon-rewind"></i> <span class="i-name">icon-rewind</span><span class="i-code">0xe85e</span></div>
|
<div title="Code: 0xe85e" class="the-icons span3"><i class="demo-icon icon-rewind"></i> <span class="i-name">icon-rewind</span><span class="i-code">0xe85e</span></div>
|
||||||
<div title="Code: 0xe85f" class="the-icons span3"><i class="icon-chart-line"></i> <span class="i-name">icon-chart-line</span><span class="i-code">0xe85f</span></div>
|
<div title="Code: 0xe85f" class="the-icons span3"><i class="demo-icon icon-chart-line"></i> <span class="i-name">icon-chart-line</span><span class="i-code">0xe85f</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe860" class="the-icons span3"><i class="icon-bell-off"></i> <span class="i-name">icon-bell-off</span><span class="i-code">0xe860</span></div>
|
<div title="Code: 0xe860" class="the-icons span3"><i class="demo-icon icon-bell-off"></i> <span class="i-name">icon-bell-off</span><span class="i-code">0xe860</span></div>
|
||||||
<div title="Code: 0xe861" class="the-icons span3"><i class="icon-bell-off-empty"></i> <span class="i-name">icon-bell-off-empty</span><span class="i-code">0xe861</span></div>
|
<div title="Code: 0xe861" class="the-icons span3"><i class="demo-icon icon-bell-off-empty"></i> <span class="i-name">icon-bell-off-empty</span><span class="i-code">0xe861</span></div>
|
||||||
<div title="Code: 0xe862" class="the-icons span3"><i class="icon-plug"></i> <span class="i-name">icon-plug</span><span class="i-code">0xe862</span></div>
|
<div title="Code: 0xe862" class="the-icons span3"><i class="demo-icon icon-plug"></i> <span class="i-name">icon-plug</span><span class="i-code">0xe862</span></div>
|
||||||
<div title="Code: 0xe863" class="the-icons span3"><i class="icon-eye-off"></i> <span class="i-name">icon-eye-off</span><span class="i-code">0xe863</span></div>
|
<div title="Code: 0xe863" class="the-icons span3"><i class="demo-icon icon-eye-off"></i> <span class="i-name">icon-eye-off</span><span class="i-code">0xe863</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe864" class="the-icons span3"><i class="icon-reschedule"></i> <span class="i-name">icon-reschedule</span><span class="i-code">0xe864</span></div>
|
<div title="Code: 0xe864" class="the-icons span3"><i class="demo-icon icon-reschedule"></i> <span class="i-name">icon-reschedule</span><span class="i-code">0xe864</span></div>
|
||||||
<div title="Code: 0xe865" class="the-icons span3"><i class="icon-cw"></i> <span class="i-name">icon-cw</span><span class="i-code">0xe865</span></div>
|
<div title="Code: 0xe865" class="the-icons span3"><i class="demo-icon icon-cw"></i> <span class="i-name">icon-cw</span><span class="i-code">0xe865</span></div>
|
||||||
<div title="Code: 0xe866" class="the-icons span3"><i class="icon-host"></i> <span class="i-name">icon-host</span><span class="i-code">0xe866</span></div>
|
<div title="Code: 0xe866" class="the-icons span3"><i class="demo-icon icon-host"></i> <span class="i-name">icon-host</span><span class="i-code">0xe866</span></div>
|
||||||
<div title="Code: 0xe867" class="the-icons span3"><i class="icon-thumbs-up"></i> <span class="i-name">icon-thumbs-up</span><span class="i-code">0xe867</span></div>
|
<div title="Code: 0xe867" class="the-icons span3"><i class="demo-icon icon-thumbs-up"></i> <span class="i-name">icon-thumbs-up</span><span class="i-code">0xe867</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe868" class="the-icons span3"><i class="icon-thumbs-down"></i> <span class="i-name">icon-thumbs-down</span><span class="i-code">0xe868</span></div>
|
<div title="Code: 0xe868" class="the-icons span3"><i class="demo-icon icon-thumbs-down"></i> <span class="i-name">icon-thumbs-down</span><span class="i-code">0xe868</span></div>
|
||||||
<div title="Code: 0xe869" class="the-icons span3"><i class="icon-spinner"></i> <span class="i-name">icon-spinner</span><span class="i-code">0xe869</span></div>
|
<div title="Code: 0xe869" class="the-icons span3"><i class="demo-icon icon-spinner"></i> <span class="i-name">icon-spinner</span><span class="i-code">0xe869</span></div>
|
||||||
<div title="Code: 0xe86a" class="the-icons span3"><i class="icon-attach"></i> <span class="i-name">icon-attach</span><span class="i-code">0xe86a</span></div>
|
<div title="Code: 0xe86a" class="the-icons span3"><i class="demo-icon icon-attach"></i> <span class="i-name">icon-attach</span><span class="i-code">0xe86a</span></div>
|
||||||
<div title="Code: 0xe86b" class="the-icons span3"><i class="icon-keyboard"></i> <span class="i-name">icon-keyboard</span><span class="i-code">0xe86b</span></div>
|
<div title="Code: 0xe86b" class="the-icons span3"><i class="demo-icon icon-keyboard"></i> <span class="i-name">icon-keyboard</span><span class="i-code">0xe86b</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe86c" class="the-icons span3"><i class="icon-menu"></i> <span class="i-name">icon-menu</span><span class="i-code">0xe86c</span></div>
|
<div title="Code: 0xe86c" class="the-icons span3"><i class="demo-icon icon-menu"></i> <span class="i-name">icon-menu</span><span class="i-code">0xe86c</span></div>
|
||||||
<div title="Code: 0xe86d" class="the-icons span3"><i class="icon-wifi"></i> <span class="i-name">icon-wifi</span><span class="i-code">0xe86d</span></div>
|
<div title="Code: 0xe86d" class="the-icons span3"><i class="demo-icon icon-wifi"></i> <span class="i-name">icon-wifi</span><span class="i-code">0xe86d</span></div>
|
||||||
<div title="Code: 0xe86e" class="the-icons span3"><i class="icon-moon"></i> <span class="i-name">icon-moon</span><span class="i-code">0xe86e</span></div>
|
<div title="Code: 0xe86e" class="the-icons span3"><i class="demo-icon icon-moon"></i> <span class="i-name">icon-moon</span><span class="i-code">0xe86e</span></div>
|
||||||
<div title="Code: 0xe86f" class="the-icons span3"><i class="icon-chart-pie"></i> <span class="i-name">icon-chart-pie</span><span class="i-code">0xe86f</span></div>
|
<div title="Code: 0xe86f" class="the-icons span3"><i class="demo-icon icon-chart-pie"></i> <span class="i-name">icon-chart-pie</span><span class="i-code">0xe86f</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div title="Code: 0xe870" class="the-icons span3"><i class="icon-chart-area"></i> <span class="i-name">icon-chart-area</span><span class="i-code">0xe870</span></div>
|
<div title="Code: 0xe870" class="the-icons span3"><i class="demo-icon icon-chart-area"></i> <span class="i-name">icon-chart-area</span><span class="i-code">0xe870</span></div>
|
||||||
<div title="Code: 0xe871" class="the-icons span3"><i class="icon-chart-bar"></i> <span class="i-name">icon-chart-bar</span><span class="i-code">0xe871</span></div>
|
<div title="Code: 0xe871" class="the-icons span3"><i class="demo-icon icon-chart-bar"></i> <span class="i-name">icon-chart-bar</span><span class="i-code">0xe871</span></div>
|
||||||
<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: 0xe872" class="the-icons span3"><i class="demo-icon 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 title="Code: 0xe873" class="the-icons span3"><i class="demo-icon icon-magic"></i> <span class="i-name">icon-magic</span><span class="i-code">0xe873</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<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 title="Code: 0xe874" class="the-icons span3"><i class="demo-icon icon-spin6 animate-spin"></i> <span class="i-name">icon-spin6</span><span class="i-code">0xe874</span></div>
|
||||||
|
<div title="Code: 0xe875" class="the-icons span3"><i class="demo-icon icon-down-small"></i> <span class="i-name">icon-down-small</span><span class="i-code">0xe875</span></div>
|
||||||
|
<div title="Code: 0xe876" class="the-icons span3"><i class="demo-icon icon-left-small"></i> <span class="i-name">icon-left-small</span><span class="i-code">0xe876</span></div>
|
||||||
|
<div title="Code: 0xe877" class="the-icons span3"><i class="demo-icon icon-right-small"></i> <span class="i-name">icon-right-small</span><span class="i-code">0xe877</span></div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div title="Code: 0xe878" class="the-icons span3"><i class="demo-icon icon-up-small"></i> <span class="i-name">icon-up-small</span><span class="i-code">0xe878</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container footer">Generated by <a href="http://fontello.com">fontello.com</a></div>
|
<div class="container footer">Generated by <a href="http://fontello.com">fontello.com</a></div>
|
||||||
|
@ -3,10 +3,7 @@
|
|||||||
|
|
||||||
namespace Icinga\Forms\Config\Resource;
|
namespace Icinga\Forms\Config\Resource;
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
use Icinga\Data\ConfigObject;
|
|
||||||
use Icinga\Data\ResourceFactory;
|
|
||||||
use Icinga\Application\Platform;
|
use Icinga\Application\Platform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,7 +20,9 @@ class DbResourceForm extends Form
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Form::createElements()
|
* Create and add elements to this form
|
||||||
|
*
|
||||||
|
* @param array $formData The data sent by the user
|
||||||
*/
|
*/
|
||||||
public function createElements(array $formData)
|
public function createElements(array $formData)
|
||||||
{
|
{
|
||||||
@ -107,35 +106,4 @@ class DbResourceForm extends Form
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate that the current configuration points to a valid resource
|
|
||||||
*
|
|
||||||
* @see Form::onSuccess()
|
|
||||||
*/
|
|
||||||
public function onSuccess()
|
|
||||||
{
|
|
||||||
if (false === static::isValidResource($this)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate the resource configuration by trying to connect with it
|
|
||||||
*
|
|
||||||
* @param Form $form The form to fetch the configuration values from
|
|
||||||
*
|
|
||||||
* @return bool Whether validation succeeded or not
|
|
||||||
*/
|
|
||||||
public static function isValidResource(Form $form)
|
|
||||||
{
|
|
||||||
$result = ResourceFactory::createResource(new ConfigObject($form->getValues()))->inspect();
|
|
||||||
if ($result->hasError()) {
|
|
||||||
$form->addError(sprintf($form->translate('Connectivity validation failed: %s'), $result->getError()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: display diagnostics in $result->toArray() to the user
|
|
||||||
|
|
||||||
return ! $result->hasError();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,7 @@
|
|||||||
|
|
||||||
namespace Icinga\Forms\Config\Resource;
|
namespace Icinga\Forms\Config\Resource;
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
use Icinga\Data\ConfigObject;
|
|
||||||
use Icinga\Data\ResourceFactory;
|
|
||||||
use Icinga\Protocol\Ldap\LdapConnection;
|
use Icinga\Protocol\Ldap\LdapConnection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,7 +20,9 @@ class LdapResourceForm extends Form
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Form::createElements()
|
* Create and add elements to this form
|
||||||
|
*
|
||||||
|
* @param array $formData The data sent by the user
|
||||||
*/
|
*/
|
||||||
public function createElements(array $formData)
|
public function createElements(array $formData)
|
||||||
{
|
{
|
||||||
@ -132,39 +131,4 @@ class LdapResourceForm extends Form
|
|||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate that the current configuration points to a valid resource
|
|
||||||
*
|
|
||||||
* @see Form::onSuccess()
|
|
||||||
*/
|
|
||||||
public function onSuccess()
|
|
||||||
{
|
|
||||||
if (false === static::isValidResource($this)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate the resource configuration by trying to connect with it
|
|
||||||
*
|
|
||||||
* @param Form $form The form to fetch the configuration values from
|
|
||||||
*
|
|
||||||
* @return bool Whether validation succeeded or not
|
|
||||||
*/
|
|
||||||
public static function isValidResource(Form $form)
|
|
||||||
{
|
|
||||||
$result = ResourceFactory::createResource(new ConfigObject($form->getValues()))->inspect();
|
|
||||||
if ($result->hasError()) {
|
|
||||||
$form->addError(sprintf(
|
|
||||||
'%s (%s)',
|
|
||||||
$form->translate('Connectivity validation failed, connection to the given resource not possible.'),
|
|
||||||
$result->getError()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: display diagnostics in $result->toArray() to the user
|
|
||||||
|
|
||||||
return ! $result->hasError();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -4,15 +4,20 @@
|
|||||||
namespace Icinga\Forms\Config;
|
namespace Icinga\Forms\Config;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Icinga\Web\Notification;
|
use Icinga\Application\Platform;
|
||||||
|
use Icinga\Exception\ConfigurationError;
|
||||||
|
use Icinga\Data\ConfigObject;
|
||||||
|
use Icinga\Data\Inspectable;
|
||||||
|
use Icinga\Data\Inspection;
|
||||||
|
use Icinga\Data\ResourceFactory;
|
||||||
use Icinga\Forms\ConfigForm;
|
use Icinga\Forms\ConfigForm;
|
||||||
use Icinga\Forms\Config\Resource\DbResourceForm;
|
use Icinga\Forms\Config\Resource\DbResourceForm;
|
||||||
use Icinga\Forms\Config\Resource\FileResourceForm;
|
use Icinga\Forms\Config\Resource\FileResourceForm;
|
||||||
use Icinga\Forms\Config\Resource\LdapResourceForm;
|
use Icinga\Forms\Config\Resource\LdapResourceForm;
|
||||||
use Icinga\Forms\Config\Resource\LivestatusResourceForm;
|
use Icinga\Forms\Config\Resource\LivestatusResourceForm;
|
||||||
use Icinga\Forms\Config\Resource\SshResourceForm;
|
use Icinga\Forms\Config\Resource\SshResourceForm;
|
||||||
use Icinga\Application\Platform;
|
use Icinga\Web\Form;
|
||||||
use Icinga\Exception\ConfigurationError;
|
use Icinga\Web\Notification;
|
||||||
|
|
||||||
class ResourceConfigForm extends ConfigForm
|
class ResourceConfigForm extends ConfigForm
|
||||||
{
|
{
|
||||||
@ -23,6 +28,7 @@ class ResourceConfigForm extends ConfigForm
|
|||||||
{
|
{
|
||||||
$this->setName('form_config_resource');
|
$this->setName('form_config_resource');
|
||||||
$this->setSubmitLabel($this->translate('Save Changes'));
|
$this->setSubmitLabel($this->translate('Save Changes'));
|
||||||
|
$this->setValidatePartial(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -141,7 +147,9 @@ class ResourceConfigForm extends ConfigForm
|
|||||||
$resourceForm = $this->getResourceForm($this->getElement('type')->getValue());
|
$resourceForm = $this->getResourceForm($this->getElement('type')->getValue());
|
||||||
|
|
||||||
if (($el = $this->getElement('force_creation')) === null || false === $el->isChecked()) {
|
if (($el = $this->getElement('force_creation')) === null || false === $el->isChecked()) {
|
||||||
if (method_exists($resourceForm, 'isValidResource') && false === $resourceForm::isValidResource($this)) {
|
$inspection = static::inspectResource($this);
|
||||||
|
if ($inspection !== null && $inspection->hasError()) {
|
||||||
|
$this->error($inspection->getError());
|
||||||
$this->addElement($this->getForceCreationCheckbox());
|
$this->addElement($this->getForceCreationCheckbox());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -255,4 +263,103 @@ class ResourceConfigForm extends ConfigForm
|
|||||||
|
|
||||||
$this->addElements($this->getResourceForm($resourceType)->createElements($formData)->getElements());
|
$this->addElements($this->getResourceForm($resourceType)->createElements($formData)->getElements());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a resource by using the given form's values and return its inspection results
|
||||||
|
*
|
||||||
|
* @param Form $form
|
||||||
|
*
|
||||||
|
* @return Inspection
|
||||||
|
*/
|
||||||
|
public static function inspectResource(Form $form)
|
||||||
|
{
|
||||||
|
if ($form->getValue('type') !== 'ssh') {
|
||||||
|
$resource = ResourceFactory::createResource(new ConfigObject($form->getValues()));
|
||||||
|
if ($resource instanceof Inspectable) {
|
||||||
|
return $resource->inspect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the configured resource's inspection checks and show the result, if necessary
|
||||||
|
*
|
||||||
|
* This will only run any validation if the user pushed the 'resource_validation' button.
|
||||||
|
*
|
||||||
|
* @param array $formData
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isValidPartial(array $formData)
|
||||||
|
{
|
||||||
|
if ($this->getElement('resource_validation')->isChecked() && parent::isValid($formData)) {
|
||||||
|
$inspection = static::inspectResource($this);
|
||||||
|
if ($inspection !== null) {
|
||||||
|
$join = function ($e) use (& $join) {
|
||||||
|
return is_string($e) ? $e : join("\n", array_map($join, $e));
|
||||||
|
};
|
||||||
|
$this->addElement(
|
||||||
|
'note',
|
||||||
|
'inspection_output',
|
||||||
|
array(
|
||||||
|
'order' => 0,
|
||||||
|
'value' => '<strong>' . $this->translate('Validation Log') . "</strong>\n\n"
|
||||||
|
. join("\n", array_map($join, $inspection->toArray())),
|
||||||
|
'decorators' => array(
|
||||||
|
'ViewHelper',
|
||||||
|
array('HtmlTag', array('tag' => 'pre', 'class' => 'log-output')),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($inspection->hasError()) {
|
||||||
|
$this->warning(sprintf(
|
||||||
|
$this->translate('Failed to successfully validate the configuration: %s'),
|
||||||
|
$inspection->getError()
|
||||||
|
));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info($this->translate('The configuration has been successfully validated.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a submit button to this form and one to manually validate the configuration
|
||||||
|
*
|
||||||
|
* Calls parent::addSubmitButton() to add the submit button.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addSubmitButton()
|
||||||
|
{
|
||||||
|
parent::addSubmitButton()
|
||||||
|
->getElement('btn_submit')
|
||||||
|
->setDecorators(array('ViewHelper'));
|
||||||
|
|
||||||
|
$this->addElement(
|
||||||
|
'submit',
|
||||||
|
'resource_validation',
|
||||||
|
array(
|
||||||
|
'ignore' => true,
|
||||||
|
'label' => $this->translate('Validate Configuration'),
|
||||||
|
'decorators' => array('ViewHelper')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->addDisplayGroup(
|
||||||
|
array('btn_submit', 'resource_validation'),
|
||||||
|
'submit_validation',
|
||||||
|
array(
|
||||||
|
'decorators' => array(
|
||||||
|
'FormElements',
|
||||||
|
array('HtmlTag', array('tag' => 'div', 'class' => 'control-group'))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,7 @@
|
|||||||
|
|
||||||
namespace Icinga\Forms\Config\UserBackend;
|
namespace Icinga\Forms\Config\UserBackend;
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
use Icinga\Data\ConfigObject;
|
|
||||||
use Icinga\Data\ResourceFactory;
|
|
||||||
use Icinga\Authentication\User\DbUserBackend;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Form class for adding/modifying database user backends
|
* Form class for adding/modifying database user backends
|
||||||
@ -43,7 +39,9 @@ class DbBackendForm extends Form
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Form::createElements()
|
* Create and add elements to this form
|
||||||
|
*
|
||||||
|
* @param array $formData
|
||||||
*/
|
*/
|
||||||
public function createElements(array $formData)
|
public function createElements(array $formData)
|
||||||
{
|
{
|
||||||
@ -56,6 +54,20 @@ class DbBackendForm extends Form
|
|||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The name of this authentication provider that is used to differentiate it from others'
|
'The name of this authentication provider that is used to differentiate it from others'
|
||||||
),
|
),
|
||||||
|
'validators' => array(
|
||||||
|
array(
|
||||||
|
'Regex',
|
||||||
|
false,
|
||||||
|
array(
|
||||||
|
'pattern' => '/^[^\\[\\]:]+$/',
|
||||||
|
'messages' => array(
|
||||||
|
'regexNotMatch' => $this->translate(
|
||||||
|
'The name cannot contain \'[\', \']\' or \':\'.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$this->addElement(
|
$this->addElement(
|
||||||
@ -67,7 +79,7 @@ class DbBackendForm extends Form
|
|||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The database connection to use for authenticating with this provider'
|
'The database connection to use for authenticating with this provider'
|
||||||
),
|
),
|
||||||
'multiOptions' => false === empty($this->resources)
|
'multiOptions' => !empty($this->resources)
|
||||||
? array_combine($this->resources, $this->resources)
|
? array_combine($this->resources, $this->resources)
|
||||||
: array()
|
: array()
|
||||||
)
|
)
|
||||||
@ -80,49 +92,5 @@ class DbBackendForm extends Form
|
|||||||
'value' => 'db'
|
'value' => 'db'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate that the selected resource is a valid database user backend
|
|
||||||
*
|
|
||||||
* @see Form::onSuccess()
|
|
||||||
*/
|
|
||||||
public function onSuccess()
|
|
||||||
{
|
|
||||||
if (false === static::isValidUserBackend($this)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate the configuration by creating a backend and requesting the user count
|
|
||||||
*
|
|
||||||
* @param Form $form The form to fetch the configuration values from
|
|
||||||
*
|
|
||||||
* @return bool Whether validation succeeded or not
|
|
||||||
*/
|
|
||||||
public static function isValidUserBackend(Form $form)
|
|
||||||
{
|
|
||||||
$backend = new DbUserBackend(ResourceFactory::createResource($form->getResourceConfig()));
|
|
||||||
$result = $backend->inspect();
|
|
||||||
if ($result->hasError()) {
|
|
||||||
$form->addError(sprintf($form->translate('Using the specified backend failed: %s'), $result->getError()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: display diagnostics in $result->toArray() to the user
|
|
||||||
|
|
||||||
return ! $result->hasError();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the configuration for the chosen resource
|
|
||||||
*
|
|
||||||
* @return ConfigObject
|
|
||||||
*/
|
|
||||||
public function getResourceConfig()
|
|
||||||
{
|
|
||||||
return ResourceFactory::getResourceConfig($this->getValue('resource'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,8 @@
|
|||||||
|
|
||||||
namespace Icinga\Forms\Config\UserBackend;
|
namespace Icinga\Forms\Config\UserBackend;
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Icinga\Authentication\User\LdapUserBackend;
|
|
||||||
use Icinga\Data\Inspection;
|
|
||||||
use Icinga\Web\Form;
|
|
||||||
use Icinga\Data\ConfigObject;
|
|
||||||
use Icinga\Data\ResourceFactory;
|
use Icinga\Data\ResourceFactory;
|
||||||
use Icinga\Exception\AuthenticationException;
|
use Icinga\Web\Form;
|
||||||
use Icinga\Authentication\User\UserBackend;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Form class for adding/modifying LDAP user backends
|
* Form class for adding/modifying LDAP user backends
|
||||||
@ -46,7 +40,9 @@ class LdapBackendForm extends Form
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Form::createElements()
|
* Create and add elements to this form
|
||||||
|
*
|
||||||
|
* @param array $formData
|
||||||
*/
|
*/
|
||||||
public function createElements(array $formData)
|
public function createElements(array $formData)
|
||||||
{
|
{
|
||||||
@ -60,6 +56,20 @@ class LdapBackendForm extends Form
|
|||||||
'label' => $this->translate('Backend Name'),
|
'label' => $this->translate('Backend Name'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The name of this authentication provider that is used to differentiate it from others.'
|
'The name of this authentication provider that is used to differentiate it from others.'
|
||||||
|
),
|
||||||
|
'validators' => array(
|
||||||
|
array(
|
||||||
|
'Regex',
|
||||||
|
false,
|
||||||
|
array(
|
||||||
|
'pattern' => '/^[^\\[\\]:]+$/',
|
||||||
|
'messages' => array(
|
||||||
|
'regexNotMatch' => $this->translate(
|
||||||
|
'The name cannot contain \'[\', \']\' or \':\'.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -72,11 +82,65 @@ class LdapBackendForm extends Form
|
|||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The LDAP connection to use for authenticating with this provider.'
|
'The LDAP connection to use for authenticating with this provider.'
|
||||||
),
|
),
|
||||||
'multiOptions' => false === empty($this->resources)
|
'multiOptions' => !empty($this->resources)
|
||||||
? array_combine($this->resources, $this->resources)
|
? array_combine($this->resources, $this->resources)
|
||||||
: array()
|
: array()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$baseDn = null;
|
||||||
|
$hasAdOid = false;
|
||||||
|
if (! $isAd && !empty($this->resources)) {
|
||||||
|
$this->addElement(
|
||||||
|
'button',
|
||||||
|
'discovery_btn',
|
||||||
|
array(
|
||||||
|
'type' => 'submit',
|
||||||
|
'value' => 'discovery_btn',
|
||||||
|
'label' => $this->translate('Discover', 'A button to discover LDAP capabilities'),
|
||||||
|
'title' => $this->translate(
|
||||||
|
'Push to fill in the chosen connection\'s default settings.'
|
||||||
|
),
|
||||||
|
'decorators' => array(
|
||||||
|
array('ViewHelper', array('separator' => '')),
|
||||||
|
array('HtmlTag', array('tag' => 'div', 'class' => 'element'))
|
||||||
|
),
|
||||||
|
'formnovalidate' => 'formnovalidate'
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->addDisplayGroup(
|
||||||
|
array('resource', 'discovery_btn'),
|
||||||
|
'connection_discovery',
|
||||||
|
array(
|
||||||
|
'decorators' => array(
|
||||||
|
'FormElements',
|
||||||
|
array('HtmlTag', array('tag' => 'div', 'class' => 'control-group'))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($this->getElement('discovery_btn')->isChecked()) {
|
||||||
|
$connection = ResourceFactory::create(
|
||||||
|
isset($formData['resource']) ? $formData['resource'] : reset($this->resources)
|
||||||
|
);
|
||||||
|
$capabilities = $connection->bind()->getCapabilities();
|
||||||
|
$baseDn = $capabilities->getDefaultNamingContext();
|
||||||
|
$hasAdOid = $capabilities->isActiveDirectory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($isAd || $hasAdOid) {
|
||||||
|
// ActiveDirectory defaults
|
||||||
|
$userClass = 'user';
|
||||||
|
$filter = '!(objectClass=computer)';
|
||||||
|
$userNameAttribute = 'sAMAccountName';
|
||||||
|
} else {
|
||||||
|
// OpenLDAP defaults
|
||||||
|
$userClass = 'inetOrgPerson';
|
||||||
|
$filter = null;
|
||||||
|
$userNameAttribute = 'uid';
|
||||||
|
}
|
||||||
|
|
||||||
$this->addElement(
|
$this->addElement(
|
||||||
'text',
|
'text',
|
||||||
'user_class',
|
'user_class',
|
||||||
@ -87,7 +151,7 @@ class LdapBackendForm extends Form
|
|||||||
'disabled' => $isAd ?: null,
|
'disabled' => $isAd ?: null,
|
||||||
'label' => $this->translate('LDAP User Object Class'),
|
'label' => $this->translate('LDAP User Object Class'),
|
||||||
'description' => $this->translate('The object class used for storing users on the LDAP server.'),
|
'description' => $this->translate('The object class used for storing users on the LDAP server.'),
|
||||||
'value' => $isAd ? 'user' : 'inetOrgPerson'
|
'value' => $userClass
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$this->addElement(
|
$this->addElement(
|
||||||
@ -96,7 +160,7 @@ class LdapBackendForm extends Form
|
|||||||
array(
|
array(
|
||||||
'preserveDefault' => true,
|
'preserveDefault' => true,
|
||||||
'allowEmpty' => true,
|
'allowEmpty' => true,
|
||||||
'value' => $isAd ? '!(objectClass=computer)' : null,
|
'value' => $filter,
|
||||||
'label' => $this->translate('LDAP Filter'),
|
'label' => $this->translate('LDAP Filter'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'An additional filter to use when looking up users using the specified connection. '
|
'An additional filter to use when looking up users using the specified connection. '
|
||||||
@ -139,7 +203,7 @@ class LdapBackendForm extends Form
|
|||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The attribute name used for storing the user name on the LDAP server.'
|
'The attribute name used for storing the user name on the LDAP server.'
|
||||||
),
|
),
|
||||||
'value' => $isAd ? 'sAMAccountName' : 'uid'
|
'value' => $userNameAttribute
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$this->addElement(
|
$this->addElement(
|
||||||
@ -154,48 +218,15 @@ class LdapBackendForm extends Form
|
|||||||
'text',
|
'text',
|
||||||
'base_dn',
|
'base_dn',
|
||||||
array(
|
array(
|
||||||
|
'preserveDefault' => true,
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'label' => $this->translate('LDAP Base DN'),
|
'label' => $this->translate('LDAP Base DN'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The path where users can be found on the LDAP server. Leave ' .
|
'The path where users can be found on the LDAP server. Leave ' .
|
||||||
'empty to select all users available using the specified connection.'
|
'empty to select all users available using the specified connection.'
|
||||||
)
|
),
|
||||||
|
'value' => $baseDn
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate that the selected resource is a valid ldap user backend
|
|
||||||
*
|
|
||||||
* @see Form::onSuccess()
|
|
||||||
*/
|
|
||||||
public function onSuccess()
|
|
||||||
{
|
|
||||||
if (false === static::isValidUserBackend($this)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate the configuration by creating a backend and requesting the user count
|
|
||||||
*
|
|
||||||
* @param Form $form The form to fetch the configuration values from
|
|
||||||
*
|
|
||||||
* @return bool Whether validation succeeded or not
|
|
||||||
*/
|
|
||||||
public static function isValidUserBackend(Form $form)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var $result Inspection
|
|
||||||
*/
|
|
||||||
$result = UserBackend::create(null, new ConfigObject($form->getValues()))->inspect();
|
|
||||||
if ($result->hasError()) {
|
|
||||||
$form->addError($result->getError());
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: display diagnostics in $result->toArray() to the user
|
|
||||||
|
|
||||||
return ! $result->hasError();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,26 +4,39 @@
|
|||||||
namespace Icinga\Forms\Config;
|
namespace Icinga\Forms\Config;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use Icinga\Forms\ConfigForm;
|
|
||||||
use Icinga\Web\Notification;
|
|
||||||
use Icinga\Application\Config;
|
use Icinga\Application\Config;
|
||||||
use Icinga\Application\Platform;
|
use Icinga\Authentication\User\UserBackend;
|
||||||
use Icinga\Data\ConfigObject;
|
|
||||||
use Icinga\Data\ResourceFactory;
|
|
||||||
use Icinga\Exception\ConfigurationError;
|
use Icinga\Exception\ConfigurationError;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
use Icinga\Exception\NotFoundError;
|
||||||
|
use Icinga\Data\ConfigObject;
|
||||||
|
use Icinga\Data\Inspectable;
|
||||||
|
use Icinga\Data\Inspection;
|
||||||
|
use Icinga\Forms\ConfigForm;
|
||||||
|
use Icinga\Forms\Config\UserBackend\ExternalBackendForm;
|
||||||
use Icinga\Forms\Config\UserBackend\DbBackendForm;
|
use Icinga\Forms\Config\UserBackend\DbBackendForm;
|
||||||
use Icinga\Forms\Config\UserBackend\LdapBackendForm;
|
use Icinga\Forms\Config\UserBackend\LdapBackendForm;
|
||||||
use Icinga\Forms\Config\UserBackend\ExternalBackendForm;
|
use Icinga\Web\Form;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Form for managing user backends
|
||||||
|
*/
|
||||||
class UserBackendConfigForm extends ConfigForm
|
class UserBackendConfigForm extends ConfigForm
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The available resources split by type
|
* The available user backend resources split by type
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $resources;
|
protected $resources;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The backend to load when displaying the form for the first time
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $backendToLoad;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize this form
|
* Initialize this form
|
||||||
*/
|
*/
|
||||||
@ -31,20 +44,45 @@ class UserBackendConfigForm extends ConfigForm
|
|||||||
{
|
{
|
||||||
$this->setName('form_config_authbackend');
|
$this->setName('form_config_authbackend');
|
||||||
$this->setSubmitLabel($this->translate('Save Changes'));
|
$this->setSubmitLabel($this->translate('Save Changes'));
|
||||||
|
$this->setValidatePartial(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the resource configuration to use
|
* Set the resource configuration to use
|
||||||
*
|
*
|
||||||
* @param Config $resources The resource configuration
|
* @param Config $resourceConfig The resource configuration
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
|
*
|
||||||
|
* @throws ConfigurationError In case there are no valid resources for authentication available
|
||||||
*/
|
*/
|
||||||
public function setResourceConfig(Config $resourceConfig)
|
public function setResourceConfig(Config $resourceConfig)
|
||||||
{
|
{
|
||||||
$resources = array();
|
$resources = array();
|
||||||
foreach ($resourceConfig as $name => $resource) {
|
foreach ($resourceConfig as $name => $resource) {
|
||||||
$resources[strtolower($resource->type)][] = $name;
|
if (in_array($resource->type, array('db', 'ldap'))) {
|
||||||
|
$resources[$resource->type][] = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($resources)) {
|
||||||
|
$externalBackends = $this->config->toArray();
|
||||||
|
array_walk(
|
||||||
|
$externalBackends,
|
||||||
|
function (& $authBackendCfg) {
|
||||||
|
if (! isset($authBackendCfg['backend']) || $authBackendCfg['backend'] !== 'external') {
|
||||||
|
$authBackendCfg = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (count(array_filter($externalBackends)) > 0 && (
|
||||||
|
$this->backendToLoad === null || !isset($externalBackends[$this->backendToLoad])
|
||||||
|
)) {
|
||||||
|
throw new ConfigurationError($this->translate(
|
||||||
|
'Could not find any valid user backend resources.'
|
||||||
|
. ' Please configure a resource for authentication first.'
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->resources = $resources;
|
$this->resources = $resources;
|
||||||
@ -57,6 +95,8 @@ class UserBackendConfigForm extends ConfigForm
|
|||||||
* @param string $type The backend type for which to return a form
|
* @param string $type The backend type for which to return a form
|
||||||
*
|
*
|
||||||
* @return Form
|
* @return Form
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException In case the given backend type is invalid
|
||||||
*/
|
*/
|
||||||
public function getBackendForm($type)
|
public function getBackendForm($type)
|
||||||
{
|
{
|
||||||
@ -84,81 +124,103 @@ class UserBackendConfigForm extends ConfigForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a particular user backend
|
* Populate the form with the given backend's config
|
||||||
*
|
*
|
||||||
* The backend to add is identified by the array-key `name'.
|
* @param string $name
|
||||||
*
|
|
||||||
* @param array $values The values to extend the configuration with
|
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*
|
*
|
||||||
* @throws InvalidArgumentException In case the backend does already exist
|
* @throws NotFoundError In case no backend with the given name is found
|
||||||
*/
|
*/
|
||||||
public function add(array $values)
|
public function load($name)
|
||||||
{
|
{
|
||||||
$name = isset($values['name']) ? $values['name'] : '';
|
if (! $this->config->hasSection($name)) {
|
||||||
if (! $name) {
|
throw new NotFoundError('No user backend called "%s" found', $name);
|
||||||
throw new InvalidArgumentException($this->translate('User backend name missing'));
|
|
||||||
} elseif ($this->config->hasSection($name)) {
|
|
||||||
throw new InvalidArgumentException($this->translate('User backend already exists'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($values['name']);
|
$this->backendToLoad = $name;
|
||||||
$this->config->setSection($name, $values);
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edit a particular user backend
|
* Add a new user backend
|
||||||
*
|
*
|
||||||
* @param string $name The name of the backend to edit
|
* The backend to add is identified by the array-key `name'.
|
||||||
* @param array $values The values to edit the configuration with
|
|
||||||
*
|
*
|
||||||
* @return array The edited backend configuration
|
* @param array $data
|
||||||
*
|
*
|
||||||
* @throws InvalidArgumentException In case the backend does not exist
|
* @return $this
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException In case $data does not contain a backend name
|
||||||
|
* @throws IcingaException In case a backend with the same name already exists
|
||||||
*/
|
*/
|
||||||
public function edit($name, array $values)
|
public function add(array $data)
|
||||||
{
|
{
|
||||||
if (! $name) {
|
if (! isset($data['name'])) {
|
||||||
throw new InvalidArgumentException($this->translate('Old user backend name missing'));
|
throw new InvalidArgumentException('Key \'name\' missing');
|
||||||
} elseif (! ($newName = isset($values['name']) ? $values['name'] : '')) {
|
|
||||||
throw new InvalidArgumentException($this->translate('New user backend name missing'));
|
|
||||||
} elseif (! $this->config->hasSection($name)) {
|
|
||||||
throw new InvalidArgumentException($this->translate('Unknown user backend provided'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$backendConfig = $this->config->getSection($name);
|
$backendName = $data['name'];
|
||||||
if ($newName !== $name) {
|
if ($this->config->hasSection($backendName)) {
|
||||||
// Only remove the old entry if it has changed as the order gets screwed when editing backend names
|
throw new IcingaException(
|
||||||
$this->config->removeSection($name);
|
$this->translate('A user backend with the name "%s" does already exist'),
|
||||||
|
$backendName
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($values['name']);
|
unset($data['name']);
|
||||||
$this->config->setSection($newName, $backendConfig->merge($values));
|
$this->config->setSection($backendName, $data);
|
||||||
return $backendConfig;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the given user backend
|
* Edit a user backend
|
||||||
*
|
*
|
||||||
* @param string $name The name of the backend to remove
|
* @param string $name
|
||||||
|
* @param array $data
|
||||||
*
|
*
|
||||||
* @return array The removed backend configuration
|
* @return $this
|
||||||
*
|
*
|
||||||
* @throws InvalidArgumentException In case the backend does not exist
|
* @throws NotFoundError In case no backend with the given name is found
|
||||||
*/
|
*/
|
||||||
public function remove($name)
|
public function edit($name, array $data)
|
||||||
{
|
{
|
||||||
if (! $name) {
|
if (! $this->config->hasSection($name)) {
|
||||||
throw new InvalidArgumentException($this->translate('user backend name missing'));
|
throw new NotFoundError('No user backend called "%s" found', $name);
|
||||||
} elseif (! $this->config->hasSection($name)) {
|
|
||||||
throw new InvalidArgumentException($this->translate('Unknown user backend provided'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$backendConfig = $this->config->getSection($name);
|
$backendConfig = $this->config->getSection($name);
|
||||||
|
if (isset($data['name'])) {
|
||||||
|
if ($data['name'] !== $name) {
|
||||||
$this->config->removeSection($name);
|
$this->config->removeSection($name);
|
||||||
return $backendConfig;
|
$name = $data['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($data['name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$backendConfig->merge($data);
|
||||||
|
foreach ($backendConfig->toArray() as $k => $v) {
|
||||||
|
if ($v === null) {
|
||||||
|
unset($backendConfig->$k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->config->setSection($name, $backendConfig);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a user backend
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function delete($name)
|
||||||
|
{
|
||||||
|
$this->config->removeSection($name);
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -169,14 +231,12 @@ class UserBackendConfigForm extends ConfigForm
|
|||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*
|
*
|
||||||
* @throws InvalidArgumentException In case the backend does not exist
|
* @throws NotFoundError In case no backend with the given name is found
|
||||||
*/
|
*/
|
||||||
public function move($name, $position)
|
public function move($name, $position)
|
||||||
{
|
{
|
||||||
if (! $name) {
|
if (! $this->config->hasSection($name)) {
|
||||||
throw new InvalidArgumentException($this->translate('User backend name missing'));
|
throw new NotFoundError('No user backend called "%s" found', $name);
|
||||||
} elseif (! $this->config->hasSection($name)) {
|
|
||||||
throw new InvalidArgumentException($this->translate('Unknown user backend provided'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$backendOrder = $this->config->keys();
|
$backendOrder = $this->config->keys();
|
||||||
@ -194,105 +254,9 @@ class UserBackendConfigForm extends ConfigForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add or edit an user backend and save the configuration
|
* Create and add elements to this form
|
||||||
*
|
*
|
||||||
* Performs a connectivity validation using the submitted values. A checkbox is
|
* @param array $formData
|
||||||
* added to the form to skip the check if it fails and redirection is aborted.
|
|
||||||
*
|
|
||||||
* @see Form::onSuccess()
|
|
||||||
*/
|
|
||||||
public function onSuccess()
|
|
||||||
{
|
|
||||||
if (($el = $this->getElement('force_creation')) === null || false === $el->isChecked()) {
|
|
||||||
$backendForm = $this->getBackendForm($this->getElement('type')->getValue());
|
|
||||||
if (false === $backendForm::isValidUserBackend($this)) {
|
|
||||||
$this->addElement($this->getForceCreationCheckbox());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$authBackend = $this->request->getQuery('backend');
|
|
||||||
try {
|
|
||||||
if ($authBackend === null) { // create new backend
|
|
||||||
$this->add($this->getValues());
|
|
||||||
$message = $this->translate('User backend "%s" has been successfully created');
|
|
||||||
} else { // edit existing backend
|
|
||||||
$this->edit($authBackend, $this->getValues());
|
|
||||||
$message = $this->translate('User backend "%s" has been successfully changed');
|
|
||||||
}
|
|
||||||
} catch (InvalidArgumentException $e) {
|
|
||||||
Notification::error($e->getMessage());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->save()) {
|
|
||||||
Notification::success(sprintf($message, $this->getElement('name')->getValue()));
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Populate the form in case an user backend is being edited
|
|
||||||
*
|
|
||||||
* @see Form::onRequest()
|
|
||||||
*
|
|
||||||
* @throws ConfigurationError In case the backend name is missing in the request or is invalid
|
|
||||||
*/
|
|
||||||
public function onRequest()
|
|
||||||
{
|
|
||||||
$authBackend = $this->request->getQuery('backend');
|
|
||||||
if ($authBackend !== null) {
|
|
||||||
if ($authBackend === '') {
|
|
||||||
throw new ConfigurationError($this->translate('User backend name missing'));
|
|
||||||
} elseif (! $this->config->hasSection($authBackend)) {
|
|
||||||
throw new ConfigurationError($this->translate('Unknown user backend provided'));
|
|
||||||
} elseif ($this->config->getSection($authBackend)->backend === null) {
|
|
||||||
throw new ConfigurationError(
|
|
||||||
sprintf($this->translate('Backend "%s" has no `backend\' setting'), $authBackend)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$configValues = $this->config->getSection($authBackend)->toArray();
|
|
||||||
$configValues['type'] = $configValues['backend'];
|
|
||||||
$configValues['name'] = $authBackend;
|
|
||||||
$this->populate($configValues);
|
|
||||||
} elseif (empty($this->resources)) {
|
|
||||||
$externalBackends = array_filter(
|
|
||||||
$this->config->toArray(),
|
|
||||||
function ($authBackendCfg) {
|
|
||||||
return isset($authBackendCfg['backend']) && $authBackendCfg['backend'] === 'external';
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
if (false === empty($externalBackends)) {
|
|
||||||
throw new ConfigurationError($this->translate('Could not find any resources for authentication'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a checkbox to be displayed at the beginning of the form
|
|
||||||
* which allows the user to skip the connection validation
|
|
||||||
*
|
|
||||||
* @return Zend_Form_Element
|
|
||||||
*/
|
|
||||||
protected function getForceCreationCheckbox()
|
|
||||||
{
|
|
||||||
return $this->createElement(
|
|
||||||
'checkbox',
|
|
||||||
'force_creation',
|
|
||||||
array(
|
|
||||||
'order' => 0,
|
|
||||||
'ignore' => true,
|
|
||||||
'label' => $this->translate('Force Changes'),
|
|
||||||
'description' => $this->translate('Check this box to enforce changes without connectivity validation')
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see Form::createElements()
|
|
||||||
*/
|
*/
|
||||||
public function createElements(array $formData)
|
public function createElements(array $formData)
|
||||||
{
|
{
|
||||||
@ -302,7 +266,7 @@ class UserBackendConfigForm extends ConfigForm
|
|||||||
if (isset($this->resources['db'])) {
|
if (isset($this->resources['db'])) {
|
||||||
$backendTypes['db'] = $this->translate('Database');
|
$backendTypes['db'] = $this->translate('Database');
|
||||||
}
|
}
|
||||||
if (isset($this->resources['ldap']) && ($backendType === 'ldap' || Platform::extensionLoaded('ldap'))) {
|
if (isset($this->resources['ldap'])) {
|
||||||
$backendTypes['ldap'] = 'LDAP';
|
$backendTypes['ldap'] = 'LDAP';
|
||||||
$backendTypes['msldap'] = 'ActiveDirectory';
|
$backendTypes['msldap'] = 'ActiveDirectory';
|
||||||
}
|
}
|
||||||
@ -336,21 +300,186 @@ class UserBackendConfigForm extends ConfigForm
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (isset($formData['force_creation']) && $formData['force_creation']) {
|
if (isset($formData['skip_validation']) && $formData['skip_validation']) {
|
||||||
// In case another error occured and the checkbox was displayed before
|
// In case another error occured and the checkbox was displayed before
|
||||||
$this->addElement($this->getForceCreationCheckbox());
|
$this->addSkipValidationCheckbox();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addElements($this->getBackendForm($backendType)->createElements($formData)->getElements());
|
$this->addSubForm($this->getBackendForm($backendType)->create($formData), 'backend_form');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the configuration for the chosen resource
|
* Populate the configuration of the backend to load
|
||||||
*
|
|
||||||
* @return ConfigObject
|
|
||||||
*/
|
*/
|
||||||
public function getResourceConfig()
|
public function onRequest()
|
||||||
{
|
{
|
||||||
return ResourceFactory::getResourceConfig($this->getValue('resource'));
|
if ($this->backendToLoad) {
|
||||||
|
$data = $this->config->getSection($this->backendToLoad)->toArray();
|
||||||
|
$data['name'] = $this->backendToLoad;
|
||||||
|
$data['type'] = $data['backend'];
|
||||||
|
$this->populate($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve all form element values
|
||||||
|
*
|
||||||
|
* @param bool $suppressArrayNotation Ignored
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getValues($suppressArrayNotation = false)
|
||||||
|
{
|
||||||
|
$values = parent::getValues();
|
||||||
|
$values = array_merge($values, $values['backend_form']);
|
||||||
|
unset($values['backend_form']);
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether the given values are valid
|
||||||
|
*
|
||||||
|
* @param array $formData The data to validate
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isValid($formData)
|
||||||
|
{
|
||||||
|
if (! parent::isValid($formData)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($el = $this->getElement('skip_validation')) === null || false === $el->isChecked()) {
|
||||||
|
$inspection = static::inspectUserBackend($this);
|
||||||
|
if ($inspection && $inspection->hasError()) {
|
||||||
|
$this->error($inspection->getError());
|
||||||
|
if ($el === null) {
|
||||||
|
$this->addSkipValidationCheckbox();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a user backend by using the given form's values and return its inspection results
|
||||||
|
*
|
||||||
|
* Returns null for non-inspectable backends.
|
||||||
|
*
|
||||||
|
* @param Form $form
|
||||||
|
*
|
||||||
|
* @return Inspection|null
|
||||||
|
*/
|
||||||
|
public static function inspectUserBackend(Form $form)
|
||||||
|
{
|
||||||
|
$backend = UserBackend::create(null, new ConfigObject($form->getValues()));
|
||||||
|
if ($backend instanceof Inspectable) {
|
||||||
|
return $backend->inspect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a checkbox to the form by which the user can skip the connection validation
|
||||||
|
*/
|
||||||
|
protected function addSkipValidationCheckbox()
|
||||||
|
{
|
||||||
|
$this->addElement(
|
||||||
|
'checkbox',
|
||||||
|
'skip_validation',
|
||||||
|
array(
|
||||||
|
'order' => 0,
|
||||||
|
'ignore' => true,
|
||||||
|
'required' => true,
|
||||||
|
'label' => $this->translate('Skip Validation'),
|
||||||
|
'description' => $this->translate(
|
||||||
|
'Check this box to enforce changes without validating that authentication is possible.'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the configured backend's inspection checks and show the result, if necessary
|
||||||
|
*
|
||||||
|
* This will only run any validation if the user pushed the 'backend_validation' button.
|
||||||
|
*
|
||||||
|
* @param array $formData
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isValidPartial(array $formData)
|
||||||
|
{
|
||||||
|
if ($this->getElement('backend_validation')->isChecked() && parent::isValid($formData)) {
|
||||||
|
$inspection = static::inspectUserBackend($this);
|
||||||
|
if ($inspection !== null) {
|
||||||
|
$join = function ($e) use (& $join) {
|
||||||
|
return is_string($e) ? $e : join("\n", array_map($join, $e));
|
||||||
|
};
|
||||||
|
$this->addElement(
|
||||||
|
'note',
|
||||||
|
'inspection_output',
|
||||||
|
array(
|
||||||
|
'order' => 0,
|
||||||
|
'value' => '<strong>' . $this->translate('Validation Log') . "</strong>\n\n"
|
||||||
|
. join("\n", array_map($join, $inspection->toArray())),
|
||||||
|
'decorators' => array(
|
||||||
|
'ViewHelper',
|
||||||
|
array('HtmlTag', array('tag' => 'pre', 'class' => 'log-output')),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($inspection->hasError()) {
|
||||||
|
$this->warning(sprintf(
|
||||||
|
$this->translate('Failed to successfully validate the configuration: %s'),
|
||||||
|
$inspection->getError()
|
||||||
|
));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info($this->translate('The configuration has been successfully validated.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a submit button to this form and one to manually validate the configuration
|
||||||
|
*
|
||||||
|
* Calls parent::addSubmitButton() to add the submit button.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addSubmitButton()
|
||||||
|
{
|
||||||
|
parent::addSubmitButton()
|
||||||
|
->getElement('btn_submit')
|
||||||
|
->setDecorators(array('ViewHelper'));
|
||||||
|
|
||||||
|
$this->addElement(
|
||||||
|
'submit',
|
||||||
|
'backend_validation',
|
||||||
|
array(
|
||||||
|
'ignore' => true,
|
||||||
|
'label' => $this->translate('Validate Configuration'),
|
||||||
|
'decorators' => array('ViewHelper')
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$this->addDisplayGroup(
|
||||||
|
array('btn_submit', 'backend_validation'),
|
||||||
|
'submit_validation',
|
||||||
|
array(
|
||||||
|
'decorators' => array(
|
||||||
|
'FormElements',
|
||||||
|
array('HtmlTag', array('tag' => 'div', 'class' => 'control-group'))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
|
|
||||||
namespace Icinga\Forms\Config;
|
namespace Icinga\Forms\Config;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
|
||||||
use Icinga\Web\Notification;
|
|
||||||
use Icinga\Forms\ConfigForm;
|
use Icinga\Forms\ConfigForm;
|
||||||
|
use Icinga\Exception\NotFoundError;
|
||||||
|
use Icinga\Web\Notification;
|
||||||
|
|
||||||
class UserBackendReorderForm extends ConfigForm
|
class UserBackendReorderForm extends ConfigForm
|
||||||
{
|
{
|
||||||
@ -29,7 +29,9 @@ class UserBackendReorderForm extends ConfigForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Form::createElements()
|
* Create and add elements to this form
|
||||||
|
*
|
||||||
|
* @param array $formData
|
||||||
*/
|
*/
|
||||||
public function createElements(array $formData)
|
public function createElements(array $formData)
|
||||||
{
|
{
|
||||||
@ -39,8 +41,6 @@ class UserBackendReorderForm extends ConfigForm
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the user backend order and save the configuration
|
* Update the user backend order and save the configuration
|
||||||
*
|
|
||||||
* @see Form::onSuccess()
|
|
||||||
*/
|
*/
|
||||||
public function onSuccess()
|
public function onSuccess()
|
||||||
{
|
{
|
||||||
@ -55,8 +55,8 @@ class UserBackendReorderForm extends ConfigForm
|
|||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (InvalidArgumentException $e) {
|
} catch (NotFoundError $_) {
|
||||||
Notification::error($e->getMessage());
|
Notification::error(sprintf($this->translate('User backend "%s" not found'), $backendName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,10 +205,7 @@ class PreferenceForm extends Form
|
|||||||
array(
|
array(
|
||||||
'ignore' => true,
|
'ignore' => true,
|
||||||
'label' => $this->translate('Save to the Preferences'),
|
'label' => $this->translate('Save to the Preferences'),
|
||||||
'decorators' => array(
|
'decorators' => array('ViewHelper')
|
||||||
'ViewHelper',
|
|
||||||
array('HtmlTag', array('tag' => 'div'))
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -219,10 +216,7 @@ class PreferenceForm extends Form
|
|||||||
array(
|
array(
|
||||||
'ignore' => true,
|
'ignore' => true,
|
||||||
'label' => $this->translate('Save for the current Session'),
|
'label' => $this->translate('Save for the current Session'),
|
||||||
'decorators' => array(
|
'decorators' => array('ViewHelper')
|
||||||
'ViewHelper',
|
|
||||||
array('HtmlTag', array('tag' => 'div'))
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -54,6 +54,7 @@ $iframeClass = $isIframe ? ' iframe' : '';
|
|||||||
<div id="layout" class="default-layout<?php if ($showFullscreen): ?> fullscreen-layout<?php endif ?>">
|
<div id="layout" class="default-layout<?php if ($showFullscreen): ?> fullscreen-layout<?php endif ?>">
|
||||||
<?= $this->render('body.phtml') ?>
|
<?= $this->render('body.phtml') ?>
|
||||||
</div>
|
</div>
|
||||||
|
<iframe id="fileupload-frame-target" name="fileupload-frame-target"></iframe>
|
||||||
<!--[if IE 8]>
|
<!--[if IE 8]>
|
||||||
<script type="text/javascript" src="<?= $this->href($ie8jsfile) ?>"></script>
|
<script type="text/javascript" src="<?= $this->href($ie8jsfile) ?>"></script>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
|
10
application/layouts/scripts/wrapped.phtml
Normal file
10
application/layouts/scripts/wrapped.phtml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<?php if (isset($this->layout()->redirectUrl)): ?>
|
||||||
|
<meta name="redirectUrl" content="<?= $this->layout()->redirectUrl; ?>">
|
||||||
|
<?php endif ?>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<?= $this->render('inline.phtml'); ?>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,8 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||||
|
|
||||||
use \Zend_View_Helper_FormElement;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to generate a "datetime" element
|
* Helper to generate a "datetime" element
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
<div class="controls">
|
|
||||||
<?= $this->tabs->showOnlyCloseButton() ?>
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<?= $form; ?>
|
|
||||||
</div>
|
|
@ -1,6 +0,0 @@
|
|||||||
<div class="controls">
|
|
||||||
<?= $this->tabs->showOnlyCloseButton() ?>
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<?= $form; ?>
|
|
||||||
</div>
|
|
@ -33,7 +33,7 @@
|
|||||||
</td>
|
</td>
|
||||||
<td data-base-target="_self">
|
<td data-base-target="_self">
|
||||||
<?php if ($i > 0): ?>
|
<?php if ($i > 0): ?>
|
||||||
<button type="submit" name="backend_newpos" value="<?= sprintf(
|
<button type="submit" name="backend_newpos" class="icon-only" value="<?= sprintf(
|
||||||
'%s|%s',
|
'%s|%s',
|
||||||
$backendNames[$i],
|
$backendNames[$i],
|
||||||
$i - 1
|
$i - 1
|
||||||
@ -43,11 +43,11 @@
|
|||||||
$this->translate('Move user backend %s upwards'),
|
$this->translate('Move user backend %s upwards'),
|
||||||
$backendNames[$i]
|
$backendNames[$i]
|
||||||
); ?>">
|
); ?>">
|
||||||
<?= $this->icon('up-big'); ?>
|
<?= $this->icon('up-small'); ?>
|
||||||
</button>
|
</button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<?php if ($i + 1 < count($backendNames)): ?>
|
<?php if ($i + 1 < count($backendNames)): ?>
|
||||||
<button type="submit" name="backend_newpos" value="<?= sprintf(
|
<button type="submit" name="backend_newpos" class="icon-only" value="<?= sprintf(
|
||||||
'%s|%s',
|
'%s|%s',
|
||||||
$backendNames[$i],
|
$backendNames[$i],
|
||||||
$i + 1
|
$i + 1
|
||||||
@ -57,7 +57,7 @@
|
|||||||
$this->translate('Move user backend %s downwards'),
|
$this->translate('Move user backend %s downwards'),
|
||||||
$backendNames[$i]
|
$backendNames[$i]
|
||||||
); ?>">
|
); ?>">
|
||||||
<?= $this->icon('down-big'); ?>
|
<?= $this->icon('down-small'); ?>
|
||||||
</button>
|
</button>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
|
@ -46,8 +46,6 @@ Requires: %{name}-vendor-HTMLPurifier
|
|||||||
Requires: %{name}-vendor-JShrink
|
Requires: %{name}-vendor-JShrink
|
||||||
Requires: %{name}-vendor-lessphp
|
Requires: %{name}-vendor-lessphp
|
||||||
Requires: %{name}-vendor-Parsedown
|
Requires: %{name}-vendor-Parsedown
|
||||||
Requires: %{zend}
|
|
||||||
Obsoletes: %{name}-vendor-zend
|
|
||||||
|
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@ -84,6 +82,10 @@ Requires: %{php}-gd %{php}-intl
|
|||||||
%{?fedora:Requires: php-pecl-imagick}
|
%{?fedora:Requires: php-pecl-imagick}
|
||||||
%{?rhel:Requires: php-pecl-imagick}
|
%{?rhel:Requires: php-pecl-imagick}
|
||||||
%{?suse_version:Requires: %{php}-gettext %{php}-json %{php}-openssl %{php}-posix}
|
%{?suse_version:Requires: %{php}-gettext %{php}-json %{php}-openssl %{php}-posix}
|
||||||
|
Requires: %{zend}
|
||||||
|
Obsoletes: %{name}-vendor-zend
|
||||||
|
Requires: %{zend}-Db-Adapter-Pdo-Mysql
|
||||||
|
Requires: %{zend}-Db-Adapter-Pdo-Pgsql
|
||||||
|
|
||||||
%description -n php-Icinga
|
%description -n php-Icinga
|
||||||
Icinga Web 2 PHP library
|
Icinga Web 2 PHP library
|
||||||
|
@ -8,6 +8,7 @@ use Icinga\Data\ConfigObject;
|
|||||||
use Icinga\Application\Logger\Writer\FileWriter;
|
use Icinga\Application\Logger\Writer\FileWriter;
|
||||||
use Icinga\Application\Logger\Writer\SyslogWriter;
|
use Icinga\Application\Logger\Writer\SyslogWriter;
|
||||||
use Icinga\Exception\ConfigurationError;
|
use Icinga\Exception\ConfigurationError;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logger
|
* Logger
|
||||||
@ -226,13 +227,7 @@ class Logger
|
|||||||
$messages = array();
|
$messages = array();
|
||||||
$error = $message;
|
$error = $message;
|
||||||
do {
|
do {
|
||||||
$messages[] = sprintf(
|
$messages[] = IcingaException::describe($error);
|
||||||
'%s in %s:%d with message: %s',
|
|
||||||
get_class($error),
|
|
||||||
$error->getFile(),
|
|
||||||
$error->getLine(),
|
|
||||||
$error->getMessage()
|
|
||||||
);
|
|
||||||
} while ($error = $error->getPrevious());
|
} while ($error = $error->getPrevious());
|
||||||
$message = implode(' <- ', $messages);
|
$message = implode(' <- ', $messages);
|
||||||
}
|
}
|
||||||
|
@ -260,7 +260,7 @@ class DbUserBackend extends DbRepository implements UserBackendInterface, Inspec
|
|||||||
$insp->write($this->ds->inspect());
|
$insp->write($this->ds->inspect());
|
||||||
try {
|
try {
|
||||||
$users = $this->select()->where('is_active', true)->count();
|
$users = $this->select()->where('is_active', true)->count();
|
||||||
if ($users > 1) {
|
if ($users >= 1) {
|
||||||
$insp->write(sprintf('%s active users', $users));
|
$insp->write(sprintf('%s active users', $users));
|
||||||
} else {
|
} else {
|
||||||
return $insp->error('0 active users', $users);
|
return $insp->error('0 active users', $users);
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
namespace Icinga\Cli;
|
namespace Icinga\Cli;
|
||||||
|
|
||||||
use Icinga\Application\ApplicationBootstrap as App;
|
use Icinga\Application\ApplicationBootstrap as App;
|
||||||
|
use Icinga\Exception\IcingaException;
|
||||||
use Icinga\Exception\ProgrammingError;
|
use Icinga\Exception\ProgrammingError;
|
||||||
use Icinga\Cli\Params;
|
use Icinga\Cli\Params;
|
||||||
use Icinga\Cli\Screen;
|
use Icinga\Cli\Screen;
|
||||||
@ -265,7 +266,8 @@ class Loader
|
|||||||
if ($obj && $obj instanceof Command && $obj->showTrace()) {
|
if ($obj && $obj instanceof Command && $obj->showTrace()) {
|
||||||
echo $this->formatTrace($e->getTrace());
|
echo $this->formatTrace($e->getTrace());
|
||||||
}
|
}
|
||||||
$this->fail($e->getMessage());
|
|
||||||
|
$this->fail(IcingaException::describe($e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,6 +59,7 @@ class Inspection
|
|||||||
if ($entry instanceof Inspection) {
|
if ($entry instanceof Inspection) {
|
||||||
$this->log[$entry->description] = $entry->toArray();
|
$this->log[$entry->description] = $entry->toArray();
|
||||||
} else {
|
} else {
|
||||||
|
Logger::debug($entry);
|
||||||
$this->log[] = $entry;
|
$this->log[] = $entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,7 +78,8 @@ class Inspection
|
|||||||
if (isset($this->error)) {
|
if (isset($this->error)) {
|
||||||
throw new ProgrammingError('Inspection object used after error');
|
throw new ProgrammingError('Inspection object used after error');
|
||||||
}
|
}
|
||||||
$this->write($entry);
|
Logger::error($entry);
|
||||||
|
$this->log[] = $entry;
|
||||||
$this->error = $entry;
|
$this->error = $entry;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
9
library/Icinga/Data/Paginatable.php
Normal file
9
library/Icinga/Data/Paginatable.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||||
|
|
||||||
|
namespace Icinga\Data;
|
||||||
|
|
||||||
|
use Countable;
|
||||||
|
|
||||||
|
interface Paginatable extends Limitable, Countable {};
|
||||||
|
|
@ -3,6 +3,4 @@
|
|||||||
|
|
||||||
namespace Icinga\Data;
|
namespace Icinga\Data;
|
||||||
|
|
||||||
use Countable;
|
interface QueryInterface extends Fetchable, Filterable, Paginatable, Sortable {};
|
||||||
|
|
||||||
interface QueryInterface extends Fetchable, Filterable, Limitable, Sortable, Countable {};
|
|
||||||
|
14
library/Icinga/Data/SortRules.php
Normal file
14
library/Icinga/Data/SortRules.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||||
|
|
||||||
|
namespace Icinga\Data;
|
||||||
|
|
||||||
|
interface SortRules
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Return some sort rules
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getSortRules();
|
||||||
|
}
|
@ -40,4 +40,24 @@ class IcingaException extends Exception
|
|||||||
$e = new ReflectionClass(get_called_class());
|
$e = new ReflectionClass(get_called_class());
|
||||||
return $e->newInstanceArgs($args);
|
return $e->newInstanceArgs($args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the given exception formatted as one-liner
|
||||||
|
*
|
||||||
|
* The format used is: %class% in %path%:%line% with message: %message%
|
||||||
|
*
|
||||||
|
* @param Exception $exception
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function describe(Exception $exception)
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
'%s in %s:%d with message: %s',
|
||||||
|
get_class($exception),
|
||||||
|
$exception->getFile(),
|
||||||
|
$exception->getLine(),
|
||||||
|
$exception->getMessage()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,7 +314,7 @@ class LdapConnection implements Selectable, Inspectable
|
|||||||
public function bind()
|
public function bind()
|
||||||
{
|
{
|
||||||
if ($this->bound) {
|
if ($this->bound) {
|
||||||
return;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
$ds = $this->getConnection();
|
$ds = $this->getConnection();
|
||||||
@ -332,6 +332,7 @@ class LdapConnection implements Selectable, Inspectable
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->bound = true;
|
$this->bound = true;
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,7 +78,7 @@ abstract class Repository implements Selectable
|
|||||||
protected $filterColumns;
|
protected $filterColumns;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default sort rules to be applied on a query
|
* The sort rules to be applied on a query
|
||||||
*
|
*
|
||||||
* This may be initialized by concrete repository implementations, in the following format
|
* This may be initialized by concrete repository implementations, in the following format
|
||||||
* <pre><code>
|
* <pre><code>
|
||||||
@ -284,7 +284,7 @@ abstract class Repository implements Selectable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the default sort rules to be applied on a query
|
* Return the sort rules to be applied on a query
|
||||||
*
|
*
|
||||||
* Calls $this->initializeSortRules() in case $this->sortRules is null.
|
* Calls $this->initializeSortRules() in case $this->sortRules is null.
|
||||||
*
|
*
|
||||||
|
@ -9,12 +9,13 @@ use Icinga\Application\Benchmark;
|
|||||||
use Icinga\Application\Logger;
|
use Icinga\Application\Logger;
|
||||||
use Icinga\Data\QueryInterface;
|
use Icinga\Data\QueryInterface;
|
||||||
use Icinga\Data\Filter\Filter;
|
use Icinga\Data\Filter\Filter;
|
||||||
|
use Icinga\Data\SortRules;
|
||||||
use Icinga\Exception\QueryException;
|
use Icinga\Exception\QueryException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query class supposed to mediate between a repository and its datasource's query
|
* Query class supposed to mediate between a repository and its datasource's query
|
||||||
*/
|
*/
|
||||||
class RepositoryQuery implements QueryInterface, Iterator
|
class RepositoryQuery implements QueryInterface, SortRules, Iterator
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The repository being used
|
* The repository being used
|
||||||
@ -212,6 +213,16 @@ class RepositoryQuery implements QueryInterface, Iterator
|
|||||||
return $this->query->getFilter();
|
return $this->query->getFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the sort rules being applied on this query
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getSortRules()
|
||||||
|
{
|
||||||
|
return $this->repository->getSortRules();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a sort rule for this query
|
* Add a sort rule for this query
|
||||||
*
|
*
|
||||||
@ -226,7 +237,7 @@ class RepositoryQuery implements QueryInterface, Iterator
|
|||||||
*/
|
*/
|
||||||
public function order($field = null, $direction = null, $ignoreDefault = false)
|
public function order($field = null, $direction = null, $ignoreDefault = false)
|
||||||
{
|
{
|
||||||
$sortRules = $this->repository->getSortRules();
|
$sortRules = $this->getSortRules();
|
||||||
if ($field === null) {
|
if ($field === null) {
|
||||||
// Use first available sort rule as default
|
// Use first available sort rule as default
|
||||||
if (empty($sortRules)) {
|
if (empty($sortRules)) {
|
||||||
|
@ -37,13 +37,13 @@ class Controller extends ModuleActionController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (($sort = $request->getPost('sort'))) {
|
if (($sort = $request->getPost('sort')) || ($direction = $request->getPost('dir'))) {
|
||||||
$url = Url::fromRequest();
|
$url = Url::fromRequest();
|
||||||
|
if ($sort) {
|
||||||
$url->setParam('sort', $sort);
|
$url->setParam('sort', $sort);
|
||||||
if (($dir = $request->getPost('dir'))) {
|
$url->remove('dir');
|
||||||
$url->setParam('dir', $dir);
|
|
||||||
} else {
|
} else {
|
||||||
$url->removeParam('dir');
|
$url->setParam('dir', $direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->redirectNow($url);
|
$this->redirectNow($url);
|
||||||
|
@ -96,6 +96,9 @@ class ActionController extends Zend_Controller_Action
|
|||||||
if ($this->rerenderLayout = $request->getUrl()->shift('renderLayout')) {
|
if ($this->rerenderLayout = $request->getUrl()->shift('renderLayout')) {
|
||||||
$this->xhrLayout = 'body';
|
$this->xhrLayout = 'body';
|
||||||
}
|
}
|
||||||
|
if ($request->getUrl()->shift('_disableLayout')) {
|
||||||
|
$this->_helper->layout()->disableLayout();
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->requiresLogin()) {
|
if ($this->requiresLogin()) {
|
||||||
$this->redirectToLogin(Url::fromRequest());
|
$this->redirectToLogin(Url::fromRequest());
|
||||||
@ -455,11 +458,11 @@ class ActionController extends Zend_Controller_Action
|
|||||||
foreach ($notifications->getMessages() as $m) {
|
foreach ($notifications->getMessages() as $m) {
|
||||||
$notificationList[] = rawurlencode($m->type . ' ' . $m->message);
|
$notificationList[] = rawurlencode($m->type . ' ' . $m->message);
|
||||||
}
|
}
|
||||||
$resp->setHeader('X-Icinga-Notification', implode('&', $notificationList));
|
$resp->setHeader('X-Icinga-Notification', implode('&', $notificationList), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->reloadCss) {
|
if ($this->reloadCss) {
|
||||||
$resp->setHeader('X-Icinga-CssReload', 'now');
|
$resp->setHeader('X-Icinga-CssReload', 'now', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->view->title) {
|
if ($this->view->title) {
|
||||||
@ -469,18 +472,19 @@ class ActionController extends Zend_Controller_Action
|
|||||||
}
|
}
|
||||||
$resp->setHeader(
|
$resp->setHeader(
|
||||||
'X-Icinga-Title',
|
'X-Icinga-Title',
|
||||||
rawurlencode($this->view->title . ' :: Icinga Web')
|
rawurlencode($this->view->title . ' :: Icinga Web'),
|
||||||
|
true
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$resp->setHeader('X-Icinga-Title', rawurlencode('Icinga Web'));
|
$resp->setHeader('X-Icinga-Title', rawurlencode('Icinga Web'), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->rerenderLayout) {
|
if ($this->rerenderLayout) {
|
||||||
$this->getResponse()->setHeader('X-Icinga-Container', 'layout');
|
$this->getResponse()->setHeader('X-Icinga-Container', 'layout', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->autorefreshInterval !== null) {
|
if ($this->autorefreshInterval !== null) {
|
||||||
$resp->setHeader('X-Icinga-Refresh', $this->autorefreshInterval);
|
$resp->setHeader('X-Icinga-Refresh', $this->autorefreshInterval, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
namespace Icinga\Web;
|
namespace Icinga\Web;
|
||||||
|
|
||||||
use LogicException;
|
|
||||||
use Zend_Config;
|
use Zend_Config;
|
||||||
use Zend_Form;
|
use Zend_Form;
|
||||||
use Zend_Form_Element;
|
use Zend_Form_Element;
|
||||||
use Zend_View_Interface;
|
use Zend_View_Interface;
|
||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
use Icinga\Authentication\Manager;
|
use Icinga\Authentication\Manager;
|
||||||
|
use Icinga\Exception\ProgrammingError;
|
||||||
use Icinga\Security\SecurityException;
|
use Icinga\Security\SecurityException;
|
||||||
use Icinga\Util\Translator;
|
use Icinga\Util\Translator;
|
||||||
use Icinga\Web\Form\ErrorLabeller;
|
use Icinga\Web\Form\ErrorLabeller;
|
||||||
@ -84,7 +84,7 @@ class Form extends Zend_Form
|
|||||||
/**
|
/**
|
||||||
* The url to redirect to upon success
|
* The url to redirect to upon success
|
||||||
*
|
*
|
||||||
* @var string|Url
|
* @var Url
|
||||||
*/
|
*/
|
||||||
protected $redirectUrl;
|
protected $redirectUrl;
|
||||||
|
|
||||||
@ -160,6 +160,13 @@ class Form extends Zend_Form
|
|||||||
*/
|
*/
|
||||||
protected $notifications;
|
protected $notifications;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hints of this form
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $hints;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the Autosubmit decorator should be applied to this form
|
* Whether the Autosubmit decorator should be applied to this form
|
||||||
*
|
*
|
||||||
@ -222,12 +229,12 @@ class Form extends Zend_Form
|
|||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*
|
*
|
||||||
* @throws LogicException If the callback is not callable
|
* @throws ProgrammingError If the callback is not callable
|
||||||
*/
|
*/
|
||||||
public function setOnSuccess($onSuccess)
|
public function setOnSuccess($onSuccess)
|
||||||
{
|
{
|
||||||
if (! is_callable($onSuccess)) {
|
if (! is_callable($onSuccess)) {
|
||||||
throw new LogicException('The option `onSuccess\' is not callable');
|
throw new ProgrammingError('The option `onSuccess\' is not callable');
|
||||||
}
|
}
|
||||||
$this->onSuccess = $onSuccess;
|
$this->onSuccess = $onSuccess;
|
||||||
return $this;
|
return $this;
|
||||||
@ -262,9 +269,17 @@ class Form extends Zend_Form
|
|||||||
* @param string|Url $url The url to redirect to
|
* @param string|Url $url The url to redirect to
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
|
*
|
||||||
|
* @throws ProgrammingError In case $url is neither a string nor a instance of Icinga\Web\Url
|
||||||
*/
|
*/
|
||||||
public function setRedirectUrl($url)
|
public function setRedirectUrl($url)
|
||||||
{
|
{
|
||||||
|
if (is_string($url)) {
|
||||||
|
$url = Url::fromPath($url, array(), $this->getRequest());
|
||||||
|
} elseif (! $url instanceof Url) {
|
||||||
|
throw new ProgrammingError('$url must be a string or instance of Icinga\Web\Url');
|
||||||
|
}
|
||||||
|
|
||||||
$this->redirectUrl = $url;
|
$this->redirectUrl = $url;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
@ -272,14 +287,16 @@ class Form extends Zend_Form
|
|||||||
/**
|
/**
|
||||||
* Return the url to redirect to upon success
|
* Return the url to redirect to upon success
|
||||||
*
|
*
|
||||||
* @return string|Url
|
* @return Url
|
||||||
*/
|
*/
|
||||||
public function getRedirectUrl()
|
public function getRedirectUrl()
|
||||||
{
|
{
|
||||||
if ($this->redirectUrl === null) {
|
if ($this->redirectUrl === null) {
|
||||||
$url = Url::fromRequest(array(), $this->getRequest());
|
$this->redirectUrl = $this->getRequest()->getUrl();
|
||||||
|
if ($this->getMethod() === 'get') {
|
||||||
// Be sure to remove all form dependent params because we do not want to submit it again
|
// Be sure to remove all form dependent params because we do not want to submit it again
|
||||||
$this->redirectUrl = $url->without(array_keys($this->getElements()));
|
$this->redirectUrl = $this->redirectUrl->without(array_keys($this->getElements()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->redirectUrl;
|
return $this->redirectUrl;
|
||||||
@ -566,6 +583,49 @@ class Form extends Zend_Form
|
|||||||
return $this->notifications;
|
return $this->notifications;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the hints for this form
|
||||||
|
*
|
||||||
|
* @param array $hints
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setHints(array $hints)
|
||||||
|
{
|
||||||
|
$this->hints = $hints;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a hint for this form
|
||||||
|
*
|
||||||
|
* If $hint is an array the second value should be an
|
||||||
|
* array as well containing additional HTML properties.
|
||||||
|
*
|
||||||
|
* @param string|array $hint
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function addHint($hint)
|
||||||
|
{
|
||||||
|
$this->hints[] = $hint;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the hints of this form
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getHints()
|
||||||
|
{
|
||||||
|
if ($this->hints === null) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->hints;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set whether the Autosubmit decorator should be applied to this form
|
* Set whether the Autosubmit decorator should be applied to this form
|
||||||
*
|
*
|
||||||
@ -600,22 +660,26 @@ class Form extends Zend_Form
|
|||||||
*/
|
*/
|
||||||
public function create(array $formData = array())
|
public function create(array $formData = array())
|
||||||
{
|
{
|
||||||
if (false === $this->created) {
|
if (! $this->created) {
|
||||||
$this->createElements($formData);
|
$this->createElements($formData);
|
||||||
$this->addFormIdentification()
|
$this->addFormIdentification()
|
||||||
->addCsrfCounterMeasure()
|
->addCsrfCounterMeasure()
|
||||||
->addSubmitButton();
|
->addSubmitButton();
|
||||||
|
|
||||||
if ($this->getAttrib('action') === null) {
|
|
||||||
// Use Form::getAttrib() instead of Form::getAction() here because we want to explicitly check against
|
// Use Form::getAttrib() instead of Form::getAction() here because we want to explicitly check against
|
||||||
// null. Form::getAction() would return the empty string '' if the action is not set.
|
// null. Form::getAction() would return the empty string '' if the action is not set.
|
||||||
// For not setting the action attribute use Form::setAction(''). This is required for for the
|
// For not setting the action attribute use Form::setAction(''). This is required for for the
|
||||||
// accessibility's enable/disable auto-refresh mechanic
|
// accessibility's enable/disable auto-refresh mechanic
|
||||||
|
if ($this->getAttrib('action') === null) {
|
||||||
|
$action = $this->getRequest()->getUrl();
|
||||||
|
if ($this->getMethod() === 'get') {
|
||||||
|
$action = $action->without(array_keys($this->getElements()));
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(el): Re-evalute this necessity. JavaScript could use the container's URL if there's no action set.
|
// TODO(el): Re-evalute this necessity. JavaScript could use the container's URL if there's no action set.
|
||||||
// We MUST set an action as JS gets confused otherwise, if
|
// We MUST set an action as JS gets confused otherwise, if
|
||||||
// this form is being displayed in an additional column
|
// this form is being displayed in an additional column
|
||||||
$this->setAction(Url::fromRequest()->without(array_keys($this->getElements())));
|
$this->setAction($action);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->created = true;
|
$this->created = true;
|
||||||
@ -862,7 +926,7 @@ class Form extends Zend_Form
|
|||||||
*/
|
*/
|
||||||
public function addFormIdentification()
|
public function addFormIdentification()
|
||||||
{
|
{
|
||||||
if (false === $this->uidDisabled && $this->getElement($this->uidElementName) === null) {
|
if (! $this->uidDisabled && $this->getElement($this->uidElementName) === null) {
|
||||||
$this->addElement(
|
$this->addElement(
|
||||||
'hidden',
|
'hidden',
|
||||||
$this->uidElementName,
|
$this->uidElementName,
|
||||||
@ -884,7 +948,7 @@ class Form extends Zend_Form
|
|||||||
*/
|
*/
|
||||||
public function addCsrfCounterMeasure()
|
public function addCsrfCounterMeasure()
|
||||||
{
|
{
|
||||||
if (false === $this->tokenDisabled && $this->getElement($this->tokenElementName) === null) {
|
if (! $this->tokenDisabled && $this->getElement($this->tokenElementName) === null) {
|
||||||
$this->addElement(new CsrfCounterMeasure($this->tokenElementName));
|
$this->addElement(new CsrfCounterMeasure($this->tokenElementName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -946,12 +1010,20 @@ class Form extends Zend_Form
|
|||||||
|
|
||||||
$formData = $this->getRequestData();
|
$formData = $this->getRequestData();
|
||||||
if ($this->getUidDisabled() || $this->wasSent($formData)) {
|
if ($this->getUidDisabled() || $this->wasSent($formData)) {
|
||||||
|
if (($frameUpload = (bool) $request->getUrl()->shift('_frameUpload', false))) {
|
||||||
|
$this->getView()->layout()->setLayout('wrapped');
|
||||||
|
}
|
||||||
|
|
||||||
$this->populate($formData); // Necessary to get isSubmitted() to work
|
$this->populate($formData); // Necessary to get isSubmitted() to work
|
||||||
if (! $this->getSubmitLabel() || $this->isSubmitted()) {
|
if (! $this->getSubmitLabel() || $this->isSubmitted()) {
|
||||||
if ($this->isValid($formData)
|
if ($this->isValid($formData)
|
||||||
&& (($this->onSuccess !== null && false !== call_user_func($this->onSuccess, $this))
|
&& (($this->onSuccess !== null && false !== call_user_func($this->onSuccess, $this))
|
||||||
|| ($this->onSuccess === null && false !== $this->onSuccess()))) {
|
|| ($this->onSuccess === null && false !== $this->onSuccess()))) {
|
||||||
|
if (! $frameUpload) {
|
||||||
$this->getResponse()->redirectAndExit($this->getRedirectUrl());
|
$this->getResponse()->redirectAndExit($this->getRedirectUrl());
|
||||||
|
} else {
|
||||||
|
$this->getView()->layout()->redirectUrl = $this->getRedirectUrl()->getAbsoluteUrl();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} elseif ($this->getValidatePartial()) {
|
} elseif ($this->getValidatePartial()) {
|
||||||
// The form can't be processed but we may want to show validation errors though
|
// The form can't be processed but we may want to show validation errors though
|
||||||
@ -1087,10 +1159,11 @@ class Form extends Zend_Form
|
|||||||
->addDecorator('HtmlTag', array('tag' => 'div', 'class' => 'header'));
|
->addDecorator('HtmlTag', array('tag' => 'div', 'class' => 'header'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addDecorator('FormErrors', array('onlyCustomFormErrors' => true))
|
$this->addDecorator('FormDescriptions')
|
||||||
->addDecorator('FormNotifications')
|
->addDecorator('FormNotifications')
|
||||||
->addDecorator('FormDescriptions')
|
->addDecorator('FormErrors', array('onlyCustomFormErrors' => true))
|
||||||
->addDecorator('FormElements')
|
->addDecorator('FormElements')
|
||||||
|
->addDecorator('FormHints')
|
||||||
//->addDecorator('HtmlTag', array('tag' => 'dl', 'class' => 'zend_form'))
|
//->addDecorator('HtmlTag', array('tag' => 'dl', 'class' => 'zend_form'))
|
||||||
->addDecorator('Form');
|
->addDecorator('Form');
|
||||||
}
|
}
|
||||||
|
@ -7,35 +7,10 @@ use Zend_Form_Decorator_Abstract;
|
|||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decorator to add a list of descriptions at the top of a form
|
* Decorator to add a list of descriptions at the top or bottom of a form
|
||||||
*
|
|
||||||
* The description for required form elements is automatically being handled.
|
|
||||||
*/
|
*/
|
||||||
class FormDescriptions extends Zend_Form_Decorator_Abstract
|
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
|
* Render form descriptions
|
||||||
*
|
*
|
||||||
@ -55,18 +30,7 @@ class FormDescriptions extends Zend_Form_Decorator_Abstract
|
|||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
$descriptions = $this->recurseForm($form, $entirelyRequired);
|
$descriptions = $this->recurseForm($form);
|
||||||
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)) {
|
if (empty($descriptions)) {
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
@ -93,52 +57,14 @@ class FormDescriptions extends Zend_Form_Decorator_Abstract
|
|||||||
* Recurse the given form and return the descriptions for it and all of its subforms
|
* Recurse the given form and return the descriptions for it and all of its subforms
|
||||||
*
|
*
|
||||||
* @param Form $form The form to recurse
|
* @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
|
* @return array
|
||||||
*/
|
*/
|
||||||
protected function recurseForm(Form $form, & $entirelyRequired = null, $elementsPassed = false)
|
protected function recurseForm(Form $form)
|
||||||
{
|
{
|
||||||
$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());
|
$descriptions = array($form->getDescriptions());
|
||||||
foreach ($form->getSubForms() as $subForm) {
|
foreach ($form->getSubForms() as $subForm) {
|
||||||
$descriptions[] = $this->recurseForm($subForm, $entirelyRequired, $elementsPassed);
|
$descriptions[] = $this->recurseForm($subForm);
|
||||||
}
|
|
||||||
|
|
||||||
if ($entirelyRequired) {
|
|
||||||
foreach ($requiredLabels as $label) {
|
|
||||||
$label->setRequiredSuffix('');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return call_user_func_array('array_merge', $descriptions);
|
return call_user_func_array('array_merge', $descriptions);
|
||||||
|
142
library/Icinga/Web/Form/Decorator/FormHints.php
Normal file
142
library/Icinga/Web/Form/Decorator/FormHints.php
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
<?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 hints at the top or bottom of a form
|
||||||
|
*
|
||||||
|
* The hint for required form elements is automatically being handled.
|
||||||
|
*/
|
||||||
|
class FormHints 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 hints
|
||||||
|
*
|
||||||
|
* @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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hints = $this->recurseForm($form, $entirelyRequired);
|
||||||
|
if ($entirelyRequired !== null) {
|
||||||
|
$hints[] = $form->getView()->translate(sprintf(
|
||||||
|
'Required fields are marked with %s and must be filled in to complete the form.',
|
||||||
|
$form->getRequiredCue()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($hints)) {
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
|
||||||
|
$html = '<ul class="hints">';
|
||||||
|
foreach ($hints as $hint) {
|
||||||
|
if (is_array($hint)) {
|
||||||
|
list($hint, $properties) = $hint;
|
||||||
|
$html .= '<li' . $view->propertiesToString($properties) . '>' . $view->escape($hint) . '</li>';
|
||||||
|
} else {
|
||||||
|
$html .= '<li>' . $view->escape($hint) . '</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 hints 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$hints = array($form->getHints());
|
||||||
|
foreach ($form->getSubForms() as $subForm) {
|
||||||
|
$hints[] = $this->recurseForm($subForm, $entirelyRequired, $elementsPassed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($entirelyRequired) {
|
||||||
|
foreach ($requiredLabels as $label) {
|
||||||
|
$label->setRequiredSuffix('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return call_user_func_array('array_merge', $hints);
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ namespace Icinga\Web\Form;
|
|||||||
use BadMethodCallException;
|
use BadMethodCallException;
|
||||||
use Zend_Translate_Adapter;
|
use Zend_Translate_Adapter;
|
||||||
use Zend_Validate_NotEmpty;
|
use Zend_Validate_NotEmpty;
|
||||||
|
use Zend_Validate_File_MimeType;
|
||||||
use Icinga\Web\Form\Validator\DateTimeValidator;
|
use Icinga\Web\Form\Validator\DateTimeValidator;
|
||||||
use Icinga\Web\Form\Validator\ReadablePathValidator;
|
use Icinga\Web\Form\Validator\ReadablePathValidator;
|
||||||
use Icinga\Web\Form\Validator\WritablePathValidator;
|
use Icinga\Web\Form\Validator\WritablePathValidator;
|
||||||
@ -43,6 +44,11 @@ class ErrorLabeller extends Zend_Translate_Adapter
|
|||||||
|
|
||||||
return array(
|
return array(
|
||||||
Zend_Validate_NotEmpty::IS_EMPTY => sprintf(t('%s is required and must not be empty'), $label),
|
Zend_Validate_NotEmpty::IS_EMPTY => sprintf(t('%s is required and must not be empty'), $label),
|
||||||
|
Zend_Validate_File_MimeType::FALSE_TYPE => sprintf(
|
||||||
|
t('%s (%%value%%) has a false MIME type of "%%type%%"'),
|
||||||
|
$label
|
||||||
|
),
|
||||||
|
Zend_Validate_File_MimeType::NOT_DETECTED => sprintf(t('%s (%%value%%) has no MIME type'), $label),
|
||||||
WritablePathValidator::NOT_WRITABLE => sprintf(t('%s is not writable', 'config.path'), $label),
|
WritablePathValidator::NOT_WRITABLE => sprintf(t('%s is not writable', 'config.path'), $label),
|
||||||
WritablePathValidator::DOES_NOT_EXIST => sprintf(t('%s does not exist', 'config.path'), $label),
|
WritablePathValidator::DOES_NOT_EXIST => sprintf(t('%s does not exist', 'config.path'), $label),
|
||||||
ReadablePathValidator::NOT_READABLE => sprintf(t('%s is not readable', 'config.path'), $label),
|
ReadablePathValidator::NOT_READABLE => sprintf(t('%s is not readable', 'config.path'), $label),
|
||||||
|
@ -8,7 +8,6 @@ use RecursiveDirectoryIterator;
|
|||||||
use RecursiveIteratorIterator;
|
use RecursiveIteratorIterator;
|
||||||
use RegexIterator;
|
use RegexIterator;
|
||||||
use RecursiveRegexIterator;
|
use RecursiveRegexIterator;
|
||||||
use Zend_Controller_Front;
|
|
||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
use lessc;
|
use lessc;
|
||||||
|
|
||||||
@ -31,8 +30,6 @@ class LessCompiler
|
|||||||
*/
|
*/
|
||||||
private $lessc;
|
private $lessc;
|
||||||
|
|
||||||
private $baseUrl;
|
|
||||||
|
|
||||||
private $source;
|
private $source;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,6 +41,17 @@ class LessCompiler
|
|||||||
$this->lessc = new lessc();
|
$this->lessc = new lessc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable the extendend import functionality
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function disableExtendedImport()
|
||||||
|
{
|
||||||
|
$this->lessc->importDisabled = true;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function compress()
|
public function compress()
|
||||||
{
|
{
|
||||||
$this->lessc->setPreserveComments(false);
|
$this->lessc->setPreserveComments(false);
|
||||||
|
@ -118,7 +118,13 @@ class MenuRenderer extends RecursiveIteratorIterator
|
|||||||
try {
|
try {
|
||||||
return $child->getRenderer()->render($child);
|
return $child->getRenderer()->render($child);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
Logger::error('Could not invoke custom renderer. Exception: '. $e->getMessage());
|
Logger::error(
|
||||||
|
'Could not invoke custom menu renderer. %s in %s:%d with message: %s',
|
||||||
|
get_class($e),
|
||||||
|
$e->getFile(),
|
||||||
|
$e->getLine(),
|
||||||
|
$e->getMessage()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,6 +99,7 @@ class StyleSheet
|
|||||||
}
|
}
|
||||||
|
|
||||||
$less = new LessCompiler();
|
$less = new LessCompiler();
|
||||||
|
$less->disableExtendedImport();
|
||||||
foreach ($lessFiles as $file) {
|
foreach ($lessFiles as $file) {
|
||||||
$less->addFile($file);
|
$less->addFile($file);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
namespace Icinga\Web\Widget;
|
namespace Icinga\Web\Widget;
|
||||||
|
|
||||||
use Icinga\Data\QueryInterface;
|
use Icinga\Data\Paginatable;
|
||||||
use Icinga\Exception\ProgrammingError;
|
use Icinga\Exception\ProgrammingError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -14,7 +14,7 @@ class Paginator extends AbstractWidget
|
|||||||
/**
|
/**
|
||||||
* The query the paginator widget is created for
|
* The query the paginator widget is created for
|
||||||
*
|
*
|
||||||
* @var QueryInterface
|
* @var Paginatable
|
||||||
*/
|
*/
|
||||||
protected $query;
|
protected $query;
|
||||||
|
|
||||||
@ -28,11 +28,11 @@ class Paginator extends AbstractWidget
|
|||||||
/**
|
/**
|
||||||
* Set the query to create the paginator widget for
|
* Set the query to create the paginator widget for
|
||||||
*
|
*
|
||||||
* @param QueryInterface $query
|
* @param Paginatable $query
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setQuery(QueryInterface $query)
|
public function setQuery(Paginatable $query)
|
||||||
{
|
{
|
||||||
$this->query = $query;
|
$this->query = $query;
|
||||||
return $this;
|
return $this;
|
||||||
|
@ -3,30 +3,26 @@
|
|||||||
|
|
||||||
namespace Icinga\Web\Widget;
|
namespace Icinga\Web\Widget;
|
||||||
|
|
||||||
|
use Icinga\Application\Icinga;
|
||||||
|
use Icinga\Data\Sortable;
|
||||||
|
use Icinga\Data\SortRules;
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
use Icinga\Web\Request;
|
use Icinga\Web\Request;
|
||||||
use Icinga\Data\Sortable;
|
|
||||||
use Icinga\Application\Icinga;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SortBox widget
|
* SortBox widget
|
||||||
*
|
*
|
||||||
* The "SortBox" Widget allows you to create a generic sort input for sortable views. It automatically creates a form
|
* The "SortBox" Widget allows you to create a generic sort input for sortable views. It automatically creates a select
|
||||||
* containing a select box with all sort options and a dropbox with the sort direction. It also handles automatic
|
* box with all sort options and a dropbox with the sort direction. It also handles automatic submission of sorting
|
||||||
* submission of sorting changes and draws an additional submit button when JavaScript is disabled.
|
* changes and draws an additional submit button when JavaScript is disabled.
|
||||||
*
|
*
|
||||||
* The constructor takes an string for the component name and an array containing the select options, where the key is
|
* The constructor takes a string for the component name and an array containing the select options, where the key is
|
||||||
* the value to be submitted and the value is the label that will be shown. You then should call setRequest in order
|
* the value to be submitted and the value is the label that will be shown. You then should call setRequest in order
|
||||||
* to make sure the form is correctly populated when a request with a sort parameter is being made.
|
* to make sure the form is correctly populated when a request with a sort parameter is being made.
|
||||||
*
|
*
|
||||||
* Example:
|
* Call setQuery in case you'll do not want to handle URL parameters manually, but to automatically apply the user's
|
||||||
* <pre><code>
|
* chosen sort rules on the given sortable query. This will also allow the SortBox to display the user the correct
|
||||||
* $this->view->sortControl = new SortBox(
|
* default sort rules if the given query provides already some sort rules.
|
||||||
* $this->getRequest()->getActionName(),
|
|
||||||
* $columns
|
|
||||||
* );
|
|
||||||
* $this->view->sortControl->setRequest($this->getRequest());
|
|
||||||
* </code></pre>
|
|
||||||
*/
|
*/
|
||||||
class SortBox extends AbstractWidget
|
class SortBox extends AbstractWidget
|
||||||
{
|
{
|
||||||
@ -38,25 +34,25 @@ class SortBox extends AbstractWidget
|
|||||||
protected $sortFields;
|
protected $sortFields;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the form that will be created
|
* The name used to uniquely identfy the forms being created
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $name;
|
protected $name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A request object used for initial form population
|
* The request to fetch sort rules from
|
||||||
*
|
*
|
||||||
* @var Request
|
* @var Request
|
||||||
*/
|
*/
|
||||||
protected $request;
|
protected $request;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* What to apply sort parameters on
|
* The query to apply sort rules on
|
||||||
*
|
*
|
||||||
* @var Sortable
|
* @var Sortable
|
||||||
*/
|
*/
|
||||||
protected $query = null;
|
protected $query;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a SortBox with the entries from $sortFields
|
* Create a SortBox with the entries from $sortFields
|
||||||
@ -84,9 +80,9 @@ class SortBox extends AbstractWidget
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply the parameters from the given request on this SortBox
|
* Set the request to fetch sort rules from
|
||||||
*
|
*
|
||||||
* @param Request $request The request to use for populating the form
|
* @param Request $request
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
@ -97,6 +93,8 @@ class SortBox extends AbstractWidget
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Set the query to apply sort rules on
|
||||||
|
*
|
||||||
* @param Sortable $query
|
* @param Sortable $query
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
@ -107,19 +105,54 @@ class SortBox extends AbstractWidget
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the sort rules from the given or current request on the query
|
||||||
|
*
|
||||||
|
* @param Request $request
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
public function handleRequest(Request $request = null)
|
public function handleRequest(Request $request = null)
|
||||||
{
|
{
|
||||||
if ($this->query !== null) {
|
if ($this->query !== null) {
|
||||||
if ($request === null) {
|
if ($request === null) {
|
||||||
$request = Icinga::app()->getFrontController()->getRequest();
|
$request = Icinga::app()->getFrontController()->getRequest();
|
||||||
}
|
}
|
||||||
if ($sort = $request->getParam('sort')) {
|
|
||||||
|
if (($sort = $request->getParam('sort'))) {
|
||||||
$this->query->order($sort, $request->getParam('dir'));
|
$this->query->order($sort, $request->getParam('dir'));
|
||||||
|
} elseif (($dir = $request->getParam('dir'))) {
|
||||||
|
$this->query->order(null, $dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the default sort rule for the query
|
||||||
|
*
|
||||||
|
* @param string $column An optional column
|
||||||
|
*
|
||||||
|
* @return array An array of two values: $column, $direction
|
||||||
|
*/
|
||||||
|
protected function getSortDefaults($column = null)
|
||||||
|
{
|
||||||
|
$direction = null;
|
||||||
|
if ($this->query !== null && $this->query instanceof SortRules) {
|
||||||
|
$sortRules = $this->query->getSortRules();
|
||||||
|
if ($column === null) {
|
||||||
|
$column = key($sortRules);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($column !== null && isset($sortRules[$column]['order'])) {
|
||||||
|
$direction = strtoupper($sortRules[$column]['order']) === Sortable::SORT_DESC ? 'desc' : 'asc';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array($column, $direction);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render this SortBox as HTML
|
* Render this SortBox as HTML
|
||||||
*
|
*
|
||||||
@ -127,43 +160,68 @@ class SortBox extends AbstractWidget
|
|||||||
*/
|
*/
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
$form = new Form();
|
$columnForm = new Form();
|
||||||
$form->setTokenDisabled();
|
$columnForm->setTokenDisabled();
|
||||||
$form->setName($this->name);
|
$columnForm->setName($this->name . '-column');
|
||||||
$form->setAttrib('class', 'sort-control inline');
|
$columnForm->setAttrib('class', 'inline');
|
||||||
|
$columnForm->addElement(
|
||||||
$form->addElement(
|
|
||||||
'select',
|
'select',
|
||||||
'sort',
|
'sort',
|
||||||
array(
|
array(
|
||||||
'autosubmit' => true,
|
'autosubmit' => true,
|
||||||
'label' => $this->view()->translate('Sort by'),
|
'label' => $this->view()->translate('Sort by'),
|
||||||
'multiOptions' => $this->sortFields
|
'multiOptions' => $this->sortFields,
|
||||||
)
|
'decorators' => array(
|
||||||
);
|
|
||||||
$form->getElement('sort')->setDecorators(array(
|
|
||||||
array('ViewHelper'),
|
array('ViewHelper'),
|
||||||
array('Label')
|
array('Label')
|
||||||
));
|
)
|
||||||
$form->addElement(
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$orderForm = new Form();
|
||||||
|
$orderForm->setTokenDisabled();
|
||||||
|
$orderForm->setName($this->name . '-order');
|
||||||
|
$orderForm->setAttrib('class', 'inline');
|
||||||
|
$orderForm->addElement(
|
||||||
'select',
|
'select',
|
||||||
'dir',
|
'dir',
|
||||||
array(
|
array(
|
||||||
'autosubmit' => true,
|
'autosubmit' => true,
|
||||||
|
'label' => $this->view()->translate('Direction', 'sort direction'),
|
||||||
'multiOptions' => array(
|
'multiOptions' => array(
|
||||||
'asc' => 'Asc',
|
'asc' => $this->view()->translate('Ascending', 'sort direction'),
|
||||||
'desc' => 'Desc',
|
'desc' => $this->view()->translate('Descending', 'sort direction')
|
||||||
),
|
),
|
||||||
'decorators' => array(
|
'decorators' => array(
|
||||||
array('ViewHelper')
|
array('ViewHelper'),
|
||||||
|
array('Label', array('class' => 'no-js'))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$column = null;
|
||||||
if ($this->request) {
|
if ($this->request) {
|
||||||
$form->populate($this->request->getParams());
|
$url = $this->request->getUrl();
|
||||||
|
if ($url->hasParam('sort')) {
|
||||||
|
$column = $url->getParam('sort');
|
||||||
|
|
||||||
|
if ($url->hasParam('dir')) {
|
||||||
|
$direction = $url->getParam('dir');
|
||||||
|
} else {
|
||||||
|
list($_, $direction) = $this->getSortDefaults($column);
|
||||||
|
}
|
||||||
|
} elseif ($url->hasParam('dir')) {
|
||||||
|
$direction = $url->getParam('dir');
|
||||||
|
list($column, $_) = $this->getSortDefaults();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $form;
|
if ($column === null) {
|
||||||
|
list($column, $direction) = $this->getSortDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
$columnForm->populate(array('sort' => $column));
|
||||||
|
$orderForm->populate(array('dir' => $direction));
|
||||||
|
return '<div class="sort-control">' . $columnForm . $orderForm . '</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -309,7 +309,7 @@ EOT;
|
|||||||
|
|
||||||
private function renderRefreshTab()
|
private function renderRefreshTab()
|
||||||
{
|
{
|
||||||
$url = Url::fromRequest()->without('renderLayout');
|
$url = Icinga::app()->getFrontController()->getRequest()->getUrl();
|
||||||
$tab = $this->get($this->getActiveName());
|
$tab = $this->get($this->getActiveName());
|
||||||
|
|
||||||
if ($tab !== null) {
|
if ($tab !== null) {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||||
|
|
||||||
use \Zend_Controller_Action_Exception;
|
|
||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
use Icinga\Module\Doc\DocController;
|
use Icinga\Module\Doc\DocController;
|
||||||
|
|
||||||
@ -25,10 +24,7 @@ class Doc_IcingawebController extends DocController
|
|||||||
return $path;
|
return $path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new Zend_Controller_Action_Exception(
|
$this->httpNotFound($this->translate('Documentation for Icinga Web 2 is not available'));
|
||||||
$this->translate('Documentation for Icinga Web 2 is not available'),
|
|
||||||
404
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||||
|
|
||||||
use \Zend_Controller_Action_Exception;
|
|
||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
use Icinga\Module\Doc\DocController;
|
use Icinga\Module\Doc\DocController;
|
||||||
use Icinga\Module\Doc\Exception\DocException;
|
use Icinga\Module\Doc\Exception\DocException;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||||
|
|
||||||
use \Zend_Controller_Action_Exception;
|
|
||||||
use Icinga\Application\Icinga;
|
use Icinga\Application\Icinga;
|
||||||
use Icinga\Module\Doc\DocController;
|
use Icinga\Module\Doc\DocController;
|
||||||
use Icinga\Module\Doc\DocParser;
|
use Icinga\Module\Doc\DocParser;
|
||||||
|
@ -9,6 +9,7 @@ class Monitoring_TacticalController extends MonitoringController
|
|||||||
{
|
{
|
||||||
public function indexAction()
|
public function indexAction()
|
||||||
{
|
{
|
||||||
|
$this->setAutorefreshInterval(15);
|
||||||
$this->getTabs()->add(
|
$this->getTabs()->add(
|
||||||
'tactical_overview',
|
'tactical_overview',
|
||||||
array(
|
array(
|
||||||
|
@ -16,7 +16,7 @@ abstract class CommandForm extends Form
|
|||||||
/**
|
/**
|
||||||
* Monitoring backend
|
* Monitoring backend
|
||||||
*
|
*
|
||||||
* @var Backend
|
* @var MonitoringBackend
|
||||||
*/
|
*/
|
||||||
protected $backend;
|
protected $backend;
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ abstract class CommandForm extends Form
|
|||||||
/**
|
/**
|
||||||
* Get the monitoring backend
|
* Get the monitoring backend
|
||||||
*
|
*
|
||||||
* @return Backend
|
* @return MonitoringBackend
|
||||||
*/
|
*/
|
||||||
public function getBackend()
|
public function getBackend()
|
||||||
{
|
{
|
||||||
|
@ -13,8 +13,7 @@ use Icinga\Web\Notification;
|
|||||||
class DeleteCommentCommandForm extends CommandForm
|
class DeleteCommentCommandForm extends CommandForm
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Zend_Form::init() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
@ -22,8 +21,7 @@ class DeleteCommentCommandForm extends CommandForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Icinga\Web\Form::createElements() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function createElements(array $formData = array())
|
public function createElements(array $formData = array())
|
||||||
{
|
{
|
||||||
@ -59,8 +57,7 @@ class DeleteCommentCommandForm extends CommandForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Icinga\Web\Form::addSubmitButton() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function addSubmitButton()
|
public function addSubmitButton()
|
||||||
{
|
{
|
||||||
@ -81,8 +78,7 @@ class DeleteCommentCommandForm extends CommandForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Icinga\Web\Form::onSuccess() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function onSuccess()
|
public function onSuccess()
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
namespace Icinga\Module\Monitoring\Forms\Command\Object;
|
namespace Icinga\Module\Monitoring\Forms\Command\Object;
|
||||||
|
|
||||||
use Icinga\Module\Monitoring\Command\Object\DeleteCommentCommand;
|
use Icinga\Module\Monitoring\Command\Object\DeleteCommentCommand;
|
||||||
use \Icinga\Module\Monitoring\Forms\Command\CommandForm;
|
use Icinga\Module\Monitoring\Forms\Command\CommandForm;
|
||||||
use Icinga\Web\Notification;
|
use Icinga\Web\Notification;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,8 +20,7 @@ class DeleteCommentsCommandForm extends CommandForm
|
|||||||
protected $comments;
|
protected $comments;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Zend_Form::init() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
@ -29,8 +28,7 @@ class DeleteCommentsCommandForm extends CommandForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Icinga\Web\Form::createElements() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function createElements(array $formData = array())
|
public function createElements(array $formData = array())
|
||||||
{
|
{
|
||||||
@ -45,8 +43,7 @@ class DeleteCommentsCommandForm extends CommandForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Icinga\Web\Form::getSubmitLabel() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function getSubmitLabel()
|
public function getSubmitLabel()
|
||||||
{
|
{
|
||||||
@ -54,8 +51,7 @@ class DeleteCommentsCommandForm extends CommandForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Icinga\Web\Form::onSuccess() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function onSuccess()
|
public function onSuccess()
|
||||||
{
|
{
|
||||||
@ -78,7 +74,7 @@ class DeleteCommentsCommandForm extends CommandForm
|
|||||||
*
|
*
|
||||||
* @param array $comments
|
* @param array $comments
|
||||||
*
|
*
|
||||||
* @return this fluent interface
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setComments(array $comments)
|
public function setComments(array $comments)
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
namespace Icinga\Module\Monitoring\Forms\Command\Object;
|
namespace Icinga\Module\Monitoring\Forms\Command\Object;
|
||||||
|
|
||||||
use Icinga\Module\Monitoring\Command\Object\DeleteDowntimeCommand;
|
use Icinga\Module\Monitoring\Command\Object\DeleteDowntimeCommand;
|
||||||
use \Icinga\Module\Monitoring\Forms\Command\CommandForm;
|
use Icinga\Module\Monitoring\Forms\Command\CommandForm;
|
||||||
use Icinga\Web\Notification;
|
use Icinga\Web\Notification;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,8 +13,7 @@ use Icinga\Web\Notification;
|
|||||||
class DeleteDowntimeCommandForm extends CommandForm
|
class DeleteDowntimeCommandForm extends CommandForm
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Zend_Form::init() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
@ -22,8 +21,7 @@ class DeleteDowntimeCommandForm extends CommandForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Icinga\Web\Form::createElements() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function createElements(array $formData = array())
|
public function createElements(array $formData = array())
|
||||||
{
|
{
|
||||||
@ -59,8 +57,7 @@ class DeleteDowntimeCommandForm extends CommandForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Icinga\Web\Form::addSubmitButton() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function addSubmitButton()
|
public function addSubmitButton()
|
||||||
{
|
{
|
||||||
@ -81,8 +78,7 @@ class DeleteDowntimeCommandForm extends CommandForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Icinga\Web\Form::onSuccess() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function onSuccess()
|
public function onSuccess()
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
namespace Icinga\Module\Monitoring\Forms\Command\Object;
|
namespace Icinga\Module\Monitoring\Forms\Command\Object;
|
||||||
|
|
||||||
use Icinga\Module\Monitoring\Command\Object\DeleteDowntimeCommand;
|
use Icinga\Module\Monitoring\Command\Object\DeleteDowntimeCommand;
|
||||||
use \Icinga\Module\Monitoring\Forms\Command\CommandForm;
|
use Icinga\Module\Monitoring\Forms\Command\CommandForm;
|
||||||
use Icinga\Web\Notification;
|
use Icinga\Web\Notification;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,8 +20,7 @@ class DeleteDowntimesCommandForm extends CommandForm
|
|||||||
protected $downtimes;
|
protected $downtimes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Zend_Form::init() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
@ -29,8 +28,7 @@ class DeleteDowntimesCommandForm extends CommandForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Icinga\Web\Form::createElements() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function createElements(array $formData = array())
|
public function createElements(array $formData = array())
|
||||||
{
|
{
|
||||||
@ -45,8 +43,7 @@ class DeleteDowntimesCommandForm extends CommandForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Icinga\Web\Form::getSubmitLabel() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function getSubmitLabel()
|
public function getSubmitLabel()
|
||||||
{
|
{
|
||||||
@ -54,8 +51,7 @@ class DeleteDowntimesCommandForm extends CommandForm
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (non-PHPDoc)
|
* {@inheritdoc}
|
||||||
* @see \Icinga\Web\Form::onSuccess() For the method documentation.
|
|
||||||
*/
|
*/
|
||||||
public function onSuccess()
|
public function onSuccess()
|
||||||
{
|
{
|
||||||
@ -76,7 +72,7 @@ class DeleteDowntimesCommandForm extends CommandForm
|
|||||||
/**
|
/**
|
||||||
* Set the downtimes to be deleted upon success
|
* Set the downtimes to be deleted upon success
|
||||||
*
|
*
|
||||||
* @param type $downtimes
|
* @param array $downtimes
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
*/
|
*/
|
||||||
|
@ -109,7 +109,10 @@ class BackendConfigForm extends ConfigForm
|
|||||||
|
|
||||||
$backendName = $data['name'];
|
$backendName = $data['name'];
|
||||||
if ($this->config->hasSection($backendName)) {
|
if ($this->config->hasSection($backendName)) {
|
||||||
throw new IcingaException('A monitoring backend with the name "%s" does already exist', $backendName);
|
throw new IcingaException(
|
||||||
|
$this->translate('A monitoring backend with the name "%s" does already exist'),
|
||||||
|
$backendName
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($data['name']);
|
unset($data['name']);
|
||||||
@ -309,11 +312,16 @@ class BackendConfigForm extends ConfigForm
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (($el = $this->getElement('skip_validation')) === null || false === $el->isChecked()) {
|
||||||
$resourceConfig = ResourceFactory::getResourceConfig($this->getValue('resource'));
|
$resourceConfig = ResourceFactory::getResourceConfig($this->getValue('resource'));
|
||||||
if (! self::isValidIdoSchema($this, $resourceConfig) || !self::isValidIdoInstance($this, $resourceConfig)) {
|
if (! self::isValidIdoSchema($this, $resourceConfig) || !self::isValidIdoInstance($this, $resourceConfig)) {
|
||||||
|
if ($el === null) {
|
||||||
$this->addSkipValidationCheckbox();
|
$this->addSkipValidationCheckbox();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,10 @@ class InstanceConfigForm extends ConfigForm
|
|||||||
|
|
||||||
$instanceName = $data['name'];
|
$instanceName = $data['name'];
|
||||||
if ($this->config->hasSection($instanceName)) {
|
if ($this->config->hasSection($instanceName)) {
|
||||||
throw new IcingaException('A monitoring instance with the name "%s" does already exist', $instanceName);
|
throw new IcingaException(
|
||||||
|
$this->translate('A monitoring instance with the name "%s" does already exist'),
|
||||||
|
$instanceName
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($data['name']);
|
unset($data['name']);
|
||||||
|
@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Monitoring\Forms;
|
namespace Icinga\Module\Monitoring\Forms;
|
||||||
|
|
||||||
use Icinga\Data\Filter\FilterNot;
|
|
||||||
use Icinga\Web\Url;
|
use Icinga\Web\Url;
|
||||||
use \Zend_Form;
|
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
use Icinga\Data\Filter\Filter;
|
use Icinga\Data\Filter\Filter;
|
||||||
|
|
||||||
@ -15,7 +13,7 @@ use Icinga\Data\Filter\Filter;
|
|||||||
class EventOverviewForm extends Form
|
class EventOverviewForm extends Form
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Initialize this form
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
@ -28,7 +26,7 @@ class EventOverviewForm extends Form
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Form::createElements()
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function createElements(array $formData)
|
public function createElements(array $formData)
|
||||||
{
|
{
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
namespace Icinga\Module\Monitoring\Forms\Setup;
|
namespace Icinga\Module\Monitoring\Forms\Setup;
|
||||||
|
|
||||||
use Icinga\Data\ConfigObject;
|
use Icinga\Data\ConfigObject;
|
||||||
|
use Icinga\Forms\Config\ResourceConfigForm;
|
||||||
use Icinga\Forms\Config\Resource\DbResourceForm;
|
use Icinga\Forms\Config\Resource\DbResourceForm;
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
use Icinga\Module\Monitoring\Forms\Config\BackendConfigForm;
|
use Icinga\Module\Monitoring\Forms\Config\BackendConfigForm;
|
||||||
@ -71,13 +72,17 @@ class IdoResourcePage extends Form
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (! isset($formData['skip_validation']) || !$formData['skip_validation']) {
|
if (! isset($formData['skip_validation']) || !$formData['skip_validation']) {
|
||||||
$configObject = new ConfigObject($this->getValues());
|
$inspection = ResourceConfigForm::inspectResource($this);
|
||||||
if (! DbResourceForm::isValidResource($this, $configObject)) {
|
if ($inspection !== null && $inspection->hasError()) {
|
||||||
|
$this->error($inspection->getError());
|
||||||
$this->addSkipValidationCheckbox($this->translate(
|
$this->addSkipValidationCheckbox($this->translate(
|
||||||
'Check this to not to validate connectivity with the given database server.'
|
'Check this to not to validate connectivity with the given database server.'
|
||||||
));
|
));
|
||||||
return false;
|
return false;
|
||||||
} elseif (
|
}
|
||||||
|
|
||||||
|
$configObject = new ConfigObject($this->getValues());
|
||||||
|
if (
|
||||||
! BackendConfigForm::isValidIdoSchema($this, $configObject)
|
! BackendConfigForm::isValidIdoSchema($this, $configObject)
|
||||||
|| !BackendConfigForm::isValidIdoInstance($this, $configObject)
|
|| !BackendConfigForm::isValidIdoInstance($this, $configObject)
|
||||||
) {
|
) {
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Monitoring\Forms;
|
namespace Icinga\Module\Monitoring\Forms;
|
||||||
|
|
||||||
use \Zend_Form;
|
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
use Icinga\Data\Filter\Filter;
|
use Icinga\Data\Filter\Filter;
|
||||||
|
|
||||||
@ -13,7 +12,7 @@ use Icinga\Data\Filter\Filter;
|
|||||||
class StatehistoryForm extends Form
|
class StatehistoryForm extends Form
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Initialize this form
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function init()
|
public function init()
|
||||||
{
|
{
|
||||||
@ -56,7 +55,7 @@ class StatehistoryForm extends Form
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Form::createElements()
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function createElements(array $formData)
|
public function createElements(array $formData)
|
||||||
{
|
{
|
||||||
|
@ -60,5 +60,8 @@ class ProgramstatusQuery extends IdoQuery
|
|||||||
if (version_compare($this->getIdoVersion(), '1.11.8', '<')) {
|
if (version_compare($this->getIdoVersion(), '1.11.8', '<')) {
|
||||||
$this->columnMap['programstatus']['program_version'] = '(NULL)';
|
$this->columnMap['programstatus']['program_version'] = '(NULL)';
|
||||||
}
|
}
|
||||||
|
if (version_compare($this->getIdoVersion(), '1.8', '<')) {
|
||||||
|
$this->columnMap['programstatus']['disable_notif_expire_time'] = '(NULL)';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,13 +60,13 @@ class DeleteCommentCommand extends IcingaCommand
|
|||||||
/**
|
/**
|
||||||
* Set whether the command affects a service
|
* Set whether the command affects a service
|
||||||
*
|
*
|
||||||
* @param boolean $value The value, defaults to true
|
* @param bool $isService
|
||||||
*
|
*
|
||||||
* @return this fluent interface
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setIsService($value = true)
|
public function setIsService($isService = true)
|
||||||
{
|
{
|
||||||
$this->isService = (bool) $value;
|
$this->isService = (bool) $isService;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,17 +27,20 @@ class DeleteDowntimeCommand extends IcingaCommand
|
|||||||
/**
|
/**
|
||||||
* Set if this command affects a service
|
* Set if this command affects a service
|
||||||
*
|
*
|
||||||
* @param type $value
|
* @param bool $isService
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setIsService($value = true)
|
public function setIsService($isService = true)
|
||||||
{
|
{
|
||||||
$this->isService = (bool) $value;
|
$this->isService = (bool) $isService;
|
||||||
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether the command affects a service
|
* Return whether the command affects a service
|
||||||
*
|
*
|
||||||
* @return type
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function getIsService()
|
public function getIsService()
|
||||||
{
|
{
|
||||||
|
@ -3,9 +3,20 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Monitoring\Command\Transport;
|
namespace Icinga\Module\Monitoring\Command\Transport;
|
||||||
|
|
||||||
|
use Icinga\Module\Monitoring\Command\IcingaCommand;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for Icinga command transports
|
* Interface for Icinga command transports
|
||||||
*/
|
*/
|
||||||
interface CommandTransportInterface
|
interface CommandTransportInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Send an Icinga command over the Icinga command transport
|
||||||
|
*
|
||||||
|
* @param IcingaCommand $command The command to send
|
||||||
|
* @param int|null $now Timestamp of the command or null for now
|
||||||
|
*
|
||||||
|
* @throws \Icinga\Module\Monitoring\Exception\CommandTransportException If sending the Icinga command failed
|
||||||
|
*/
|
||||||
|
public function send(IcingaCommand $command, $now = null);
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,9 @@ use Exception;
|
|||||||
use RuntimeException;
|
use RuntimeException;
|
||||||
use Icinga\Application\Logger;
|
use Icinga\Application\Logger;
|
||||||
use Icinga\Exception\ConfigurationError;
|
use Icinga\Exception\ConfigurationError;
|
||||||
use Icinga\Module\Monitoring\Command\Exception\TransportException;
|
|
||||||
use Icinga\Module\Monitoring\Command\IcingaCommand;
|
use Icinga\Module\Monitoring\Command\IcingaCommand;
|
||||||
use Icinga\Module\Monitoring\Command\Renderer\IcingaCommandFileCommandRenderer;
|
use Icinga\Module\Monitoring\Command\Renderer\IcingaCommandFileCommandRenderer;
|
||||||
|
use Icinga\Module\Monitoring\Exception\CommandTransportException;
|
||||||
use Icinga\Util\File;
|
use Icinga\Util\File;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -104,7 +104,7 @@ class LocalCommandFile implements CommandTransportInterface
|
|||||||
* @param int|null $now
|
* @param int|null $now
|
||||||
*
|
*
|
||||||
* @throws ConfigurationError
|
* @throws ConfigurationError
|
||||||
* @throws TransportException
|
* @throws CommandTransportException
|
||||||
*/
|
*/
|
||||||
public function send(IcingaCommand $command, $now = null)
|
public function send(IcingaCommand $command, $now = null)
|
||||||
{
|
{
|
||||||
@ -129,7 +129,7 @@ class LocalCommandFile implements CommandTransportInterface
|
|||||||
// Assume RuntimeException thrown by SplFileObject in the format: __METHOD__ . "({$filename}): Message"
|
// Assume RuntimeException thrown by SplFileObject in the format: __METHOD__ . "({$filename}): Message"
|
||||||
$message = substr($message, $pos + 1);
|
$message = substr($message, $pos + 1);
|
||||||
}
|
}
|
||||||
throw new TransportException(
|
throw new CommandTransportException(
|
||||||
'Can\'t send external Icinga command to the local command file "%s": %s',
|
'Can\'t send external Icinga command to the local command file "%s": %s',
|
||||||
$this->path,
|
$this->path,
|
||||||
$message
|
$message
|
||||||
|
@ -6,9 +6,9 @@ namespace Icinga\Module\Monitoring\Command\Transport;
|
|||||||
use Icinga\Application\Logger;
|
use Icinga\Application\Logger;
|
||||||
use Icinga\Data\ResourceFactory;
|
use Icinga\Data\ResourceFactory;
|
||||||
use Icinga\Exception\ConfigurationError;
|
use Icinga\Exception\ConfigurationError;
|
||||||
use Icinga\Module\Monitoring\Command\Exception\TransportException;
|
|
||||||
use Icinga\Module\Monitoring\Command\IcingaCommand;
|
use Icinga\Module\Monitoring\Command\IcingaCommand;
|
||||||
use Icinga\Module\Monitoring\Command\Renderer\IcingaCommandFileCommandRenderer;
|
use Icinga\Module\Monitoring\Command\Renderer\IcingaCommandFileCommandRenderer;
|
||||||
|
use Icinga\Module\Monitoring\Exception\CommandTransportException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A remote Icinga command file
|
* A remote Icinga command file
|
||||||
@ -224,7 +224,7 @@ class RemoteCommandFile implements CommandTransportInterface
|
|||||||
* @param int|null $now
|
* @param int|null $now
|
||||||
*
|
*
|
||||||
* @throws ConfigurationError
|
* @throws ConfigurationError
|
||||||
* @throws TransportException
|
* @throws CommandTransportException
|
||||||
*/
|
*/
|
||||||
public function send(IcingaCommand $command, $now = null)
|
public function send(IcingaCommand $command, $now = null)
|
||||||
{
|
{
|
||||||
@ -260,7 +260,7 @@ class RemoteCommandFile implements CommandTransportInterface
|
|||||||
);
|
);
|
||||||
exec($ssh, $output, $status);
|
exec($ssh, $output, $status);
|
||||||
if ($status !== 0) {
|
if ($status !== 0) {
|
||||||
throw new TransportException(
|
throw new CommandTransportException(
|
||||||
'Can\'t send external Icinga command: %s',
|
'Can\'t send external Icinga command: %s',
|
||||||
implode(' ', $output)
|
implode(' ', $output)
|
||||||
);
|
);
|
||||||
|
@ -36,8 +36,10 @@ class Customvar extends DataView
|
|||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'varname' => array(
|
'varname' => array(
|
||||||
'varname' => self::SORT_ASC,
|
'columns' => array(
|
||||||
'varvalue' => self::SORT_ASC,
|
'varname',
|
||||||
|
'varvalue'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ namespace Icinga\Module\Monitoring\DataView;
|
|||||||
|
|
||||||
use IteratorAggregate;
|
use IteratorAggregate;
|
||||||
use Icinga\Data\QueryInterface;
|
use Icinga\Data\QueryInterface;
|
||||||
|
use Icinga\Data\SortRules;
|
||||||
use Icinga\Data\Filter\Filter;
|
use Icinga\Data\Filter\Filter;
|
||||||
use Icinga\Data\Filter\FilterMatch;
|
use Icinga\Data\Filter\FilterMatch;
|
||||||
use Icinga\Data\PivotTable;
|
use Icinga\Data\PivotTable;
|
||||||
@ -18,7 +19,7 @@ use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
|||||||
/**
|
/**
|
||||||
* A read-only view of an underlying query
|
* A read-only view of an underlying query
|
||||||
*/
|
*/
|
||||||
abstract class DataView implements QueryInterface, IteratorAggregate
|
abstract class DataView implements QueryInterface, SortRules, IteratorAggregate
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The query used to populate the view
|
* The query used to populate the view
|
||||||
|
@ -49,8 +49,7 @@ class EventHistory extends DataView
|
|||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'timestamp' => array(
|
'timestamp' => array(
|
||||||
'columns' => array('timestamp'),
|
'order' => self::SORT_DESC
|
||||||
'order' => 'DESC'
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||||
|
|
||||||
namespace Icinga\Module\Monitoring\Command\Exception;
|
namespace Icinga\Module\Monitoring\Exception;
|
||||||
|
|
||||||
use Icinga\Exception\IcingaException;
|
use Icinga\Exception\IcingaException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception thrown if a command was not sent
|
* Exception thrown if a command was not sent
|
||||||
*/
|
*/
|
||||||
class TransportException extends IcingaException
|
class CommandTransportException extends IcingaException
|
||||||
{
|
{
|
||||||
}
|
}
|
@ -3,41 +3,50 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Monitoring\Web\Menu;
|
namespace Icinga\Module\Monitoring\Web\Menu;
|
||||||
|
|
||||||
use Icinga\Web\Menu as Menu;
|
use Icinga\Web\Menu;
|
||||||
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
|
||||||
use Icinga\Web\Menu\MenuItemRenderer;
|
use Icinga\Web\Menu\MenuItemRenderer;
|
||||||
|
use Icinga\Module\Monitoring\Backend\MonitoringBackend;
|
||||||
|
|
||||||
class BackendAvailabilityMenuItemRenderer extends MenuItemRenderer
|
class BackendAvailabilityMenuItemRenderer extends MenuItemRenderer
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Checks whether the monitoring backend is running or not
|
* Get whether or not the monitoring backend is currently running
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function isCurrentlyRunning()
|
protected function isCurrentlyRunning()
|
||||||
{
|
{
|
||||||
return MonitoringBackend::instance()->select()->from(
|
$programStatus = MonitoringBackend::instance()
|
||||||
|
->select()
|
||||||
|
->from(
|
||||||
'programstatus',
|
'programstatus',
|
||||||
array(
|
array('is_currently_running')
|
||||||
'is_currently_running'
|
|
||||||
)
|
)
|
||||||
)->getQuery()->fetchRow()->is_currently_running;
|
->fetchRow();
|
||||||
|
return $programStatus !== false ? (bool) $programStatus : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see MenuItemRenderer::render()
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function render(Menu $menu)
|
public function render(Menu $menu)
|
||||||
{
|
{
|
||||||
return $this->getBadge() . $this->createLink($menu);
|
return $this->getBadge() . $this->createLink($menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the problem badge HTML
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
protected function getBadge()
|
protected function getBadge()
|
||||||
{
|
{
|
||||||
if (! (bool)$this->isCurrentlyRunning()) {
|
if (! $this->isCurrentlyRunning()) {
|
||||||
return sprintf(
|
return sprintf(
|
||||||
'<div title="%s" class="badge-container"><span class="badge badge-critical">%s</span></div>',
|
'<div title="%s" class="badge-container"><span class="badge badge-critical">%d</span></div>',
|
||||||
mt('monitoring', 'monitoring backend is not running'),
|
sprintf(
|
||||||
|
mt('monitoring', 'Monitoring backend %s is not running'), MonitoringBackend::instance()->getName()
|
||||||
|
),
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -51,10 +60,12 @@ class BackendAvailabilityMenuItemRenderer extends MenuItemRenderer
|
|||||||
*/
|
*/
|
||||||
public function getSummary()
|
public function getSummary()
|
||||||
{
|
{
|
||||||
if (! (bool)$this->isCurrentlyRunning()) {
|
if (! $this->isCurrentlyRunning()) {
|
||||||
return array(
|
return array(
|
||||||
'problems' => 1,
|
'problems' => 1,
|
||||||
'title' => mt('monitoring', 'monitoring backend is not running')
|
'title' => sprintf(
|
||||||
|
mt('monitoring', 'Monitoring backend %s is not running'), MonitoringBackend::instance()->getName()
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -89,9 +89,6 @@ class AdminAccountPage extends Form
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (count($choices) > 1) {
|
if (count($choices) > 1) {
|
||||||
$this->addDescription($this->translate(
|
|
||||||
'Below are several options you can choose from for how to define the desired account.'
|
|
||||||
));
|
|
||||||
$this->addElement(
|
$this->addElement(
|
||||||
'select',
|
'select',
|
||||||
'user_type',
|
'user_type',
|
||||||
@ -99,6 +96,7 @@ class AdminAccountPage extends Form
|
|||||||
'required' => true,
|
'required' => true,
|
||||||
'autosubmit' => true,
|
'autosubmit' => true,
|
||||||
'label' => $this->translate('Type Of Definition'),
|
'label' => $this->translate('Type Of Definition'),
|
||||||
|
'description' => $this->translate('Choose how to define the desired account.'),
|
||||||
'multiOptions' => $choices,
|
'multiOptions' => $choices,
|
||||||
'value' => $choice
|
'value' => $choice
|
||||||
)
|
)
|
||||||
@ -124,7 +122,7 @@ class AdminAccountPage extends Form
|
|||||||
'label' => $this->translate('Username'),
|
'label' => $this->translate('Username'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'Define the initial administrative account by providing a username that reflects'
|
'Define the initial administrative account by providing a username that reflects'
|
||||||
. ' a user created later or one that is authenticated using external mechanisms'
|
. ' a user created later or one that is authenticated using external mechanisms.'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -139,7 +137,7 @@ class AdminAccountPage extends Form
|
|||||||
'label' => $this->translate('Username'),
|
'label' => $this->translate('Username'),
|
||||||
'description' => sprintf(
|
'description' => sprintf(
|
||||||
$this->translate(
|
$this->translate(
|
||||||
'Choose a user reported by the %s backend as the initial administrative account',
|
'Choose a user reported by the %s backend as the initial administrative account.',
|
||||||
'setup.admin'
|
'setup.admin'
|
||||||
),
|
),
|
||||||
$this->backendConfig['backend'] === 'db'
|
$this->backendConfig['backend'] === 'db'
|
||||||
@ -159,7 +157,7 @@ class AdminAccountPage extends Form
|
|||||||
'required' => true,
|
'required' => true,
|
||||||
'label' => $this->translate('Username'),
|
'label' => $this->translate('Username'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'Enter the username to be used when creating an initial administrative account'
|
'Enter the username to be used when creating an initial administrative account.'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -170,7 +168,9 @@ class AdminAccountPage extends Form
|
|||||||
'required' => true,
|
'required' => true,
|
||||||
'renderPassword' => true,
|
'renderPassword' => true,
|
||||||
'label' => $this->translate('Password'),
|
'label' => $this->translate('Password'),
|
||||||
'description' => $this->translate('Enter the password to assign to the newly created account')
|
'description' => $this->translate(
|
||||||
|
'Enter the password to assign to the newly created account.'
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$this->addElement(
|
$this->addElement(
|
||||||
@ -181,7 +181,7 @@ class AdminAccountPage extends Form
|
|||||||
'renderPassword' => true,
|
'renderPassword' => true,
|
||||||
'label' => $this->translate('Repeat password'),
|
'label' => $this->translate('Repeat password'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'Please repeat the password given above to avoid typing errors'
|
'Please repeat the password given above to avoid typing errors.'
|
||||||
),
|
),
|
||||||
'validators' => array(
|
'validators' => array(
|
||||||
array('identical', false, array('new_user_password'))
|
array('identical', false, array('new_user_password'))
|
||||||
|
@ -3,11 +3,12 @@
|
|||||||
|
|
||||||
namespace Icinga\Module\Setup\Forms;
|
namespace Icinga\Module\Setup\Forms;
|
||||||
|
|
||||||
use Icinga\Web\Form;
|
use Icinga\Data\ConfigObject;
|
||||||
|
use Icinga\Forms\Config\UserBackendConfigForm;
|
||||||
use Icinga\Forms\Config\UserBackend\DbBackendForm;
|
use Icinga\Forms\Config\UserBackend\DbBackendForm;
|
||||||
use Icinga\Forms\Config\UserBackend\LdapBackendForm;
|
use Icinga\Forms\Config\UserBackend\LdapBackendForm;
|
||||||
use Icinga\Forms\Config\UserBackend\ExternalBackendForm;
|
use Icinga\Forms\Config\UserBackend\ExternalBackendForm;
|
||||||
use Icinga\Data\ConfigObject;
|
use Icinga\Web\Form;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wizard page to define authentication backend specific details
|
* Wizard page to define authentication backend specific details
|
||||||
@ -66,14 +67,14 @@ class AuthBackendPage extends Form
|
|||||||
$this->setRequiredCue(null);
|
$this->setRequiredCue(null);
|
||||||
$backendForm = new DbBackendForm();
|
$backendForm = new DbBackendForm();
|
||||||
$backendForm->setRequiredCue(null);
|
$backendForm->setRequiredCue(null);
|
||||||
$backendForm->createElements($formData)->removeElement('resource');
|
$backendForm->create($formData)->removeElement('resource');
|
||||||
$this->addDescription($this->translate(
|
$this->addDescription($this->translate(
|
||||||
'As you\'ve chosen to use a database for authentication all you need '
|
'As you\'ve chosen to use a database for authentication all you need '
|
||||||
. 'to do now is defining a name for your first authentication backend.'
|
. 'to do now is defining a name for your first authentication backend.'
|
||||||
));
|
));
|
||||||
} elseif ($this->config['type'] === 'ldap') {
|
} elseif ($this->config['type'] === 'ldap') {
|
||||||
$backendForm = new LdapBackendForm();
|
$backendForm = new LdapBackendForm();
|
||||||
$backendForm->createElements($formData)->removeElement('resource');
|
$backendForm->create($formData)->removeElement('resource');
|
||||||
$this->addDescription($this->translate(
|
$this->addDescription($this->translate(
|
||||||
'Before you are able to authenticate using the LDAP connection defined earlier you need to'
|
'Before you are able to authenticate using the LDAP connection defined earlier you need to'
|
||||||
. ' provide some more information so that Icinga Web 2 is able to locate account details.'
|
. ' provide some more information so that Icinga Web 2 is able to locate account details.'
|
||||||
@ -97,15 +98,30 @@ class AuthBackendPage extends Form
|
|||||||
);
|
);
|
||||||
} else { // $this->config['type'] === 'external'
|
} else { // $this->config['type'] === 'external'
|
||||||
$backendForm = new ExternalBackendForm();
|
$backendForm = new ExternalBackendForm();
|
||||||
$backendForm->createElements($formData);
|
$backendForm->create($formData);
|
||||||
$this->addDescription($this->translate(
|
$this->addDescription($this->translate(
|
||||||
'You\'ve chosen to authenticate using a web server\'s mechanism so it may be necessary'
|
'You\'ve chosen to authenticate using a web server\'s mechanism so it may be necessary'
|
||||||
. ' to adjust usernames before any permissions, restrictions, etc. are being applied.'
|
. ' to adjust usernames before any permissions, restrictions, etc. are being applied.'
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addElements($backendForm->getElements());
|
$backendForm->getElement('name')->setValue('icingaweb2');
|
||||||
$this->getElement('name')->setValue('icingaweb2');
|
$this->addSubForm($backendForm, 'backend_form');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve all form element values
|
||||||
|
*
|
||||||
|
* @param bool $suppressArrayNotation Ignored
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getValues($suppressArrayNotation = false)
|
||||||
|
{
|
||||||
|
$values = parent::getValues();
|
||||||
|
$values = array_merge($values, $values['backend_form']);
|
||||||
|
unset($values['backend_form']);
|
||||||
|
return $values;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,7 +133,7 @@ class AuthBackendPage extends Form
|
|||||||
*/
|
*/
|
||||||
public function isValid($data)
|
public function isValid($data)
|
||||||
{
|
{
|
||||||
if (false === parent::isValid($data)) {
|
if (! parent::isValid($data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +146,9 @@ class AuthBackendPage extends Form
|
|||||||
'value' => $this->getResourceConfig()
|
'value' => $this->getResourceConfig()
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
if (! LdapBackendForm::isValidUserBackend($self)) {
|
$inspection = UserBackendConfigForm::inspectUserBackend($self);
|
||||||
|
if ($inspection && $inspection->hasError()) {
|
||||||
|
$this->error($inspection->getError());
|
||||||
$this->addSkipValidationCheckbox();
|
$this->addSkipValidationCheckbox();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
namespace Icinga\Module\Setup\Forms;
|
namespace Icinga\Module\Setup\Forms;
|
||||||
|
|
||||||
use Icinga\Web\Form;
|
use Icinga\Web\Form;
|
||||||
|
use Icinga\Forms\Config\ResourceConfigForm;
|
||||||
use Icinga\Forms\Config\Resource\LdapResourceForm;
|
use Icinga\Forms\Config\Resource\LdapResourceForm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,12 +66,14 @@ class LdapResourcePage extends Form
|
|||||||
*/
|
*/
|
||||||
public function isValid($data)
|
public function isValid($data)
|
||||||
{
|
{
|
||||||
if (false === parent::isValid($data)) {
|
if (! parent::isValid($data)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false === isset($data['skip_validation']) || $data['skip_validation'] == 0) {
|
if (! isset($data['skip_validation']) || $data['skip_validation'] == 0) {
|
||||||
if (false === LdapResourceForm::isValidResource($this)) {
|
$inspection = ResourceConfigForm::inspectResource($this);
|
||||||
|
if ($inspection !== null && $inspection->hasError()) {
|
||||||
|
$this->error($inspection->getError());
|
||||||
$this->addSkipValidationCheckbox();
|
$this->addSkipValidationCheckbox();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*! Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
/*! Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||||
|
|
||||||
form.sort-control {
|
div.sort-control {
|
||||||
.dontprint;
|
.dontprint;
|
||||||
float: right;
|
float: right;
|
||||||
|
|
||||||
@ -15,7 +15,13 @@ form.sort-control {
|
|||||||
}
|
}
|
||||||
|
|
||||||
select[name=dir] {
|
select[name=dir] {
|
||||||
width: 5em;
|
width: 8em;
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html.no-js div.sort-control form {
|
||||||
|
display: table;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-top: 0.25em;
|
||||||
|
}
|
||||||
|
@ -25,7 +25,7 @@ label {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
input, select {
|
input, select, textarea {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-moz-box-sizing: border-box;
|
-moz-box-sizing: border-box;
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
@ -44,10 +44,19 @@ input[type=submit] {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border: 2px solid #ddd;
|
border: 1px solid;
|
||||||
border-color: @colorPetrol;
|
border-color: @colorPetrol;
|
||||||
background: @colorPetrol;
|
background: @colorPetrol;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
background-color: #666;
|
||||||
|
border-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover[disabled], &:active[disabled], &:focus[disabled] {
|
||||||
|
background-color: #666;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=submit]:hover, a.button:hover, input[type=submit]:focus {
|
input[type=submit]:hover, a.button:hover, input[type=submit]:focus {
|
||||||
@ -87,10 +96,6 @@ button::-moz-focus-inner {
|
|||||||
outline: 0;
|
outline: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
select::-moz-focus-inner {
|
select::-moz-focus-inner {
|
||||||
border: 0;
|
border: 0;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
@ -190,7 +195,8 @@ form ul.form-notifications {
|
|||||||
}
|
}
|
||||||
|
|
||||||
form div.element {
|
form div.element {
|
||||||
margin: 0.5em 0;
|
margin-top: 0.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
form label {
|
form label {
|
||||||
@ -200,6 +206,14 @@ form label {
|
|||||||
width: 10em;
|
width: 10em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
form div.element > * {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
form dt {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
select, input[type=text], textarea {
|
select, input[type=text], textarea {
|
||||||
width: 20em;
|
width: 20em;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -259,3 +273,76 @@ form ul.descriptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
form ul.hints {
|
||||||
|
.non-list-like-list;
|
||||||
|
padding: 0.5em 0.5em 0 0.5em;
|
||||||
|
|
||||||
|
li {
|
||||||
|
font-size: 0.8em;
|
||||||
|
padding-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.control-group {
|
||||||
|
& > * {
|
||||||
|
float: left;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.element {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: ".";
|
||||||
|
visibility: hidden;
|
||||||
|
display: block;
|
||||||
|
height: 0;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
button, .button-like {
|
||||||
|
font-size: 0.9em;
|
||||||
|
font-weight: bold;
|
||||||
|
outline: 0;
|
||||||
|
color: #fff;
|
||||||
|
padding: 0.2em;
|
||||||
|
border: 1px solid;
|
||||||
|
border-color: @colorPetrol;
|
||||||
|
background: @colorPetrol;
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
background-color: #666;
|
||||||
|
border-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover, &:focus, &:active {
|
||||||
|
background-color: #333;
|
||||||
|
border-color: #333;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&[disabled] {
|
||||||
|
background-color: #666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.icon-only {
|
||||||
|
font-size: 1.5em;
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
color: inherit;
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
&:hover, &:focus, &:active {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a.button-like {
|
||||||
|
cursor: default;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
@ -47,6 +47,10 @@ html {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#fileupload-frame-target {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
#responsive-debug {
|
#responsive-debug {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
font-family: Courier new, monospace;
|
font-family: Courier new, monospace;
|
||||||
@ -401,3 +405,13 @@ html {
|
|||||||
padding-top: 0em;
|
padding-top: 0em;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hide non-javascript elements if javascript is enabled
|
||||||
|
html.js *.no-js {
|
||||||
|
.sr-only;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide javascript elements if javascript is disabled
|
||||||
|
html.no-js *.js {
|
||||||
|
.sr-only;
|
||||||
|
}
|
@ -12,6 +12,15 @@ p code {
|
|||||||
padding: 0.3em;
|
padding: 0.3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre.log-output {
|
||||||
|
padding: 0.5em;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
max-height: 12em;
|
||||||
|
overflow: auto;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: #39a;
|
color: #39a;
|
||||||
}
|
}
|
||||||
@ -104,7 +113,7 @@ table.benchmark {
|
|||||||
.info-box {
|
.info-box {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
border: 1px solid lightgrey;
|
border: 1px solid lightgrey;
|
||||||
background-color: #fbfcc5;
|
background-color: #f2f4fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Action table */
|
/* Action table */
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user