Skip to content

N°9144 Add data audit setup step#801

Merged
Timmy38 merged 25 commits intofeature/uninstallationfrom
feature/9144_split_setup
Feb 19, 2026
Merged

N°9144 Add data audit setup step#801
Timmy38 merged 25 commits intofeature/uninstallationfrom
feature/9144_split_setup

Conversation

@Timmy38
Copy link
Contributor

@Timmy38 Timmy38 commented Feb 12, 2026

No description provided.

@Timmy38 Timmy38 self-assigned this Feb 12, 2026
@CombodoApplicationsAccount CombodoApplicationsAccount added the internal Work made by Combodo label Feb 12, 2026
@Molkobain Molkobain requested a review from Copilot February 12, 2026 17:26
@Molkobain Molkobain added this to the 3.3.0 milestone Feb 12, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the setup wizard into dedicated step classes and adds a new “data audit / compatibility check” step during upgrade, backed by a new step-based installation/audit sequencer.

Changes:

  • Split wizard step logic into individual setup/wizardsteps/* classes and update WizardController to use them (UpdateWizardStateAndGetNextStep).
  • Add a new upgrade-only wizard step (WizStepDataAudit) that runs a dry-run compilation + audit via DataAuditSequencer.
  • Introduce StepSequencer + ApplicationInstallSequencer infrastructure and update unattended install to use it.

Reviewed changes

Copilot reviewed 33 out of 35 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
setup/wizardsteps/WizardStep.php New base class for wizard steps (+ dependency checking helper).
setup/wizardsteps/WizStepWelcome.php New welcome step implementation.
setup/wizardsteps/WizStepInstallOrUpgrade.php New install/upgrade selection step implementation.
setup/wizardsteps/WizStepDetectedInfo.php New upgrade-detection step (chooses license vs misc params).
setup/wizardsteps/WizStepLicense.php New license step (incl. GDPR consent gating).
setup/wizardsteps/WizStepLicense2.php Upgrade-specific license step.
setup/wizardsteps/WizStepDBParams.php New DB params step implementation.
setup/wizardsteps/WizStepAdminAccount.php New admin account step implementation.
setup/wizardsteps/AbstractWizStepMiscParams.php Shared misc params helpers (symlink + force-uninstall flags).
setup/wizardsteps/WizStepInstallMiscParams.php New install misc params step (URL/graphviz/sample data).
setup/wizardsteps/WizStepUpgradeMiscParams.php New upgrade misc params step (URL/graphviz + force-uninstall).
setup/wizardsteps/WizStepModulesChoice.php Module/extension selection step; routes to DataAudit on upgrade.
setup/wizardsteps/WizStepDataAudit.php New compatibility check step (runs audit sequencer before Summary).
setup/wizardsteps/WizStepSummary.php New summary step (now also includes backup option on upgrade).
setup/wizardsteps/WizStepInstall.php Install/upgrade execution step using sequencer + progress UI.
setup/wizardsteps/WizStepDone.php Final step (backup download + hub iframe + enter iTop button).
setup/wizardcontroller.class.inc.php Loads new step files, switches to UpdateWizardStateAndGetNextStep, and respects CanComeBack().
setup/wizard.php Removes legacy wizardsteps.class.inc.php include.
setup/ajax.dataloader.php Removes legacy wizardsteps.class.inc.php include (relies on controller includes).
setup/unattended-install/unattended-install.php Uses ApplicationInstallSequencer for unattended installs.
setup/unattended-install/InstallationFileService.php Removes legacy wizardsteps.class.inc.php include.
setup/setup.js Minor formatting changes to button update logic.
setup/sequencers/StepSequencer.php New base sequencer with ExecuteAllSteps() loop.
setup/sequencers/ApplicationInstallSequencer.php New main install/upgrade sequencer (split out of old installer).
setup/sequencers/DataAuditSequencer.php New dry-run compile + audit + cleanup sequencer for compatibility checks.
setup/applicationinstaller.class.inc.php Reduced to compatibility wrapper (class_alias) pointing to sequencer.
setup/SetupDBBackup.php Moves SetupDBBackup out of old installer into its own file.
setup/runtimeenv.class.inc.php Minor formatting fix.
setup/feature_removal/get_model_reflection.php Disables MetaModel cache in reflection script.
setup/feature_removal/SetupAudit.php Forces model reflection loading for both envs.
setup/feature_removal/ModelReflectionSerializer.php Adjusts command invocation + error message.
css/setup.scss Makes installation progress visible (removes forced display:none).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 36 to 46
IssueLog::Info(__METHOD__, null, ['env' => $sEnv]);
$sPHPExec = trim(utils::GetConfig()->Get('php_path'));
$sOutput = "";
$iRes = 0;

exec(sprintf("$sPHPExec %s/get_model_reflection.php --env='%s'", __DIR__, $sEnv), $sOutput, $iRes);
$sCommandLine = sprintf("$sPHPExec %s/get_model_reflection.php --env=%s", __DIR__, $sEnv);
exec($sCommandLine, $sOutput, $iRes);
if ($iRes != 0) {
$this->LogErrorWithProperLogger("Cannot get classes", null, ['env' => $sEnv, 'code' => $iRes, "output" => $sOutput]);
throw new CoreException("Cannot get classes");
throw new CoreException("Cannot get classes from env ".$sEnv);
}
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetModelFromEnvironment() builds a shell command using $sPHPExec (from config) and $sEnv without shell escaping, then executes it via exec(). This is vulnerable to command injection if either value contains spaces or shell metacharacters. Build the command using escapeshellcmd() / escapeshellarg() (or better, bypass the shell entirely) before calling exec().

Copilot uses AI. Check for mistakes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Timmy38 not sure, but this could actually be a solution to the issue you had with quotes on Linux vs Windows.

Comment on lines +393 to +397
}

if (isset($aChoice['sub_options'])) {
$aScores[$sChoiceId] = array_merge($aScores[$sChoiceId], $this->GuessDefaultsFromModules($aChoice['sub_options'], $aDefaults, $sChoiceId));
}
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In GuessDefaultsFromModules(), the recursive call for sub_options passes $sChoiceId as the $aModules argument (GuessDefaultsFromModules(..., $sChoiceId)). This will break module lookup ($aModules[$sModuleId]...) and can cause runtime errors when a choice has sub_options. Pass the $aModules array and $sChoiceId as the parent id instead.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@Hipska Hipska left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering what exactly get's audited, it's not clear by reading the code.

I was also wondering if these audits are extendible by means of extensions.

Also, some suggestions that can picked up while doing this refactoring of wizard steps.


use Combodo\iTop\Setup\FeatureRemoval\SetupAudit;

class DataAuditSequencer extends ApplicationInstallSequencer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overall remark. you add 2 sequencer. why not adding tests to make sure setup automata is what was designed. and to help the team see the sequence easily?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we could test the setup sequence without executing all complex steps(mocking). it could nice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A new StepSequencerTest class has been added and uses mock versions of both sequencers

* @param bool $bMoveForward True if the wizard is moving forward 'Next >>' button pressed, false otherwise
* @return hash array('class' => $sNextClass, 'state' => $sNextState)
*/
abstract public function UpdateWizardStateAndGetNextStep($bMoveForward = true);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return an array is ok. an object would be nicer here. to type the 2 elements. WizardState for ex.

