diff --git a/modules/setup/application/views/scripts/form/setup-requirements.phtml b/modules/setup/application/views/scripts/form/setup-requirements.phtml
index 09d337a02..47842efde 100644
--- a/modules/setup/application/views/scripts/form/setup-requirements.phtml
+++ b/modules/setup/application/views/scripts/form/setup-requirements.phtml
@@ -11,7 +11,17 @@ $requirements = $form->getRequirements();
= $requirement->title; ?> |
- = $requirement->description; ?> |
+
+ description)): ?>
+
+ description as $desc): ?>
+ - = $desc; ?>
+
+
+
+ = $requirement->description; ?>
+
+ |
= $requirement->message; ?> |
diff --git a/modules/setup/library/Setup/Requirements.php b/modules/setup/library/Setup/Requirements.php
index 4b3d411cb..ab9e693e5 100644
--- a/modules/setup/library/Setup/Requirements.php
+++ b/modules/setup/library/Setup/Requirements.php
@@ -9,6 +9,9 @@ use IteratorAggregate;
/**
* Container to store and handle requirements
+ *
+ * TODO: Requirements should be registered as objects with a specific purpose (PhpModRequirement, PhpIniRequirement, ..)
+ * so that it's not necessary to define unique identifiers which may differ between different modules.
*/
class Requirements implements IteratorAggregate
{
@@ -41,12 +44,40 @@ class Requirements implements IteratorAggregate
*
* @return self
*/
- public function add($requirement)
+ public function add($name, $requirement)
{
- $this->requirements[] = $requirement;
+ $this->requirements[$name] = array_key_exists($name, $this->requirements)
+ ? $this->combine($this->requirements[$name], $requirement)
+ : $requirement;
return $this;
}
+ /**
+ * Combine the two given requirements
+ *
+ * Returns the most important requirement with the description from the other one being added.
+ *
+ * @param object $oldRequirement
+ * @param object $newRequirement
+ *
+ * @return object
+ */
+ protected function combine($oldRequirement, $newRequirement)
+ {
+ if ($newRequirement->state === static::STATE_MANDATORY && $oldRequirement->state === static::STATE_OPTIONAL) {
+ $tempRequirement = $oldRequirement;
+ $oldRequirement = $newRequirement;
+ $newRequirement = $tempRequirement;
+ }
+
+ if (! is_array($oldRequirement->description)) {
+ $oldRequirement->description = array($oldRequirement->description);
+ }
+
+ $oldRequirement->description[] = $newRequirement->description;
+ return $oldRequirement;
+ }
+
/**
* Return all registered requirements
*
@@ -70,6 +101,7 @@ class Requirements implements IteratorAggregate
/**
* Register an optional requirement
*
+ * @param string $name
* @param string $title
* @param string $description
* @param bool $state
@@ -77,20 +109,24 @@ class Requirements implements IteratorAggregate
*
* @return self
*/
- public function addOptional($title, $description, $state, $message)
+ public function addOptional($name, $title, $description, $state, $message)
{
- $this->add((object) array(
- 'title' => $title,
- 'message' => $message,
- 'description' => $description,
- 'state' => (bool) $state ? static::STATE_OK : static::STATE_OPTIONAL
- ));
+ $this->add(
+ $name,
+ (object) array(
+ 'title' => $title,
+ 'message' => $message,
+ 'description' => $description,
+ 'state' => (bool) $state ? static::STATE_OK : static::STATE_OPTIONAL
+ )
+ );
return $this;
}
/**
* Register a mandatory requirement
*
+ * @param string $name
* @param string $title
* @param string $description
* @param bool $state
@@ -98,14 +134,17 @@ class Requirements implements IteratorAggregate
*
* @return self
*/
- public function addMandatory($title, $description, $state, $message)
+ public function addMandatory($name, $title, $description, $state, $message)
{
- $this->add((object) array(
- 'title' => $title,
- 'message' => $message,
- 'description' => $description,
- 'state' => (bool) $state ? static::STATE_OK : static::STATE_MANDATORY
- ));
+ $this->add(
+ $name,
+ (object) array(
+ 'title' => $title,
+ 'message' => $message,
+ 'description' => $description,
+ 'state' => (bool) $state ? static::STATE_OK : static::STATE_MANDATORY
+ )
+ );
return $this;
}
@@ -118,8 +157,8 @@ class Requirements implements IteratorAggregate
*/
public function merge(Requirements $requirements)
{
- foreach ($requirements->getAll() as $requirement) {
- $this->add($requirement);
+ foreach ($requirements->getAll() as $name => $requirement) {
+ $this->add($name, $requirement);
}
return $this;
diff --git a/modules/setup/library/Setup/WebWizard.php b/modules/setup/library/Setup/WebWizard.php
index 395c5af8e..58c7c6259 100644
--- a/modules/setup/library/Setup/WebWizard.php
+++ b/modules/setup/library/Setup/WebWizard.php
@@ -366,6 +366,7 @@ class WebWizard extends Wizard implements SetupWizard
$phpVersion = Platform::getPhpVersion();
$requirements->addMandatory(
+ 'php_version_>=_5_3_2',
mt('setup', 'PHP Version'),
mt(
'setup',
@@ -378,6 +379,7 @@ class WebWizard extends Wizard implements SetupWizard
$defaultTimezone = Platform::getPhpConfig('date.timezone');
$requirements->addMandatory(
+ 'existing_default_timezone',
mt('setup', 'Default Timezone'),
sprintf(
mt('setup', 'It is required that a default timezone has been set using date.timezone in %s.'),
@@ -390,6 +392,7 @@ class WebWizard extends Wizard implements SetupWizard
);
$requirements->addOptional(
+ 'platform=linux',
mt('setup', 'Linux Platform'),
mt(
'setup',
@@ -401,6 +404,7 @@ class WebWizard extends Wizard implements SetupWizard
);
$requirements->addMandatory(
+ 'existing_php_mod_openssl',
mt('setup', 'PHP Module: OpenSSL'),
mt('setup', 'The PHP module for OpenSSL is required to generate cryptographically safe password salts.'),
Platform::extensionLoaded('openssl'),
@@ -410,6 +414,7 @@ class WebWizard extends Wizard implements SetupWizard
);
$requirements->addOptional(
+ 'existing_php_mod_json',
mt('setup', 'PHP Module: JSON'),
mt('setup', 'The JSON module for PHP is required for various export functionalities as well as APIs.'),
Platform::extensionLoaded('json'),
@@ -419,6 +424,7 @@ class WebWizard extends Wizard implements SetupWizard
);
$requirements->addOptional(
+ 'existing_php_mod_ldap',
mt('setup', 'PHP Module: LDAP'),
mt('setup', 'If you\'d like to authenticate users using LDAP the corresponding PHP module is required'),
Platform::extensionLoaded('ldap'),
@@ -428,6 +434,7 @@ class WebWizard extends Wizard implements SetupWizard
);
$requirements->addOptional(
+ 'existing_php_mod_intl',
mt('setup', 'PHP Module: INTL'),
mt(
'setup',
@@ -442,6 +449,7 @@ class WebWizard extends Wizard implements SetupWizard
// TODO(6172): Remove this requirement once we do not ship dompdf with Icinga Web 2 anymore
$requirements->addOptional(
+ 'existing_php_mod_dom',
mt('setup', 'PHP Module: DOM'),
mt('setup', 'To be able to export views and reports to PDF, the DOM module for PHP is required.'),
Platform::extensionLoaded('dom'),
@@ -451,6 +459,7 @@ class WebWizard extends Wizard implements SetupWizard
);
$requirements->addOptional(
+ 'existing_php_mod_gd',
mt('setup', 'PHP Module: GD'),
mt(
'setup',
@@ -464,6 +473,7 @@ class WebWizard extends Wizard implements SetupWizard
);
$requirements->addOptional(
+ 'existing_php_mod_imagick',
mt('setup', 'PHP Module: Imagick'),
mt(
'setup',
@@ -477,6 +487,7 @@ class WebWizard extends Wizard implements SetupWizard
);
$requirements->addOptional(
+ 'existing_php_mod_pdo_mysql',
mt('setup', 'PHP Module: PDO-MySQL'),
mt(
'setup',
@@ -489,6 +500,7 @@ class WebWizard extends Wizard implements SetupWizard
);
$requirements->addOptional(
+ 'existing_php_mod_pdo_pgsql',
mt('setup', 'PHP Module: PDO-PostgreSQL'),
mt(
'setup',
@@ -503,6 +515,7 @@ class WebWizard extends Wizard implements SetupWizard
$mysqlAdapterFound = Platform::zendClassExists('Zend_Db_Adapter_Pdo_Mysql');
$requirements->addOptional(
+ 'existing_class_Zend_Db_Adapter_Pdo_Mysql',
mt('setup', 'Zend Database Adapter For MySQL'),
mt('setup', 'The Zend database adapter for MySQL is required to access a MySQL database.'),
$mysqlAdapterFound,
@@ -513,6 +526,7 @@ class WebWizard extends Wizard implements SetupWizard
$pgsqlAdapterFound = Platform::zendClassExists('Zend_Db_Adapter_Pdo_Pgsql');
$requirements->addOptional(
+ 'existing_class_Zend_Db_Adapter_Pdo_Pgsql',
mt('setup', 'Zend Database Adapter For PostgreSQL'),
mt('setup', 'The Zend database adapter for PostgreSQL is required to access a PostgreSQL database.'),
$pgsqlAdapterFound,
@@ -523,6 +537,7 @@ class WebWizard extends Wizard implements SetupWizard
$configDir = Icinga::app()->getConfigDir();
$requirements->addMandatory(
+ 'writable_directory_' . $configDir,
mt('setup', 'Writable Config Directory'),
mt(
'setup',
@@ -539,8 +554,6 @@ class WebWizard extends Wizard implements SetupWizard
);
foreach ($this->getWizards() as $wizard) {
- // TODO(8191): Ensure that equal requirements are not shown individually but only
- // once with their description properly being merged together!
$requirements->merge($wizard->getRequirements());
}
diff --git a/public/css/icinga/setup.less b/public/css/icinga/setup.less
index d6692b501..0bf8eb7b2 100644
--- a/public/css/icinga/setup.less
+++ b/public/css/icinga/setup.less
@@ -176,6 +176,12 @@
margin: 0 1em 0 0;
}
+ ul {
+ margin: 0;
+ padding-left: 1em;
+ list-style-type: square;
+ }
+
&.state {
color: white;
padding: 0.4em;