N°8796 - Add PHP code style validation in iTop and extensions - format whole code base

This commit is contained in:
odain
2025-11-07 20:39:38 +01:00
parent 7681c157ec
commit b0a792afab
369 changed files with 22041 additions and 26866 deletions

View File

@@ -1,4 +1,5 @@
<?php
// Copyright (C) 2024 Combodo SAS
//
// This file is part of iTop.
@@ -41,10 +42,9 @@ require_once(__DIR__.'/hubruntimeenvironment.class.inc.php');
*/
class DBBackupWithErrorReporting extends DBBackup
{
protected $aInfos = [];
protected $aInfos = array();
protected $aErrors = array();
protected $aErrors = [];
protected function LogInfo($sMsg)
{
@@ -79,19 +79,16 @@ function DoBackup($sTargetFile)
// Make sure the target directory exists
$sBackupDir = dirname($sTargetFile);
SetupUtils::builddir($sBackupDir);
$oBackup = new DBBackupWithErrorReporting();
$oBackup->SetMySQLBinDir(MetaModel::GetConfig()->GetModuleSetting('itop-backup', 'mysql_bindir', ''));
$sSourceConfigFile = APPCONF.utils::GetCurrentEnvironment().'/'.ITOP_CONFIG_FILE;
$oMutex = new iTopMutex('backup.'.utils::GetCurrentEnvironment());
$oMutex->Lock();
try
{
try {
$oBackup->CreateCompressedBackup($sTargetFile, $sSourceConfigFile);
}
catch (Exception $e)
{
} catch (Exception $e) {
$oMutex->Unlock();
throw $e;
}
@@ -101,22 +98,22 @@ function DoBackup($sTargetFile)
/**
* Outputs the status of the current ajax execution (as a JSON structure)
*
*
* @param string $sMessage
* @param bool $bSuccess
* @param number $iErrorCode
* @param array $aMoreFields
* Extra fields to pass to the caller, if needed
*/
function ReportStatus($sMessage, $bSuccess, $iErrorCode = 0, $aMoreFields = array())
function ReportStatus($sMessage, $bSuccess, $iErrorCode = 0, $aMoreFields = [])
{
// Do not use AjaxPage during setup phases, because it uses InterfaceDiscovery in Twig compilation
$oPage = new JsonPage();
$aResult = array(
$aResult = [
'code' => $iErrorCode,
'message' => $sMessage,
'fields' => $aMoreFields
);
'fields' => $aMoreFields,
];
$oPage->SetData($aResult);
$oPage->SetOutputDataOnly(true);
$oPage->output();
@@ -124,154 +121,137 @@ function ReportStatus($sMessage, $bSuccess, $iErrorCode = 0, $aMoreFields = arra
/**
* Helper to output the status of a successful execution
*
*
* @param string $sMessage
* @param array $aMoreFields
* Extra fields to pass to the caller, if needed
*/
function ReportSuccess($sMessage, $aMoreFields = array())
function ReportSuccess($sMessage, $aMoreFields = [])
{
ReportStatus($sMessage, true, 0, $aMoreFields);
}
/**
* Helper to output the status of a failed execution
*
*
* @param string $sMessage
* @param number $iErrorCode
* @param array $aMoreFields
* Extra fields to pass to the caller, if needed
*/
function ReportError($sMessage, $iErrorCode, $aMoreFields = array())
function ReportError($sMessage, $iErrorCode, $aMoreFields = [])
{
if ($iErrorCode==0)
{
if ($iErrorCode == 0) {
// 0 means no error, so change it if no meaningful error code is supplied
$iErrorCode = -1;
}
ReportStatus($sMessage, false, $iErrorCode, $aMoreFields);
}
try
{
try {
SetupUtils::ExitMaintenanceMode(false); // Reset maintenance mode in case of problem
utils::PushArchiveMode(false);
ini_set('max_execution_time', max(3600, ini_get('max_execution_time'))); // Under Windows SQL/backup operations are part of the PHP timeout and require extra time
ini_set('display_errors', 1); // Make sure that fatal errors remain visible from the end-user
// Most of the ajax calls are done without the MetaModel being loaded
// Therefore, the language must be passed as an argument,
// and the dictionnaries be loaded here
// Therefore, the language must be passed as an argument,
// and the dictionnaries be loaded here
$sLanguage = utils::ReadParam('language', '');
if ($sLanguage!='')
{
foreach (glob(APPROOT.'env-production/dictionaries/*.dict.php') as $sFilePath)
{
require_once ($sFilePath);
if ($sLanguage != '') {
foreach (glob(APPROOT.'env-production/dictionaries/*.dict.php') as $sFilePath) {
require_once($sFilePath);
}
$aLanguages = Dict::GetLanguages();
if (array_key_exists($sLanguage, $aLanguages))
{
if (array_key_exists($sLanguage, $aLanguages)) {
Dict::SetUserLanguage($sLanguage);
}
}
$sOperation = utils::ReadParam('operation', '');
switch ($sOperation)
{
switch ($sOperation) {
case 'check_before_backup':
require_once (APPROOT.'/application/startup.inc.php');
require_once (APPROOT.'/application/loginwebpage.class.inc.php');
require_once(APPROOT.'/application/startup.inc.php');
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin)
$sDBBackupPath = utils::GetDataPath().'backups/manual';
$aChecks = SetupUtils::CheckBackupPrerequisites($sDBBackupPath);
$bFailed = false;
foreach ($aChecks as $oCheckResult)
{
if ($oCheckResult->iSeverity==CheckResult::ERROR)
{
foreach ($aChecks as $oCheckResult) {
if ($oCheckResult->iSeverity == CheckResult::ERROR) {
$bFailed = true;
ReportError($oCheckResult->sLabel, -2);
}
}
if (!$bFailed)
{
if (!$bFailed) {
// Continue the checks
$fFreeSpace = SetupUtils::CheckDiskSpace($sDBBackupPath);
if ($fFreeSpace!==false)
{
if ($fFreeSpace !== false) {
$sMessage = Dict::Format('iTopHub:BackupFreeDiskSpaceIn', SetupUtils::HumanReadableSize($fFreeSpace), dirname($sDBBackupPath));
ReportSuccess($sMessage);
}
else
{
} else {
ReportError(Dict::S('iTopHub:FailedToCheckFreeDiskSpace'), -1);
}
}
break;
break;
case 'do_backup':
require_once (APPROOT.'/application/startup.inc.php');
require_once (APPROOT.'/application/loginwebpage.class.inc.php');
require_once(APPROOT.'/application/startup.inc.php');
require_once(APPROOT.'/application/loginwebpage.class.inc.php');
LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin)
try
{
if (MetaModel::GetConfig()->Get('demo_mode')) throw new Exception('Sorry the installation of extensions is not allowed in demo mode');
try {
if (MetaModel::GetConfig()->Get('demo_mode')) {
throw new Exception('Sorry the installation of extensions is not allowed in demo mode');
}
SetupLog::Info('Backup starts...');
set_time_limit(0);
$sBackupPath = APPROOT.'/data/backups/manual/backup-';
$iSuffix = 1;
$sSuffix = '';
// Generate a unique name...
do
{
do {
$sBackupFile = $sBackupPath.date('Y-m-d-His').$sSuffix;
$sSuffix = '-'.$iSuffix;
$iSuffix++ ;
}
while (file_exists($sBackupFile));
} while (file_exists($sBackupFile));
$oBackup = DoBackup($sBackupFile);
$aErrors = $oBackup->GetErrors();
if (count($aErrors)>0)
{
if (count($aErrors) > 0) {
SetupLog::Error('Backup failed.');
SetupLog::Error(implode("\n", $aErrors));
ReportError(Dict::S('iTopHub:BackupFailed'), -1, $aErrors);
}
else
{
ReportError(Dict::S('iTopHub:BackupFailed'), -1, $aErrors);
} else {
SetupLog::Info('Backup successfully completed.');
ReportSuccess(Dict::S('iTopHub:BackupOk'));
}
}
catch (Exception $e)
{
} catch (Exception $e) {
SetupLog::Error($e->getMessage());
ReportError($e->getMessage(), $e->getCode());
}
break;
break;
case 'compile':
SetupLog::Info('Deployment starts...');
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
if (!file_exists(utils::GetDataPath().'hub/compile_authent') || $sAuthent !== file_get_contents(utils::GetDataPath().'hub/compile_authent'))
{
throw new SecurityException(Dict::S('iTopHub:FailAuthent'));
if (!file_exists(utils::GetDataPath().'hub/compile_authent') || $sAuthent !== file_get_contents(utils::GetDataPath().'hub/compile_authent')) {
throw new SecurityException(Dict::S('iTopHub:FailAuthent'));
}
// First step: prepare the datamodel, if it fails, roll-back
$aSelectedExtensionCodes = utils::ReadParam('extension_codes', array());
$aSelectedExtensionDirs = utils::ReadParam('extension_dirs', array());
$aSelectedExtensionCodes = utils::ReadParam('extension_codes', []);
$aSelectedExtensionDirs = utils::ReadParam('extension_dirs', []);
$oRuntimeEnv = new HubRunTimeEnvironment('production', false); // use a temp environment: production-build
$oRuntimeEnv->MoveSelectedExtensions(APPROOT.'/data/downloaded-extensions/', $aSelectedExtensionDirs);
$oConfig = new Config(APPCONF.'production/'.ITOP_CONFIG_FILE);
if ($oConfig->Get('demo_mode')) throw new Exception('Sorry the installation of extensions is not allowed in demo mode');
if ($oConfig->Get('demo_mode')) {
throw new Exception('Sorry the installation of extensions is not allowed in demo mode');
}
$aSelectModules = $oRuntimeEnv->CompileFrom('production', false); // WARNING symlinks does not seem to be compatible with manual Commit
@@ -289,21 +269,19 @@ try
$oRuntimeEnv->Commit();
// Report the success in a way that will be detected by the ajax caller
SetupLog::Info('Compilation completed...');
SetupLog::Info('Compilation completed...');
ReportSuccess('Ok'); // No access to Dict::S here
break;
break;
case 'move_to_production':
// Second step: update the schema and the data
// Everything happening below is based on env-production
$oRuntimeEnv = new RunTimeEnvironment('production', true);
try
{
try {
SetupLog::Info('Move to production starts...');
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
if (!file_exists(utils::GetDataPath().'hub/compile_authent') || $sAuthent !== file_get_contents(utils::GetDataPath().'hub/compile_authent'))
{
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
if (!file_exists(utils::GetDataPath().'hub/compile_authent') || $sAuthent !== file_get_contents(utils::GetDataPath().'hub/compile_authent')) {
throw new SecurityException(Dict::S('iTopHub:FailAuthent'));
}
unlink(utils::GetDataPath().'hub/compile_authent');
@@ -315,15 +293,11 @@ try
$aAvailableModules = $oRuntimeEnv->AnalyzeInstallation($oConfig, $oRuntimeEnv->GetBuildDir(), true);
$aSelectedModules = array();
foreach ($aAvailableModules as $sModuleId => $aModule)
{
if (($sModuleId == ROOT_MODULE) || ($sModuleId == DATAMODEL_MODULE))
{
$aSelectedModules = [];
foreach ($aAvailableModules as $sModuleId => $aModule) {
if (($sModuleId == ROOT_MODULE) || ($sModuleId == DATAMODEL_MODULE)) {
continue;
}
else
{
} else {
$aSelectedModules[] = $sModuleId;
}
}
@@ -349,17 +323,14 @@ try
// Default choices = as before
$oExtensionsMap->LoadChoicesFromDatabase($oConfig);
foreach ($oExtensionsMap->GetAllExtensions() as $oExtension)
{
foreach ($oExtensionsMap->GetAllExtensions() as $oExtension) {
// Plus all "remote" extensions
if ($oExtension->sSource==iTopExtension::SOURCE_REMOTE)
{
if ($oExtension->sSource == iTopExtension::SOURCE_REMOTE) {
$oExtensionsMap->MarkAsChosen($oExtension->sCode);
}
}
$aSelectedExtensionCodes = array();
foreach ($oExtensionsMap->GetChoices() as $oExtension)
{
$aSelectedExtensionCodes = [];
foreach ($oExtensionsMap->GetChoices() as $oExtension) {
$aSelectedExtensionCodes[] = $oExtension->sCode;
}
$aSelectedExtensions = $oExtensionsMap->GetChoices();
@@ -368,34 +339,27 @@ try
// Report the success in a way that will be detected by the ajax caller
SetupLog::Info('Deployment successfully completed.');
ReportSuccess(Dict::S('iTopHub:CompiledOK'));
}
catch (Exception $e)
{
if(file_exists(utils::GetDataPath().'hub/compile_authent'))
{
} catch (Exception $e) {
if (file_exists(utils::GetDataPath().'hub/compile_authent')) {
unlink(utils::GetDataPath().'hub/compile_authent');
}
// Note: at this point, the dictionnary is not necessarily loaded
SetupLog::Error(get_class($e).': '.Dict::S('iTopHub:ConfigurationSafelyReverted')."\n".$e->getMessage());
SetupLog::Error('Debug trace: '.$e->getTraceAsString());
ReportError($e->getMessage(), $e->getCode());
}
finally
{
} finally {
SetupUtils::ExitReadOnlyMode();
}
break;
break;
default:
ReportError("Invalid operation: '$sOperation'", -1);
}
}
catch (Exception $e)
{
} catch (Exception $e) {
SetupLog::Error(get_class($e).': '.Dict::S('iTopHub:ConfigurationSafelyReverted')."\n".$e->getMessage());
SetupLog::Error('Debug trace: '.$e->getTraceAsString());
utils::PopArchiveMode();
ReportError($e->getMessage(), $e->getCode());
}