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

This commit is contained in:
odain
2025-11-07 15:39:53 +01:00
parent 12f23113f5
commit 890a2568c8
2110 changed files with 53099 additions and 63885 deletions

View File

@@ -1,20 +1,19 @@
<?php
/**
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\FilesInformation\Service;
use Dict;
use MetaModel;
use utils;
class FilesInformation
{
private static $sItopOwner;
private static $sItopOwner;
/**
* Check iTop files access rights to tell if core update is possible
@@ -25,47 +24,39 @@ class FilesInformation
* @throws \Combodo\iTop\FilesInformation\Service\FileNotExistException
* @throws \Exception
*/
public static function CanUpdateCore(&$sMessage)
{
self::Init();
// Check than iTop can write everywhere
$aFilesInfo = FilesIntegrity::GetInstalledFiles(APPROOT.'manifest.xml');
if ($aFilesInfo === false)
{
$sMessage = Dict::Format('FilesInformation:Error:MissingFile', 'manifest.xml');
return 'No';
}
// generate files and folders list
$aInstalledFiles = array();
foreach (array_keys($aFilesInfo) as $sFile)
{
$sLocalDirPath = utils::LocalPath(APPROOT.dirname($sFile));
if ($sLocalDirPath !== false)
{
if (!isset($aInstalledFiles[$sLocalDirPath]))
{
$aInstalledFiles[$sLocalDirPath] = true;
}
$aInstalledFiles[$sFile] = true;
}
}
if (!self::CanWriteRecursive('', $sMessage, $aInstalledFiles))
{
return 'No';
}
public static function CanUpdateCore(&$sMessage)
{
self::Init();
// Check than iTop can write everywhere
$aFilesInfo = FilesIntegrity::GetInstalledFiles(APPROOT.'manifest.xml');
if ($aFilesInfo === false) {
$sMessage = Dict::Format('FilesInformation:Error:MissingFile', 'manifest.xml');
return 'No';
}
// generate files and folders list
$aInstalledFiles = [];
foreach (array_keys($aFilesInfo) as $sFile) {
$sLocalDirPath = utils::LocalPath(APPROOT.dirname($sFile));
if ($sLocalDirPath !== false) {
if (!isset($aInstalledFiles[$sLocalDirPath])) {
$aInstalledFiles[$sLocalDirPath] = true;
}
$aInstalledFiles[$sFile] = true;
}
}
if (!self::CanWriteRecursive('', $sMessage, $aInstalledFiles)) {
return 'No';
}
try
{
FilesIntegrity::CheckInstallationIntegrity(APPROOT, false);
}
catch (FileIntegrityException $e)
{
$sMessage = $e->getMessage();
return 'Warning';
}
try {
FilesIntegrity::CheckInstallationIntegrity(APPROOT, false);
} catch (FileIntegrityException $e) {
$sMessage = $e->getMessage();
return 'Warning';
}
return 'Yes';
}
return 'Yes';
}
/**
* @param string $sRootPath
@@ -75,32 +66,27 @@ class FilesInformation
* @return bool
* @throws \Combodo\iTop\FilesInformation\Service\FileNotExistException
*/
private static function CanWriteRecursive($sRootPath = '', &$sMessage = null, $aInstalledFiles = array())
{
$aDirStats = FilesInformationUtils::Scan($sRootPath, false);
foreach ($aDirStats as $sFileName => $aFileStats)
{
// For name normalization
$sLocalPath = utils::LocalPath(APPROOT.$sRootPath.DIRECTORY_SEPARATOR.$sFileName);
if (($sLocalPath === false) || !isset($aInstalledFiles[$sLocalPath]))
{
continue;
}
if (!self::CanWriteToFile($aFileStats))
{
$sMessage = Dict::Format('FilesInformation:Error:CantWriteToFile', $sRootPath.DIRECTORY_SEPARATOR.$sFileName);
return false;
}
if (($sFileName != '.') && ($aFileStats['type'] == 'dir'))
{
if (!self::CanWriteRecursive($sRootPath.DIRECTORY_SEPARATOR.$sFileName, $sMessage, $aInstalledFiles))
{
return false;
}
}
}
return true;
}
private static function CanWriteRecursive($sRootPath = '', &$sMessage = null, $aInstalledFiles = [])
{
$aDirStats = FilesInformationUtils::Scan($sRootPath, false);
foreach ($aDirStats as $sFileName => $aFileStats) {
// For name normalization
$sLocalPath = utils::LocalPath(APPROOT.$sRootPath.DIRECTORY_SEPARATOR.$sFileName);
if (($sLocalPath === false) || !isset($aInstalledFiles[$sLocalPath])) {
continue;
}
if (!self::CanWriteToFile($aFileStats)) {
$sMessage = Dict::Format('FilesInformation:Error:CantWriteToFile', $sRootPath.DIRECTORY_SEPARATOR.$sFileName);
return false;
}
if (($sFileName != '.') && ($aFileStats['type'] == 'dir')) {
if (!self::CanWriteRecursive($sRootPath.DIRECTORY_SEPARATOR.$sFileName, $sMessage, $aInstalledFiles)) {
return false;
}
}
}
return true;
}
/**
* Check if iTop can write
@@ -110,48 +96,45 @@ class FilesInformation
* @throws \Combodo\iTop\FilesInformation\Service\FileNotExistException
*/
public static function IsWritable($sFilename)
{
$aFileStats = FilesInformationUtils::GetFileStat(utils::LocalPath($sFilename));
return self::CanWriteToFile($aFileStats);
}
{
$aFileStats = FilesInformationUtils::GetFileStat(utils::LocalPath($sFilename));
return self::CanWriteToFile($aFileStats);
}
private static function CanWriteToFile($aFileStats)
{
if ($aFileStats['writable'])
{
return true;
}
if ($aFileStats['file_owner'] == self::$sItopOwner)
{
// If iTop owns the file, no pb to write
return true;
}
return false;
}
private static function CanWriteToFile($aFileStats)
{
if ($aFileStats['writable']) {
return true;
}
if ($aFileStats['file_owner'] == self::$sItopOwner) {
// If iTop owns the file, no pb to write
return true;
}
return false;
}
/**
* @throws \Combodo\iTop\FilesInformation\Service\FileNotExistException
*/
private static function Init()
{
clearstatcache();
/**
* @throws \Combodo\iTop\FilesInformation\Service\FileNotExistException
*/
private static function Init()
{
clearstatcache();
$sSourceConfigFile = MetaModel::GetConfig()->GetLoadedFile();
$sSourceConfigFile = utils::LocalPath($sSourceConfigFile);
$sSourceConfigFile = MetaModel::GetConfig()->GetLoadedFile();
$sSourceConfigFile = utils::LocalPath($sSourceConfigFile);
$aConfigFiles = FilesInformationUtils::Scan(dirname($sSourceConfigFile));
if (!isset($aConfigFiles[basename($sSourceConfigFile)]))
{
return;
}
$aConfigStats = $aConfigFiles[basename($sSourceConfigFile)];
self::$sItopOwner = $aConfigStats['file_owner'];
}
$aConfigFiles = FilesInformationUtils::Scan(dirname($sSourceConfigFile));
if (!isset($aConfigFiles[basename($sSourceConfigFile)])) {
return;
}
$aConfigStats = $aConfigFiles[basename($sSourceConfigFile)];
self::$sItopOwner = $aConfigStats['file_owner'];
}
public static function GetItopDiskSpace()
{
return FilesInformationUtils::GetDirSize(realpath(APPROOT));
}
public static function GetItopDiskSpace()
{
return FilesInformationUtils::GetDirSize(realpath(APPROOT));
}
/**
* @param $sLocalDirPath
@@ -160,12 +143,11 @@ class FilesInformation
* @throws \Combodo\iTop\FilesInformation\Service\FileNotExistException
*/
public static function GetDirInfo($sLocalDirPath)
{
if (utils::AbsolutePath($sLocalDirPath) === false)
{
return array();
}
return FilesInformationUtils::Scan($sLocalDirPath);
}
{
if (utils::AbsolutePath($sLocalDirPath) === false) {
return [];
}
return FilesInformationUtils::Scan($sLocalDirPath);
}
}

