From f8114bce81911ba28a8aa9d97fc82b99c839fa17 Mon Sep 17 00:00:00 2001 From: "lenaick.moreira" Date: Mon, 24 Aug 2026 16:24:21 +0200 Subject: [PATCH] =?UTF-8?q?N=C2=B09134=20-=20Detect=20extension=20with=20n?= =?UTF-8?q?o=20code=20when=20installing=20by=20data=20feature=20removal=20?= =?UTF-8?q?extension?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataFeatureRemovalController.php | 6 ++++-- setup/itopextension.class.inc.php | 3 ++- setup/runtimeenv.class.inc.php | 3 ++- .../Layout/Extension/ExtensionDetails.php | 4 +++- .../setup/RunTimeEnvironmentTest.php | 21 ++++++++++++------- 5 files changed, 25 insertions(+), 12 deletions(-) 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 7be84562ab..977758cada 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 @@ -24,6 +24,7 @@ use ContextTag; use CoreException; use Dict; use Exception; +use iTopExtension; use MetaModel; use MFCompiler; use RunTimeEnvironment; @@ -464,13 +465,14 @@ class DataFeatureRemovalController extends Controller 'extensions_not_uninstallable' => [], ]; foreach ($aAvailableExtensions as $sCode => &$aExtensionData) { + $sCode = $sCode !== '' ? $sCode : iTopExtension::CODE_NO_CODE; if (!isset($aSelectedExtensionsFromUI[$sCode])) { continue; } if ($aExtensionData['installed'] && $aSelectedExtensionsFromUI[$sCode] !== 'on') { $aExtensionData['extra_flags']['selected'] = false; - $sLabel = $aAvailableExtensions[$sCode]['label']; + $sLabel = $aExtensionData['label']; $this->aExtensionsToCheck['to_be_removed'][$sCode] = $sLabel; if (! $this->bForcedUninstallation && $aExtensionData['extra_flags']['uninstallable']) { $this->bForcedUninstallation = true; @@ -480,7 +482,7 @@ class DataFeatureRemovalController extends Controller } } elseif (!$aExtensionData['installed'] && $aSelectedExtensionsFromUI[$sCode] === 'on') { $aExtensionData['extra_flags']['selected'] = true; - $sLabel = $aAvailableExtensions[$sCode]['label']; + $sLabel = $aExtensionData['label']; $this->aExtensionsToCheck['to_be_installed'][$sCode] = $sLabel; } } diff --git a/setup/itopextension.class.inc.php b/setup/itopextension.class.inc.php index 898eb8599d..971db71c49 100644 --- a/setup/itopextension.class.inc.php +++ b/setup/itopextension.class.inc.php @@ -13,6 +13,7 @@ class iTopExtension public const SOURCE_WIZARD = 'datamodels'; public const SOURCE_MANUAL = 'extensions'; public const SOURCE_REMOTE = 'data'; + public const CODE_NO_CODE = 'no_code'; /** * @var string @@ -193,7 +194,7 @@ class iTopExtension public function HasCode(): bool { - return $this->sCode !== ''; + return $this->sCode !== '' && $this->sCode !== self::CODE_NO_CODE; } public function HasLabel(): bool diff --git a/setup/runtimeenv.class.inc.php b/setup/runtimeenv.class.inc.php index fb161a40aa..e6c9ebabea 100644 --- a/setup/runtimeenv.class.inc.php +++ b/setup/runtimeenv.class.inc.php @@ -1330,7 +1330,8 @@ class RunTimeEnvironment $oExtensionsMap->DeclareExtensionAsRemoved($aRemovedExtensionCodes); foreach ($oExtensionsMap->GetAllExtensions() as $oExtension) { - $oExtension->MarkAsChosen(in_array($oExtension->sCode, $aSelectedExtensionCodes)); + $sExtensionCode = $oExtension->sCode !== '' ? $oExtension->sCode : iTopExtension::CODE_NO_CODE; + $oExtension->MarkAsChosen(in_array($sExtensionCode, $aSelectedExtensionCodes)); } // Check that all the extensions have a code diff --git a/sources/Application/UI/Base/Layout/Extension/ExtensionDetails.php b/sources/Application/UI/Base/Layout/Extension/ExtensionDetails.php index ef3578142b..7327b9ae4f 100644 --- a/sources/Application/UI/Base/Layout/Extension/ExtensionDetails.php +++ b/sources/Application/UI/Base/Layout/Extension/ExtensionDetails.php @@ -9,6 +9,7 @@ use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu; use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenuItem\PopoverMenuItemFactory; use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock; use Dict; +use iTopExtension; use JSButtonItem; class ExtensionDetails extends UIContentBlock @@ -179,7 +180,8 @@ class ExtensionDetails extends UIContentBlock protected function InitializeToggler() { - $sName = 'aSelectedExtensions['.$this->GetCode().']'; + $sCode = $this->GetCode() !== '' ? $this->GetCode() : iTopExtension::CODE_NO_CODE; + $sName = 'aSelectedExtensions['.$sCode.']'; $this->oToggler = new Toggler(); $this->oToggler->SetName($sName); $this->oToggler->SetTooltip(Dict::Format('UI:Layout:ExtensionsDetails:TogglerTooltip', $this->GetLabel())); diff --git a/tests/php-unit-tests/unitary-tests/setup/RunTimeEnvironmentTest.php b/tests/php-unit-tests/unitary-tests/setup/RunTimeEnvironmentTest.php index 81301843ba..2088c82416 100644 --- a/tests/php-unit-tests/unitary-tests/setup/RunTimeEnvironmentTest.php +++ b/tests/php-unit-tests/unitary-tests/setup/RunTimeEnvironmentTest.php @@ -2,15 +2,10 @@ namespace Combodo\iTop\Test\UnitTest\Setup; -use Combodo\iTop\DataFeatureRemoval\Service\DataFeatureRemoverExtensionService; use Combodo\iTop\Test\UnitTest\ItopTestCase; -use Config; use CoreException; -use DOMFormatException; -use Exception; use iTopExtensionsMap; use RunTimeEnvironment; -use utils; class RunTimeEnvironmentTest extends ItopTestCase { @@ -20,7 +15,19 @@ class RunTimeEnvironmentTest extends ItopTestCase $this->RequireOnceItopFile('/setup/runtimeenv.class.inc.php'); } - public function testDoCompileCallCheckExtensionsValidity(): void + public function provideDoCompileCallCheckExtensionsValidity(): array + { + $this->RequireOnceItopFile('/approot.inc.php'); + $this->RequireOnceItopFile('/setup/itopextension.class.inc.php'); + + return [ + 'setup call DoCompile with empty string' => [['']], + 'data feature removal call DoCompile with fake code' => [[\iTopExtension::CODE_NO_CODE]], + ]; + } + + /** @dataProvider provideDoCompileCallCheckExtensionsValidity */ + public function testDoCompileCallCheckExtensionsValidity(array $aSelectedExtensionCodes): void { [$sEnvironment, $sExtensionsDirRelative] = $this->CreateFixtureContext('env-missing-label-'); @@ -45,7 +52,7 @@ XML; $this->expectException(CoreException::class); $oExtensionMap->expects($this->once())->method('CheckExtensionsValidity')->willThrowException(new CoreException('')); - $oRuntimeEnvironment->DoCompile([""], [], [], false); + $oRuntimeEnvironment->DoCompile($aSelectedExtensionCodes, aRemovedExtensionCodes: [], aSelectedModules: []); } private function CreateFixtureContext(string $sEnvPrefix): array