1<?php 2/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ 3 4namespace Icinga\Module\Setup; 5 6use PDOException; 7use Icinga\Web\Form; 8use Icinga\Web\Wizard; 9use Icinga\Web\Request; 10use Icinga\Application\Config; 11use Icinga\Application\Icinga; 12use Icinga\Module\Setup\Forms\ModulePage; 13use Icinga\Module\Setup\Forms\WelcomePage; 14use Icinga\Module\Setup\Forms\SummaryPage; 15use Icinga\Module\Setup\Forms\DbResourcePage; 16use Icinga\Module\Setup\Forms\AuthBackendPage; 17use Icinga\Module\Setup\Forms\AdminAccountPage; 18use Icinga\Module\Setup\Forms\LdapDiscoveryPage; 19//use Icinga\Module\Setup\Forms\LdapDiscoveryConfirmPage; 20use Icinga\Module\Setup\Forms\LdapResourcePage; 21use Icinga\Module\Setup\Forms\RequirementsPage; 22use Icinga\Module\Setup\Forms\GeneralConfigPage; 23use Icinga\Module\Setup\Forms\AuthenticationPage; 24use Icinga\Module\Setup\Forms\DatabaseCreationPage; 25use Icinga\Module\Setup\Forms\UserGroupBackendPage; 26use Icinga\Module\Setup\Steps\DatabaseStep; 27use Icinga\Module\Setup\Steps\GeneralConfigStep; 28use Icinga\Module\Setup\Steps\ResourceStep; 29use Icinga\Module\Setup\Steps\AuthenticationStep; 30use Icinga\Module\Setup\Steps\UserGroupStep; 31use Icinga\Module\Setup\Utils\EnableModuleStep; 32use Icinga\Module\Setup\Utils\DbTool; 33use Icinga\Module\Setup\Requirement\OSRequirement; 34use Icinga\Module\Setup\Requirement\ClassRequirement; 35use Icinga\Module\Setup\Requirement\PhpConfigRequirement; 36use Icinga\Module\Setup\Requirement\PhpModuleRequirement; 37use Icinga\Module\Setup\Requirement\PhpVersionRequirement; 38use Icinga\Module\Setup\Requirement\ConfigDirectoryRequirement; 39use Icinga\Module\Monitoring\Forms\Config\Transport\ApiTransportForm; 40 41/** 42 * Icinga Web 2 Setup Wizard 43 */ 44class WebWizard extends Wizard implements SetupWizard 45{ 46 /** 47 * The privileges required by Icinga Web 2 to create the database and a login 48 * 49 * @var array 50 */ 51 protected $databaseCreationPrivileges = array( 52 'CREATE', 53 'CREATE USER', // MySQL 54 'CREATEROLE' // PostgreSQL 55 ); 56 57 /** 58 * The privileges required by Icinga Web 2 to setup the database 59 * 60 * @var array 61 */ 62 protected $databaseSetupPrivileges = array( 63 'CREATE', 64 'ALTER', // MySQL only 65 'REFERENCES' 66 ); 67 68 /** 69 * The privileges required by Icinga Web 2 to operate the database 70 * 71 * @var array 72 */ 73 protected $databaseUsagePrivileges = array( 74 'SELECT', 75 'INSERT', 76 'UPDATE', 77 'DELETE', 78 'EXECUTE', 79 'TEMPORARY', // PostgreSql 80 'CREATE TEMPORARY TABLES' // MySQL 81 ); 82 83 /** 84 * The database tables operated by Icinga Web 2 85 * 86 * @var array 87 */ 88 protected $databaseTables = array( 89 'icingaweb_group', 90 'icingaweb_group_membership', 91 'icingaweb_user', 92 'icingaweb_user_preference' 93 ); 94 95 /** 96 * Register all pages and module wizards for this wizard 97 */ 98 protected function init() 99 { 100 $this->addPage(new WelcomePage()); 101 $this->addPage(new ModulePage()); 102 $this->addPage(new RequirementsPage()); 103 $this->addPage(new AuthenticationPage()); 104 $this->addPage(new DbResourcePage(array('name' => 'setup_auth_db_resource'))); 105 $this->addPage(new DatabaseCreationPage(array('name' => 'setup_auth_db_creation'))); 106 $this->addPage(new LdapDiscoveryPage()); 107 //$this->addPage(new LdapDiscoveryConfirmPage()); 108 $this->addPage(new LdapResourcePage()); 109 $this->addPage(new AuthBackendPage()); 110 $this->addPage(new UserGroupBackendPage()); 111 $this->addPage(new AdminAccountPage()); 112 $this->addPage(new GeneralConfigPage()); 113 $this->addPage(new DbResourcePage(array('name' => 'setup_config_db_resource'))); 114 $this->addPage(new DatabaseCreationPage(array('name' => 'setup_config_db_creation'))); 115 $this->addPage(new SummaryPage(array('name' => 'setup_summary'))); 116 117 if (($modulePageData = $this->getPageData('setup_modules')) !== null) { 118 $modulePage = $this->getPage('setup_modules')->populate($modulePageData); 119 foreach ($modulePage->getModuleWizards() as $moduleWizard) { 120 $this->addPage($moduleWizard); 121 } 122 } 123 } 124 125 /** 126 * Setup the given page that is either going to be displayed or validated 127 * 128 * @param Form $page The page to setup 129 * @param Request $request The current request 130 */ 131 public function setupPage(Form $page, Request $request) 132 { 133 if ($page->getName() === 'setup_requirements') { 134 $page->setWizard($this); 135 } elseif ($page->getName() === 'setup_authentication_backend') { 136 /** @var AuthBackendPage $page */ 137 138 $authData = $this->getPageData('setup_authentication_type'); 139 if ($authData['type'] === 'db') { 140 $page->setResourceConfig($this->getPageData('setup_auth_db_resource')); 141 } elseif ($authData['type'] === 'ldap') { 142 $page->setResourceConfig($this->getPageData('setup_ldap_resource')); 143 144 $suggestions = $this->getPageData('setup_ldap_discovery'); 145 if (isset($suggestions['backend'])) { 146 $page->setSuggestions($suggestions['backend']); 147 } 148 149 if ($this->getDirection() === static::FORWARD) { 150 $backendConfig = $this->getPageData('setup_authentication_backend'); 151 if ($backendConfig !== null && $request->getPost('name') !== $backendConfig['name']) { 152 $pageData = & $this->getPageData(); 153 unset($pageData['setup_usergroup_backend']); 154 } 155 } 156 } 157 158 if ($this->getDirection() === static::FORWARD) { 159 $backendConfig = $this->getPageData('setup_authentication_backend'); 160 if ($backendConfig !== null && $request->getPost('backend') !== $backendConfig['backend']) { 161 $pageData = & $this->getPageData(); 162 unset($pageData['setup_usergroup_backend']); 163 } 164 } 165 /*} elseif ($page->getName() === 'setup_ldap_discovery_confirm') { 166 $page->setResourceConfig($this->getPageData('setup_ldap_discovery'));*/ 167 } elseif ($page->getName() === 'setup_auth_db_resource') { 168 $page->addDescription(mt( 169 'setup', 170 'Now please configure the database resource where to store users and user groups.' 171 )); 172 $page->addDescription(mt( 173 'setup', 174 'Note that the database itself does not need to exist at this time as' 175 . ' it is going to be created once the wizard is about to be finished.' 176 )); 177 } elseif ($page->getName() === 'setup_usergroup_backend') { 178 $page->setResourceConfig($this->getPageData('setup_ldap_resource')); 179 $page->setBackendConfig($this->getPageData('setup_authentication_backend')); 180 } elseif ($page->getName() === 'setup_admin_account') { 181 $page->setBackendConfig($this->getPageData('setup_authentication_backend')); 182 $page->setGroupConfig($this->getPageData('setup_usergroup_backend')); 183 $authData = $this->getPageData('setup_authentication_type'); 184 if ($authData['type'] === 'db') { 185 $page->setResourceConfig($this->getPageData('setup_auth_db_resource')); 186 } elseif ($authData['type'] === 'ldap') { 187 $page->setResourceConfig($this->getPageData('setup_ldap_resource')); 188 } 189 } elseif ($page->getName() === 'setup_auth_db_creation' || $page->getName() === 'setup_config_db_creation') { 190 $page->setDatabaseSetupPrivileges( 191 array_unique(array_merge($this->databaseCreationPrivileges, $this->databaseSetupPrivileges)) 192 ); 193 $page->setDatabaseUsagePrivileges($this->databaseUsagePrivileges); 194 $page->setResourceConfig( 195 $this->getPageData('setup_auth_db_resource') ?: $this->getPageData('setup_config_db_resource') 196 ); 197 } elseif ($page->getName() === 'setup_summary') { 198 $page->setSubjectTitle('Icinga Web 2'); 199 $page->setSummary($this->getSetup()->getSummary()); 200 } elseif ($page->getName() === 'setup_config_db_resource') { 201 $page->addDescription(mt( 202 'setup', 203 'Now please configure the database resource where to store user preferences.' 204 )); 205 $page->addDescription(mt( 206 'setup', 207 'Note that the database itself does not need to exist at this time as' 208 . ' it is going to be created once the wizard is about to be finished.' 209 )); 210 211 $ldapData = $this->getPageData('setup_ldap_resource'); 212 if ($ldapData !== null && $request->getPost('name') === $ldapData['name']) { 213 $page->error( 214 mt('setup', 'The given resource name must be unique and is already in use by the LDAP resource') 215 ); 216 } 217 } elseif ($page->getName() === 'setup_ldap_resource') { 218 $suggestion = $this->getPageData('setup_ldap_discovery'); 219 if (isset($suggestion['resource'])) { 220 $page->populate($suggestion['resource']); 221 } 222 223 if ($this->getDirection() === static::FORWARD) { 224 $resourceConfig = $this->getPageData('setup_ldap_resource'); 225 if ($resourceConfig !== null && $request->getPost('name') !== $resourceConfig['name']) { 226 $pageData = & $this->getPageData(); 227 unset($pageData['setup_usergroup_backend']); 228 } 229 } 230 } elseif ($page->getName() === 'setup_general_config') { 231 $authData = $this->getPageData('setup_authentication_type'); 232 if ($authData['type'] === 'db') { 233 $page 234 ->create($this->getRequestData($page, $request)) 235 ->getElement('global_config_backend') 236 ->setValue('db'); 237 $page->info( 238 mt( 239 'setup', 240 'Note that choosing "Database" as preference storage causes' 241 . ' Icinga Web 2 to use the same database as for authentication.' 242 ), 243 false 244 ); 245 } 246 } elseif ($page->getName() === 'setup_authentication_type' && $this->getDirection() === static::FORWARD) { 247 $authData = $this->getPageData($page->getName()); 248 if ($authData !== null && $request->getPost('type') !== $authData['type']) { 249 // Drop any existing page data in case the authentication type has changed, 250 // otherwise it will conflict with other forms that depend on this one 251 $pageData = & $this->getPageData(); 252 unset($pageData['setup_admin_account']); 253 unset($pageData['setup_authentication_backend']); 254 255 if ($authData['type'] === 'db') { 256 unset($pageData['setup_auth_db_resource']); 257 unset($pageData['setup_auth_db_creation']); 258 } elseif ($request->getPost('type') === 'db') { 259 unset($pageData['setup_config_db_resource']); 260 unset($pageData['setup_config_db_creation']); 261 } 262 } 263 } 264 } 265 266 /** 267 * Return the new page to set as current page 268 * 269 * {@inheritdoc} Runs additional checks related to some registered pages. 270 * 271 * @param string $requestedPage The name of the requested page 272 * @param Form $originPage The origin page 273 * 274 * @return Form The new page 275 * 276 * @throws InvalidArgumentException In case the requested page does not exist or is not permitted yet 277 */ 278 protected function getNewPage($requestedPage, Form $originPage) 279 { 280 $skip = false; 281 $newPage = parent::getNewPage($requestedPage, $originPage); 282 if ($newPage->getName() === 'setup_auth_db_resource') { 283 $authData = $this->getPageData('setup_authentication_type'); 284 $skip = $authData['type'] !== 'db'; 285 } elseif ($newPage->getname() === 'setup_ldap_discovery') { 286 $authData = $this->getPageData('setup_authentication_type'); 287 $skip = $authData['type'] !== 'ldap'; 288 /*} elseif ($newPage->getName() === 'setup_ldap_discovery_confirm') { 289 $skip = false === $this->hasPageData('setup_ldap_discovery');*/ 290 } elseif ($newPage->getName() === 'setup_ldap_resource') { 291 $authData = $this->getPageData('setup_authentication_type'); 292 $skip = $authData['type'] !== 'ldap'; 293 } elseif ($newPage->getName() === 'setup_usergroup_backend') { 294 $backendConfig = $this->getPageData('setup_authentication_backend'); 295 $skip = $backendConfig['backend'] !== 'ldap'; 296 } elseif ($newPage->getName() === 'setup_config_db_resource') { 297 $authData = $this->getPageData('setup_authentication_type'); 298 $configData = $this->getPageData('setup_general_config'); 299 $skip = $authData['type'] === 'db' || $configData['global_config_backend'] !== 'db'; 300 } elseif (in_array($newPage->getName(), array('setup_auth_db_creation', 'setup_config_db_creation'))) { 301 if (($newPage->getName() === 'setup_auth_db_creation' || $this->hasPageData('setup_config_db_resource')) 302 && (($config = $this->getPageData('setup_auth_db_resource')) !== null 303 || ($config = $this->getPageData('setup_config_db_resource')) !== null) 304 && !$config['skip_validation'] 305 ) { 306 $db = new DbTool($config); 307 308 try { 309 $db->connectToDb(); // Are we able to login on the database? 310 if (array_search(reset($this->databaseTables), $db->listTables(), true) === false) { 311 // In case the database schema does not yet exist the 312 // user needs the privileges to setup the database 313 $skip = $db->checkPrivileges($this->databaseSetupPrivileges, $this->databaseTables); 314 } else { 315 // In case the database schema exists the user needs the required privileges 316 // to operate the database, if those are missing we ask for another user 317 $skip = $db->checkPrivileges($this->databaseUsagePrivileges, $this->databaseTables); 318 } 319 } catch (PDOException $_) { 320 try { 321 $db->connectToHost(); // Are we able to login on the server? 322 // It is not possible to reliably determine whether a database exists or not if a user can't 323 // log in to the database, so we just require the user to be able to create the database 324 $skip = $db->checkPrivileges( 325 array_unique( 326 array_merge($this->databaseCreationPrivileges, $this->databaseSetupPrivileges) 327 ), 328 $this->databaseTables 329 ); 330 } catch (PDOException $_) { 331 // We are NOT able to login on the server.. 332 } 333 } 334 } else { 335 $skip = true; 336 } 337 } 338 339 return $skip ? $this->skipPage($newPage) : $newPage; 340 } 341 342 /** 343 * Add buttons to the given page based on its position in the page-chain 344 * 345 * @param Form $page The page to add the buttons to 346 */ 347 protected function addButtons(Form $page) 348 { 349 parent::addButtons($page); 350 351 $pages = $this->getPages(); 352 $index = array_search($page, $pages, true); 353 if ($index === 0) { 354 $page->getElement(static::BTN_NEXT)->setLabel( 355 mt('setup', 'Start', 'setup.welcome.btn.next') 356 ); 357 } elseif ($index === count($pages) - 1) { 358 $page->getElement(static::BTN_NEXT)->setLabel( 359 mt('setup', 'Setup Icinga Web 2', 'setup.summary.btn.finish') 360 ); 361 } 362 363 $authData = $this->getPageData('setup_authentication_type'); 364 $veto = $page->getName() === 'setup_authentication_backend' && $authData['type'] === 'db'; 365 if (! $veto && in_array($page->getName(), array( 366 'setup_authentication_backend', 367 'setup_auth_db_resource', 368 'setup_config_db_resource', 369 'setup_ldap_resource', 370 'setup_monitoring_ido', 371 'setup_icingadb_resource', 372 'setup_icingadb_redis', 373 'setup_icingadb_api_transport' 374 ))) { 375 $page->addElement( 376 'submit', 377 'backend_validation', 378 array( 379 'ignore' => true, 380 'label' => t('Validate Configuration'), 381 'data-progress-label' => t('Validation In Progress'), 382 'decorators' => array('ViewHelper') 383 ) 384 ); 385 $page->getDisplayGroup('buttons')->addElement($page->getElement('backend_validation')); 386 } 387 388 if ($page->getName() === 'setup_command_transport') { 389 if ($page->getSubForm('transport_form')->getSubForm('transport_form') instanceof ApiTransportForm) { 390 $page->addElement( 391 'submit', 392 'transport_validation', 393 array( 394 'ignore' => true, 395 'label' => t('Validate Configuration'), 396 'data-progress-label' => t('Validation In Progress'), 397 'decorators' => array('ViewHelper') 398 ) 399 ); 400 $page->getDisplayGroup('buttons')->addElement($page->getElement('transport_validation')); 401 } 402 } 403 } 404 405 /** 406 * Clear the session being used by this wizard 407 * 408 * @param bool $removeToken If true, the setup token will be removed 409 */ 410 public function clearSession($removeToken = true) 411 { 412 parent::clearSession(); 413 414 if ($removeToken) { 415 $tokenPath = Config::resolvePath('setup.token'); 416 if (file_exists($tokenPath)) { 417 @unlink($tokenPath); 418 } 419 } 420 } 421 422 /** 423 * Return the setup for this wizard 424 * 425 * @return Setup 426 */ 427 public function getSetup() 428 { 429 $pageData = $this->getPageData(); 430 $setup = new Setup(); 431 432 if (isset($pageData['setup_auth_db_resource']) 433 && !$pageData['setup_auth_db_resource']['skip_validation'] 434 && (! isset($pageData['setup_auth_db_creation']) 435 || !$pageData['setup_auth_db_creation']['skip_validation'] 436 ) 437 ) { 438 $setup->addStep( 439 new DatabaseStep(array( 440 'tables' => $this->databaseTables, 441 'privileges' => $this->databaseUsagePrivileges, 442 'resourceConfig' => $pageData['setup_auth_db_resource'], 443 'adminName' => isset($pageData['setup_auth_db_creation']['username']) 444 ? $pageData['setup_auth_db_creation']['username'] 445 : null, 446 'adminPassword' => isset($pageData['setup_auth_db_creation']['password']) 447 ? $pageData['setup_auth_db_creation']['password'] 448 : null, 449 'schemaPath' => Config::module('setup') 450 ->get('schema', 'path', Icinga::app()->getBaseDir('etc' . DIRECTORY_SEPARATOR . 'schema')) 451 )) 452 ); 453 } elseif (isset($pageData['setup_config_db_resource']) 454 && !$pageData['setup_config_db_resource']['skip_validation'] 455 && (! isset($pageData['setup_config_db_creation']) 456 || !$pageData['setup_config_db_creation']['skip_validation'] 457 ) 458 ) { 459 $setup->addStep( 460 new DatabaseStep(array( 461 'tables' => $this->databaseTables, 462 'privileges' => $this->databaseUsagePrivileges, 463 'resourceConfig' => $pageData['setup_config_db_resource'], 464 'adminName' => isset($pageData['setup_config_db_creation']['username']) 465 ? $pageData['setup_config_db_creation']['username'] 466 : null, 467 'adminPassword' => isset($pageData['setup_config_db_creation']['password']) 468 ? $pageData['setup_config_db_creation']['password'] 469 : null, 470 'schemaPath' => Config::module('setup') 471 ->get('schema', 'path', Icinga::app()->getBaseDir('etc' . DIRECTORY_SEPARATOR . 'schema')) 472 )) 473 ); 474 } 475 476 $setup->addStep( 477 new GeneralConfigStep(array( 478 'generalConfig' => $pageData['setup_general_config'], 479 'resourceName' => isset($pageData['setup_auth_db_resource']['name']) 480 ? $pageData['setup_auth_db_resource']['name'] 481 : (isset($pageData['setup_config_db_resource']['name']) 482 ? $pageData['setup_config_db_resource']['name'] 483 : null 484 ) 485 )) 486 ); 487 488 $adminAccountType = $pageData['setup_admin_account']['user_type']; 489 if ($adminAccountType === 'user_group') { 490 $adminAccountData = array('groupname' => $pageData['setup_admin_account'][$adminAccountType]); 491 } else { 492 $adminAccountData = array('username' => $pageData['setup_admin_account'][$adminAccountType]); 493 if ($adminAccountType === 'new_user' && !$pageData['setup_auth_db_resource']['skip_validation'] 494 && (! isset($pageData['setup_auth_db_creation']) 495 || !$pageData['setup_auth_db_creation']['skip_validation'] 496 ) 497 ) { 498 $adminAccountData['resourceConfig'] = $pageData['setup_auth_db_resource']; 499 $adminAccountData['password'] = $pageData['setup_admin_account']['new_user_password']; 500 } 501 } 502 $authType = $pageData['setup_authentication_type']['type']; 503 $setup->addStep( 504 new AuthenticationStep(array( 505 'adminAccountData' => $adminAccountData, 506 'backendConfig' => $pageData['setup_authentication_backend'], 507 'resourceName' => $authType === 'db' ? $pageData['setup_auth_db_resource']['name'] : ( 508 $authType === 'ldap' ? $pageData['setup_ldap_resource']['name'] : null 509 ) 510 )) 511 ); 512 513 if ($authType !== 'external') { 514 $setup->addStep( 515 new UserGroupStep(array( 516 'backendConfig' => $pageData['setup_authentication_backend'], 517 'groupConfig' => isset($pageData['setup_usergroup_backend']) 518 ? $pageData['setup_usergroup_backend'] 519 : null, 520 'resourceName' => $authType === 'db' 521 ? $pageData['setup_auth_db_resource']['name'] 522 : $pageData['setup_ldap_resource']['name'], 523 'resourceConfig' => $authType === 'db' 524 ? $pageData['setup_auth_db_resource'] 525 : null, 526 'username' => $authType === 'db' 527 ? $pageData['setup_admin_account'][$adminAccountType] 528 : null 529 )) 530 ); 531 } 532 533 if (isset($pageData['setup_auth_db_resource']) 534 || isset($pageData['setup_config_db_resource']) 535 || isset($pageData['setup_ldap_resource']) 536 ) { 537 $setup->addStep( 538 new ResourceStep(array( 539 'dbResourceConfig' => isset($pageData['setup_auth_db_resource']) 540 ? array_diff_key($pageData['setup_auth_db_resource'], array('skip_validation' => null)) 541 : (isset($pageData['setup_config_db_resource']) 542 ? array_diff_key($pageData['setup_config_db_resource'], array('skip_validation' => null)) 543 : null 544 ), 545 'ldapResourceConfig' => isset($pageData['setup_ldap_resource']) 546 ? array_diff_key($pageData['setup_ldap_resource'], array('skip_validation' => null)) 547 : null 548 )) 549 ); 550 } 551 552 foreach ($this->getWizards() as $wizard) { 553 if ($wizard->isComplete()) { 554 $setup->addSteps($wizard->getSetup()->getSteps()); 555 } 556 } 557 558 $setup->addStep(new EnableModuleStep(array_keys($this->getPage('setup_modules')->getCheckedModules()))); 559 560 return $setup; 561 } 562 563 /** 564 * Return the requirements of this wizard 565 * 566 * @return RequirementSet 567 */ 568 public function getRequirements($skipModules = false) 569 { 570 $set = new RequirementSet(); 571 572 $set->add(new PhpVersionRequirement(array( 573 'condition' => array('>=', '5.6'), 574 'description' => mt( 575 'setup', 576 'Running Icinga Web 2 requires PHP version 5.6.' 577 ) 578 ))); 579 580 $set->add(new OSRequirement(array( 581 'optional' => true, 582 'condition' => 'linux', 583 'description' => mt( 584 'setup', 585 'Icinga Web 2 is developed for and tested on Linux. While we cannot' 586 . ' guarantee they will, other platforms may also perform as well.' 587 ) 588 ))); 589 590 $set->add(new PhpModuleRequirement(array( 591 'condition' => 'OpenSSL', 592 'description' => mt( 593 'setup', 594 'The PHP module for OpenSSL is required to generate cryptographically safe password salts.' 595 ) 596 ))); 597 598 $set->add(new PhpModuleRequirement(array( 599 'optional' => true, 600 'condition' => 'JSON', 601 'description' => mt( 602 'setup', 603 'The JSON module for PHP is required for various export functionalities as well as APIs.' 604 ) 605 ))); 606 607 $set->add(new PhpModuleRequirement(array( 608 'optional' => true, 609 'condition' => 'LDAP', 610 'description' => mt( 611 'setup', 612 'If you\'d like to authenticate users using LDAP the corresponding PHP module is required.' 613 ) 614 ))); 615 616 $set->add(new PhpModuleRequirement(array( 617 'optional' => true, 618 'condition' => 'INTL', 619 'description' => mt( 620 'setup', 621 'If you want your users to benefit from language, timezone and date/time' 622 . ' format negotiation, the INTL module for PHP is required.' 623 ) 624 ))); 625 626 // TODO(6172): Remove this requirement once we do not ship dompdf with Icinga Web 2 anymore 627 $set->add(new PhpModuleRequirement(array( 628 'optional' => true, 629 'condition' => 'DOM', 630 'description' => mt( 631 'setup', 632 'To be able to export views and reports to PDF, the DOM module for PHP is required.' 633 ) 634 ))); 635 636 $set->add(new PhpModuleRequirement(array( 637 'optional' => true, 638 'condition' => 'GD', 639 'description' => mt( 640 'setup', 641 'In case you want views being exported to PDF, you\'ll need the GD extension for PHP.' 642 ) 643 ))); 644 645 $set->add(new PhpModuleRequirement(array( 646 'optional' => true, 647 'condition' => 'Imagick', 648 'description' => mt( 649 'setup', 650 'In case you want graphs being exported to PDF as well, you\'ll need the ImageMagick extension for PHP.' 651 ) 652 ))); 653 654 $mysqlSet = new RequirementSet(true); 655 $mysqlSet->add(new PhpModuleRequirement(array( 656 'optional' => true, 657 'condition' => 'pdo_mysql', 658 'alias' => 'PDO-MySQL', 659 'description' => mt( 660 'setup', 661 'To store users or preferences in a MySQL database the PDO-MySQL module for PHP is required.' 662 ) 663 ))); 664 $mysqlSet->add(new ClassRequirement(array( 665 'optional' => true, 666 'condition' => 'Zend_Db_Adapter_Pdo_Mysql', 667 'alias' => mt('setup', 'Zend database adapter for MySQL'), 668 'description' => mt( 669 'setup', 670 'The Zend database adapter for MySQL is required to access a MySQL database.' 671 ), 672 'textAvailable' => mt( 673 'setup', 674 'The Zend database adapter for MySQL is available.', 675 'setup.requirement.class' 676 ), 677 'textMissing' => mt( 678 'setup', 679 'The Zend database adapter for MySQL is missing.', 680 'setup.requirement.class' 681 ) 682 ))); 683 $set->merge($mysqlSet); 684 685 $pgsqlSet = new RequirementSet(true); 686 $pgsqlSet->add(new PhpModuleRequirement(array( 687 'optional' => true, 688 'condition' => 'pdo_pgsql', 689 'alias' => 'PDO-PostgreSQL', 690 'description' => mt( 691 'setup', 692 'To store users or preferences in a PostgreSQL database the PDO-PostgreSQL module for PHP is required.' 693 ) 694 ))); 695 $pgsqlSet->add(new ClassRequirement(array( 696 'optional' => true, 697 'condition' => 'Zend_Db_Adapter_Pdo_Pgsql', 698 'alias' => mt('setup', 'Zend database adapter for PostgreSQL'), 699 'description' => mt( 700 'setup', 701 'The Zend database adapter for PostgreSQL is required to access a PostgreSQL database.' 702 ), 703 'textAvailable' => mt( 704 'setup', 705 'The Zend database adapter for PostgreSQL is available.', 706 'setup.requirement.class' 707 ), 708 'textMissing' => mt( 709 'setup', 710 'The Zend database adapter for PostgreSQL is missing.', 711 'setup.requirement.class' 712 ) 713 ))); 714 $set->merge($pgsqlSet); 715 716 $set->add(new ConfigDirectoryRequirement(array( 717 'condition' => Icinga::app()->getConfigDir(), 718 'description' => mt( 719 'setup', 720 'The Icinga Web 2 configuration directory defaults to "/etc/icingaweb2", if' . 721 ' not explicitly set in the environment variable "ICINGAWEB_CONFIGDIR".' 722 ) 723 ))); 724 725 if (! $skipModules) { 726 foreach ($this->getWizards() as $wizard) { 727 $set->merge($wizard->getRequirements()); 728 } 729 } 730 731 return $set; 732 } 733} 734