View File

@@ -1,25 +1,22 @@
<?php
/**
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\FilesInformation\Service;
use Exception;
class FilesInformationException extends Exception
{
}
class FileNotExistException extends FilesInformationException
{
}
class FileIntegrityException extends FilesInformationException
{
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
@@ -10,178 +11,160 @@ use utils;
class FilesInformationUtils
{
public static function Init()
{
clearstatcache();
}
public static function Init()
{
clearstatcache();
}
/**
* @param string $sPath
* @param bool $bGetDirSize
*
* @return array
* @throws \Combodo\iTop\FilesInformation\Service\FileNotExistException
*/
public static function Scan($sPath = '', $bGetDirSize = true)
{
$aFileStats = array();
/**
* @param string $sPath
* @param bool $bGetDirSize
*
* @return array
* @throws \Combodo\iTop\FilesInformation\Service\FileNotExistException
*/
public static function Scan($sPath = '', $bGetDirSize = true)
{
$aFileStats = [];
$sRealRootPath = utils::AbsolutePath($sPath);
if (empty($sRealRootPath))
{
return $aFileStats;
}
$sRealRootPath = utils::AbsolutePath($sPath);
if (empty($sRealRootPath)) {
return $aFileStats;
}
$aFiles = scandir($sRealRootPath);
$aFiles = scandir($sRealRootPath);
foreach ($aFiles as $sScanFile)
{
if ($sScanFile == '..')
{
continue;
}
$sFile = $sRealRootPath.DIRECTORY_SEPARATOR.$sScanFile;
$sFileName = utils::LocalPath($sFile);
$aFileStat = self::GetFileStat($sFileName, $bGetDirSize);
$aFileStat['basename'] = $sScanFile;
$aFileStats[$sScanFile] = $aFileStat;
}
foreach ($aFiles as $sScanFile) {
if ($sScanFile == '..') {
continue;
}
$sFile = $sRealRootPath.DIRECTORY_SEPARATOR.$sScanFile;
$sFileName = utils::LocalPath($sFile);
$aFileStat = self::GetFileStat($sFileName, $bGetDirSize);
$aFileStat['basename'] = $sScanFile;
$aFileStats[$sScanFile] = $aFileStat;
}
return $aFileStats;
}
return $aFileStats;
}
/**
* @param string $sFilename
*
* @param bool $bGetDirSize
*
* @return array
* @throws \Combodo\iTop\FilesInformation\Service\FileNotExistException
*/
public static function GetFileStat($sFilename, $bGetDirSize = true)
{
$sFile = realpath(APPROOT.$sFilename);
$aStats = @stat($sFile);
if (!$aStats)
{
throw new FileNotExistException($sFilename);
}
/**
* @param string $sFilename
*
* @param bool $bGetDirSize
*
* @return array
* @throws \Combodo\iTop\FilesInformation\Service\FileNotExistException
*/
public static function GetFileStat($sFilename, $bGetDirSize = true)
{
$sFile = realpath(APPROOT.$sFilename);
$aStats = @stat($sFile);
if (!$aStats) {
throw new FileNotExistException($sFilename);
}
$aFileStats = array();
$aFileStats['name'] = $sFilename;
$aFileStats['size'] = $aStats['size'];
$aFileStats = [];
$aFileStats['name'] = $sFilename;
$aFileStats['size'] = $aStats['size'];
if (is_dir($sFile))
{
// Special dir case
if ($bGetDirSize)
{
// The size is computed by aggregating the sizes on the children
$aFileStats['size'] = self::GetDirSize($sFile);
}
}
if (is_dir($sFile)) {
// Special dir case
if ($bGetDirSize) {
// The size is computed by aggregating the sizes on the children
$aFileStats['size'] = self::GetDirSize($sFile);
}
}
$aFileStats['display_size'] = utils::BytesToFriendlyFormat($aFileStats['size']);
$aFileStats['display_size'] = utils::BytesToFriendlyFormat($aFileStats['size']);
$aFileStats['perms'] = sprintf("0%o", 0777 & $aStats['mode']);
$aFileStats['mode'] = $aStats['mode'];
$aFileStats['perms'] = sprintf("0%o", 0777 & $aStats['mode']);
$aFileStats['mode'] = $aStats['mode'];
$aTypes = array(
0140000=>'socket',
0120000=>'link',
0100000=>'file',
0060000=>'block',
0040000=>'dir',
0020000=>'char',
0010000=>'fifo'
);
$iRawMode = $aStats['mode'];
$iMode = decoct($iRawMode & 0170000); // File Encoding Bit
$aTypes = [
0140000 => 'socket',
0120000 => 'link',
0100000 => 'file',
0060000 => 'block',
0040000 => 'dir',
0020000 => 'char',
0010000 => 'fifo',
];
$iRawMode = $aStats['mode'];
$iMode = decoct($iRawMode & 0170000); // File Encoding Bit
$sDisplayMode =(array_key_exists(octdec($iMode),$aTypes))?$aTypes[octdec($iMode)][0]:'u';
$sDisplayMode.=(($iRawMode&0x0100)?'r':'-').(($iRawMode&0x0080)?'w':'-');
$sDisplayMode.=(($iRawMode&0x0040)?(($iRawMode&0x0800)?'s':'x'):(($iRawMode&0x0800)?'S':'-'));
$sDisplayMode.=(($iRawMode&0x0020)?'r':'-').(($iRawMode&0x0010)?'w':'-');
$sDisplayMode.=(($iRawMode&0x0008)?(($iRawMode&0x0400)?'s':'x'):(($iRawMode&0x0400)?'S':'-'));
$sDisplayMode.=(($iRawMode&0x0004)?'r':'-').(($iRawMode&0x0002)?'w':'-');
$sDisplayMode.=(($iRawMode&0x0001)?(($iRawMode&0x0200)?'t':'x'):(($iRawMode&0x0200)?'T':'-'));
$sDisplayMode = (array_key_exists(octdec($iMode), $aTypes)) ? $aTypes[octdec($iMode)][0] : 'u';
$sDisplayMode .= (($iRawMode & 0x0100) ? 'r' : '-').(($iRawMode & 0x0080) ? 'w' : '-');
$sDisplayMode .= (($iRawMode & 0x0040) ? (($iRawMode & 0x0800) ? 's' : 'x') : (($iRawMode & 0x0800) ? 'S' : '-'));
$sDisplayMode .= (($iRawMode & 0x0020) ? 'r' : '-').(($iRawMode & 0x0010) ? 'w' : '-');
$sDisplayMode .= (($iRawMode & 0x0008) ? (($iRawMode & 0x0400) ? 's' : 'x') : (($iRawMode & 0x0400) ? 'S' : '-'));
$sDisplayMode .= (($iRawMode & 0x0004) ? 'r' : '-').(($iRawMode & 0x0002) ? 'w' : '-');
$sDisplayMode .= (($iRawMode & 0x0001) ? (($iRawMode & 0x0200) ? 't' : 'x') : (($iRawMode & 0x0200) ? 'T' : '-'));
$aFileStats['display_mode'] = $sDisplayMode;
$aFileStats['type'] = $aTypes[octdec($iMode)];
$aFileStats['readable'] = is_readable($sFile);
$aFileStats['writable'] = is_writable($sFile);
$aFileStats['file_owner'] = $aStats['uid'];
$aFileStats['file_group'] = $aStats['gid'];
if (function_exists('posix_getpwuid'))
{
$aPwUid = @posix_getpwuid($aStats['uid']);
if (isset($aPwUid['name']))
{
$aFileStats['owner_name'] = $aPwUid['name'];
}
}
if (empty($aFileStats['owner_name']))
{
$aFileStats['owner_name'] = '';
}
if (function_exists('posix_getgrgid'))
{
$aGrGid = @posix_getgrgid($aStats['gid']);
if (isset($aGrGid['name']))
{
$aFileStats['group_name'] = $aGrGid['name'];
}
}
if (empty($aFileStats['group_name']))
{
$aFileStats['group_name'] = '';
}
$aFileStats['mtime'] = date('Y-m-d H:i:s', $aStats['mtime']);
$aFileStats['ctime'] = date('Y-m-d H:i:s', $aStats['ctime']);
$aFileStats['display_mode'] = $sDisplayMode;
$aFileStats['type'] = $aTypes[octdec($iMode)];
$aFileStats['readable'] = is_readable($sFile);
$aFileStats['writable'] = is_writable($sFile);
$aFileStats['file_owner'] = $aStats['uid'];
$aFileStats['file_group'] = $aStats['gid'];
if (function_exists('posix_getpwuid')) {
$aPwUid = @posix_getpwuid($aStats['uid']);
if (isset($aPwUid['name'])) {
$aFileStats['owner_name'] = $aPwUid['name'];
}
}
if (empty($aFileStats['owner_name'])) {
$aFileStats['owner_name'] = '';
}
if (function_exists('posix_getgrgid')) {
$aGrGid = @posix_getgrgid($aStats['gid']);
if (isset($aGrGid['name'])) {
$aFileStats['group_name'] = $aGrGid['name'];
}
}
if (empty($aFileStats['group_name'])) {
$aFileStats['group_name'] = '';
}
$aFileStats['mtime'] = date('Y-m-d H:i:s', $aStats['mtime']);
$aFileStats['ctime'] = date('Y-m-d H:i:s', $aStats['ctime']);
return $aFileStats;
}
return $aFileStats;
}
/**
* @param string $sPath relative iTop path
*
* @return string absolute path
* @throws \Combodo\iTop\FilesInformation\Service\FileNotExistException
*/
public static function GetAbsolutePath($sPath)
{
$sRootPath = realpath(APPROOT);
$sFullPath = realpath($sRootPath.DIRECTORY_SEPARATOR.$sPath);
if (($sFullPath === false) || !utils::StartsWith($sFullPath, $sRootPath))
{
throw new FileNotExistException($sPath);
}
return $sFullPath;
}
/**
* @param string $sPath relative iTop path
*
* @return string absolute path
* @throws \Combodo\iTop\FilesInformation\Service\FileNotExistException
*/
public static function GetAbsolutePath($sPath)
{
$sRootPath = realpath(APPROOT);
$sFullPath = realpath($sRootPath.DIRECTORY_SEPARATOR.$sPath);
if (($sFullPath === false) || !utils::StartsWith($sFullPath, $sRootPath)) {
throw new FileNotExistException($sPath);
}
return $sFullPath;
}
public static function GetDirSize($sRealRootPath)
{
$aFiles = scandir($sRealRootPath);
$iSize = 0;
foreach ($aFiles as $sScanFile)
{
if (($sScanFile == '.') || ($sScanFile == '..'))
{
continue;
}
$sFile = $sRealRootPath.DIRECTORY_SEPARATOR.$sScanFile;
if (is_dir($sFile))
{
$iSize += self::GetDirSize($sFile);
}
else
{
$aStats = @stat($sFile);
if (is_array($aStats)) {
$iSize += $aStats['size'];
}
}
}
return $iSize;
}
public static function GetDirSize($sRealRootPath)
{
$aFiles = scandir($sRealRootPath);
$iSize = 0;
foreach ($aFiles as $sScanFile) {
if (($sScanFile == '.') || ($sScanFile == '..')) {
continue;
}
$sFile = $sRealRootPath.DIRECTORY_SEPARATOR.$sScanFile;
if (is_dir($sFile)) {
$iSize += self::GetDirSize($sFile);
} else {
$aStats = @stat($sFile);
if (is_array($aStats)) {
$iSize += $aStats['size'];
}
}
}
return $iSize;
}
}