$aNextStepInfo = $oStep->ProcessParams(true); // true => moving forward
$aNextStepInfo = $oStep->UpdateWizardStateAndGetNextStep(true); // true => moving forward
if (in_array($aNextStepInfo['class'], $aPossibleSteps)) {
$oNextStep = new $aNextStepInfo['class']($this, $aNextStepInfo['state']);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it could be nice to check the type of 'class' value before instanciation. also adding type.

Copy link
Contributor Author

@Timmy38 Timmy38 Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A new method GetWizardStep check that the next step is a subclass of WizardStep

if ($oStep->CanComeBack()) {
$this->PushStep(['class' => $sCurrentStepClass, 'state' => $sCurrentState]);
}
$aPossibleSteps = $oStep->GetPossibleSteps();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetPossibleSteps seems useless to me. unless we keep it to test setup automata and use DumpXXX somewhere.

@@ -169,7 +195,7 @@ protected function Back()
$sCurrentStepClass = utils::ReadParam('_class', $this->sInitialStepClass);
$sCurrentState = utils::ReadParam('_state', $this->sInitialState);
$oStep = new $sCurrentStepClass($this, $sCurrentState);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it could be nice to check the type before instanciation. also adding type afterwhile (@var XXX varname).

Copy link
Contributor Author

@Timmy38 Timmy38 Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above about GetWizardStep (with typing)

Copy link
Contributor

@odain-cbd odain-cbd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lot of changes in setup wizard. but no test coverage of the controller/automata to make sure we are ok with sequence(s). it would be nice to add some test(s) and help the team figure out the sequence.
test would garantee the result and reduce end 2 end validation from a browser...

@Timmy38 Timmy38 merged commit c4d7c89 into feature/uninstallation Feb 19, 2026
@Timmy38 Timmy38 deleted the feature/9144_split_setup branch February 19, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal Work made by Combodo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants