N°8764 - Halt setup if database is not compatible with an uninstallation

This commit is contained in:
odain
2026-01-09 08:28:01 +01:00
committed by Eric Espie
parent cf7a193f7b
commit f787cf0950
5 changed files with 156 additions and 47 deletions

View File

@@ -2,8 +2,12 @@
namespace Combodo\iTop\Setup\FeatureRemoval;
use ContextTag;
use CoreException;
use Exception;
use IssueLog;
use SetupLog;
use Utils;
class ModelReflectionSerializer
{
@@ -29,27 +33,38 @@ class ModelReflectionSerializer
public function GetModelFromEnvironment(string $sEnv): array
{
\IssueLog::Info(__METHOD__, null, ['env' => $sEnv]);
$sPHPExec = trim(\MetaModel::GetConfig()->Get('php_path'));
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);
if ($iRes != 0) {
\IssueLog::Error("Cannot get classes", null, ['env' => $sEnv, 'code' => $iRes, "output" => $sOutput]);
$this->LogErrorWithProperLogger("Cannot get classes", null, ['env' => $sEnv, 'code' => $iRes, "output" => $sOutput]);
throw new CoreException("Cannot get classes");
}
$aClasses = json_decode($sOutput[0] ?? null, true);
if (false === $aClasses) {
\IssueLog::Error("Invalid JSON", null, ["output" => $sOutput]);
$this->LogErrorWithProperLogger("Invalid JSON", null, ['env' => $sEnv, "output" => $sOutput]);
throw new Exception("cannot get classes");
}
if (!is_array($aClasses)) {
\IssueLog::Error("not an array", null, ["classes" => $aClasses]);
throw new Exception("cannot get classes");
$this->LogErrorWithProperLogger("not an array", null, ['env' => $sEnv, "classes" => $aClasses, "output" => $sOutput]);
throw new Exception("cannot get classes from $sEnv");
}
return $aClasses;
}
//could be shared with others in log APIs ?
private function LogErrorWithProperLogger($sMessage, $sChannel = null, $aContext = []): void
{
if (ContextTag::Check(ContextTag::TAG_SETUP)) {
SetupLog::Error($sMessage, $sChannel, $aContext);
} else {
IssueLog::Error($sMessage, $sChannel, $aContext);
}
}
}

View File

@@ -16,21 +16,34 @@ class SetupAudit
private string $sEnvBeforeExtensionRemoval;
private string $sEnvAfterExtensionRemoval;
private array $aClassesBeforeRemoval;
private array $aClassesAfterRemoval;
private array $aRemovedClasses;
private array $aFinalClassesRemoved;
private bool $bClassesInitialized = false;
private array $aClassesBeforeRemoval = [];
private array $aClassesAfterRemoval = [];
private array $aRemovedClasses = [];
private array $aFinalClassesRemoved = [];
public function __construct(string $sEnvBeforeExtensionRemoval, string $sEnvAfterExtensionRemoval = DryRemovalRuntimeEnvironment::DRY_REMOVAL_AUDIT_ENV)
{
$this->sEnvBeforeExtensionRemoval = $sEnvBeforeExtensionRemoval;
$this->sEnvAfterExtensionRemoval = $sEnvAfterExtensionRemoval;
}
public function ComputeClasses(array $aClassesBeforeRemoval = null)
{
if ($this->bClassesInitialized) {
return;
}
$sCurrentEnvt = MetaModel::GetEnvironment();
if ($sCurrentEnvt === $this->sEnvBeforeExtensionRemoval) {
$this->aClassesBeforeRemoval = MetaModel::GetClasses();
if (is_null($aClassesBeforeRemoval)) {
if ($sCurrentEnvt === $this->sEnvBeforeExtensionRemoval) {
$this->aClassesBeforeRemoval = MetaModel::GetClasses();
} else {
$this->aClassesBeforeRemoval = ModelReflectionSerializer::GetInstance()->GetModelFromEnvironment($this->sEnvBeforeExtensionRemoval);
}
} else {
$this->aClassesBeforeRemoval = ModelReflectionSerializer::GetInstance()->GetModelFromEnvironment($this->sEnvBeforeExtensionRemoval);
$this->aClassesBeforeRemoval = $aClassesBeforeRemoval;
}
if ($sCurrentEnvt === $this->sEnvAfterExtensionRemoval) {
@@ -39,8 +52,7 @@ class SetupAudit
$this->aClassesAfterRemoval = ModelReflectionSerializer::GetInstance()->GetModelFromEnvironment($this->sEnvAfterExtensionRemoval);
}
$this->aRemovedClasses = [];
$this->aFinalClassesRemoved = [];
$this->bClassesInitialized = true;
}
/*public function SetSelectedExtensions(Config $oConfig, array $aSelectedExtensions)
@@ -56,6 +68,8 @@ class SetupAudit
public function GetRemovedClasses(): array
{
$this->ComputeClasses();
if (count($this->aRemovedClasses) == 0) {
if (count($this->aClassesBeforeRemoval) == 0) {
return $this->aRemovedClasses;