View File

@@ -1,13 +1,12 @@
<?php
/**
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
namespace Combodo\iTop\FilesInformation\Service;
use Dict;
use DOMDocument;
use DOMElement;
@@ -16,7 +15,6 @@ use DOMXPath;
class FilesIntegrity
{
/**
* Get the files defined in the manifest.xml
*
@@ -27,11 +25,10 @@ class FilesIntegrity
*/
public static function GetInstalledFiles($sManifest)
{
$aFiles = array();
$aFiles = [];
$aManifestStats = @stat($sManifest);
if ($aManifestStats === false)
{
if ($aManifestStats === false) {
// No manifest
return false;
}
@@ -40,28 +37,20 @@ class FilesIntegrity
@$oManifestDocument->load($sManifest);
$oXPath = new DOMXPath($oManifestDocument);
$oNodeList = $oXPath->query('/files');
if ($oNodeList->length == 0)
{
if ($oNodeList->length == 0) {
// no files
return false;
}
foreach ($oNodeList as $oItems)
{
foreach ($oItems->childNodes as $oFileNode)
{
if (($oFileNode instanceof DOMNode))
{
if ($oFileNode->hasChildNodes())
{
$aFileInfo = array();
foreach ($oNodeList as $oItems) {
foreach ($oItems->childNodes as $oFileNode) {
if (($oFileNode instanceof DOMNode)) {
if ($oFileNode->hasChildNodes()) {
$aFileInfo = [];
$sFilePath = uniqid(); // just in case no path...
foreach ($oFileNode->childNodes as $oFileInfo)
{
if ($oFileInfo instanceof DOMElement)
{
foreach ($oFileNode->childNodes as $oFileInfo) {
if ($oFileInfo instanceof DOMElement) {
$aFileInfo[$oFileInfo->tagName] = $oFileInfo->textContent;
if ($oFileInfo->tagName == 'path')
{
if ($oFileInfo->tagName == 'path') {
$sFilePath = $oFileInfo->textContent;
}
}
@@ -88,51 +77,44 @@ class FilesIntegrity
{
$aFilesInfo = FilesIntegrity::GetInstalledFiles($sRootPath.'manifest.xml');
if ($aFilesInfo === false)
{
if ($aFilesInfo === false) {
throw new FileIntegrityException(Dict::Format('FilesInformation:Error:MissingFile', 'manifest.xml'));
}
$bHasErrors = false;
$sErrorFiles ="";
$sErrorFiles = "";
@clearstatcache();
foreach ($aFilesInfo as $aFileInfo)
{
foreach ($aFilesInfo as $aFileInfo) {
$sFile = $sRootPath.$aFileInfo['path'];
if (is_file($sFile))
{
if (is_file($sFile)) {
$aStats = @stat($sFile);
$iSize = $aStats['size'];
$sContent = file_get_contents($sFile);
$sChecksum = md5($sContent);
if (($iSize != $aFileInfo['size']) || ($sChecksum != $aFileInfo['md5']))
{
if($bExitAtFirstError) {
if (($iSize != $aFileInfo['size']) || ($sChecksum != $aFileInfo['md5'])) {
if ($bExitAtFirstError) {
throw new FileIntegrityException(Dict::Format('FilesInformation:Error:CorruptedFile', $sFile));
} else {
$bHasErrors = true;
$sErrorFiles .='<li> '.$aFileInfo['path'].'</li>';
$sErrorFiles .= '<li> '.$aFileInfo['path'].'</li>';
}
}
}
// Packed with missing files...
}
if($bHasErrors){
throw new FileIntegrityException(Dict::Format('FilesInformation:Error:ListCorruptedFile','<ul> '.$sErrorFiles.'</ul>'));
if ($bHasErrors) {
throw new FileIntegrityException(Dict::Format('FilesInformation:Error:ListCorruptedFile', '<ul> '.$sErrorFiles.'</ul>'));
}
}
public static function IsInstallationConform($sRootPath, &$sErrorMsg)
{
$sErrorMsg = '';
try
{
try {
self::CheckInstallationIntegrity($sRootPath);
return true;
}
catch (FileIntegrityException $e)
{
} catch (FileIntegrityException $e) {
$sErrorMsg = $e->getMessage();
}
return false;