/**
* All the steps of the iTop installation wizard
* @copyright Copyright (C) 2010-2012 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
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');
/**
* First step of the iTop Installation Wizard: Welcome screen
*/
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)
{
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('
');
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.');
}
}
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', '');
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', '');
$sPreviousVersionDir = '';
if ($sInstallMode == '')
{
$sDBBackupPath = APPROOT.'data/'.ITOP_APPLICATION.strftime('-backup-%Y-%m-%d.zip');
$bDBBackup = true;
$aPreviousInstance = SetupUtils::GetPreviousInstance(APPROOT);
if ($aPreviousInstance['found'])
{
$sInstallMode = 'upgrade';
$sSourceDir = APPROOT;
$sDBServer = $aPreviousInstance['db_server'];
$sDBUser = $aPreviousInstance['db_user'];
$sDBPwd = $aPreviousInstance['db_pwd'];
$sDBName = $aPreviousInstance['db_name'];
$sDBPrefix = $aPreviousInstance['db_prefix'];
$sStyle = '';
$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 ' : '';
$oPage->p('');
//$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);
$this->oWizard->SaveParameter('copy_extensions_from', '');
$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;
}
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 the 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.'.'.ITOP_REVISION."
");
if ($sInstalledVersion == (ITOP_VERSION.'.'.ITOP_REVISION))
{
// 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($sLatestDMDir);
}
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.'.'.ITOP_REVISION.") 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.
$oPage->p(" The datamodel will be upgraded from version $sInstalledDataModelVersion to version $sUpgradeDMVersion.");
$oPage->add('');
$oPage->add('');
$oPage->add('');
}
// Check if there are "extensions" to preserve and if it's possible
if (is_dir($sPreviousVersionDir.'/extensions'))
{
$aExtensions = glob($sPreviousVersionDir.'/extensions/*', GLOB_ONLYDIR);
if (($aExtensions !== false) && (count($aExtensions)>0) && (realpath($sPreviousVersionDir.'/extensions') != realpath(APPROOT.'extensions')) )
{
$aWritableDirs = array('extensions');
$aErrors = SetupUtils::CheckWritableDirs($aWritableDirs);
if (count($aErrors) > 0)
{
$oPage->p("Cannot copy the extensions from '$sPreviousVersionDir/extensions' to '".APPROOT."extensions' due to the following access rights issue(s):");
foreach($aErrors as $sDir => $oCheckResult)
{
$oPage->p(' '.$oCheckResult->sLabel);
}
}
else
{
$oPage->p("Note: The extensions present in '$sPreviousVersionDir/extensions' will be copied to '".APPROOT."extensions'.");
$oPage->add('');
}
}
}
$oPage->add_ready_script(
<<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' => '');
}
public function Display(WebPage $oPage)
{
$aLicenses = array();
foreach (glob(APPROOT.'setup/licenses/*.xml') as $sFile)
{
$oXml = simplexml_load_file($sFile);
foreach($oXml->license as $oLicense)
{
$aLicenses[] = $oLicense;
}
}
$oPage->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('');
$sChecked = ($this->oWizard->GetParameter('accept_license', 'no') == 'yes') ? ' checked ' : '';
$oPage->p('');
$oPage->add_ready_script('$("#accept").bind("click change", function() { WizardUpdateButtons(); });');
}
/**
* 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 'return ($("#accept").attr("checked") === "checked");';
}
}
/**
* License acceptation screen (when upgrading)
*/
class WizStepLicense2 extends WizStepLicense
{
public function GetPossibleSteps()
{
return array('WizStepUpgradeMiscParams');
}
public function ProcessParams($bMoveForward = true)
{
return array('class' => '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', '');
return array('class' => 'WizStepAdminAccount', 'state' => '');
}
public function Display(WebPage $oPage)
{
$oPage->add('
');
$oPage->add_script(
<<add_ready_script(
<< $aChoice)
{
$sChoiceId = $sParentId.self::$SEP.$index;
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, the whole choice is selected
$aDefaults[$sChoiceId] = $sChoiceId;
$iScore = 99; // The whole parent choice is selected
break;
}
}
}
if (isset($aChoice['sub_options']))
{
$aScores[$sChoiceId] = $this->GetDefaults($aChoice['sub_options'], $aDefaults, $sChoiceId);
}
$index++;
}
$aAlternatives = isset($aInfo['alternatives']) ? $aInfo['alternatives'] : array();
$sChoiceName = null;
$aScores = array();
$sChoiceIdNone = null;
foreach($aAlternatives as $index => $aChoice)
{
$sChoiceId = $sParentId.self::$SEP.$index;
if ($sChoiceName == null)
{
$sChoiceName = $sChoiceId;
}
if (!$this->bUpgrade && isset($aChoice['default']) && $aChoice['default'])
{
$aDefaults[$sChoiceName] = $sChoiceId;
}
if (isset($aChoice['sub_options']))
{
$aScores[$sChoiceId] = $this->GetDefaults($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;
}
$aScores[$sChoiceId] = 0;
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] = 0;
$aScores[$sChoiceId]++;
$iMaxScore = max($iMaxScore, $aScores[$sChoiceId]);
$iScore = 99; // The whole parent choice is selected
}
}
}
}
}
if ($iMaxScore > 0)
{
//echo "Scores:
".print_r($aScores, true)."
";
// The choice with the bigger score wins !
asort($aScores, SORT_NUMERIC);
$aKeys = array_keys($aScores);
$sBetterChoiceId = array_pop($aKeys);
$aDefaults[$sChoiceName] = $sBetterChoiceId;
}
return $iScore;
}
/**
* Converts the list of selected "choices" into a list of "modules": take into account the selected and the mandatory modules
* @param hash $aInfo Info about the "choice" array('options' => array(...), 'alternatives' => array(...))
* @param hash $aSelectedChoices List of selected choices array('name' => 'selected_value_id')
* @param hash $aModules Return parameter: List of selected modules array('module_id' => true)
* @param string $sParentId Used for recursion
* @return void
*/
protected function GetSelectedModules($aInfo, $aSelectedChoices, &$aModules, $sParentId = '', $sDisplayChoices = '')
{
if ($sParentId == '')
{
// Check once (before recursing) that the hidden modules are selected
foreach(SetupUtils::AnalyzeInstallation($this->oWizard) as $sModuleId => $aModule)
{
if ($sModuleId != ROOT_MODULE)
{
if (($aModule['category'] == 'authentication') || (!$aModule['visible']))
{
$aModules[$sModuleId] = true;
}
}
}
}
$aOptions = isset($aInfo['options']) ? $aInfo['options'] : array();
foreach($aOptions as $index => $aChoice)
{
$sChoiceId = $sParentId.self::$SEP.$index;
if ( (isset($aChoice['mandatory']) && $aChoice['mandatory']) ||
(isset($aSelectedChoices[$sChoiceId]) && ($aSelectedChoices[$sChoiceId] == $sChoiceId)) )
{
$sDisplayChoices .= '
'.$aChoice['title'].'
';
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 .= '
';
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 .= '
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()
);
try
{
$sDefaultAppPath = utils::GetDefaultUrlAppRoot();
}
catch(Exception $e)
{
$sDefaultAppPath = '..';
}
$aAvailableModules = SetupUtils::AnalyzeInstallation($this->oWizard);
foreach($aAvailableModules as $sModuleId => $aModule)
{
if ($sModuleId == ROOT_MODULE) continue; // Convention: the version number of the application (and datamodel) are stored as a module named ROOT_MODULE
$sModuleLabel = $aModule['label'];
$sModuleHelp = $aModule['doc.more_information'];
$sMoreInfo = (!empty($aModule['doc.more_information'])) ? "more info": '';
if (($aModule['category'] != 'authentication') && ($aModule['visible']))
{
if (($bAddExtensionsOnly) && (!$this->IsExtension($aModule))) continue;
if ($this->IsExtension($aModule))
{
$iStepIndex = count($aSteps) - 1;
}
else
{
$iStepIndex = 0;
}
$aSteps[$iStepIndex]['options'][] = array(
'title' => $sModuleLabel,
'description' => '',
'more_info' => $sMoreInfo,
'default' => true, // by default offer to install all modules
'modules' => array($sModuleId),
'mandatory' => ($aModule['install']['flag'] & MODULE_ACTION_MANDATORY) ? true : false,
);
}
}
if (count($aSteps[count($aSteps) - 1]['options']) == 0)
{
// No extensions at all, remove the last step
array_pop($aSteps);
}
if (array_key_exists($index, $aSteps))
{
$aStepInfo = $aSteps[$index];
}
return $aStepInfo;
}
protected function GetExtensionsStepInfo()
{
// let the user select from the list of modules located in the "extensions" folder
}
protected function IsExtension($aModule)
{
// root_dir is the directory containing the module, check if its parent is "extensions"
if (basename(dirname($aModule['root_dir'])) == 'extensions')
{
return true;
}
return false;
}
protected function DisplayOptions($oPage, $aStepInfo, $aSelectedComponents, $aDefaults, $sParentId = '')
{
$aOptions = isset($aStepInfo['options']) ? $aStepInfo['options'] : array();
$aAlternatives = isset($aStepInfo['alternatives']) ? $aStepInfo['alternatives'] : array();
$index = 0;
foreach($aOptions as $index => $aChoice)
{
$sAttributes = '';
$sChoiceId = $sParentId.self::$SEP.$index;
$bIsDefault = array_key_exists($sChoiceId, $aDefaults);
$bSelected = isset($aSelectedComponents[$sChoiceId]) && ($aSelectedComponents[$sChoiceId] == $sChoiceId);
$bMandatory = (isset($aChoice['mandatory']) && $aChoice['mandatory']) || ($this->bUpgrade && $bIsDefault);
if ($bMandatory)
{
$oPage->add('
');
}
protected function GetSourceFilePath()
{
$sSourceDir = $this->oWizard->GetParameter('source_dir');
return $sSourceDir.'/installation.xml';
}
}
/**
* Summary of the installation tasks
*/
class WizStepSummary extends WizardStep
{
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 ProcessParams($bMoveForward = true)
{
return array('class' => 'WizStepDone', 'state' => '');
}
public function Display(WebPage $oPage)
{
$oPage->add_style(
<<BuildConfig();
$sMode = $aInstallParams['mode'];
$sPreinstallationPhase = '';
$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('');
$oPage->add('');
$sJSONData = json_encode($aInstallParams);
$oPage->add('');
$oPage->add_ready_script(
<<oWizard->GetParameter('install_mode', 'install');
$aSelectedModules = json_decode($this->oWizard->GetParameter('selected_modules'), 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';
}
if (($sMode == 'upgrade'))
{
// Copy the previous extensions, if any
$sPreviousExtensionsDir = $this->oWizard->GetParameter('copy_extensions_from');
if (is_dir($sPreviousExtensionsDir))
{
// Copy the extensions one by one to merge them with the existing extensions in /extensions
$aExtensions = glob($sPreviousExtensionsDir.'/*', GLOB_ONLYDIR);
foreach($aExtensions as $sDirPath)
{
$sExtName = basename($sDirPath);
$aCopies[] = array('source' => $sDirPath, 'destination' => 'extensions/'.$sExtName); // Source is an absolute path, destination is relative to APPROOT
}
}
}
$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,
'prefix' => $this->oWizard->GetParameter('db_prefix'),
),
'url' => $this->oWizard->GetParameter('application_url'),
'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,
'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),
);
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(
<<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();
$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.");
}
if (($this->oWizard->GetParameter('mode', '') == 'upgrade') && $this->oWizard->GetParameter('db_backup', false))
{
$sBackupDestination = $this->oWizard->GetParameter('db_backup_path', '');
if (file_exists($sBackupDestination))
{
// To mitigate security risks: pass only the filename without the extension, the download will add the extension itself
$sTruncatedFilePath = preg_replace('/\.zip$/', '', $sBackupDestination);
$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('
');
$sForm = '';
$oPage->add('');
$sForm = addslashes($sForm);
$oPage->add_ready_script("$('#wiz_form').after('$sForm');");
}
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)
{
$oParameters = new PHPParameters();
// For security reasons: add the extension now so that this action can be used to read *only* .zip files from the disk...
$sBackupFile = $aParameters['backup'].'.zip';
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/zip');
$oPage->SetContentDisposition('attachment', basename($sBackupFile));
$oPage->add(file_get_contents($sBackupFile));
}
}
}