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 f7f32be0c8..8df5baec9f 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 @@ -13,6 +13,7 @@ require_once APPROOT.'setup/feature_removal/DryRemovalRuntimeEnvironment.php'; use Combodo\iTop\Application\TwigBase\Controller\Controller; use Combodo\iTop\DataFeatureRemoval\Helper\DataFeatureRemovalException; use Combodo\iTop\DataFeatureRemoval\Helper\DataFeatureRemovalHelper; +use Combodo\iTop\DataFeatureRemoval\Helper\DataFeatureRemovalLog; use Combodo\iTop\DataFeatureRemoval\Service\DataCleanupService; use Combodo\iTop\DataFeatureRemoval\Service\DataFeatureRemoverExtensionService; use Combodo\iTop\Setup\FeatureRemoval\DryRemovalRuntimeEnvironment; @@ -26,9 +27,11 @@ use utils; class DataFeatureRemovalController extends Controller { - private array $aSelectedExtensionsForCheck = []; + private array $aRemovedExtensionsForCheck = []; private array $aCountClassesToCleanup = []; private array $aAnalysisDataTable = []; + private array $aDeletionExecutionSummary = []; + private int $iCount = 0; public function OperationMain($sErrorMessage = null): void @@ -75,7 +78,7 @@ class DataFeatureRemovalController extends Controller $this->m_sOperation = 'Main'; try { - if (count($this->aSelectedExtensionsForCheck) > 0) { + if (count($this->aRemovedExtensionsForCheck) > 0) { $this->Analyze(); } $this->OperationMain(); @@ -87,10 +90,8 @@ class DataFeatureRemovalController extends Controller private function Analyze(): void { + $this->Compile($this->aRemovedExtensionsForCheck); $sSourceEnv = MetaModel::GetEnvironment(); - $oDryRemovalRuntimeEnvironment = new DryRemovalRuntimeEnvironment($sSourceEnv, $this->aSelectedExtensionsForCheck); - $oDryRemovalRuntimeEnvironment->CompileFrom($sSourceEnv); - $oSetupAudit = new SetupAudit($sSourceEnv); $aGetRemovedClasses = $oSetupAudit->RunDataAudit(); IssueLog::Debug(__METHOD__, null, ['aGetRemovedClasses' => $aGetRemovedClasses]); @@ -115,14 +116,78 @@ class DataFeatureRemovalController extends Controller IssueLog::Info(__METHOD__.' Extensions given in parameter', null, ['aAddedExtensions' => $aAddedExtensions, 'aRemovedExtensions' => $aRemovedExtensions]); + $this->Compile(array_keys($aRemovedExtensions), false); + $sSourceEnv = MetaModel::GetEnvironment(); $oSetupAudit = new SetupAudit($sSourceEnv); $aGetRemovedClasses = array_keys($oSetupAudit->RunDataAudit()); IssueLog::Debug(__METHOD__, null, ['aGetRemovedClasses' => $aGetRemovedClasses]); + $aParams['sTransactionId'] = utils::GetNewTransactionId(); + $aParams['aClasses'] = $aGetRemovedClasses; + + [$aParams['aDeletionPlanSummary'], $aParams['iQueryCount'], $aParams['bDeletionPossible']] = $this->GetDeletionPlanSummaryTable($aGetRemovedClasses); + [$aParams['aDeletionExecutionSummary'], $aParams['bHasDeletionExecution']] = $this->GetExecutionSummaryTable(); + + $aParams['aAddedExtensions'] = $aAddedExtensions; + $aParams['aRemovedExtensions'] = $aRemovedExtensions; + $aParams['aExtensions'] = $this->GetExtensionsTableDiff($aAddedExtensions, $aRemovedExtensions); + + $this->DisplayPage($aParams, 'AnalysisResult'); + } + + private function Compile(array $aRemovedExtensions, bool $bForceCompilation = true): void + { + $sSourceEnv = MetaModel::GetEnvironment(); + $sBuildDir = APPROOT."/env-$sSourceEnv-build"; + $bIsDirEmpty = count(scandir($sBuildDir)) === 2; + + if ($bIsDirEmpty || $bForceCompilation) { + $oRuntimeEnvironment = new DryRemovalRuntimeEnvironment($sSourceEnv, $aRemovedExtensions); + DataFeatureRemovalLog::Info( + __METHOD__, + null, + ['sSourceEnv' => $sSourceEnv, 'sBuildDir' => $sBuildDir, 'bIsDirEmpty' => $bIsDirEmpty, glob("$sBuildDir/*")] + ); + $oRuntimeEnvironment->CompileFrom($sSourceEnv); + } + } + + private function GetExecutionSummaryTable(): array + { + $sName = 'ExcutionSummary'; + + $aTableData = []; + if (count($this->aDeletionExecutionSummary) === 0) { + return [$aTableData, false]; + } + + $aColumns = ['Class', 'Total Deleted Count' , 'Total Updated Count', 'Deleted Count' , 'Updated Count']; + $aRows = []; + foreach ($this->aDeletionExecutionSummary as $sClass => $oDeletionPlanSummaryEntity) { + $aRows[] = [ + $sClass, + $oDeletionPlanSummaryEntity->iTotalDeletedCount, + $oDeletionPlanSummaryEntity->iTotalUpdatedCount, + $oDeletionPlanSummaryEntity->iDeletedCount, + $oDeletionPlanSummaryEntity->iUpdatedCount, + ]; + } + + $aTableData = $this->GetTableData($sName, $aColumns, $aRows); + + $bHasDeletionExecution = count($this->aDeletionExecutionSummary) === 0; + + return [$aTableData, $bHasDeletionExecution]; + + } + + private function GetDeletionPlanSummaryTable(array $aRemovedClasses): array + { + $sName = 'DeletionPlanSummary'; $oDataCleanupService = new DataCleanupService(); - $aDeletionPlanSummaryEntities = $oDataCleanupService->GetCleanupSummary($aGetRemovedClasses); - $aColumns = ['Class', 'DeleteCount' , 'UpdateCount', 'IssueCount']; + $aDeletionPlanSummaryEntities = $oDataCleanupService->GetCleanupSummary($aRemovedClasses); + $aColumns = ['Class', 'Delete Count' , 'Update Count', 'Issue Count']; $aRows = []; $iQueryCount = 0; $bHasIssues = false; @@ -137,17 +202,7 @@ class DataFeatureRemovalController extends Controller $iQueryCount += $oDeletionPlanSummaryEntity->iDeleteCount; $iQueryCount += $oDeletionPlanSummaryEntity->iUpdateCount; } - - $aParams['sTransactionId'] = utils::GetNewTransactionId(); - $aParams['aDeletionPlanSummary'] = $this->GetTableData('Extensions', $aColumns, $aRows); - $aParams['aClasses'] = $aGetRemovedClasses; - $aParams['iQueryCount'] = $iQueryCount; - $aParams['bDeletionPossible'] = !$bHasIssues; - $aParams['aAddedExtensions'] = $aAddedExtensions; - $aParams['aRemovedExtensions'] = $aRemovedExtensions; - $aParams['aExtensions'] = $this->GetExtensionsTableDiff($aAddedExtensions, $aRemovedExtensions); - - $this->DisplayPage($aParams); + return [$this->GetTableData($sName, $aColumns, $aRows), $iQueryCount, !$bHasIssues]; } public function OperationDeletionPlan(): void @@ -186,27 +241,28 @@ class DataFeatureRemovalController extends Controller public function OperationDoDeletion(): void { - $aParams = []; $this->ValidateTransactionId(); $aClasses = utils::ReadPostedParam('classes', null, utils::ENUM_SANITIZATION_FILTER_CLASS); $oDataCleanupService = new DataCleanupService(); $aDeletionExecutionSummary = $oDataCleanupService->ExecuteCleanup($aClasses); - $aColumns = ['Class', 'DeletedCount' , 'UpdatedCount']; - $aRows = []; + foreach ($aDeletionExecutionSummary as $oDeletionExecutionSummaryEntity) { - $aRows[] = [ - $oDeletionExecutionSummaryEntity->sClass, - $oDeletionExecutionSummaryEntity->iDeleteCount, - $oDeletionExecutionSummaryEntity->iUpdateCount, - ]; + if (isset($this->aDeletionExecutionSummary[$oDeletionExecutionSummaryEntity->sClass])) { + /** @var \Combodo\iTop\DataFeatureRemoval\Entity\DataCleanupSummaryEntity $oTotal */ + $oTotal = $this->aDeletionExecutionSummary[$oDeletionExecutionSummaryEntity->sClass]; + $oTotal->iTotalUpdateCount += $oDeletionExecutionSummaryEntity->iUpdateCount; + $oTotal->iTotalDeleteCount += $oDeletionExecutionSummaryEntity->iDeleteCount; + $oTotal->iUpdateCount = $oDeletionExecutionSummaryEntity->iUpdateCount; + $oTotal->iDeleteCount = $oDeletionExecutionSummaryEntity->iDeleteCount; + } else { + $oTotal = $oDeletionExecutionSummaryEntity; + } + $this->aDeletionExecutionSummary[$oDeletionExecutionSummaryEntity->sClass] = $oTotal; } - $aParams['sTransactionId'] = utils::GetNewTransactionId(); - $aParams['aDeletionExecutionSummary'] = $this->GetTableData('Extensions', $aColumns, $aRows); - - $this->DisplayPage($aParams); + $this->OperationAnalysisResult(); } private function GetExtensionsTableDiff(array $aAddedExtensions, array $aRemovedExtensions): array @@ -256,7 +312,7 @@ HTML, if ($oExtension->bRemovedFromDisk) { $sDisabledHtml = 'disabled=""'; $sChecked = 'checked'; - } elseif (in_array($sCode, $this->aSelectedExtensionsForCheck)) { + } elseif (in_array($sCode, $this->aRemovedExtensionsForCheck)) { $sChecked = 'checked'; } @@ -322,7 +378,7 @@ HTML, */ public function ReadRemovedExtensions(): void { - if (count($this->aSelectedExtensionsForCheck) > 0) { + if (count($this->aRemovedExtensionsForCheck) > 0) { return; } @@ -330,14 +386,14 @@ HTML, foreach ($aSelectedExtensionsFromUI as $sCode => $aData) { $sValue = $aData['enable'] ?? 'off'; if (($sValue) === 'on') { - $this->aSelectedExtensionsForCheck[] = $sCode; + $this->aRemovedExtensionsForCheck[] = $sCode; } } // Add source removed to check foreach (DataFeatureRemoverExtensionService::GetInstance()->ReadItopExtensions() as $sCode => $oExtension) { if ($oExtension->bRemovedFromDisk) { - $this->aSelectedExtensionsForCheck[] = $sCode; + $this->aRemovedExtensionsForCheck[] = $sCode; } } } diff --git a/datamodels/2.x/combodo-data-feature-removal/src/Entity/DataCleanupSummaryEntity.php b/datamodels/2.x/combodo-data-feature-removal/src/Entity/DataCleanupSummaryEntity.php index 2bfe87f783..c227fdeea9 100644 --- a/datamodels/2.x/combodo-data-feature-removal/src/Entity/DataCleanupSummaryEntity.php +++ b/datamodels/2.x/combodo-data-feature-removal/src/Entity/DataCleanupSummaryEntity.php @@ -8,6 +8,8 @@ class DataCleanupSummaryEntity public int $iIssueCount = 0; public int $iUpdateCount = 0; public int $iDeleteCount = 0; + public int $iTotalUpdateCount = 0; + public int $iTotalDeleteCount = 0; /** * @param string $sClass diff --git a/datamodels/2.x/combodo-data-feature-removal/src/Service/ObjectServiceSummary.php b/datamodels/2.x/combodo-data-feature-removal/src/Service/ObjectServiceSummary.php index 73c428f296..27635136fc 100644 --- a/datamodels/2.x/combodo-data-feature-removal/src/Service/ObjectServiceSummary.php +++ b/datamodels/2.x/combodo-data-feature-removal/src/Service/ObjectServiceSummary.php @@ -23,7 +23,7 @@ class ObjectServiceSummary implements iObjectService public function Update(DBObject $oToUpdate, string $sAttCode, $value): void { $sClass = get_class($oToUpdate); - DataFeatureRemovalLog::Info('Object to update', null, ['class' => $sClass, 'id' => $oToUpdate->GetKey(), 'code' => $sAttCode, 'value' => "$value"]); + DataFeatureRemovalLog::Debug('Object to update', null, ['class' => $sClass, 'id' => $oToUpdate->GetKey(), 'code' => $sAttCode, 'value' => "$value"]); if (! array_key_exists($sClass, $this->aSummary)) { $this->aSummary[$sClass] = new DataCleanupSummaryEntity($sClass); } @@ -33,7 +33,7 @@ class ObjectServiceSummary implements iObjectService public function Delete(string $sClass, string $sId): void { - DataFeatureRemovalLog::Info('Object to delete', null, ['class' => $sClass, 'id' => $sId]); + DataFeatureRemovalLog::Debug('Object to delete', null, ['class' => $sClass, 'id' => $sId]); if (!array_key_exists($sClass, $this->aSummary)) { $this->aSummary[$sClass] = new DataCleanupSummaryEntity($sClass); } @@ -43,7 +43,7 @@ class ObjectServiceSummary implements iObjectService public function SetIssue(string $sClass): void { - DataFeatureRemovalLog::Info('Issue on object', null, ['class' => $sClass]); + DataFeatureRemovalLog::Debug('Issue on object', null, ['class' => $sClass]); if (!array_key_exists($sClass, $this->aSummary)) { $this->aSummary[$sClass] = new DataCleanupSummaryEntity($sClass); } diff --git a/setup/extensionsmap.class.inc.php b/setup/extensionsmap.class.inc.php index 8c240f9fc9..a04edb2139 100644 --- a/setup/extensionsmap.class.inc.php +++ b/setup/extensionsmap.class.inc.php @@ -108,6 +108,7 @@ class iTopExtensionsMap $this->ProcessWizardChoices($aStepInfo['alternatives']); } } + // TODO Add aModuleVersion from module definition on disk in extensions return true; } diff --git a/setup/feature_removal/ModelReflectionSerializer.php b/setup/feature_removal/ModelReflectionSerializer.php index 53ed1d5dfa..321b79160e 100644 --- a/setup/feature_removal/ModelReflectionSerializer.php +++ b/setup/feature_removal/ModelReflectionSerializer.php @@ -6,7 +6,6 @@ use ContextTag; use CoreException; use Exception; use IssueLog; -use MetaModel; use SetupLog; use utils; @@ -34,7 +33,7 @@ class ModelReflectionSerializer public function GetModelFromEnvironment(string $sEnv): array { - IssueLog::Info(__METHOD__, null, ['env' => $sEnv]); + IssueLog::Debug(__METHOD__, null, ['env' => $sEnv]); $sPHPExec = trim(utils::GetConfig()->Get('php_path')); $sOutput = ""; diff --git a/setup/modulediscovery.class.inc.php b/setup/modulediscovery.class.inc.php index 7ac863c23a..f8841f7e12 100755 --- a/setup/modulediscovery.class.inc.php +++ b/setup/modulediscovery.class.inc.php @@ -425,14 +425,15 @@ class ModuleDiscovery continue; } - SetupLog::Info("Module considered as removed", null, ['extension_code' => $oExtension->sCode, 'module_name' => $sModuleName, 'module_version' => $sModuleVersion, ModuleFileReader::MODULE_FILE_PATH => $sCurrentModuleFilePath]); + IssueLog::Info("Module considered as removed", null, ['extension_code' => $oExtension->sCode, 'module_name' => $sModuleName, 'module_version' => $sModuleVersion, ModuleFileReader::MODULE_FILE_PATH => $sCurrentModuleFilePath]); return true; } if (count($aNonMatchingPaths) > 0) { //add log for support - SetupLog::Debug("Module kept as it came from non removed extensions", null, ['module_name' => $sModuleName, 'module_version' => $sModuleVersion, ModuleFileReader::MODULE_FILE_PATH => $sModuleFilePath, 'non_matching_paths' => $aNonMatchingPaths]); + IssueLog::Info("Module kept as it came from non removed extensions", null, ['module_name' => $sModuleName, 'module_version' => $sModuleVersion, ModuleFileReader::MODULE_FILE_PATH => $sModuleFilePath, 'non_matching_paths' => $aNonMatchingPaths]); } + IssueLog::Debug(__METHOD__.' Module loaded', null, ['name' => $sModuleName, 'version' => $sModuleVersion]); return false; } diff --git a/setup/runtimeenv.class.inc.php b/setup/runtimeenv.class.inc.php index f6a80b69b7..015ba98411 100644 --- a/setup/runtimeenv.class.inc.php +++ b/setup/runtimeenv.class.inc.php @@ -99,6 +99,7 @@ class RunTimeEnvironment $this->sBuildEnv = $sEnvironment.'-build'; } $this->oExtensionsMap = null; + SetupLog::Enable(APPROOT.'log/setup.log'); } /** @@ -1566,7 +1567,7 @@ class RunTimeEnvironment public function ExitMaintenanceMode(): void { - if (SetupUtils::IsInMaintenanceMode()){ + if (SetupUtils::IsInMaintenanceMode()) { SetupUtils::ExitMaintenanceMode(); } } diff --git a/setup/unattended-install/xml_setup/upgrade.xml b/setup/unattended-install/xml_setup/upgrade.xml index deb1ce314c..adf49e1ac7 100644 --- a/setup/unattended-install/xml_setup/upgrade.xml +++ b/setup/unattended-install/xml_setup/upgrade.xml @@ -40,5 +40,5 @@ - off + on diff --git a/tests/php-unit-tests/unitary-tests/datamodels/2.x/combodo-data-feature-removal/simulate-audit-from-setup.php b/tests/php-unit-tests/unitary-tests/datamodels/2.x/combodo-data-feature-removal/simulate-audit-from-setup.php new file mode 100644 index 0000000000..93fabb3280 --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/datamodels/2.x/combodo-data-feature-removal/simulate-audit-from-setup.php @@ -0,0 +1,51 @@ + "combodo-data-feature-removal", + "exec_page" => "index.php", + 'exec_env' => 'production', +]; + +new ContextTag(ContextTag::TAG_SETUP); +$sToken = SetupUtils::CreateSetupToken(); + +$aPostParams = [ + "auth_user" => 'admin', + "auth_pwd" => 'admin', + 'login_mode' => 'form', + 'operation' => 'AnalysisResult', + 'aRemovedExtensions[itop-container-mgmt]' => 'Containerization', + 'setup_token' => $sToken, +]; + +$sHiddenPostedInput = ""; +foreach ($aPostParams as $sKey => $sVal) { + $sHiddenPostedInput .= << +INPUT; +} + +$sRedirectURL = utils::GetAbsoluteUrlModulePage('combodo-data-feature-removal', 'index.php'); + +$sDiv = << +DIV; + +$sReadyJs = <<add($sDiv); +$oP->add_ready_script($sReadyJs); +$oP->output();