N°9144 DataAuditSequencer v0

This commit is contained in:
Timothee
2026-01-29 10:02:56 +01:00
parent fd6ce5f5c4
commit ea44e39b2c
13 changed files with 303 additions and 223 deletions

View File

@@ -17,14 +17,18 @@
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
use Combodo\iTop\Setup\FeatureRemoval\DryRemovalRuntimeEnvironment;
use Combodo\iTop\Setup\FeatureRemoval\InplaceSetupAudit;
use Combodo\iTop\Setup\FeatureRemoval\ModelReflectionSerializer;
use Combodo\iTop\Setup\FeatureRemoval\SetupAudit;
require_once(APPROOT.'setup/parameters.class.inc.php');
require_once(APPROOT.'setup/StepSequencer.php');
require_once(APPROOT.'setup/xmldataloader.class.inc.php');
require_once(APPROOT.'setup/backup.class.inc.php');
require_once APPROOT.'setup/feature_removal/SetupAudit.php';
require_once APPROOT.'setup/feature_removal/InplaceSetupAudit.php';
require_once APPROOT.'setup/feature_removal/DryRemovalRuntimeEnvironment.php';
/**
* The base class for the installation process.
@@ -40,7 +44,7 @@ require_once APPROOT.'setup/feature_removal/InplaceSetupAudit.php';
* @license http://opensource.org/licenses/AGPL-3.0
*/
class ApplicationBuildSequencer extends StepSequencer
class ApplicationInstallSequencer extends StepSequencer
{
/** @var \Parameters */
@@ -68,7 +72,7 @@ class ApplicationBuildSequencer extends StepSequencer
/**
* @return string
*/
private function GetTargetEnv()
protected function GetTargetEnv()
{
$sTargetEnvironment = $this->oParams->Get('target_env', '');
if ($sTargetEnvironment !== '') {
@@ -81,7 +85,7 @@ class ApplicationBuildSequencer extends StepSequencer
/**
* @return string
*/
private function GetTargetDir()
protected function GetTargetDir()
{
$sTargetEnv = $this->GetTargetEnv();
return 'env-'.$sTargetEnv;
@@ -89,7 +93,7 @@ class ApplicationBuildSequencer extends StepSequencer
private function GetConfig()
protected function GetConfig()
{
$sTargetEnvironment = $this->GetTargetEnv();
$sConfigFile = APPCONF.$sTargetEnvironment.'/'.ITOP_CONFIG_FILE;
@@ -195,7 +199,6 @@ class ApplicationBuildSequencer extends StepSequencer
$sExtensionDir = $this->oParams->Get('extensions_dir', 'extensions');
$aMiscOptions = $this->oParams->Get('options', []);
$aRemovedExtensionCodes = $this->oParams->Get('removed_extensions', []);
$sSkipDataAudit = $this->oParams->Get('skip-data-audit', '');
$bUseSymbolicLinks = null;
if ((isset($aMiscOptions['symlinks']) && $aMiscOptions['symlinks'])) {
@@ -207,24 +210,18 @@ class ApplicationBuildSequencer extends StepSequencer
}
}
$aParamValues = $this->oParams->GetParamForConfigArray();
$bIsSetupDataAuditEnabled = $this->IsSetupDataAuditEnabled($sSkipDataAudit, $aParamValues);
$this->DoCompile(
$aRemovedExtensionCodes,
$aSelectedModules,
$sSourceDir,
$sExtensionDir,
$bIsSetupDataAuditEnabled,
$bUseSymbolicLinks
);
if ($bIsSetupDataAuditEnabled) {
$sNextStep = 'setup-audit';
$sNextStepLabel = 'Checking data consistency with the new data model';
} else {
$sNextStep = 'db-schema';
$sNextStepLabel = 'Updating database schema';
}
$sNextStep = 'db-schema';
$sNextStepLabel = 'Updating database schema';
$aResult = [
'status' => self::OK,
@@ -235,17 +232,6 @@ class ApplicationBuildSequencer extends StepSequencer
];
break;
case 'setup-audit':
$this->DoSetupAudit();
$aResult = [
'status' => self::OK,
'message' => '',
'next-step' => 'db-schema',
'next-step-label' => 'Updating database schema',
'percentage-completed' => 50,
];
break;
case 'db-schema':
$aSelectedModules = $this->oParams->Get('selected_modules', []);
@@ -368,7 +354,7 @@ class ApplicationBuildSequencer extends StepSequencer
return $aResult;
}
private function EnterReadOnlyMode()
protected function EnterReadOnlyMode()
{
if ($this->GetTargetEnv() != 'production') {
return;
@@ -381,7 +367,7 @@ class ApplicationBuildSequencer extends StepSequencer
SetupUtils::EnterReadOnlyMode($this->GetConfig());
}
private function ExitReadOnlyMode()
protected function ExitReadOnlyMode()
{
if ($this->GetTargetEnv() != 'production') {
return;
@@ -441,7 +427,6 @@ class ApplicationBuildSequencer extends StepSequencer
* @param array $aSelectedModules
* @param string $sSourceDir
* @param string $sExtensionDir
* @param bool $bIsSetupDataAuditEnabled
* @param boolean $bUseSymbolicLinks
*
* @return void
@@ -450,7 +435,7 @@ class ApplicationBuildSequencer extends StepSequencer
*
* @since 3.1.0 N°2013 added the aParamValues param
*/
protected function DoCompile($aRemovedExtensionCodes, $aSelectedModules, $sSourceDir, $sExtensionDir, bool &$bIsSetupDataAuditEnabled, $bUseSymbolicLinks = null)
protected function DoCompile($aRemovedExtensionCodes, $aSelectedModules, $sSourceDir, $sExtensionDir, $bUseSymbolicLinks = null)
{
/**
* @since 3.2.0 move the ContextTag init at the very beginning of the method
@@ -491,15 +476,7 @@ class ApplicationBuildSequencer extends StepSequencer
}
$bIsAlreadyInMaintenanceMode = SetupUtils::IsInMaintenanceMode();
if ($bIsSetupDataAuditEnabled) {
if ($bIsAlreadyInMaintenanceMode) {
//required to read DM before calling SaveModelInfo
SetupUtils::ExitMaintenanceMode();
$bIsAlreadyInMaintenanceMode = false;
}
$bIsSetupDataAuditEnabled = $this->SaveModelInfo($sEnvironment);
}
if (($sEnvironment == 'production') && !$bIsAlreadyInMaintenanceMode) {
$sConfigFilePath = utils::GetConfigFilePath($sEnvironment);
@@ -592,12 +569,12 @@ class ApplicationBuildSequencer extends StepSequencer
}
}
private function GetModelInfoPath(string $sEnv): string
protected function GetModelInfoPath(string $sEnv): string
{
return APPROOT."data/beforecompilation_".$sEnv."_modelinfo.json";
}
private function SaveModelInfo(string $sEnvironment): bool
protected function SaveModelInfo(string $sEnvironment): bool
{
$sModelInfoPath = $this->GetModelInfoPath($sEnvironment);
try {
@@ -610,7 +587,7 @@ class ApplicationBuildSequencer extends StepSequencer
return (bool) file_put_contents($sModelInfoPath, json_encode($aModelInfo));
}
private function GetPreviousModelInfo(string $sEnvironment): array
protected function GetPreviousModelInfo(string $sEnvironment): array
{
$sContent = file_get_contents($this->GetModelInfoPath($sEnvironment));
$aModelInfo = json_decode($sContent, true);
@@ -631,9 +608,9 @@ class ApplicationBuildSequencer extends StepSequencer
$oContextTag = new ContextTag(ContextTag::TAG_SETUP);
$sTargetEnvironment = $this->GetTargetEnv();
$aPreviousCompilationModelInfo = $this->GetPreviousModelInfo($sTargetEnvironment);
$sPreviousEnvironment = 'production';
$oSetupAudit = new InplaceSetupAudit($aPreviousCompilationModelInfo, $sTargetEnvironment);
$oSetupAudit = new SetupAudit($sPreviousEnvironment, $sTargetEnvironment);
$oSetupAudit->GetIssues(true);
$iCount = $oSetupAudit->GetDataToCleanupCount();
@@ -643,7 +620,8 @@ class ApplicationBuildSequencer extends StepSequencer
}
}
private function IsSetupDataAuditEnabled($sSkipDataAudit, array $aParamValues): bool
protected function IsSetupDataAuditEnabled($sSkipDataAudit, array $aParamValues): bool
{
if ($sSkipDataAudit === "checked") {
SetupLog::Info("Setup data audit disabled", null, ['skip-data-audit' => $sSkipDataAudit]);
@@ -1034,7 +1012,155 @@ class SetupDBBackup extends DBBackup
}
}
class DataAuditSequencer extends ApplicationInstallSequencer
{
/**
* @return string
*/
protected function GetTargetDir()
{
$sTargetEnv = $this->GetTargetEnv();
return 'env-dry-'.$sTargetEnv;
}
/**
* Executes the next step of the installation and reports about the progress
* and the next step to perform
*
* @param string $sStep The identifier of the step to execute
* @param string|null $sInstallComment
*
* @return array (status => , message => , percentage-completed => , next-step => , next-step-label => )
*/
public function ExecuteStep($sStep = '', $sInstallComment = null)
{
try {
$fStart = microtime(true);
SetupLog::Info("##### STEP {$sStep} start");
$this->EnterReadOnlyMode();
switch ($sStep) {
case '':
$aResult = [
'status' => self::OK,
'message' => '',
'percentage-completed' => 20,
'next-step' => 'compile',
'next-step-label' => 'Compiling the data model',
];
// Log the parameters...
$oDoc = new DOMDocument('1.0', 'UTF-8');
$oDoc->preserveWhiteSpace = false;
$oDoc->formatOutput = true;
$this->oParams->ToXML($oDoc, null, 'installation');
$sXML = $oDoc->saveXML();
$sSafeXml = preg_replace("|<pwd>([^<]*)</pwd>|", "<pwd>**removed**</pwd>", $sXML);
SetupLog::Info("======= Data Audit starts =======\nParameters:\n$sSafeXml\n");
// Save the response file as a stand-alone file as well
$sFileName = 'data-audit-'.date('Y-m-d');
$index = 0;
while (file_exists(APPROOT.'log/'.$sFileName.'.xml')) {
$index++;
$sFileName = 'data-audit-'.date('Y-m-d').'-'.$index;
}
file_put_contents(APPROOT.'log/'.$sFileName.'.xml', $sSafeXml);
break;
case 'compile':
$aSelectedModules = $this->oParams->Get('selected_modules');
$sSourceDir = $this->oParams->Get('source_dir', 'datamodels/latest');
$sExtensionDir = $this->oParams->Get('extensions_dir', 'extensions');
$aRemovedExtensionCodes = $this->oParams->Get('removed_extensions', []);
$this->DoCompile(
$aRemovedExtensionCodes,
$aSelectedModules,
$sSourceDir,
$sExtensionDir,
false
);
$aResult = [
'status' => self::OK,
'message' => '',
'next-step' => 'setup-audit',
'next-step-label' => 'Checking data consistency with the new data model',
'percentage-completed' => 60,
];
break;
case 'setup-audit':
$this->DoSetupAudit();
$aResult = [
'status' => self::OK,
'message' => '',
'next-step' => 'cleanup',
'next-step-label' => 'Temporary folders cleanup',
'percentage-completed' => 80,
];
break;
case 'cleanup' ;
$this->DoCleanup();
$aResult = [
'status' => self::OK,
'message' => '',
'next-step' => '',
'next-step-label' => 'Completed',
'percentage-completed' => 100,
];
break;
default:
$aResult = [
'status' => self::ERROR,
'message' => '',
'next-step' => '',
'next-step-label' => "Unknown setup step '$sStep'.",
'percentage-completed' => 100,
];
break;
}
} catch (Exception $e) {
$aResult = [
'status' => self::ERROR,
'message' => $e->getMessage(),
'next-step' => '',
'next-step-label' => '',
'percentage-completed' => 100,
];
SetupLog::Error('An exception occurred: '.$e->getMessage().' at line '.$e->getLine().' in file '.$e->getFile());
$idx = 0;
// Log the call stack, but not the parameters since they may contain passwords or other sensitive data
SetupLog::Ok("Call stack:");
foreach ($e->getTrace() as $aTrace) {
$sLine = empty($aTrace['line']) ? "" : $aTrace['line'];
$sFile = empty($aTrace['file']) ? "" : $aTrace['file'];
$sClass = empty($aTrace['class']) ? "" : $aTrace['class'];
$sType = empty($aTrace['type']) ? "" : $aTrace['type'];
$sFunction = empty($aTrace['function']) ? "" : $aTrace['function'];
$sVerb = empty($sClass) ? $sFunction : "$sClass{$sType}$sFunction";
SetupLog::Ok("#$idx $sFile($sLine): $sVerb(...)");
$idx++;
}
} finally {
$fDuration = round(microtime(true) - $fStart, 2);
SetupLog::Info("##### STEP {$sStep} duration: {$fDuration}s");
}
return $aResult;
}
protected function DoCleanup(){
SetupUtils::tidydir($this->GetTargetDir());
}
}
/**
* For compatibility with older scripts
*/
class_alias('ApplicationBuildSequencer', 'ApplicationInstaller');
class_alias('ApplicationInstallSequencer', 'ApplicationInstaller');

View File

@@ -41,7 +41,7 @@ class ModelReflectionSerializer
exec(sprintf("$sPHPExec %s/get_model_reflection.php --env='%s'", __DIR__, $sEnv), $sOutput, $iRes);
if ($iRes != 0) {
$this->LogErrorWithProperLogger("Cannot get classes1", null, ['env' => $sEnv, 'code' => $iRes, "output" => $sOutput]);
throw new CoreException("Cannot get classes2");
throw new CoreException("Cannot get classes from env ".$sEnv);
}
$aClasses = json_decode($sOutput[0] ?? null, true);

View File

@@ -5,7 +5,7 @@ require_once(APPROOT.'application/application.inc.php');
$sEnv = null;
if (isset($argv)) {
foreach ($argv as $iArg => $sArg) {
if (preg_match('/^--env=(.*)$/', $sArg, $aMatches)) {
if (preg_match('/^--env=\'(.*)\'$/', $sArg, $aMatches)) {
$sEnv = $aMatches[1];
}
}

View File

@@ -272,7 +272,7 @@ $bFoundIssues = false;
$bInstall = utils::ReadParam('install', true, true /* CLI allowed */);
if ($bInstall) {
echo "Starting the unattended installation...\n";
$oWizard = new ApplicationBuildSequencer($oParams);
$oWizard = new ApplicationInstallSequencer($oParams);
$bRes = $oWizard->ExecuteAllSteps();
if (!$bRes) {
echo "\nencountered installation issues!";

View File

@@ -26,7 +26,7 @@ require_once(APPROOT.'core/mutex.class.inc.php');
require_once(APPROOT.'setup/extensionsmap.class.inc.php');
require_once(APPROOT.'setup/wizardsteps/WizardStep.php');
require_once(APPROOT.'setup/wizardsteps/AbstractWizStepBuild.php');
require_once(APPROOT.'setup/wizardsteps/AbstractWizStepInstall.php');
require_once(APPROOT.'setup/wizardsteps/WizStepWelcome.php');
require_once(APPROOT.'setup/wizardsteps/WizStepInstallOrUpgrade.php');
require_once(APPROOT.'setup/wizardsteps/WizStepDetectedInfo.php');
@@ -34,8 +34,8 @@ require_once(APPROOT.'setup/wizardsteps/WizStepLicense.php');
require_once(APPROOT.'setup/wizardsteps/WizStepLicense2.php');
require_once(APPROOT.'setup/wizardsteps/AbstractWizStepMiscParams.php');
require_once(APPROOT.'setup/wizardsteps/WizStepAdminAccount.php');
require_once(APPROOT.'setup/wizardsteps/WizStepAudit.php');
require_once(APPROOT.'setup/wizardsteps/WizStepBuild.php');
require_once(APPROOT.'setup/wizardsteps/WizStepInstall.php');
require_once(APPROOT.'setup/wizardsteps/WizStepDataAudit.php');
require_once(APPROOT.'setup/wizardsteps/WizStepDBParams.php');
require_once(APPROOT.'setup/wizardsteps/WizStepDone.php');
require_once(APPROOT.'setup/wizardsteps/WizStepInstallMiscParams.php');

View File

@@ -1,6 +1,6 @@
<?php
abstract class AbstractWizStepBuild extends WizardStep {
abstract class AbstractWizStepInstall extends WizardStep {
/**
* Prepare the parameters to execute the installation asynchronously
* @return array A big hash array that can be converted to XML or JSON with all the needed parameters

View File

@@ -1,123 +0,0 @@
<?php
/**
* Copyright (C) 2013-2026 Combodo SAS
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\WebPage;
/**
* @since 3.3.0
*/
class WizStepAudit extends AbstractWizStepBuild
{
public function GetTitle()
{
return 'Checking upgrade';
}
public function GetPossibleSteps()
{
return ['WizStepSummary'];
}
public function GetNextButtonLabel()
{
return 'Next';
}
public function CanMoveForward()
{
return true;
}
public function ProcessParams($bMoveForward = true)
{
return ['class' => 'WizStepSummary', 'state' => ''];
}
public function Display(WebPage $oPage)
{
$oPage->add('<h2>Progress bar</h2>');
}
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 ApplicationBuildSequencer($oParameters);
$aRes = $oInstaller->ExecuteStep($sStep);
if (($aRes['status'] != ApplicationBuildSequencer::ERROR) && ($aRes['next-step'] != '')) {
// Tell the web page to move the progress bar and to launch the next step
$sMessage = addslashes(utils::EscapeHtml($aRes['next-step-label']));
$oPage->add_ready_script(
<<<EOF
$("#wiz_form").data("installation_status", "running");
WizardUpdateButtons();
$('#setup_msg').html('$sMessage');
$('#progress').progression( {Current:{$aRes['percentage-completed']}, Maximum: 100} );
//$("#percentage").html('{$aRes['percentage-completed']} % completed<br/>{$aRes['next-step-label']}');
ExecuteStep('{$aRes['next-step']}');
EOF
);
} elseif ($aRes['status'] != ApplicationBuildSequencer::ERROR) {
// Installation complete, move to the next step of the wizard
$oPage->add_ready_script(
<<<EOF
$("#wiz_form").data("installation_status", "completed");
$('#progress').progression( {Current:100, Maximum: 100} );
WizardUpdateButtons();
$("#btn_next").off("click.install");
$("#btn_next").trigger('click');
EOF
);
} else {
$sMessage = addslashes(utils::EscapeHtml($aRes['message']));
$sMessage = str_replace("\n", '<br>', $sMessage);
$oPage->add_ready_script(
<<<EOF
$("#wiz_form").data("installation_status", "error");
WizardUpdateButtons();
$('#setup_msg').html('$sMessage');
EOF
);
}
}
/**
* 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 true;';
return 'return (($("#wiz_form").data("installation_status") === "not started") || ($("#wiz_form").data("installation_status") === "completed"));';
}
/**
* Tells whether the "Next" button should be enabled interactively
* @return string A piece of javascript code returning either true or false
*/
public function JSCanMoveBackward()
{
return 'return true;';
return 'var sStatus = $("#wiz_form").data("installation_status"); return ((sStatus === "not started") || (sStatus === "error"));';
}
}

View File

@@ -0,0 +1,83 @@
<?php
/**
* Copyright (C) 2013-2026 Combodo SAS
*
* This file is part of iTop.
*
* iTop is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* iTop is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
*/
use Combodo\iTop\Application\WebPage\WebPage;
/**
* @since 3.3.0
*/
class WizStepDataAudit extends WizStepInstall
{
const SequencerClass = DataAuditSequencer::class;
public function GetTitle()
{
return 'Checking upgrade';
}
public function GetPossibleSteps()
{
return ['WizStepSummary'];
}
public function GetNextButtonLabel()
{
return 'Next';
}
public function CanMoveForward()
{
if ($this->CheckDependencies()) {
return true;
} else {
return false;
}
}
public function ProcessParams($bMoveForward = true)
{
return ['class' => 'WizStepSummary', 'state' => ''];
}
public function Display(WebPage $oPage)
{
$aInstallParams = $this->BuildConfig();
$this->AddProgressBar($oPage);
$sJSONData = json_encode($aInstallParams);
$oPage->add('<input type="hidden" id="installer_parameters" value="'.utils::EscapeHtml($sJSONData).'"/>');
$sAuthentToken = $this->oWizard->GetParameter('authent', '');
$oPage->add('<input type="hidden" id="authent_token" value="'.$sAuthentToken.'"/>');
if (!$this->CheckDependencies()) {
$oPage->error($this->sDependencyIssue);
}
$oPage->add_ready_script(
<<<JS
$("#wiz_form").data("installation_status", "not started");
ExecuteStep("");
JS
);
}
}

View File

@@ -156,7 +156,7 @@ EOF
$sChecked = ($this->oWizard->GetParameter('upgrade_type') == 'keep-previous') ? ' checked ' : '';
$sDisabled = (count($aErrors) > 0) ? ' disabled ' : '';
$oPage->p('<input id="radio_upgrade_keep" type="radio" name="upgrade_type" value="keep-previous" '.$sChecked.$sDisabled.'/><label for="radio_upgrade_keep">&nbsp;Preserve the modifications of the installed version (the dasboards inside '.ITOP_APPLICATION.' may not be editable).</label>');
$oPage->p('<input id="radio_upgrade_keep" type="radio" name="upgrade_type" value="keep-previous" '.$sChecked.$sDisabled.'/><label for="radio_upgrade_keep">&nbsp;Preserve the modifications of the installed version (the dashboards inside '.ITOP_APPLICATION.' may not be editable).</label>');
$oPage->add('<input type="hidden" name="datamodel_previous_version" value="'.utils::EscapeHtml($sInstalledDataModelVersion).'">');
$oPage->add('<input type="hidden" name="relative_source_dir" value="'.utils::EscapeHtml($sPreviousSourceDir).'">');

View File

@@ -18,25 +18,9 @@
*/
use Combodo\iTop\Application\WebPage\WebPage;
class WizStepBuild extends AbstractWizStepBuild
class WizStepInstall extends AbstractWizStepInstall
{
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;
}
const SequencerClass = ApplicationInstallSequencer::class;
public function GetTitle()
{
@@ -71,11 +55,8 @@ class WizStepBuild extends AbstractWizStepBuild
return ['class' => 'WizStepDone', 'state' => ''];
}
public function Display(WebPage $oPage)
protected function AddProgressBar(WebPage $oPage)
{
$aInstallParams = $this->BuildConfig();
$oPage->add('<fieldset id="installation_progress"><legend>Progress of the installation</legend>');
$oPage->add('<div id="progress_content">');
$oPage->LinkScriptFromAppRoot('setup/jquery.progression.js');
@@ -83,6 +64,14 @@ class WizStepBuild extends AbstractWizStepBuild
$oPage->add('</div>'); // progress_content
$oPage->add('</fieldset>');
}
public function Display(WebPage $oPage)
{
$aInstallParams = $this->BuildConfig();
$this->AddProgressBar($oPage);
$sJSONData = json_encode($aInstallParams);
$oPage->add('<input type="hidden" id="installer_parameters" value="'.utils::EscapeHtml($sJSONData).'"/>');
@@ -102,15 +91,18 @@ JS
}
/**
* @throws \Exception
*/
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 ApplicationBuildSequencer($oParameters);
$oInstaller = new (static::SequencerClass)($oParameters);
$aRes = $oInstaller->ExecuteStep($sStep);
if (($aRes['status'] != ApplicationBuildSequencer::ERROR) && ($aRes['next-step'] != '')) {
if (($aRes['status'] != $oInstaller::ERROR) && ($aRes['next-step'] != '')) {
// Tell the web page to move the progress bar and to launch the next step
$sMessage = addslashes(utils::EscapeHtml($aRes['next-step-label']));
$oPage->add_ready_script(
@@ -124,7 +116,7 @@ JS
ExecuteStep('{$aRes['next-step']}');
EOF
);
} elseif ($aRes['status'] != ApplicationBuildSequencer::ERROR) {
} elseif ($aRes['status'] != $oInstaller::ERROR) {
// Installation complete, move to the next step of the wizard
$oPage->add_ready_script(
<<<EOF

View File

@@ -93,7 +93,7 @@ class WizStepModulesChoice extends WizardStep
public function GetPossibleSteps()
{
return ['WizStepModulesChoice', 'WizStepAudit'];
return ['WizStepModulesChoice', 'WizStepDataAudit'];
}
public function GetAddedAndRemovedExtensions($aSelectedExtensions)
@@ -156,10 +156,10 @@ class WizStepModulesChoice extends WizardStep
$this->oWizard->SetParameter('extensions_not_uninstallable', json_encode(array_keys($aExtensionsNotUninstallable)));
$sMode = $this->oWizard->GetParameter('mode', 'install');
if ($sMode == 'install') {
return ['class' => 'WizStepAudit', 'state' => ''];
return ['class' => 'WizStepSummary', 'state' => ''];
}
else {
return ['class' => 'WizStepAudit', 'state' => ''];
return ['class' => 'WizStepDataAudit', 'state' => ''];
}
}

View File

@@ -21,25 +21,9 @@ use Combodo\iTop\Application\WebPage\WebPage;
/**
* Summary of the installation tasks
*/
class WizStepSummary extends AbstractWizStepBuild
class WizStepSummary extends AbstractWizStepInstall
{
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()
{
@@ -54,7 +38,7 @@ class WizStepSummary extends AbstractWizStepBuild
public function GetPossibleSteps()
{
return ['WizStepBuild'];
return ['WizStepInstall'];
}
/**
@@ -77,7 +61,7 @@ class WizStepSummary extends AbstractWizStepBuild
public function ProcessParams($bMoveForward = true)
{
return ['class' => 'WizStepBuild', 'state' => ''];
return ['class' => 'WizStepInstall', 'state' => ''];
}
public function Display(WebPage $oPage)

View File

@@ -62,6 +62,24 @@ abstract class WizardStep
*/
protected $sCurrentState;
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 __construct(WizardController $oWizard, $sCurrentState)
{
$this->oWizard = $oWizard;