* WizStepLicense WizStepDetectedInfo * WizStepDBParams + + * WizStepAdminAccount | | * WizStepMiscParams v +------> * + WizStepLicense2 +--> WizStepUpgradeMiscParams * | + * +---> <-----------------------------------+ * WizStepModulesChoice * WizStepSummary * WizStepDone */ require_once(APPROOT.'setup/setuputils.class.inc.php'); require_once(APPROOT.'setup/parameters.class.inc.php'); require_once(APPROOT.'setup/applicationinstaller.class.inc.php'); require_once(APPROOT.'setup/parameters.class.inc.php'); require_once(APPROOT.'core/mutex.class.inc.php'); require_once(APPROOT.'setup/extensionsmap.class.inc.php'); /** * First step of the iTop Installation Wizard: Welcome screen, requirements */ class WizStepWelcome extends WizardStep { protected $bCanMoveForward; public function GetTitle() { return 'Welcome to '.ITOP_APPLICATION.' version '.ITOP_VERSION; } /** * Returns the label for the " Next >> " button * @return string The label for the button */ public function GetNextButtonLabel() { return ' Continue >> '; } public function GetPossibleSteps() { return array('WizStepInstallOrUpgrade'); } public function ProcessParams($bMoveForward = true) { $sUID = SetupUtils::CreateSetupToken(); $this->oWizard->SetParameter('authent', $sUID); return array('class' => 'WizStepInstallOrUpgrade', 'state' => ''); } public function Display(WebPage $oPage) { // Store the misc_options for the future... $aMiscOptions = utils::ReadParam('option', array(), false, 'raw_data'); $sMiscOptions = $this->oWizard->GetParameter('misc_options', json_encode($aMiscOptions)); $this->oWizard->SetParameter('misc_options', $sMiscOptions); $oPage->add(""); $oPage->add_ready_script( << 0) { alert("Internet Explorer version 10 or older is NOT supported! (Check that IE is not running in compatibility mode)"); } EOF ); $oPage->add('

'.ITOP_APPLICATION.' Installation Wizard

'); $aResults = SetupUtils::CheckPhpAndExtensions(); $this->bCanMoveForward = true; $aInfo = array(); $aWarnings = array(); $aErrors = array(); foreach($aResults as $oCheckResult) { switch($oCheckResult->iSeverity) { case CheckResult::ERROR: $aErrors[] = $oCheckResult->sLabel; $this->bCanMoveForward = false; break; case CheckResult::WARNING: $aWarnings[] = $oCheckResult->sLabel; break; case CheckResult::INFO: $aInfo[] = $oCheckResult->sLabel; break; } } $sStyle = 'style="display:none;max-height:196px;overflow:auto;"'; $sToggleButtons = ''; if (count($aErrors)> 0) { $sStyle = 'style="max-height:196px;overflow:auto;"'; $sTitle = count($aErrors).' Error(s), '.count($aWarnings).' Warning(s).'; $sH2Class = 'text-error'; } else if (count($aWarnings)> 0) { $sTitle = count($aWarnings).' Warning(s) '.$sToggleButtons; $sH2Class = 'text-warning'; } else { $sTitle = 'Ok. '.$sToggleButtons; $sH2Class = 'text-valid'; } $oPage->add( <<Prerequisites validation: $sTitle
HTML ); foreach($aErrors as $sText) { $oPage->error($sText); } foreach($aWarnings as $sText) { $oPage->warning($sText); } foreach($aInfo as $sText) { $oPage->ok($sText); } $oPage->add('
'); if (!$this->bCanMoveForward) { $oPage->p('Sorry, the installation cannot continue. Please fix the errors and reload this page to launch the installation again.'); $oPage->p(''); } } public function CanMoveForward() { return $this->bCanMoveForward; } } /** * Second step of the iTop Installation Wizard: Install or Upgrade */ class WizStepInstallOrUpgrade extends WizardStep { public function GetTitle() { return 'Install or Upgrade choice'; } public function GetPossibleSteps() { return array('WizStepDetectedInfo', 'WizStepLicense'); } public function ProcessParams($bMoveForward = true) { $sNextStep = ''; $sInstallMode = utils::ReadParam('install_mode'); $this->oWizard->SaveParameter('previous_version_dir', ''); $this->oWizard->SaveParameter('db_server', ''); $this->oWizard->SaveParameter('db_user', ''); $this->oWizard->SaveParameter('db_pwd', ''); $this->oWizard->SaveParameter('db_name', ''); $this->oWizard->SaveParameter('db_prefix', ''); $this->oWizard->SaveParameter('db_backup', false); $this->oWizard->SaveParameter('db_backup_path', ''); $this->oWizard->SaveParameter('db_tls_enabled', false); $this->oWizard->SaveParameter('db_tls_ca', ''); if ($sInstallMode == 'install') { $this->oWizard->SetParameter('install_mode', 'install'); $sFullSourceDir = SetupUtils::GetLatestDataModelDir(); $this->oWizard->SetParameter('source_dir', $sFullSourceDir); $this->oWizard->SetParameter('datamodel_version', SetupUtils::GetDataModelVersion($sFullSourceDir)); $sNextStep = 'WizStepLicense'; } else { $this->oWizard->SetParameter('install_mode', 'upgrade'); $sNextStep = 'WizStepDetectedInfo'; } return array('class' => $sNextStep, 'state' => ''); } public function Display(WebPage $oPage) { $sInstallMode = $this->oWizard->GetParameter('install_mode', ''); $sDBServer = $this->oWizard->GetParameter('db_server', ''); $sDBUser = $this->oWizard->GetParameter('db_user', ''); $sDBPwd = $this->oWizard->GetParameter('db_pwd', ''); $sDBName = $this->oWizard->GetParameter('db_name', ''); $sDBPrefix = $this->oWizard->GetParameter('db_prefix', ''); $bDBBackup = $this->oWizard->GetParameter('db_backup', false); $sDBBackupPath = $this->oWizard->GetParameter('db_backup_path', ''); $sTlsEnabled = $this->oWizard->GetParameter('db_tls_enabled', false); $sTlsCA = $this->oWizard->GetParameter('db_tls_ca', ''); $sMySQLBinDir = $this->oWizard->GetParameter('mysql_bindir', null); $sPreviousVersionDir = ''; if ($sInstallMode == '') { $sDBBackupPath = APPROOT.strftime('data/backups/manual/setup-%Y-%m-%d_%H_%M'); $bDBBackup = true; $aPreviousInstance = SetupUtils::GetPreviousInstance(APPROOT); if ($aPreviousInstance['found']) { $sInstallMode = 'upgrade'; $sDBServer = $aPreviousInstance['db_server']; $sDBUser = $aPreviousInstance['db_user']; $sDBPwd = $aPreviousInstance['db_pwd']; $sDBName = $aPreviousInstance['db_name']; $sDBPrefix = $aPreviousInstance['db_prefix']; $sTlsEnabled = $aPreviousInstance['db_tls_enabled']; $sTlsCA = $aPreviousInstance['db_tls_ca']; $this->oWizard->SaveParameter('graphviz_path', $aPreviousInstance['graphviz_path']); $sMySQLBinDir = $aPreviousInstance['mysql_bindir']; $this->oWizard->SaveParameter('mysql_bindir', $aPreviousInstance['mysql_bindir']); $sPreviousVersionDir = APPROOT; } else { $sInstallMode = 'install'; } } $sPreviousVersionDir = $this->oWizard->GetParameter('previous_version_dir', $sPreviousVersionDir); $sUpgradeInfoStyle = ''; if ($sInstallMode == 'install') { $sUpgradeInfoStyle = ' style="display: none;" '; } $oPage->add('

What do you want to do?

'); $sChecked = ($sInstallMode == 'install') ? ' checked ' : ''; $oPage->p(''); $sChecked = ($sInstallMode == 'upgrade') ? ' checked ' : ''; $sDisabled = (($sInstallMode == 'install') && (empty($sPreviousVersionDir))) ? ' disabled' : ''; $oPage->p(''); $sUpgradeDir = utils::HtmlEntities($sPreviousVersionDir); $oPage->add(<< Location on the disk: HTML ); SetupUtils::DisplayDBParameters($oPage, false, $sDBServer, $sDBUser, $sDBPwd, $sDBName, $sDBPrefix, $sTlsEnabled, $sTlsCA, null); $aBackupChecks = SetupUtils::CheckBackupPrerequisites($sDBBackupPath, $sMySQLBinDir); $bCanBackup = true; $sMySQLDumpMessage = ''; foreach($aBackupChecks as $oCheck) { if ($oCheck->iSeverity == CheckResult::ERROR) { $bCanBackup = false; $sMySQLDumpMessage .= '
Error:'.$oCheck->sLabel.'
'; } else { $sMySQLDumpMessage .= '
Success:'.$oCheck->sLabel.'
'; } } $sChecked = ($bCanBackup && $bDBBackup) ? ' checked ' : ''; $sDisabled = $bCanBackup ? '' : ' disabled '; $oPage->add(''); $oPage->add('Save the backup to:'); $fFreeSpace = SetupUtils::CheckDiskSpace($sDBBackupPath); $sMessage = ''; if ($fFreeSpace !== false) { $sMessage .= SetupUtils::HumanReadableSize($fFreeSpace).' free in '.dirname($sDBBackupPath); } $oPage->add(''); $oPage->add($sMySQLDumpMessage.'
'.$sMessage.''); $oPage->add(''); $sAuthentToken = $this->oWizard->GetParameter('authent', ''); $oPage->add(''); //$oPage->add(''); $oPage->add_ready_script( <<add_ready_script( <<add_ready_script( <<add_ready_script( <<oWizard->SetParameter('mode', 'upgrade'); $this->oWizard->SetParameter('upgrade_type', $sUpgradeType); $bDisplayLicense = $this->oWizard->GetParameter('display_license'); switch ($sUpgradeType) { case 'keep-previous': $sSourceDir = utils::ReadParam('relative_source_dir', '', false, 'raw_data'); $this->oWizard->SetParameter('source_dir', $this->oWizard->GetParameter('previous_version_dir').'/'.$sSourceDir); $this->oWizard->SetParameter('datamodel_version', utils::ReadParam('datamodel_previous_version', '', false, 'raw_data')); break; case 'use-compatible': $sDataModelPath = utils::ReadParam('datamodel_path', '', false, 'raw_data'); $this->oWizard->SetParameter('source_dir', $sDataModelPath); $this->oWizard->SaveParameter('datamodel_version', ''); break; default: // Do nothing, maybe the user pressed the Back button } if ($bDisplayLicense) { $aRet = array('class' => 'WizStepLicense2', 'state' => ''); } else { $aRet = array('class' => 'WizStepUpgradeMiscParams', 'state' => ''); } return $aRet; } /** * @param \WebPage $oPage * * @throws \Exception */ public function Display(\WebPage $oPage) { $oPage->add_style( <<bCanMoveForward = true; $bDisplayLicense = true; $sPreviousVersionDir = $this->oWizard->GetParameter('previous_version_dir', ''); $aInstalledInfo = SetupUtils::GetApplicationVersion($this->oWizard); if ($aInstalledInfo === false) { throw(new Exception('No previous version of '.ITOP_APPLICATION.' found in the supplied database. The upgrade cannot continue.')); } else if (strcasecmp($aInstalledInfo['product_name'], ITOP_APPLICATION) != 0) { $oPage->p("Warning: The installed products seem different. Are you sure that you want to upgrade {$aInstalledInfo['product_name']} with ".ITOP_APPLICATION."?"); } $sInstalledVersion = $aInstalledInfo['product_version']; $sInstalledDataModelVersion = $aInstalledInfo['datamodel_version']; $oPage->add("

Information about the upgrade from version $sInstalledVersion to ".ITOP_VERSION_FULL."

"); if ($sInstalledVersion == ITOP_VERSION_FULL) { // Reinstalling the same version let's skip the license agreement... $bDisplayLicense = false; } $this->oWizard->SetParameter('license', $bDisplayLicense); // Remember for later if ($sInstalledDataModelVersion == '$ITOP_VERSION$.$WCREV$') { // Special case for upgrading some development versions (temporary) $sCompatibleDMDir = SetupUtils::GetLatestDataModelDir(); $sInstalledDataModelVersion = SetupUtils::GetDataModelVersion($sCompatibleDMDir); } else { $sCompatibleDMDir = SetupUtils::GetCompatibleDataModelDir($sInstalledDataModelVersion); } if ($sCompatibleDMDir === false) { // No compatible version exists... cannot upgrade. Either it is too old, or too new (downgrade !) $this->bCanMoveForward = false; $oPage->p("The current version of ".ITOP_APPLICATION." (".ITOP_VERSION_FULL.") does not seem to be compatible with the installed version ($sInstalledVersion)."); $oPage->p("The upgrade cannot continue, sorry."); } else { $sUpgradeDMVersion = SetupUtils::GetDataModelVersion($sCompatibleDMDir); $sPreviousSourceDir = isset($aInstalledInfo['source_dir']) ? $aInstalledInfo['source_dir'] : 'modules'; $aChanges = false; if (is_dir($sPreviousVersionDir)) { // Check if the previous version is a "genuine" one or not... $aChanges = SetupUtils::CheckVersion($sInstalledDataModelVersion, $sPreviousVersionDir.'/'.$sPreviousSourceDir); } if (($aChanges !== false) && ( (count($aChanges['added']) > 0) || (count($aChanges['removed']) > 0) || (count($aChanges['modified']) > 0)) ) { // Some changes were detected, prompt the user to keep or discard them $oPage->p(" Some modifications were detected between the ".ITOP_APPLICATION." version in '$sPreviousVersionDir' and a genuine $sInstalledVersion version."); $oPage->p("What do you want to do?"); $aWritableDirs = array('modules', 'portal'); $aErrors = SetupUtils::CheckWritableDirs($aWritableDirs); $sChecked = ($this->oWizard->GetParameter('upgrade_type') == 'keep-previous') ? ' checked ' : ''; $sDisabled = (count($aErrors) > 0) ? ' disabled ' : ''; $oPage->p(''); $oPage->add(''); $oPage->add(''); if (count($aErrors) > 0) { $oPage->p("Cannot copy the installed version due to the following access rights issue(s):"); foreach($aErrors as $sDir => $oCheckResult) { $oPage->p(' '.$oCheckResult->sLabel); } } $sChecked = ($this->oWizard->GetParameter('upgrade_type') == 'use-compatible') ? ' checked ' : ''; $oPage->p(''); $oPage->add(''); $oPage->add(''); $oPage->add('
Details of the modifications
'); if (count($aChanges['added']) > 0) { $oPage->add('
    New files added:'); foreach($aChanges['added'] as $sFilePath => $void) { $oPage->add('
  • '.$sFilePath.'
  • '); } $oPage->add('
'); } if (count($aChanges['removed']) > 0) { $oPage->add('
    Deleted files:'); foreach($aChanges['removed'] as $sFilePath => $void) { $oPage->add('
  • '.$sFilePath.'
  • '); } $oPage->add('
'); } if (count($aChanges['modified']) > 0) { $oPage->add('
    Modified files:'); foreach($aChanges['modified'] as $sFilePath => $void) { $oPage->add('
  • '.$sFilePath.'
  • '); } $oPage->add('
'); } $oPage->add('
'); } else { // No changes detected... or no way to tell because of the lack of a manifest or previous source dir // Use the "compatible" datamodel as-is. $sCompatibleDMDirToDisplay = utils::HtmlEntities($sCompatibleDMDir); $sUpgradeDMVersionToDisplay = utils::HtmlEntities($sUpgradeDMVersion); $oPage->add( <<The datamodel will be upgraded from version $sInstalledDataModelVersion to version $sUpgradeDMVersion. HTML ); } $oPage->add_ready_script( <<oWizard->GetParameter('db_name', '').$this->oWizard->GetParameter('db_prefix', ''), $this->oWizard->GetParameter('db_server', ''), $this->oWizard->GetParameter('db_user', ''), $this->oWizard->GetParameter('db_pwd', ''), $this->oWizard->GetParameter('db_tls_enabled', ''), $this->oWizard->GetParameter('db_tls_ca', '') ); if ($oMutex->IsLocked()) { $oPage->add(<<An iTop cron process is being executed on the target database. iTop cron process will be stopped during the setup execution. HTML ); } } } public function CanMoveForward() { return $this->bCanMoveForward; } /** * Tells whether the "Next" button should be enabled interactively * @return string A piece of javascript code returning either true or false */ public function JSCanMoveForward() { return << 0); return bRet; EOF ; } } /** * License acceptation screen */ class WizStepLicense extends WizardStep { public function GetTitle() { return 'License Agreement'; } public function GetPossibleSteps() { return array('WizStepDBParams'); } public function ProcessParams($bMoveForward = true) { $this->oWizard->SaveParameter('accept_license', 'no'); return array('class' => 'WizStepDBParams', 'state' => ''); } /** * @return bool * @throws \Exception * @since 2.7.7 3.0.2 3.1.0 */ private function NeedsRgpdConsent() { $sMode = $this->oWizard->GetParameter('install_mode'); $aModules = SetupUtils::AnalyzeInstallation($this->oWizard); return $sMode == 'install' && !SetupUtils::IsProductVersion($aModules); } /** * @param WebPage $oPage */ public function Display(WebPage $oPage) { $aLicenses = SetupUtils::GetLicenses(); $oPage->add_style( <<add('

Licenses agreements for the components of '.ITOP_APPLICATION.'

'); $oPage->add_style('div a.no-arrow { background:transparent; padding-left:0;}'); $oPage->add_style('.toggle { cursor:pointer; text-decoration:underline; color:#1C94C4; }'); $oPage->add('
'); $oPage->add('Components of '.ITOP_APPLICATION.''); $oPage->add('
    '); $index = 0; foreach ($aLicenses as $oLicense) { $oPage->add('
  • '.$oLicense->product.', © '.$oLicense->author.' is licensed under the '.$oLicense->license_type.' license. (Details)'); $oPage->add(''); $oPage->add_ready_script('$(".license_text a").attr("target", "_blank").addClass("no-arrow");'); $oPage->add_ready_script('$("#toggle_'.$index.'").click( function() { $("#license_'.$index.'").toggle(); } );'); $index++; } $oPage->add('
'); $oPage->add('
'); $sChecked = ($this->oWizard->GetParameter('accept_license', 'no') == 'yes') ? ' checked ' : ''; $oPage->p(''); if ($this->NeedsRgpdConsent()) { $oPage->add('
iTop software is compliant with the processing of personal data according to the European General Data Protection Regulation (GDPR).

By installing iTop you agree that some information will be collected by Combodo to help you manage your instances and for statistical purposes. This data remains anonymous until it is associated to a user account on iTop Hub.

List of collected data available in our Data privacy section.

'); $oPage->add(''); $oPage->add(''); $oPage->add('
'); } $oPage->add_ready_script('$(".check_select").bind("click change", function() { WizardUpdateButtons(); });'); $oPage->add_script( << 'WizStepUpgradeMiscParams', 'state' => ''); } } /** * Database Connection parameters screen */ class WizStepDBParams extends WizardStep { public function GetTitle() { return 'Database Configuration'; } public function GetPossibleSteps() { return array('WizStepAdminAccount'); } public function ProcessParams($bMoveForward = true) { $this->oWizard->SaveParameter('db_server', ''); $this->oWizard->SaveParameter('db_user', ''); $this->oWizard->SaveParameter('db_pwd', ''); $this->oWizard->SaveParameter('db_name', ''); $this->oWizard->SaveParameter('db_prefix', ''); $this->oWizard->SaveParameter('new_db_name', ''); $this->oWizard->SaveParameter('create_db', ''); $this->oWizard->SaveParameter('db_new_name', ''); $this->oWizard->SaveParameter('db_tls_enabled', false); $this->oWizard->SaveParameter('db_tls_ca', ''); return array('class' => 'WizStepAdminAccount', 'state' => ''); } public function Display(WebPage $oPage) { $oPage->add('

Configuration of the database connection:

'); $sDBServer = $this->oWizard->GetParameter('db_server', ''); $sDBUser = $this->oWizard->GetParameter('db_user', ''); $sDBPwd = $this->oWizard->GetParameter('db_pwd', ''); $sDBName = $this->oWizard->GetParameter('db_name', ''); $sDBPrefix = $this->oWizard->GetParameter('db_prefix', ''); $sTlsEnabled = $this->oWizard->GetParameter('db_tls_enabled', ''); $sTlsCA = $this->oWizard->GetParameter('db_tls_ca', ''); $sNewDBName = $this->oWizard->GetParameter('db_new_name', false); $oPage->add(''); SetupUtils::DisplayDBParameters($oPage, true, $sDBServer, $sDBUser, $sDBPwd, $sDBName, $sDBPrefix, $sTlsEnabled, $sTlsCA, $sNewDBName); $sAuthentToken = $this->oWizard->GetParameter('authent', ''); $oPage->add(''); $oPage->add('
'); $sCreateDB = $this->oWizard->GetParameter('create_db', 'yes'); if ($sCreateDB == 'no') { $oPage->add_ready_script('$("#existing_db").prop("checked", true);'); } else { $oPage->add_ready_script('$("#create_db").prop("checked", true);'); } } public function AsyncAction(WebPage $oPage, $sCode, $aParameters) { switch($sCode) { case 'check_db': SetupUtils:: AsyncCheckDB($oPage, $aParameters); break; } } /** * Tells whether the "Next" button should be enabled interactively * @return string A piece of javascript code returning either true or false */ public function JSCanMoveForward() { return <<oWizard->SaveParameter('admin_user', ''); $this->oWizard->SaveParameter('admin_pwd', ''); $this->oWizard->SaveParameter('confirm_pwd', ''); $this->oWizard->SaveParameter('admin_language', 'EN US'); return array('class' => 'WizStepMiscParams', 'state' => ''); } public function Display(WebPage $oPage) { $sAdminUser = $this->oWizard->GetParameter('admin_user', 'admin'); $sAdminPwd = $this->oWizard->GetParameter('admin_pwd', ''); $sConfirmPwd = $this->oWizard->GetParameter('confirm_pwd', ''); $sAdminLanguage = $this->oWizard->GetParameter('admin_language', 'EN US'); $oPage->add('

Definition of the Administrator Account

'); $oPage->add('
'); $oPage->add('Administrator Account'); $oPage->add(''); $oPage->add(''); $oPage->add(''); $oPage->add(''); $sSourceDir = APPROOT.'dictionaries/'; $aLanguages = SetupUtils::GetAvailableLanguages($sSourceDir); $oPage->add(''); $oPage->add('
Login:
Password:
Confirm password:
Language: '); $oPage->add(SetupUtils::GetLanguageSelect($sSourceDir, 'admin_language', $sAdminLanguage)); $oPage->add('
'); $oPage->add('
'); $oPage->add_ready_script( <<'); } else { $("#v_admin_user").html(''); } bPasswordsMatch = ($('#admin_pwd').val() == $('#confirm_pwd').val()); if (!bPasswordsMatch) { $('#v_admin_pwd').html(''); } else { $('#v_admin_pwd').html(''); } bRet = bPasswordsMatch && bRet; return bRet; EOF ; }} /** * Miscellaneous Parameters (URL, Sample Data) */ class WizStepMiscParams extends WizardStep { public function GetTitle() { return 'Miscellaneous Parameters'; } public function GetPossibleSteps() { return array('WizStepModulesChoice'); } public function ProcessParams($bMoveForward = true) { $this->oWizard->SaveParameter('default_language', ''); $this->oWizard->SaveParameter('application_url', ''); $this->oWizard->SaveParameter('graphviz_path', ''); $this->oWizard->SaveParameter('sample_data', 'yes'); return array('class' => 'WizStepModulesChoice', 'state' => 'start_install'); } public function Display(WebPage $oPage) { $sDefaultLanguage = $this->oWizard->GetParameter('default_language', $this->oWizard->GetParameter('admin_language')); $sApplicationURL = $this->oWizard->GetParameter('application_url', utils::GetDefaultUrlAppRoot(true)); $sDefaultGraphvizPath = (strtolower(substr(PHP_OS, 0, 3)) === 'win') ? 'C:\\Program Files\\Graphviz\\bin\\dot.exe' : '/usr/bin/dot'; $sGraphvizPath = $this->oWizard->GetParameter('graphviz_path', $sDefaultGraphvizPath); $sSampleData = $this->oWizard->GetParameter('sample_data', 'yes'); $oPage->add('

Additional parameters

'); $oPage->add('
'); $oPage->add('Default Language'); $oPage->add(''); $sSourceDir = APPROOT.'dictionaries/'; $aLanguages = SetupUtils::GetAvailableLanguages($sSourceDir); $oPage->add(''); $oPage->add('
Default Language: '); $oPage->add(SetupUtils::GetLanguageSelect($sSourceDir, 'default_language', $sDefaultLanguage)); $oPage->add('
'); $oPage->add('
'); $oPage->add('
'); $oPage->add('Application URL'); $oPage->add(''); $oPage->add(''); $oPage->add(''); $oPage->add('
URL:
Change the value above if the end-users will be accessing the application by another path due to a specific configuration of the web server.
'); $oPage->add('
'); $oPage->add('
'); $oPage->add('Path to Graphviz\' dot application'); $oPage->add(''); $oPage->add(''); $oPage->add(''); $oPage->add(''); $oPage->add('
Path:
Graphviz is required to display the impact analysis graph (i.e. impacts / depends on).
'); $oPage->add('
'); $oPage->add('
'); $oPage->add('Sample Data'); $sChecked = ($sSampleData == 'yes') ? 'checked ' : ''; $oPage->p('
'); $sAuthentToken = $this->oWizard->GetParameter('authent', ''); $oPage->add(''); $oPage->add_ready_script( <<sLabel); switch($oCheck->iSeverity) { case CheckResult::INFO: $sStatus = 'ok'; $sInfoExplanation = (json_encode($oCheck->sLabel) !== false) ? $oCheck->sLabel : 'Graphviz\' dot found'; $sMessage = json_encode('
'.$sInfoExplanation.'
'); break; default: case CheckResult::ERROR: case CheckResult::WARNING: $sStatus = 'ko'; $sErrorExplanation = (json_encode($oCheck->sLabel) !== false) ? $oCheck->sLabel : 'Could not find Graphviz\' dot'; $sMessage = json_encode('
'.$sErrorExplanation.'
'); } $oPage->add_ready_script( <<'); } else { $("#v_application_url").html(''); } bGraphviz = ($('#graphviz_path').val() != ''); if (!bGraphviz) { // Does not prevent to move forward $("#v_graphviz_path").html(''); } else { $("#v_graphviz_path").html(''); } return bRet; EOF ; } } /** * Miscellaneous Parameters (URL...) in case of upgrade */ class WizStepUpgradeMiscParams extends WizardStep { public function GetTitle() { return 'Miscellaneous Parameters'; } public function GetPossibleSteps() { return array('WizStepModulesChoice'); } public function ProcessParams($bMoveForward = true) { $this->oWizard->SaveParameter('application_url', ''); $this->oWizard->SaveParameter('graphviz_path', ''); return array('class' => 'WizStepModulesChoice', 'state' => 'start_upgrade'); } public function Display(WebPage $oPage) { $sApplicationURL = $this->oWizard->GetParameter('application_url', utils::GetAbsoluteUrlAppRoot(true)); //Preserve existing configuration (except for the str_replace based joker $SERVER_NAME$ which is lost) $sDefaultGraphvizPath = (strtolower(substr(PHP_OS, 0, 3)) === 'win') ? 'C:\\Program Files\\Graphviz\\bin\\dot.exe' : '/usr/bin/dot'; $sGraphvizPath = $this->oWizard->GetParameter('graphviz_path', $sDefaultGraphvizPath); $oPage->add('

Additional parameters

'); $oPage->add('
'); $oPage->add('Application URL'); $oPage->add(''); $oPage->add(''); $oPage->add(''); $oPage->add('
URL:
Change the value above if the end-users will be accessing the application by another path due to a specific configuration of the web server.
'); $oPage->add('
'); $oPage->add('
'); $oPage->add('Path to Graphviz\' dot application'); $oPage->add(''); $oPage->add(''); $oPage->add(''); $oPage->add(''); $oPage->add('
Path:
Graphviz is required to display the impact analysis graph (i.e. impacts / depends on).
'); $oPage->add('
'); $sAuthentToken = $this->oWizard->GetParameter('authent', ''); $oPage->add(''); $oPage->add_ready_script( <<sLabel); switch($oCheck->iSeverity) { case CheckResult::INFO: $sStatus = 'ok'; $sInfoExplanation = (json_encode($oCheck->sLabel) !== false) ? $oCheck->sLabel : 'Graphviz\' dot found'; $sMessage = json_encode('
'.$sInfoExplanation.'
'); break; default: case CheckResult::ERROR: case CheckResult::WARNING: $sStatus = 'ko'; $sErrorExplanation = (json_encode($oCheck->sLabel) !== false) ? $oCheck->sLabel : 'Could not find Graphviz\' dot'; $sMessage = json_encode('
'.$sErrorExplanation.'
'); } $oPage->add_ready_script( <<'); } else { $("#v_application_url").html(''); } bGraphviz = ($('#graphviz_path').val() != ''); if (!bGraphviz) { // Does not prevent to move forward $("#v_graphviz_path").html(''); } else { $("#v_graphviz_path").html(''); } return bRet; EOF ; } } /** * Choice of the modules to be installed */ class WizStepModulesChoice extends WizardStep { static protected $SEP = '_'; protected $bUpgrade = false; /** * * @var iTopExtensionsMap */ protected $oExtensionsMap; /** * Whether we were able to load the choices from the database or not * @var bool */ protected $bChoicesFromDatabase; public function __construct(WizardController $oWizard, $sCurrentState) { parent::__construct($oWizard, $sCurrentState); $this->bChoicesFromDatabase = false; $this->oExtensionsMap = new iTopExtensionsMap(); $sPreviousSourceDir = $this->oWizard->GetParameter('previous_version_dir', ''); $sConfigPath = null; if (($sPreviousSourceDir !== '') && is_readable($sPreviousSourceDir.'/conf/production/config-itop.php')) { $sConfigPath = $sPreviousSourceDir.'/conf/production/config-itop.php'; } else if (is_readable(utils::GetConfigFilePath('production'))) { $sConfigPath = utils::GetConfigFilePath('production'); } // only called if the config file exists : we are updating a previous installation ! // WARNING : we can't load this config directly, as it might be from another directory with a different approot_url (N°2684) if ($sConfigPath !== null) { $oConfig = new Config($sConfigPath); $this->bChoicesFromDatabase = $this->oExtensionsMap->LoadChoicesFromDatabase($oConfig); } } public function GetTitle() { $aStepInfo = $this->GetStepInfo(); $sTitle = isset($aStepInfo['title']) ? $aStepInfo['title'] : 'Modules selection'; return $sTitle; } public function GetPossibleSteps() { return array('WizStepModulesChoice', 'WizStepSummary'); } public function ProcessParams($bMoveForward = true) { // Accumulates the selected modules: $index = $this->GetStepIndex(); // use json_encode:decode to store a hash array: step_id => array(input_name => selected_input_id) $aSelectedChoices = json_decode($this->oWizard->GetParameter('selected_components', '{}'), true); $aSelected = utils::ReadParam('choice', array()); $aSelectedChoices[$index] = $aSelected; $this->oWizard->SetParameter('selected_components', json_encode($aSelectedChoices)); if ($this->GetStepInfo($index) == null) { throw new Exception('Internal error: invalid step "'.$index.'" for the choice of modules.'); } else if ($bMoveForward) { if ($this->GetStepInfo(1 + $index) != null) { return array('class' => 'WizStepModulesChoice', 'state' => (1+$index)); } else { // Exiting this step of the wizard, let's convert the selection into a list of modules $aModules = array(); $aExtensions = array(); $sDisplayChoices = '
    '; for($i = 0; $i <= $index; $i++) { $aStepInfo = $this->GetStepInfo($i); $sDisplayChoices .= $this->GetSelectedModules($aStepInfo, $aSelectedChoices[$i], $aModules, '', '', $aExtensions); } $sDisplayChoices .= '
'; if (class_exists('CreateITILProfilesInstaller')) { $this->oWizard->SetParameter('old_addon', true); } $this->oWizard->SetParameter('selected_modules', json_encode(array_keys($aModules))); $this->oWizard->SetParameter('selected_extensions', json_encode($aExtensions)); $this->oWizard->SetParameter('display_choices', $sDisplayChoices); return array('class' => 'WizStepSummary', 'state' => ''); } } } public function Display(WebPage $oPage) { $this->DisplayStep($oPage); } /** * @param \SetupPage $oPage * * @throws \Exception */ protected function DisplayStep($oPage) { // Sanity check (not stopper, to let developers go further...) try { SetupUtils::AnalyzeInstallation($this->oWizard, true); } catch(MissingDependencyException $e) { $oPage->warning($e->getHtmlDesc()); } $this->bUpgrade = ($this->oWizard->GetParameter('install_mode') != 'install'); $aStepInfo = $this->GetStepInfo(); $oPage->add_style("div.choice { margin: 0.5em;}"); $oPage->add_style("div.choice a { text-decoration:none; font-weight: bold; color: #1C94C4 }"); $oPage->add_style("div.description { margin-left: 2em; }"); $oPage->add_style(".choice-disabled { color: #999; }"); $aModules = SetupUtils::AnalyzeInstallation($this->oWizard); $sManualInstallError = SetupUtils::CheckManualInstallDirEmpty($aModules, $this->oWizard->GetParameter('extensions_dir', 'extensions')); if ($sManualInstallError !== '') { $oPage->warning($sManualInstallError); } $oPage->add(''); $sBannerPath = isset($aStepInfo['banner']) ? $aStepInfo['banner'] : ''; if (!empty($sBannerPath)) { if (substr($sBannerPath, 0, 1) == '/') { // absolute path, means relative to APPROOT $sBannerUrl = utils::GetDefaultUrlAppRoot(true).$sBannerPath; } else { // relative path: i.e. relative to the directory containing the XML file $sFullPath = dirname($this->GetSourceFilePath()).'/'.$sBannerPath; $sRealPath = realpath($sFullPath); $sBannerUrl = utils::GetDefaultUrlAppRoot(true).str_replace(realpath(APPROOT), '', $sRealPath); } $oPage->add('
'); } $sDescription = isset($aStepInfo['description']) ? $aStepInfo['description'] : ''; $oPage->add(''.$sDescription.''); $oPage->add('
'); // Build the default choices $aDefaults = $this->GetDefaults($aStepInfo, $aModules); $index = $this->GetStepIndex(); // retrieve the saved selection // use json_encode:decode to store a hash array: step_id => array(input_name => selected_input_id) $aParameters = json_decode($this->oWizard->GetParameter('selected_components', '{}'), true); if (!isset($aParameters[$index])) { $aParameters[$index] = $aDefaults; } $aSelectedComponents = $aParameters[$index]; $oPage->add('
'); $this->DisplayOptions($oPage, $aStepInfo, $aSelectedComponents, $aDefaults); $oPage->add('
'); $oPage->add_script( <<add_ready_script( <<bChoicesFromDatabase) { $this->GuessDefaultsFromModules($aInfo, $aDefaults, $aModules, $sParentId); } else { $this->GetDefaultsFromDatabase($aInfo, $aDefaults, $sParentId); } return $aDefaults; } protected function GetDefaultsFromDatabase($aInfo, &$aDefaults, $sParentId) { $aOptions = isset($aInfo['options']) ? $aInfo['options'] : array(); foreach($aOptions as $index => $aChoice) { $sChoiceId = $sParentId.self::$SEP.$index; if ($this->bUpgrade) { if ($this->oExtensionsMap->IsMarkedAsChosen($aChoice['extension_code'])) { $aDefaults[$sChoiceId] = $sChoiceId; } } else if (isset($aChoice['default']) && $aChoice['default']) { $aDefaults[$sChoiceId] = $sChoiceId; } // Recurse for sub_options (if any) if (isset($aChoice['sub_options'])) { $this->GetDefaultsFromDatabase($aChoice['sub_options'], $aDefaults, $sChoiceId); } } $aAlternatives = isset($aInfo['alternatives']) ? $aInfo['alternatives'] : array(); $sChoiceName = null; foreach($aAlternatives as $index => $aChoice) { $sChoiceId = $sParentId.self::$SEP.$index; if ($sChoiceName == null) { $sChoiceName = $sChoiceId; // All radios share the same name } if ($this->bUpgrade) { if ($this->oExtensionsMap->IsMarkedAsChosen($aChoice['extension_code'])) { $aDefaults[$sChoiceName] = $sChoiceId; } } else if (isset($aChoice['default']) && $aChoice['default']) { $aDefaults[$sChoiceName] = $sChoiceId; } // Recurse for sub_options (if any) if (isset($aChoice['sub_options'])) { $this->GetDefaultsFromDatabase($aChoice['sub_options'], $aDefaults, $sChoiceId); } } } /** * Try to guess the user choices based on the current list of installed modules... * @param array $aInfo * @param array $aDefaults * @param array $aModules * @param string $sParentId * @return array */ protected function GuessDefaultsFromModules($aInfo, &$aDefaults, $aModules, $sParentId = '') { $aRetScore = array(); $aScores = array(); $aOptions = isset($aInfo['options']) ? $aInfo['options'] : array(); foreach($aOptions as $index => $aChoice) { $sChoiceId = $sParentId.self::$SEP.$index; $aScores[$sChoiceId] = array(); if (!$this->bUpgrade && isset($aChoice['default']) && $aChoice['default']) { $aDefaults[$sChoiceId] = $sChoiceId; } if ($this->bUpgrade) { // In upgrade mode, the defaults are the installed modules foreach($aChoice['modules'] as $sModuleId) { if ($aModules[$sModuleId]['version_db'] != '') { // A module corresponding to this choice is installed $aScores[$sChoiceId][$sModuleId] = true; } } // Used for migration from 1.3.x or before // Accept that the new version can have one new module than the previous version // The option is still selected $iSelected = count($aScores[$sChoiceId]); $iNeeded = count($aChoice['modules']); if (($iSelected > 0) && (($iNeeded - $iSelected) < 2)) { // All the modules are installed, this choice is selected $aDefaults[$sChoiceId] = $sChoiceId; } $aRetScore = array_merge($aRetScore, $aScores[$sChoiceId]); } if (isset($aChoice['sub_options'])) { $aScores[$sChoiceId] = array_merge($aScores[$sChoiceId], $this->GuessDefaultsFromModules($aChoice['sub_options'], $aDefaults, $sChoiceId)); } $index++; } $aAlternatives = isset($aInfo['alternatives']) ? $aInfo['alternatives'] : array(); $sChoiceName = null; $sChoiceIdNone = null; foreach($aAlternatives as $index => $aChoice) { $sChoiceId = $sParentId.self::$SEP.$index; $aScores[$sChoiceId] = array(); if ($sChoiceName == null) { $sChoiceName = $sChoiceId; } if (!$this->bUpgrade && isset($aChoice['default']) && $aChoice['default']) { $aDefaults[$sChoiceName] = $sChoiceId; } if (isset($aChoice['sub_options'])) { // By default (i.e. install-mode), sub options can only be checked if the parent option is checked by default if ($this->bUpgrade || (isset($aChoice['default']) && $aChoice['default'])) { $aScores[$sChoiceId] = $this->GuessDefaultsFromModules($aChoice['sub_options'], $aDefaults, $aModules, $sChoiceId); } } $index++; } $iMaxScore = 0; if ($this->bUpgrade && (count($aAlternatives) > 0)) { // The installed choices have precedence over the 'default' choices // In case several choices share the same base modules, let's weight the alternative choices // based on their number of installed modules $sChoiceName = null; foreach($aAlternatives as $index => $aChoice) { $sChoiceId = $sParentId.self::$SEP.$index; if ($sChoiceName == null) { $sChoiceName = $sChoiceId; } if (array_key_exists('modules', $aChoice)) { foreach($aChoice['modules'] as $sModuleId) { if ($aModules[$sModuleId]['version_db'] != '') { // A module corresponding to this choice is installed, increase the score of this choice if (!isset($aScores[$sChoiceId])) $aScores[$sChoiceId] = array(); $aScores[$sChoiceId][$sModuleId] = true; $iMaxScore = max($iMaxScore, count($aScores[$sChoiceId])); } } //if (count($aScores[$sChoiceId]) == count($aChoice['modules'])) //{ // $iScore += 100; // Bonus for the parent when a choice is complete //} $aRetScore = array_merge($aRetScore, $aScores[$sChoiceId]); } $iMaxScore = max($iMaxScore, isset($aScores[$sChoiceId]) ? count($aScores[$sChoiceId]) : 0); } } if ($iMaxScore > 0) { $aNumericScores = array(); foreach($aScores as $sChoiceId => $aModules) { $aNumericScores[$sChoiceId] = count($aModules); } // The choice with the bigger score wins ! asort($aNumericScores, SORT_NUMERIC); $aKeys = array_keys($aNumericScores); $sBetterChoiceId = array_pop($aKeys); $aDefaults[$sChoiceName] = $sBetterChoiceId; } // echo "Scores:
".print_r($aScores, true)."

"; // echo "Defaults:
".print_r($aDefaults, true)."

"; return $aRetScore; } /** * Converts the list of selected "choices" into a list of "modules": take into account the selected and the mandatory modules * * @param array $aInfo Info about the "choice" array('options' => array(...), 'alternatives' => array(...)) * @param array $aSelectedChoices List of selected choices array('name' => 'selected_value_id') * @param array $aModules Return parameter: List of selected modules array('module_id' => true) * @param string $sParentId Used for recursion * * @return string A text representation of what will be installed */ protected function GetSelectedModules($aInfo, $aSelectedChoices, &$aModules, $sParentId = '', $sDisplayChoices = '', &$aSelectedExtensions = null) { if ($sParentId == '') { // Check once (before recursing) that the hidden modules are selected foreach(SetupUtils::AnalyzeInstallation($this->oWizard) as $sModuleId => $aModule) { if (($sModuleId != ROOT_MODULE) && !isset($aModules[$sModuleId])) { if (($aModule['category'] == 'authentication') || (!$aModule['visible'] && !isset($aModule['auto_select']))) { $aModules[$sModuleId] = true; $sDisplayChoices .= '
  • '.$aModule['label'].' (hidden)
  • '; } } } } $aOptions = isset($aInfo['options']) ? $aInfo['options'] : array(); foreach($aOptions as $index => $aChoice) { $sChoiceId = $sParentId.self::$SEP.$index; $aModuleInfo = []; // Get the extension corresponding to the choice foreach ($this->oExtensionsMap->GetAllExtensions() as $sExtensionVersion => $oExtension) { if (utils::StartsWith($sExtensionVersion, $aChoice['extension_code'].'/')) { $aModuleInfo = $oExtension->aModuleInfo; break; } } if ((isset($aChoice['mandatory']) && $aChoice['mandatory']) || (isset($aSelectedChoices[$sChoiceId]) && ($aSelectedChoices[$sChoiceId] == $sChoiceId))) { $sDisplayChoices .= '
  • '.$aChoice['title'].'
  • '; if (isset($aChoice['modules'])) { foreach ($aChoice['modules'] as $sModuleId) { $bSelected = true; if (isset($aModuleInfo[$sModuleId])) { // Test if module has 'auto_select' $aInfo = $aModuleInfo[$sModuleId]; if (isset($aInfo['auto_select'])) { // Check the module selection try { $bSelected = false; SetupInfo::SetSelectedModules($aModules); eval('$bSelected = ('.$aInfo['auto_select'].');'); } catch (Exception $e) { $bSelected = false; } } } if ($bSelected) { $aModules[$sModuleId] = true; // store the Id of the selected module SetupInfo::SetSelectedModules($aModules); } } } $sChoiceType = isset($aChoice['type']) ? $aChoice['type'] : 'wizard_option'; if ($aSelectedExtensions !== null) { $aSelectedExtensions[] = $aChoice['extension_code']; } // Recurse only for selected choices if (isset($aChoice['sub_options'])) { $sDisplayChoices .= '
      '; $sDisplayChoices = $this->GetSelectedModules($aChoice['sub_options'], $aSelectedChoices, $aModules, $sChoiceId, $sDisplayChoices, $aSelectedExtensions); $sDisplayChoices .= '
    '; } $sDisplayChoices .= ''; } } $aAlternatives = isset($aInfo['alternatives']) ? $aInfo['alternatives'] : array(); $sChoiceName = null; foreach($aAlternatives as $index => $aChoice) { $sChoiceId = $sParentId.self::$SEP.$index; if ($sChoiceName == null) { $sChoiceName = $sChoiceId; } if ( (isset($aChoice['mandatory']) && $aChoice['mandatory']) || (isset($aSelectedChoices[$sChoiceName]) && ($aSelectedChoices[$sChoiceName] == $sChoiceId)) ) { $sDisplayChoices .= '
  • '.$aChoice['title'].'
  • '; if ($aSelectedExtensions !== null) { $aSelectedExtensions[] = $aChoice['extension_code']; } if (isset($aChoice['modules'])) { foreach($aChoice['modules'] as $sModuleId) { $aModules[$sModuleId] = true; // store the Id of the selected module } } // Recurse only for selected choices if (isset($aChoice['sub_options'])) { $sDisplayChoices .= '
      '; $sDisplayChoices = $this->GetSelectedModules($aChoice['sub_options'], $aSelectedChoices, $aModules, $sChoiceId, $sDisplayChoices, $aSelectedExtensions); $sDisplayChoices .= '
    '; } $sDisplayChoices .= ''; } } if ($sParentId == '') { // Last pass (after all the user's choices are turned into "selected" modules): // Process 'auto_select' modules for modules that are not already selected $aAvailableModules = SetupUtils::AnalyzeInstallation($this->oWizard); do { // Loop while new modules are added... $bModuleAdded = false; foreach($aAvailableModules as $sModuleId => $aModule) { if (($sModuleId != ROOT_MODULE) && !array_key_exists($sModuleId, $aModules) && isset($aModule['auto_select'])) { try { $bSelected = false; SetupInfo::SetSelectedModules($aModules); eval('$bSelected = ('.$aModule['auto_select'].');'); } catch(Exception $e) { $sDisplayChoices .= '
  • Warning: auto_select failed with exception ('.$e->getMessage().') for module "'.$sModuleId.'"
  • '; $bSelected = false; } if ($bSelected) { $aModules[$sModuleId] = true; // store the Id of the selected module $sDisplayChoices .= '
  • '.$aModule['label'].' (auto_select)
  • '; $bModuleAdded = true; } } } } while($bModuleAdded); } return $sDisplayChoices; } protected function GetStepIndex() { switch($this->sCurrentState) { case 'start_install': case 'start_upgrade': $index = 0; break; default: $index = (integer)$this->sCurrentState; } return $index; } protected function GetStepInfo($idx = null) { $aStepInfo = null; if ($idx === null) { $index = $this->GetStepIndex(); } else { $index = $idx; } $aSteps = array(); $this->oWizard->SetParameter('additional_extensions_modules', json_encode(array())); // Default value, no additional extensions if (@file_exists($this->GetSourceFilePath())) { // Found an "installation.xml" file, let's us tis definition for the wizard $aParams = new XMLParameters($this->GetSourceFilePath()); $aSteps = $aParams->Get('steps', array()); // Additional step for the "extensions" $aStepDefinition = array( 'title' => 'Extensions', 'description' => '

    Select additional extensions to install. You can launch the installation again to install new extensions, but you cannot remove already installed extensions.

    ', 'banner' => '/images/extension.png', 'options' => array() ); foreach($this->oExtensionsMap->GetAllExtensions() as $oExtension) { if (($oExtension->sSource !== iTopExtension::SOURCE_WIZARD) && ($oExtension->bVisible) && (count($oExtension->aMissingDependencies) == 0)) { $aStepDefinition['options'][] = array( 'extension_code' => $oExtension->sCode, 'title' => $oExtension->sLabel, 'description' => $oExtension->sDescription, 'more_info' => $oExtension->sMoreInfoUrl, 'default' => true, // by default offer to install all modules 'modules' => $oExtension->aModules, 'mandatory' => $oExtension->bMandatory || ($oExtension->sSource === iTopExtension::SOURCE_REMOTE), 'source_label' => $this->GetExtensionSourceLabel($oExtension->sSource), ); } } // Display this step of the wizard only if there is something to display if (count($aStepDefinition['options']) !== 0) { $aSteps[] = $aStepDefinition; $this->oWizard->SetParameter('additional_extensions_modules', json_encode($aStepDefinition['options'])); } } else { // No wizard configuration provided, build a standard one with just one big list $aStepDefinition = array( 'title' => 'Modules Selection', 'description' => '

    Select the modules to install. You can launch the installation again to install new modules, but you cannot remove already installed modules.

    ', 'banner' => '/images/modules.png', 'options' => array() ); foreach($this->oExtensionsMap->GetAllExtensions() as $oExtension) { if (($oExtension->bVisible) && (count($oExtension->aMissingDependencies) == 0)) { $aStepDefinition['options'][] = array( 'extension_code' => $oExtension->sCode, 'title' => $oExtension->sLabel, 'description' => $oExtension->sDescription, 'more_info' => $oExtension->sMoreInfoUrl, 'default' => true, // by default offer to install all modules 'modules' => $oExtension->aModules, 'mandatory' => $oExtension->bMandatory || ($oExtension->sSource !== iTopExtension::SOURCE_REMOTE), 'source_label' => $this->GetExtensionSourceLabel($oExtension->sSource), ); } } $aSteps[] = $aStepDefinition; } if (array_key_exists($index, $aSteps)) { $aStepInfo = $aSteps[$index]; } return $aStepInfo; } protected function GetExtensionSourceLabel($sSource) { switch($sSource) { case iTopExtension::SOURCE_MANUAL: $sResult = 'Extension'; break; case iTopExtension::SOURCE_REMOTE: $sResult = (ITOP_APPLICATION == 'iTop') ? 'iTop-Hub' : 'ITSM-Designer'; break; default: $sResult = ''; } if ($sResult == '') { return ''; } return ''.$sResult.''; } protected function DisplayOptions($oPage, $aStepInfo, $aSelectedComponents, $aDefaults, $sParentId = '', $bAllDisabled = false) { $aOptions = isset($aStepInfo['options']) ? $aStepInfo['options'] : array(); $aAlternatives = isset($aStepInfo['alternatives']) ? $aStepInfo['alternatives'] : array(); $index = 0; $sAllDisabled = ''; if ($bAllDisabled) { $sAllDisabled = 'disabled data-disabled="disabled" '; } foreach($aOptions as $index => $aChoice) { $sAttributes = ''; $sChoiceId = $sParentId.self::$SEP.$index; $sDataId = 'data-id="'.htmlentities($aChoice['extension_code'], ENT_QUOTES, 'UTF-8').'"'; $sId = htmlentities($aChoice['extension_code'], ENT_QUOTES, 'UTF-8'); $bIsDefault = array_key_exists($sChoiceId, $aDefaults); $bSelected = isset($aSelectedComponents[$sChoiceId]) && ($aSelectedComponents[$sChoiceId] == $sChoiceId); $bMandatory = (isset($aChoice['mandatory']) && $aChoice['mandatory']) || ($this->bUpgrade && $bIsDefault); $bDisabled = false; if ($bMandatory) { $oPage->add('
     '); $bDisabled = true; } else if ($bSelected) { $oPage->add('
     '); } else { $oPage->add('
     '); } $this->DisplayChoice($oPage, $aChoice, $aSelectedComponents, $aDefaults, $sChoiceId, $bDisabled); $oPage->add('
    '); $index++; } $sChoiceName = null; $sDisabled = ''; $bDisabled = false; $sChoiceIdNone = null; foreach($aAlternatives as $index => $aChoice) { $sChoiceId = $sParentId.self::$SEP.$index; if ($sChoiceName == null) { $sChoiceName = $sChoiceId; // All radios share the same name } $bIsDefault = array_key_exists($sChoiceName, $aDefaults) && ($aDefaults[$sChoiceName] == $sChoiceId); $bMandatory = (isset($aChoice['mandatory']) && $aChoice['mandatory']) || ($this->bUpgrade && $bIsDefault); if ($bMandatory || $bAllDisabled) { // One choice is mandatory, all alternatives are disabled $sDisabled = ' disabled data-disabled="disabled"'; $bDisabled = true; } if ( (!isset($aChoice['sub_options']) || (count($aChoice['sub_options']) == 0)) && (!isset($aChoice['modules']) || (count($aChoice['modules']) == 0)) ) { $sChoiceIdNone = $sChoiceId; // the "None" / empty choice } } if (!array_key_exists($sChoiceName, $aDefaults) || ($aDefaults[$sChoiceName] == $sChoiceIdNone)) { // The "none" choice does not disable the selection !! $sDisabled = ''; $bDisabled = false; } foreach($aAlternatives as $index => $aChoice) { $sAttributes = ''; $sChoiceId = $sParentId.self::$SEP.$index; $sDataId = 'data-id="'.htmlentities($aChoice['extension_code'], ENT_QUOTES, 'UTF-8').'"'; $sId = htmlentities($aChoice['extension_code'], ENT_QUOTES, 'UTF-8'); if ($sChoiceName == null) { $sChoiceName = $sChoiceId; // All radios share the same name } $bIsDefault = array_key_exists($sChoiceName, $aDefaults) && ($aDefaults[$sChoiceName] == $sChoiceId); $bSelected = isset($aSelectedComponents[$sChoiceName]) && ($aSelectedComponents[$sChoiceName] == $sChoiceId); if ( !isset($aSelectedComponents[$sChoiceName]) && ($sChoiceIdNone != null)) { // No choice selected, select the "None" option $bSelected = ($sChoiceId == $sChoiceIdNone); } $bMandatory = (isset($aChoice['mandatory']) && $aChoice['mandatory']) || ($this->bUpgrade && $bIsDefault); if ($bSelected) { $sAttributes = ' checked '; } $sHidden = ''; if ($bMandatory && $bDisabled) { $sAttributes = ' checked '; $sHidden = ''; } $oPage->add('
    '.$sHidden.' '); $this->DisplayChoice($oPage, $aChoice, $aSelectedComponents, $aDefaults, $sChoiceId, $bDisabled && !$bSelected); $oPage->add('
    '); $index++; } } protected function DisplayChoice($oPage, $aChoice, $aSelectedComponents, $aDefaults, $sChoiceId, $bDisabled = false) { $sMoreInfo = (isset($aChoice['more_info']) && ($aChoice['more_info'] != '')) ? 'More information' : ''; $sSourceLabel = isset($aChoice['source_label']) ? $aChoice['source_label'] : ''; $sId = htmlentities($aChoice['extension_code'], ENT_QUOTES, 'UTF-8'); $oPage->add(' '.$sMoreInfo); $sDescription = isset($aChoice['description']) ? htmlentities($aChoice['description'], ENT_QUOTES, 'UTF-8') : ''; $oPage->add('
    '.$sDescription.''); if (isset($aChoice['sub_options'])) { $this->DisplayOptions($oPage, $aChoice['sub_options'], $aSelectedComponents, $aDefaults, $sChoiceId, $bDisabled); } $oPage->add('
    '); } protected function GetSourceFilePath() { $sSourceDir = $this->oWizard->GetParameter('source_dir'); return $sSourceDir.'/installation.xml'; } } /** * Summary of the installation tasks */ class WizStepSummary extends WizardStep { protected $bDependencyCheck = null; protected $sDependencyIssue = null; protected function CheckDependencies() { if (is_null($this->bDependencyCheck)) { $aSelectedModules = json_decode($this->oWizard->GetParameter('selected_modules'), true); $this->bDependencyCheck = true; try { SetupUtils::AnalyzeInstallation($this->oWizard, true, $aSelectedModules); } catch(MissingDependencyException $e) { $this->bDependencyCheck = false; $this->sDependencyIssue = $e->getHtmlDesc(); } } return $this->bDependencyCheck; } public function GetTitle() { $sMode = $this->oWizard->GetParameter('mode', 'install'); if ($sMode == 'install') { return 'Ready to install'; } else { return 'Ready to upgrade'; } } public function GetPossibleSteps() { return array('WizStepDone'); } /** * Returns the label for the " Next >> " button * @return string The label for the button */ public function GetNextButtonLabel() { return ' Install ! '; } public function CanMoveForward() { if ($this->CheckDependencies()) { return true; } else { return false; } } public function ProcessParams($bMoveForward = true) { return array('class' => 'WizStepDone', 'state' => ''); } public function Display(WebPage $oPage) { $oPage->add_style( <<BuildConfig(); $sMode = $aInstallParams['mode']; $sDestination = ITOP_APPLICATION.(($sMode == 'install') ? ' version '.ITOP_VERSION.' is about to be installed ' : ' is about to be upgraded '); $sDBDescription = ' existing database '.$aInstallParams['database']['name'].''; if (($sMode == 'install') && ($this->oWizard->GetParameter('create_db') == 'yes')) { $sDBDescription = ' new database '.$aInstallParams['database']['name'].''; } $sDestination .= 'into the '.$sDBDescription.' on the server '.$aInstallParams['database']['server'].'.'; $oPage->add('

    '.$sDestination.'

    '); $oPage->add('
    Installation Parameters'); $oPage->add('
    '); $oPage->add('
    Database Parameters
      '); $oPage->add('
    • Server Name: '.$aInstallParams['database']['server'].'
    • '); $oPage->add('
    • DB User Name: '.$aInstallParams['database']['user'].'
    • '); $oPage->add('
    • DB user password: ***
    • '); if (($sMode == 'install') && ($this->oWizard->GetParameter('create_db') == 'yes')) { $oPage->add('
    • Database Name: '.$aInstallParams['database']['name'].' (will be created)
    • '); } else { $oPage->add('
    • Database Name: '.$aInstallParams['database']['name'].'
    • '); } if ($aInstallParams['database']['prefix'] != '') { $oPage->add('
    • Prefix for the '.ITOP_APPLICATION.' tables: '.$aInstallParams['database']['prefix'].'
    • '); } else { $oPage->add('
    • Prefix for the '.ITOP_APPLICATION.' tables: none
    • '); } $oPage->add('
    '); $oPage->add('
    Data Model Configuration'); $oPage->add($this->oWizard->GetParameter('display_choices')); $oPage->add('
    '); $oPage->add('
    Other Parameters
      '); if ($sMode == 'install') { $oPage->add('
    • Default language: '.$aInstallParams['language'].'
    • '); } $oPage->add('
    • URL to access the application: '.$aInstallParams['url'].'
    • '); $oPage->add('
    • Graphviz\' dot path: '.$aInstallParams['graphviz_path'].'
    • '); if ($aInstallParams['sample_data'] == 'yes') { $oPage->add('
    • Sample data will be loaded into the database.
    • '); } if ($aInstallParams['old_addon']) { $oPage->add('
    • Compatibility mode: Using the version 1.2 of the UserRightsProfiles add-on.
    • '); } $oPage->add('
    '); if ($sMode == 'install') { $oPage->add('
    Admininistrator Account
      '); $oPage->add('
    • Login: '.$aInstallParams['admin_account']['user'].'
    • '); $oPage->add('
    • Password: '.$aInstallParams['admin_account']['pwd'].'
    • '); $oPage->add('
    • Language: '.$aInstallParams['admin_account']['language'].'
    • '); $oPage->add('
    '); } $aMiscOptions = $aInstallParams['options']; if (count($aMiscOptions) > 0) { $oPage->add('
    Miscellaneous Options
      '); foreach($aMiscOptions as $sKey => $sValue) { $oPage->add('
    • '.$sKey.': '.$sValue.'
    • '); } $oPage->add('
    '); } $aSelectedModules = $aInstallParams['selected_modules']; if (isset($aMiscOptions['generate_config'])) { $oDoc = new DOMDocument('1.0', 'UTF-8'); $oDoc->preserveWhiteSpace = false; $oDoc->formatOutput = true; $oParams = new PHPParameters(); $oParams->LoadFromHash($aInstallParams); $oParams->ToXML($oDoc, null, 'installation'); $sXML = $oDoc->saveXML(); $oPage->add('
    XML Config file
      ');
      			$oPage->add(htmlentities($sXML, ENT_QUOTES, 'UTF-8'));
      			$oPage->add('
    '); } $oPage->add('
    '); // params_summary $oPage->add('
    '); $oPage->add('
    Progress of the installation'); $oPage->add('
    '); $oPage->add_linked_script('../setup/jquery.progression.js'); $oPage->add('

    Ready to start...

    0%
    '); $oPage->add('
    '); // progress_content $oPage->add('
    '); $sJSONData = json_encode($aInstallParams); $oPage->add(''); $sAuthentToken = $this->oWizard->GetParameter('authent', ''); $oPage->add(''); if (!$this->CheckDependencies()) { $oPage->error($this->sDependencyIssue); } $oPage->add_ready_script( <<oWizard->GetParameter('install_mode', 'install'); $aSelectedModules = json_decode($this->oWizard->GetParameter('selected_modules'), true); $aSelectedExtensions = json_decode($this->oWizard->GetParameter('selected_extensions'), true); $sBackupDestination = ''; $sPreviousConfigurationFile = ''; $sDBName = $this->oWizard->GetParameter('db_name'); if ($sMode == 'upgrade') { $sPreviousVersionDir = $this->oWizard->GetParameter('previous_version_dir', ''); if (!empty($sPreviousVersionDir)) { $aPreviousInstance = SetupUtils::GetPreviousInstance($sPreviousVersionDir); if ($aPreviousInstance['found']) { $sPreviousConfigurationFile = $aPreviousInstance['configuration_file']; } } if ($this->oWizard->GetParameter('db_backup', false)) { $sBackupDestination = $this->oWizard->GetParameter('db_backup_path', ''); } } else { $sDBNewName = $this->oWizard->GetParameter('db_new_name', ''); if ($sDBNewName != '') { $sDBName = $sDBNewName; // Database will be created } } $sSourceDir = $this->oWizard->GetParameter('source_dir'); $aCopies = array(); if (($sMode == 'upgrade') && ($this->oWizard->GetParameter('upgrade_type') == 'keep-previous')) { $sPreviousVersionDir = $this->oWizard->GetParameter('previous_version_dir'); $aCopies[] = array('source' => $sSourceDir, 'destination' => 'modules'); // Source is an absolute path, destination is relative to APPROOT $aCopies[] = array('source' => $sPreviousVersionDir.'/portal', 'destination' => 'portal'); // Source is an absolute path, destination is relative to APPROOT $sSourceDir = APPROOT.'modules'; } $aInstallParams = array ( 'mode' => $sMode, 'preinstall' => array ( 'copies' => $aCopies, // 'backup' => see below ), 'source_dir' => str_replace(APPROOT, '', $sSourceDir), 'datamodel_version' => $this->oWizard->GetParameter('datamodel_version'), //TODO: let the installer compute this automatically... 'previous_configuration_file' => $sPreviousConfigurationFile, 'extensions_dir' => 'extensions', 'target_env' => 'production', 'workspace_dir' => '', 'database' => array ( 'server' => $this->oWizard->GetParameter('db_server'), 'user' => $this->oWizard->GetParameter('db_user'), 'pwd' => $this->oWizard->GetParameter('db_pwd'), 'name' => $sDBName, 'db_tls_enabled' => $this->oWizard->GetParameter('db_tls_enabled'), 'db_tls_ca' => $this->oWizard->GetParameter('db_tls_ca'), 'prefix' => $this->oWizard->GetParameter('db_prefix'), ), 'url' => $this->oWizard->GetParameter('application_url'), 'graphviz_path' => $this->oWizard->GetParameter('graphviz_path'), 'admin_account' => array ( 'user' => $this->oWizard->GetParameter('admin_user'), 'pwd' => $this->oWizard->GetParameter('admin_pwd'), 'language' => $this->oWizard->GetParameter('admin_language'), ), 'language' => $this->oWizard->GetParameter('default_language'), 'selected_modules' => $aSelectedModules, 'selected_extensions' => $aSelectedExtensions, 'sample_data' => ($this->oWizard->GetParameter('sample_data', '') == 'yes') ? true : false , 'old_addon' => $this->oWizard->GetParameter('old_addon', false), // whether or not to use the "old" userrights profile addon 'options' => json_decode($this->oWizard->GetParameter('misc_options', '[]'), true), 'mysql_bindir' => $this->oWizard->GetParameter('mysql_bindir'), ); if ($sBackupDestination != '') { $aInstallParams['preinstall']['backup'] = array ( 'destination' => $sBackupDestination, 'configuration_file' => $sPreviousConfigurationFile, ); } return $aInstallParams; } public function AsyncAction(WebPage $oPage, $sCode, $aParameters) { $oParameters = new PHPParameters(); $sStep = $aParameters['installer_step']; $sJSONParameters = $aParameters['installer_config']; $oParameters->LoadFromHash(json_decode($sJSONParameters, true /* bAssoc */)); $oInstaller = new ApplicationInstaller($oParameters); $aRes = $oInstaller->ExecuteStep($sStep); if (($aRes['status'] != ApplicationInstaller::ERROR) && ($aRes['next-step'] != '')) { // Tell the web page to move the progress bar and to launch the next step $sMessage = addslashes(htmlentities($aRes['next-step-label'], ENT_QUOTES, 'UTF-8')); $oPage->add_ready_script( <<{$aRes['next-step-label']}'); ExecuteStep('{$aRes['next-step']}'); EOF ); } else if ($aRes['status'] != ApplicationInstaller::ERROR) { // Installation complete, move to the next step of the wizard $oPage->add_ready_script( <<', $sMessage); $oPage->add_ready_script( << '', 'state' => ''); } public function Display(WebPage $oPage) { // Check if there are some manual steps required: $aManualSteps = array(); $aAvailableModules = SetupUtils::AnalyzeInstallation($this->oWizard); $sRootUrl = utils::GetAbsoluteUrlAppRoot(true); $aSelectedModules = json_decode($this->oWizard->GetParameter('selected_modules'), true); foreach($aSelectedModules as $sModuleId) { if (!empty($aAvailableModules[$sModuleId]['doc.manual_setup'])) { $aManualSteps[$aAvailableModules[$sModuleId]['label']] = $sRootUrl.$aAvailableModules[$sModuleId]['doc.manual_setup']; } } if (count($aManualSteps) > 0) { $oPage->add("

    Manual operations required

    "); $oPage->p("In order to complete the installation, the following manual operations are required:"); foreach($aManualSteps as $sModuleLabel => $sUrl) { $oPage->p("Manual instructions for $sModuleLabel"); } $oPage->add("

    Congratulations for installing ".ITOP_APPLICATION."

    "); } else { $oPage->add("

    Congratulations for installing ".ITOP_APPLICATION."

    "); $oPage->ok("The installation completed successfully."); } $bHasBackup = false; if (($this->oWizard->GetParameter('mode', '') == 'upgrade') && $this->oWizard->GetParameter('db_backup', false) && $this->oWizard->GetParameter('authent', false)) { $sBackupDestination = $this->oWizard->GetParameter('db_backup_path', ''); if (file_exists($sBackupDestination.'.tar.gz')) { $bHasBackup = true; // To mitigate security risks: pass only the filename without the extension, the download will add the extension itself $oPage->p('Your backup is ready'); $oPage->p(' Download '.basename($sBackupDestination).''); } else { $oPage->p(' Warning: Backup creation failed !'); } } // Form goes here.. No back button since the job is done ! $oPage->add(''); $oPage->add(""); $oPage->add(""); $oPage->add(""); $oPage->add('
    '); $oConfig = new Config(utils::GetConfigFilePath()); // Load the data model only, in order to load env-production/core/main.php to get the XML parameters (needed by GetModuleSettings below) // But main.php may also contain classes (defined without any module), and thus requiring the full data model // to be loaded to prevent "class not found" errors... $oProductionEnv = new RunTimeEnvironment('production'); $oProductionEnv->InitDataModel($oConfig, true); $sIframeUrl = $oConfig->GetModuleSetting('itop-hub-connector', 'setup_url', ''); if ($sIframeUrl != '') { $oPage->add(''); $oPage->add_script("window.addEventListener('message', function(event) { if (event.data === 'itophub_load_completed') { $('#fresh_content').height($('#placeholder').height()); $('#placeholder').hide(); $('#fresh_content').show(); } }, false); "); } $sForm = '
    '; $sForm .= ''; $sForm .= ''; $sForm .= "

    "; $sForm .= '
    '; $sForm = addslashes($sForm); $oPage->add_ready_script("$('#wiz_form').after('$sForm');"); // avoid leaving in a dirty state SetupUtils::ExitMaintenanceMode(false); SetupUtils::ExitReadOnlyMode(false); if (false === $bHasBackup) { SetupUtils::EraseSetupToken(); } } public function CanMoveForward() { return false; } public function CanMoveBackward() { return false; } /** * Tells whether this step of the wizard requires that the configuration file be writable * @return bool True if the wizard will possibly need to modify the configuration at some point */ public function RequiresWritableConfig() { return false; //This step executes once the config was written and secured } public function AsyncAction(WebPage $oPage, $sCode, $aParameters) { SetupUtils::EraseSetupToken(); // For security reasons: add the extension now so that this action can be used to read *only* .tar.gz files from the disk... $sBackupFile = $aParameters['backup'].'.tar.gz'; if (file_exists($sBackupFile)) { // Make sure there is NO output at all before our content, otherwise the document will be corrupted $sPreviousContent = ob_get_clean(); $oPage->SetContentType('application/gzip'); $oPage->SetContentDisposition('attachment', basename($sBackupFile)); $oPage->add(file_get_contents($sBackupFile)); } } }