diff --git a/setup/applicationinstaller.class.inc.php b/setup/applicationinstaller.class.inc.php
index eb97d32ca..77963a199 100644
--- a/setup/applicationinstaller.class.inc.php
+++ b/setup/applicationinstaller.class.inc.php
@@ -486,67 +486,74 @@ class ApplicationInstallSequencer extends StepSequencer
SetupUtils::EnterMaintenanceMode($oConfig);
}
}
-
- if (!is_dir($sTargetPath)) {
- if (!mkdir($sTargetPath)) {
- throw new Exception("Failed to create directory '$sTargetPath', please check the rights of the web server");
- } else {
- // adjust the rights if and only if the directory was just created
- // owner:rwx user/group:rx
- chmod($sTargetPath, 0755);
+ try{
+ if (!is_dir($sTargetPath)) {
+ if (!mkdir($sTargetPath)) {
+ throw new Exception("Failed to create directory '$sTargetPath', please check the rights of the web server");
+ } else {
+ // adjust the rights if and only if the directory was just created
+ // owner:rwx user/group:rx
+ chmod($sTargetPath, 0755);
+ }
+ } elseif (substr($sTargetPath, 0, strlen(APPROOT)) == APPROOT) {
+ // If the directory is under the root folder - as expected - let's clean-it before compiling
+ SetupUtils::tidydir($sTargetPath);
}
- } elseif (substr($sTargetPath, 0, strlen(APPROOT)) == APPROOT) {
- // If the directory is under the root folder - as expected - let's clean-it before compiling
- SetupUtils::tidydir($sTargetPath);
- }
- $oExtensionsMap = new iTopExtensionsMap('production', $aDirsToScan);
- $oExtensionsMap->DeclareExtensionAsRemoved($aRemovedExtensionCodes);
+ $oExtensionsMap = new iTopExtensionsMap('production', $aDirsToScan);
+ $oExtensionsMap->DeclareExtensionAsRemoved($aRemovedExtensionCodes);
- $oFactory = new ModelFactory($aDirsToScan);
+ $oFactory = new ModelFactory($aDirsToScan);
- $oDictModule = new MFDictModule('dictionaries', 'iTop Dictionaries', APPROOT.'dictionaries');
- $oFactory->LoadModule($oDictModule);
+ $oDictModule = new MFDictModule('dictionaries', 'iTop Dictionaries', APPROOT.'dictionaries');
+ $oFactory->LoadModule($oDictModule);
- $sDeltaFile = APPROOT.'core/datamodel.core.xml';
- if (file_exists($sDeltaFile)) {
- $oCoreModule = new MFCoreModule('core', 'Core Module', $sDeltaFile);
- $oFactory->LoadModule($oCoreModule);
- }
- $sDeltaFile = APPROOT.'application/datamodel.application.xml';
- if (file_exists($sDeltaFile)) {
- $oApplicationModule = new MFCoreModule('application', 'Application Module', $sDeltaFile);
- $oFactory->LoadModule($oApplicationModule);
- }
-
- $aModules = $oFactory->FindModules();
-
- foreach ($aModules as $oModule) {
- $sModule = $oModule->GetName();
- if (in_array($sModule, $aSelectedModules)) {
- $oFactory->LoadModule($oModule);
+ $sDeltaFile = APPROOT.'core/datamodel.core.xml';
+ if (file_exists($sDeltaFile)) {
+ $oCoreModule = new MFCoreModule('core', 'Core Module', $sDeltaFile);
+ $oFactory->LoadModule($oCoreModule);
}
+ $sDeltaFile = APPROOT.'application/datamodel.application.xml';
+ if (file_exists($sDeltaFile)) {
+ $oApplicationModule = new MFCoreModule('application', 'Application Module', $sDeltaFile);
+ $oFactory->LoadModule($oApplicationModule);
+ }
+
+ $aModules = $oFactory->FindModules();
+
+ foreach ($aModules as $oModule) {
+ $sModule = $oModule->GetName();
+ if (in_array($sModule, $aSelectedModules)) {
+ $oFactory->LoadModule($oModule);
+ }
+ }
+ // Dump the "reference" model, just before loading any actual delta
+ $oFactory->SaveToFile(utils::GetDataPath().'datamodel-'.$sEnvironment.'.xml');
+
+ $sDeltaFile = utils::GetDataPath().$sEnvironment.'.delta.xml';
+ if (file_exists($sDeltaFile)) {
+ $oDelta = new MFDeltaModule($sDeltaFile);
+ $oFactory->LoadModule($oDelta);
+ $oFactory->SaveToFile(utils::GetDataPath().'datamodel-'.$sEnvironment.'-with-delta.xml');
+ }
+
+ $oMFCompiler = new MFCompiler($oFactory, $sEnvironment);
+ $oMFCompiler->Compile($sTargetPath, null, $bUseSymbolicLinks);
+ //$aCompilerLog = $oMFCompiler->GetLog();
+ //SetupLog::Info(implode("\n", $aCompilerLog));
+ SetupLog::Info("Data model successfully compiled to '$sTargetPath'.");
+
+ $sCacheDir = APPROOT.'/data/cache-'.$sEnvironment.'/';
+ SetupUtils::builddir($sCacheDir);
+ SetupUtils::tidydir($sCacheDir);
}
- // Dump the "reference" model, just before loading any actual delta
- $oFactory->SaveToFile(utils::GetDataPath().'datamodel-'.$sEnvironment.'.xml');
-
- $sDeltaFile = utils::GetDataPath().$sEnvironment.'.delta.xml';
- if (file_exists($sDeltaFile)) {
- $oDelta = new MFDeltaModule($sDeltaFile);
- $oFactory->LoadModule($oDelta);
- $oFactory->SaveToFile(utils::GetDataPath().'datamodel-'.$sEnvironment.'-with-delta.xml');
+ catch(Exception $e){
+ if (($sEnvironment == 'production') && !$bIsAlreadyInMaintenanceMode) {
+ SetupUtils::ExitMaintenanceMode();
+ }
+ throw $e;
}
- $oMFCompiler = new MFCompiler($oFactory, $sEnvironment);
- $oMFCompiler->Compile($sTargetPath, null, $bUseSymbolicLinks);
- //$aCompilerLog = $oMFCompiler->GetLog();
- //SetupLog::Info(implode("\n", $aCompilerLog));
- SetupLog::Info("Data model successfully compiled to '$sTargetPath'.");
-
- $sCacheDir = APPROOT.'/data/cache-'.$sEnvironment.'/';
- SetupUtils::builddir($sCacheDir);
- SetupUtils::tidydir($sCacheDir);
-
// Special case to patch a ugly patch in itop-config-mgmt
$sFileToPatch = $sTargetPath.'/itop-config-mgmt-1.0.0/model.itop-config-mgmt.php';
if (file_exists($sFileToPatch)) {
diff --git a/setup/feature_removal/ModelReflectionSerializer.php b/setup/feature_removal/ModelReflectionSerializer.php
index 9091ef3e4..d3de6b9c9 100644
--- a/setup/feature_removal/ModelReflectionSerializer.php
+++ b/setup/feature_removal/ModelReflectionSerializer.php
@@ -46,6 +46,7 @@ class ModelReflectionSerializer
}
$aClasses = json_decode($sOutput[0] ?? null, true);
+file_put_contents('C:/tmp/uninstall.log', "\n\n".var_export($sOutput, true), FILE_APPEND);
if (false === $aClasses) {
$this->LogErrorWithProperLogger("Invalid JSON", null, ['env' => $sEnv, "output" => $sOutput]);
throw new Exception("cannot get classes");
diff --git a/setup/wizardcontroller.class.inc.php b/setup/wizardcontroller.class.inc.php
index 352ec0ea0..2f472e850 100644
--- a/setup/wizardcontroller.class.inc.php
+++ b/setup/wizardcontroller.class.inc.php
@@ -78,7 +78,7 @@ class WizardController
/**
* Pushes information about the current step onto the stack
- * @param hash $aStepInfo Array('class' => , 'state' => )
+ * @param array $aStepInfo Array('class' => , 'state' => )
*/
protected function PushStep($aStepInfo)
{
@@ -172,7 +172,9 @@ class WizardController
/** @var \WizardStep $oStep */
$oStep = new $sCurrentStepClass($this, $sCurrentState);
if ($oStep->ValidateParams()) {
- $this->PushStep(['class' => $sCurrentStepClass, 'state' => $sCurrentState]);
+ if($oStep->CanComeBack()) {
+ $this->PushStep(['class' => $sCurrentStepClass, 'state' => $sCurrentState]);
+ }
$aPossibleSteps = $oStep->GetPossibleSteps();
$aNextStepInfo = $oStep->ProcessParams(true); // true => moving forward
if (in_array($aNextStepInfo['class'], $aPossibleSteps)) {
diff --git a/setup/wizardsteps/WizStepDataAudit.php b/setup/wizardsteps/WizStepDataAudit.php
index 953f2c473..df8527b8b 100644
--- a/setup/wizardsteps/WizStepDataAudit.php
+++ b/setup/wizardsteps/WizStepDataAudit.php
@@ -27,7 +27,7 @@ class WizStepDataAudit extends WizStepInstall
public function GetTitle()
{
- return 'Checking upgrade';
+ return 'Checking compatibility';
}
@@ -56,6 +56,11 @@ class WizStepDataAudit extends WizStepInstall
return ['class' => 'WizStepSummary', 'state' => ''];
}
+ public function CanComeBack()
+ {
+ return false;
+ }
+
public function Display(WebPage $oPage)
{
diff --git a/setup/wizardsteps/WizStepModulesChoice.php b/setup/wizardsteps/WizStepModulesChoice.php
index 4754fde49..d1c03f352 100644
--- a/setup/wizardsteps/WizStepModulesChoice.php
+++ b/setup/wizardsteps/WizStepModulesChoice.php
@@ -814,7 +814,15 @@ EOF
public function GetNextButtonLabel()
{
- return $this->bCanMoveForward ? 'Next' : 'Non-uninstallable extension missing';
+ if (!$this->bCanMoveForward) {
+ return 'Non-uninstallable extension missing';
+ }
+
+ if ($this->GetStepInfo(1 + $this->GetStepIndex()) === null) {
+ return 'Check compatibility';
+ }
+
+ return 'Next';
}
}
diff --git a/setup/wizardsteps/WizStepSummary.php b/setup/wizardsteps/WizStepSummary.php
index 85e38e708..97d830451 100644
--- a/setup/wizardsteps/WizStepSummary.php
+++ b/setup/wizardsteps/WizStepSummary.php
@@ -232,7 +232,6 @@ class WizStepSummary extends AbstractWizStepInstall
$sMessage .= SetupUtils::HumanReadableSize($fFreeSpace).' free in '.dirname($sDBBackupPath);
}
$oPage->add($sMySQLDumpMessage.''.$sMessage.'');
- $oPage->add('');
$sAuthentToken = $this->oWizard->GetParameter('authent', '');
$oPage->add('');
diff --git a/setup/wizardsteps/WizardStep.php b/setup/wizardsteps/WizardStep.php
index 5aaaea37a..4fc6a65e1 100644
--- a/setup/wizardsteps/WizardStep.php
+++ b/setup/wizardsteps/WizardStep.php
@@ -137,6 +137,15 @@ abstract class WizardStep
return true;
}
+ /**
+ * Tells whether the user will come back to this step/state if he click on "Back"
+ * @return boolean True if the 'Back' button should display this step
+ */
+ public function CanComeBack()
+ {
+ return true;
+ }
+
/**
* Tells whether the "Next" button should be enabled interactively
* @return string A piece of javascript code returning either true or false