N°9567 - Make extension mgt to setup work

N°9567 - Make extension mgt to setup work
This commit is contained in:
odain
2026-05-22 14:36:37 +02:00
parent c156c09be0
commit e7ce3fcf8a
6 changed files with 81 additions and 26 deletions

View File

@@ -26,6 +26,7 @@ use Dict;
use Exception;
use MetaModel;
use MissingDependencyException;
use RunTimeEnvironment;
use SetupUtils;
use utils;
@@ -36,6 +37,7 @@ class DataFeatureRemovalController extends Controller
private array $aCountClassesToCleanup = [];
private array $aAnalysisDataTable = [];
private array $aDeletionExecutionSummary = [];
private ?RuntimeEnvironment $oRuntimeEnvironment = null;
private int $iCount = 0;
private int $iColumnCount = 2;
@@ -92,8 +94,8 @@ class DataFeatureRemovalController extends Controller
// Display changed extensions
$aHiddenInputNames = [
'selected_modules',
'selected_extensions',
'selected_modules',
'display_choices',
'added_extensions',
'removed_extensions',
@@ -109,12 +111,15 @@ class DataFeatureRemovalController extends Controller
$aAddedExtensions = json_decode($aHiddenInputs['added_extensions'], true);
$aRemovedExtensions = json_decode($aHiddenInputs['removed_extensions'], true);
if (count($aRemovedExtensions) == 0) {
if ("[]" === $aHiddenInputs['selected_modules']) {
//it does not come from setup
// we get extensions from 1st screen uiblocks
$this->ReadExtensionsDiff();
$aAddedExtensions = $this->aExtensionsToCheck['to_be_installed'];
$aHiddenInputs['added_extensions'] = utils::HtmlEntities(json_encode($aAddedExtensions));
$aHiddenInputs['added_extensions'] = $this->ConvertIntoSetupFormat($aAddedExtensions);
$aRemovedExtensions = $this->aExtensionsToCheck['to_be_removed'];
$aHiddenInputs['removed_extensions'] = utils::HtmlEntities(json_encode($aRemovedExtensions));
$aHiddenInputs['removed_extensions'] = $this->ConvertIntoSetupFormat($aRemovedExtensions);
}
$aRemoveExtensionCodes = array_keys($aRemovedExtensions);
@@ -143,6 +148,18 @@ class DataFeatureRemovalController extends Controller
return;
}
if ("[]" === $aHiddenInputs['selected_modules']) {
//to make setup redirection work, we need to pass complex data structures to setup wizards (ie extension/module lists)
$oConfig = MetaModel::GetConfig();
$aSelectedExtensions = DataFeatureRemoverExtensionService::GetInstance()->GetExtensionMap()->GetSelectedExtensions($oConfig, $aAddedExtensions, $aRemovedExtensions);
$aHiddenInputs['selected_extensions'] = $this->ConvertIntoSetupFormat($aSelectedExtensions);
$oRunTimeEnvironment = $this->GetRuntimeEnvironment($aRemovedExtensions);
$aSearchDirs = [$oRunTimeEnvironment->GetBuildDir()];
$aSelectedModules = $oRunTimeEnvironment->GetModulesToLoadFromChoices($oConfig, $aSelectedExtensions, $aSearchDirs);
$aHiddenInputs['selected_modules'] = $this->ConvertIntoSetupFormat($aSelectedModules);
}
$sSourceEnv = MetaModel::GetEnvironment();
$oSetupAudit = new SetupAudit($sSourceEnv);
$aGetRemovedClasses = array_keys($oSetupAudit->RunDataAudit());
@@ -166,6 +183,11 @@ class DataFeatureRemovalController extends Controller
$this->DisplayPage($aParams, 'AnalysisResult');
}
private function ConvertIntoSetupFormat(array $aData): string
{
return json_encode($aData);
}
/**
* @param array $aRemovedExtensions
* @param bool $bForceCompilation
@@ -183,16 +205,25 @@ class DataFeatureRemovalController extends Controller
$bIsDirEmpty = count(scandir($sBuildDir)) === 2;
if ($bIsDirEmpty || $bForceCompilation) {
$oRuntimeEnvironment = new DryRemovalRuntimeEnvironment($sSourceEnv, $aRemovedExtensions);
DataFeatureRemovalLog::Debug(
__METHOD__,
null,
['sSourceEnv' => $sSourceEnv, 'sBuildDir' => $sBuildDir, 'bIsDirEmpty' => $bIsDirEmpty, glob("$sBuildDir/*")]
);
$oRuntimeEnvironment->CompileFrom($sSourceEnv);
$this->GetRuntimeEnvironment($aRemovedExtensions)->CompileFrom($sSourceEnv);
}
}
private function GetRuntimeEnvironment(array $aRemovedExtensions): RunTimeEnvironment
{
if (is_null($this->oRuntimeEnvironment)) {
$sSourceEnv = MetaModel::GetEnvironment();
$this->oRuntimeEnvironment = new DryRemovalRuntimeEnvironment($sSourceEnv, $aRemovedExtensions);
}
return $this->oRuntimeEnvironment;
}
private function GetExecutionSummaryTable(): array
{
$sName = 'ExcutionSummary';
@@ -378,13 +409,15 @@ class DataFeatureRemovalController extends Controller
if ($aExtensionData['installed'] && $aSelectedExtensionsFromUI[$sCode] !== 'on') {
$aExtensionData['extra_flags']['selected'] = false;
$this->aExtensionsToCheck['to_be_removed'][$sCode] = $sCode;
$sLabel = $aAvailableExtensions[$sCode]['label'];
$this->aExtensionsToCheck['to_be_removed'][$sCode] = $sLabel;
if (!$aExtensionData['extra_flags']['uninstallable'] || $aExtensionData['extra_flags']['remote']) {
$this->bForcedUninstallation = true;
}
} elseif (!$aExtensionData['installed'] && $aSelectedExtensionsFromUI[$sCode] === 'on') {
$aExtensionData['extra_flags']['selected'] = true;
$this->aExtensionsToCheck['to_be_installed'][$sCode] = $sCode;
$sLabel = $aAvailableExtensions[$sCode]['label'];
$this->aExtensionsToCheck['to_be_installed'][$sCode] = $sLabel;
}
}
return count($this->aExtensionsToCheck['to_be_installed']) + count($this->aExtensionsToCheck['to_be_removed']);

View File

@@ -1,3 +0,0 @@
<?php
echo 'Access denied';

View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<authorization>
<deny users="*" /> <!-- Denies all users -->
</authorization>
</system.web>
</configuration>

View File

@@ -637,6 +637,25 @@ class iTopExtensionsMap
}
}
/**
* Return list of extensions (ie installation choices + added - removed)
* @param string[] $aAddedExtensions
* @param string[] $aRemovedExtensions
* @return string[] :
*/
public function GetSelectedExtensions(Config $oConfig, array $aAddedExtensions, array $aRemovedExtensions): array
{
$aDbChoices = self::GetChoicesFromDatabase($oConfig);
foreach ($aDbChoices as $i => $sChoice) {
if (in_array($sChoice, $aRemovedExtensions)) {
unset($aDbChoices[$i]);
}
}
return array_merge($aDbChoices, $aAddedExtensions);
}
public function GetExtraDirs(): array
{
return $this->aExtraDirs;

View File

@@ -1640,10 +1640,24 @@ class RunTimeEnvironment
$oSourceConfig = new Config(utils::GetConfigFilePath($sSourceEnv));
$aChoices = $this->GetExtensionMap()->GetChoicesFromDatabase($oSourceConfig);
return $this->GetModulesToLoadFromChoices($oSourceConfig, $aChoices, $aSearchDirs);
}
/**
* Return modules based on installation choices+package
* @param \Config $oConfig
* @param array|bool $aChoices
* @param array $aSearchDirs
* @return array|null
* @throws \ModuleInstallationException
*/
public function GetModulesToLoadFromChoices(Config $oConfig, array|bool $aChoices, array $aSearchDirs): ?array
{
if (false === $aChoices) {
return null;
}
$sSourceDir = $oSourceConfig->Get('source_dir');
$sSourceDir = $oConfig->Get('source_dir');
$sInstallFilePath = APPROOT.$sSourceDir.'/installation.xml';
if (! is_file($sInstallFilePath)) {

View File

@@ -53,12 +53,12 @@ class WizStepLandingBeforeAudit extends WizStepModulesChoice
$this->oWizard->SetParameter('db_tls_enabled', $oConfig->Get('db_tls.enabled'));
$this->oWizard->SetParameter('db_tls_ca', $oConfig->Get('db_tls.ca') ?? '');
$this->oWizard->SaveParameter('selected_modules', []);
$this->oWizard->SaveParameter('selected_extensions', []);
$this->oWizard->SaveParameter('display_choices', []);
$this->oWizard->SaveParameter('added_extensions', []);
$this->oWizard->SaveParameter('removed_extensions', []);
$this->oWizard->SaveParameter('extensions_not_uninstallable', []);
$this->oWizard->SaveParameter('selected_modules', '[]');
$this->oWizard->SaveParameter('selected_extensions', '[]');
$this->oWizard->SaveParameter('display_choices', '[]');
$this->oWizard->SaveParameter('added_extensions', '[]');
$this->oWizard->SaveParameter('removed_extensions', '[]');
$this->oWizard->SaveParameter('extensions_not_uninstallable', '[]');
$aWizardSteps = $this->GetWizardSteps();
$this->oWizard->SetWizardSteps($aWizardSteps);