diff --git a/datamodels/2.x/combodo-data-feature-removal/src/Controller/DataFeatureRemovalController.php b/datamodels/2.x/combodo-data-feature-removal/src/Controller/DataFeatureRemovalController.php index 5d35f4ced..185fdbe97 100644 --- a/datamodels/2.x/combodo-data-feature-removal/src/Controller/DataFeatureRemovalController.php +++ b/datamodels/2.x/combodo-data-feature-removal/src/Controller/DataFeatureRemovalController.php @@ -361,12 +361,8 @@ class DataFeatureRemovalController extends Controller foreach ($aExtensionsRef as $oExtension) { /** @var \iTopExtension $oExtension */ $aMetaData = [$oExtension->sVersion, $oExtension->GetExtensionSourceLabel()]; - if (SetupUtils::IsIncludedInBasePackage( - $oExtensionMap, - $oExtension->sCode, - $aBasePackageModules - )) { - $aMetaData[] = 'Included in package'; + if (SetupUtils::IsIncludedInPackage($oExtensionMap->GetFromExtensionCode($oExtension->sCode), $aBasePackageModules)) { + $aMetaData[] = 'Already in package'; } $aExtensionsData[$oExtension->sCode] = [ @@ -398,8 +394,10 @@ class DataFeatureRemovalController extends Controller try { $oRuntimeEnvironment = new RunTimeEnvironment(MetaModel::GetEnvironment(), false); - $aAvailableModules = $oRuntimeEnvironment->AnalyzeInstallation(MetaModel::GetConfig(), [APPROOT], false, null); + $aAvailableModules = $oRuntimeEnvironment->AnalyzeInstallation(MetaModel::GetConfig(), [APPROOT]); $this->aBasePackageModules = SetupUtils::GetBasePackageModules($aAvailableModules, APPROOT.'datamodels'); + + echo implode(',
', $this->aBasePackageModules); } catch (Exception $e) { DataFeatureRemovalLog::Warning(__METHOD__, null, ['error' => $e->getMessage()]); $this->aBasePackageModules = []; diff --git a/setup/setuputils.class.inc.php b/setup/setuputils.class.inc.php index d08da17d4..ea0138b66 100644 --- a/setup/setuputils.class.inc.php +++ b/setup/setuputils.class.inc.php @@ -1708,9 +1708,9 @@ JS } /** - * Build a map of modules that belong to the package base scope. + * Build a map of module IDs that belong to the package base scope. * - * @param array $aAnalyzeInstallationModules Output from AnalyzeInstallation-like methods + * @param array $aAnalyzeInstallationModules Output from AnalyzeInstallation method * @param string $sSourceDir Base directory used as package scope * * @return array @@ -1745,13 +1745,8 @@ JS /** * Returns true when all modules of a non-package extension are already included in base package modules. */ - public static function IsIncludedInBasePackage(iTopExtensionsMap $oExtensionsMap, string $sExtensionCode, array $aBasePackageModules): bool + public static function IsIncludedInPackage(?iTopExtension $oExtension, array $aBasePackageModules): bool { - if ($sExtensionCode === '') { - return false; - } - - $oExtension = $oExtensionsMap->GetFromExtensionCode($sExtensionCode); if (($oExtension === null) || ($oExtension->sSource === iTopExtension::SOURCE_WIZARD)) { return false; } diff --git a/setup/wizardsteps/WizStepModulesChoice.php b/setup/wizardsteps/WizStepModulesChoice.php index 8e401d1ad..4aecef0c3 100644 --- a/setup/wizardsteps/WizStepModulesChoice.php +++ b/setup/wizardsteps/WizStepModulesChoice.php @@ -168,6 +168,33 @@ class WizStepModulesChoice extends AbstractWizStepInstall return new WizardState(WizStepModulesChoice::class, (string)($index - 1)); } + + public function GetAllSelectedModulesUntilNow(): array + { + $aModules = []; + $aSelectedChoices = json_decode($this->oWizard->GetParameter('selected_components', '{}'), true); + $iNextStep = $this->GetStepIndex(); + $index = $iNextStep; + while(isset($aSelectedChoices[$iNextStep])){ + //Let's empty the next steps, we only want what has been chosen before + $aSelectedChoices[$iNextStep] = []; + $iNextStep++; + } + + for ($i = 0; $i < $index; $i++) { + $aStepInfo = $this->GetStepInfo($i); + $this->GetSelectedModules($aStepInfo, $aSelectedChoices[$i], $aModules ); + } + + /* + echo "===GetAllSelectedModulesUntilNow : ===
"; + echo implode(',
',array_keys($aModules)); + echo "
=======

"; + */ + + return $aModules; + } + public function GetWizardSteps(): array { $aSteps = [ @@ -571,6 +598,7 @@ EOF foreach ($this->aAnalyzeInstallationModules as $sModuleId => $aModule) { if (($sModuleId != ROOT_MODULE) && !isset($aModules[$sModuleId])) { if (($aModule['category'] == 'authentication') || (!$aModule['visible'] && !isset($aModule['auto_select']))) { + //echo "Set module ".$sModuleId." to selected1
"; $aModules[$sModuleId] = true; $sDisplayChoices .= '
  • '.$aModule['label'].' (hidden)
  • '; } @@ -613,6 +641,7 @@ EOF } } if ($bSelected) { + //echo "Set module ".$sModuleId." to selected 2
    "; $aModules[$sModuleId] = true; // store the Id of the selected module SetupInfo::SetSelectedModules($aModules); } @@ -743,8 +772,22 @@ EOF return $this->aSteps[$index] ?? null; } - public function ComputeChoiceFlags(array $aChoice, string $sChoiceId, array $aSelectedComponents, bool $bAllDisabled, bool $bDisableUninstallCheck, bool $bUpgradeMode) + public function ExtensionIsAlreadyIncludedInPreviousChoices(?iTopExtension $oITopExtension): bool { + if(is_null($oITopExtension) || empty($oITopExtension->aModules)){ + return false; + } + $aAllPreviousChoicesModules = $this->GetAllSelectedModulesUntilNow(); + + foreach($oITopExtension->aModules as $sModuleId) { + if (!isset($aAllPreviousChoicesModules[$sModuleId])) { + return false; + } + } + return true; + } + + public function ComputeChoiceFlags(array $aChoice, string $sChoiceId, array $aSelectedComponents, bool $bAllDisabled, bool $bDisableUninstallCheck, bool $bUpgradeMode) { $oITopExtension = $this->oExtensionsMap->GetFromExtensionCode($aChoice['extension_code']); //If the extension is missing from disk, it won't exist in the ExtensionsMap, thus returning null $bCanBeUninstalled = isset($aChoice['uninstallable']) ? $aChoice['uninstallable'] === true || $aChoice['uninstallable'] === 'yes' : $oITopExtension->CanBeUninstalled(); @@ -753,14 +796,17 @@ EOF $bMandatory = (isset($aChoice['mandatory']) && $aChoice['mandatory']); $bInstalled = $bMissingFromDisk || $oITopExtension?->bInstalled ?? false; $bDependencyIssue = $oITopExtension?->HasDependencyIssue() ?? false; - file_put_contents('C:/tmp/compute_choice_flags.log', "mandatory for ".$aChoice['extension_code']."=".(int)$bMandatory."\n", FILE_APPEND); + $bAlreadyIncluded = $this->ExtensionIsAlreadyIncludedInPreviousChoices($oITopExtension); $bChecked = $bSelected; $bDisabled = false; if ($bMissingFromDisk) { $bDisabled = true; $bChecked = false; - } elseif ($bMandatory) { + }elseif($bAlreadyIncluded){ + $bDisabled = true; + $bChecked = true; + }elseif ($bMandatory) { $bDisabled = true; $bChecked = true; } elseif ($bDependencyIssue) { @@ -792,6 +838,7 @@ EOF return [ 'uninstallable' => $bCanBeUninstalled, + 'already_included' => $bAlreadyIncluded, 'dependency_issue' => $bDependencyIssue, 'mandatory' => $bMandatory, 'missing' => $bMissingFromDisk, @@ -870,7 +917,7 @@ EOF ' : ''; - $sDescription = isset($aChoice['description']) ? utils::EscapeHtml($aChoice['description']) : ''; + $sDescription = isset($aChoice['description']) ? trim(utils::EscapeHtml($aChoice['description'])) : ''; $sId = utils::EscapeHtml($aChoice['extension_code']); $sDataId = 'data-id="'.utils::EscapeHtml($aChoice['extension_code']).'"'; $sDisabled = $aFlags['disabled'] ? ' disabled data-disabled="disabled"' : ''; @@ -895,20 +942,18 @@ EOF if ($aFlags['dependency_issue']) { $sTooltip .= '
    cannot be installed
    '; } + if ($aFlags['already_included']) { + if(mb_strlen($sDescription) > 0){ + $sDescription .= '
    '; + } + $sDescription .= 'All the modules included in this extension are also included in the package. To uninstall this extension, you have to delete its folder.'; + } $sMetadata = ''; if (isset($aChoice['version']) && isset($aChoice['source_label'])) { $sMetadata = 'v'.$aChoice['version'].''.$aChoice['source_label'].''; - if ($this->aBasePackageModules === null) { - $this->aBasePackageModules = SetupUtils::GetBasePackageModules( - $this->aAnalyzeInstallationModules, - $this->oWizard->GetParameter('source_dir', '') - ); - } - if (SetupUtils::IsIncludedInBasePackage($this->oExtensionsMap, $aChoice['extension_code'] ?? '', $this->aBasePackageModules)) { - $sMetadata .= 'Included in package'; - } } + $sChoiceDisabled = $aFlags['disabled'] && !$aFlags['checked'] ? 'choice-disabled' : ''; $oPage->add(' diff --git a/tests/php-unit-tests/unitary-tests/setup/WizStepModulesChoiceTest.php b/tests/php-unit-tests/unitary-tests/setup/WizStepModulesChoiceTest.php index c3a2084da..0c9cc84a4 100644 --- a/tests/php-unit-tests/unitary-tests/setup/WizStepModulesChoiceTest.php +++ b/tests/php-unit-tests/unitary-tests/setup/WizStepModulesChoiceTest.php @@ -49,6 +49,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => false, 'disabled' => false, 'checked' => false, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => false, ], @@ -72,6 +73,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => false, 'disabled' => false, 'checked' => true, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => false, ], @@ -93,6 +95,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => true, 'disabled' => true, 'checked' => false, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => false, ], @@ -114,6 +117,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => true, 'disabled' => true, 'checked' => false, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => true, ], @@ -135,6 +139,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => true, 'disabled' => true, 'checked' => false, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => true, ], @@ -158,6 +163,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => true, 'disabled' => false, 'checked' => false, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => false, ], @@ -181,6 +187,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => true, 'disabled' => true, 'checked' => true, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => false, ], @@ -204,6 +211,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => true, 'disabled' => false, 'checked' => true, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => false, ], @@ -227,6 +235,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => false, 'disabled' => true, 'checked' => true, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => true, ], @@ -250,6 +259,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => false, 'disabled' => true, 'checked' => true, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => true, ], @@ -285,6 +295,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => false, 'disabled' => false, 'checked' => false, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => false, ], @@ -320,6 +331,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => false, 'disabled' => true, 'checked' => true, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => false, ], @@ -355,6 +367,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => true, 'disabled' => true, 'checked' => true, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => false, ], @@ -390,6 +403,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => true, 'disabled' => false, 'checked' => false, + 'already_included' => false, 'dependency_issue' => false, 'mandatory' => false, ], @@ -417,6 +431,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => false, 'disabled' => true, 'checked' => false, + 'already_included' => false, 'dependency_issue' => true, 'mandatory' => false, ], @@ -444,6 +459,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => true, 'disabled' => true, 'checked' => false, + 'already_included' => false, 'dependency_issue' => true, 'mandatory' => false, ], @@ -471,6 +487,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => false, 'disabled' => false, 'checked' => false, + 'already_included' => false, 'dependency_issue' => true, 'mandatory' => false, ], @@ -498,6 +515,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => true, 'disabled' => false, 'checked' => false, + 'already_included' => false, 'dependency_issue' => true, 'mandatory' => false, ], @@ -525,6 +543,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => true, 'disabled' => true, 'checked' => true, + 'already_included' => false, 'dependency_issue' => true, 'mandatory' => true, ], @@ -552,6 +571,7 @@ class WizStepModulesChoiceTest extends ItopTestCase 'installed' => false, 'disabled' => true, 'checked' => true, + 'already_included' => false, 'dependency_issue' => true, 'mandatory' => true, ],