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

@@ -556,7 +556,7 @@ class ActionEmail extends ActionNotification
$oLog->Set('trigger_id', $oTrigger->GetKey());
$oLog->Set('action_id', $this->GetKey());
$oLog->Set('object_id', $aContextArgs['this->object()']->GetKey());
$oLog->Set('object_class', get_class($aContextArgs['this->object()']));
$oLog->Set('object_class', get_class($aContextArgs['this->object()']));
// Must be inserted now so that it gets a valid id that will make the link
// between an eventual asynchronous task (queued) and the log
$oLog->DBInsertNoReload();

View File

@@ -1,4 +1,5 @@
<?php
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (C) 2013-2024 Combodo SAS
*
@@ -56,28 +57,28 @@ class BulkExportResult extends DBObject
{
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => 'core/cmdb',
"key_type" => 'autoincrement',
"name_attcode" => array('created'),
"name_attcode" => ['created'],
"state_attcode" => '',
"reconc_keys" => array(),
"reconc_keys" => [],
"db_table" => 'priv_bulk_export_result',
"db_key_field" => 'id',
"db_finalclass_field" => '',
"display_template" => '',
);
];
MetaModel::Init_Params($aParams);
MetaModel::Init_AddAttribute(new AttributeDateTime("created", array("allowed_values"=>null, "sql"=>"created", "default_value"=>"NOW()", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("user_id", array("allowed_values"=>null, "sql"=>"user_id", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("chunk_size", array("allowed_values"=>null, "sql"=>"chunk_size", "default_value"=>0, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("format", array("allowed_values"=>null, "sql"=>"format", "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("temp_file_path", array("allowed_values"=>null, "sql"=>"temp_file_path", "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeLongText("search", array("allowed_values"=>null, "sql"=>"search", "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeLongText("status_info", array("allowed_values"=>null, "sql"=>"status_info", "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeBoolean("localize_output", array("allowed_values"=>null, "sql"=>"localize_output", "default_value"=>true, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("created", ["allowed_values" => null, "sql" => "created", "default_value" => "NOW()", "is_null_allowed" => false, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeInteger("user_id", ["allowed_values" => null, "sql" => "user_id", "default_value" => 0, "is_null_allowed" => false, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeInteger("chunk_size", ["allowed_values" => null, "sql" => "chunk_size", "default_value" => 0, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeString("format", ["allowed_values" => null, "sql" => "format", "default_value" => '', "is_null_allowed" => false, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeString("temp_file_path", ["allowed_values" => null, "sql" => "temp_file_path", "default_value" => '', "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeLongText("search", ["allowed_values" => null, "sql" => "search", "default_value" => '', "is_null_allowed" => false, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeLongText("status_info", ["allowed_values" => null, "sql" => "status_info", "default_value" => '', "is_null_allowed" => false, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeBoolean("localize_output", ["allowed_values" => null, "sql" => "localize_output", "default_value" => true, "is_null_allowed" => true, "depends_on" => []]));
}
@@ -100,23 +101,21 @@ class BulkExportResultGC implements iBackgroundProcess
{
public function GetPeriodicity()
{
return 24*3600; // seconds
return 24 * 3600; // seconds
}
public function Process($iTimeLimit)
{
$sDateLimit = date(AttributeDateTime::GetSQLFormat(), time() - 24*3600); // Every BulkExportResult older than one day will be deleted
$sDateLimit = date(AttributeDateTime::GetSQLFormat(), time() - 24 * 3600); // Every BulkExportResult older than one day will be deleted
$sOQL = "SELECT BulkExportResult WHERE created < '$sDateLimit'";
$iProcessed = 0;
while (time() < $iTimeLimit)
{
while (time() < $iTimeLimit) {
// Next one ?
$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL), array('created' => true) /* order by*/, array(), null, 1 /* limit count */);
$oSet->OptimizeColumnLoad(array('BulkExportResult' => array('temp_file_path')));
$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL), ['created' => true] /* order by*/, [], null, 1 /* limit count */);
$oSet->OptimizeColumnLoad(['BulkExportResult' => ['temp_file_path']]);
$oResult = $oSet->Fetch();
if (is_null($oResult))
{
if (is_null($oResult)) {
// Nothing to be done
break;
}
@@ -160,28 +159,24 @@ abstract class BulkExport
$this->bLocalizeOutput = false;
}
/**
* Find the first class capable of exporting the data in the given format
*
* @param string $sFormatCode The lowercase format (e.g. html, csv, spreadsheet, xlsx, xml, json, pdf...)
* @param DBSearch $oSearch The search/filter defining the set of objects to export or null when listing the supported formats
*
* @return BulkExport|null
* @throws ReflectionException
*/
static public function FindExporter($sFormatCode, $oSearch = null)
/**
* Find the first class capable of exporting the data in the given format
*
* @param string $sFormatCode The lowercase format (e.g. html, csv, spreadsheet, xlsx, xml, json, pdf...)
* @param DBSearch $oSearch The search/filter defining the set of objects to export or null when listing the supported formats
*
* @return BulkExport|null
* @throws ReflectionException
*/
public static function FindExporter($sFormatCode, $oSearch = null)
{
foreach(get_declared_classes() as $sPHPClass)
{
foreach (get_declared_classes() as $sPHPClass) {
$oRefClass = new ReflectionClass($sPHPClass);
if ($oRefClass->isSubclassOf('BulkExport') && !$oRefClass->isAbstract())
{
if ($oRefClass->isSubclassOf('BulkExport') && !$oRefClass->isAbstract()) {
/** @var BulkExport $oBulkExporter */
$oBulkExporter = new $sPHPClass();
if ($oBulkExporter->IsFormatSupported($sFormatCode, $oSearch))
{
if ($oSearch)
{
if ($oBulkExporter->IsFormatSupported($sFormatCode, $oSearch)) {
if ($oSearch) {
$oBulkExporter->SetObjectList($oSearch);
}
return $oBulkExporter;
@@ -191,37 +186,34 @@ abstract class BulkExport
return null;
}
/**
* Find the exporter corresponding to the given persistent token
*
* @param int $iPersistentToken The identifier of the BulkExportResult object storing the information
*
* @return BulkExport|null
* @throws ArchivedObjectException
* @throws CoreException
* @throws ReflectionException
*/
static public function FindExporterFromToken($iPersistentToken = null)
/**
* Find the exporter corresponding to the given persistent token
*
* @param int $iPersistentToken The identifier of the BulkExportResult object storing the information
*
* @return BulkExport|null
* @throws ArchivedObjectException
* @throws CoreException
* @throws ReflectionException
*/
public static function FindExporterFromToken($iPersistentToken = null)
{
$oBulkExporter = null;
$oInfo = MetaModel::GetObject('BulkExportResult', $iPersistentToken, false);
if ($oInfo && ($oInfo->Get('user_id') == UserRights::GetUserId()))
{
if ($oInfo && ($oInfo->Get('user_id') == UserRights::GetUserId())) {
$sFormatCode = $oInfo->Get('format');
$aStatusInfo = json_decode($oInfo->Get('status_info'),true);
$aStatusInfo = json_decode($oInfo->Get('status_info'), true);
$oSearch = DBObjectSearch::unserialize($oInfo->Get('search'));
$oSearch->SetShowObsoleteData($aStatusInfo['show_obsolete_data']);
$oBulkExporter = self::FindExporter($sFormatCode, $oSearch);
if ($oBulkExporter)
{
if ($oBulkExporter) {
$oBulkExporter->SetFormat($sFormatCode);
$oBulkExporter->SetObjectList($oSearch);
$oBulkExporter->SetChunkSize($oInfo->Get('chunk_size'));
$oBulkExporter->SetStatusInfo($aStatusInfo);
$oBulkExporter->SetLocalizeOutput($oInfo->Get('localize_output'));
$oBulkExporter->SetLocalizeOutput($oInfo->Get('localize_output'));
$oBulkExporter->sTmpFile = $oInfo->Get('temp_file_path');
$oBulkExporter->oBulkExportResult = $oInfo;
@@ -236,13 +228,11 @@ abstract class BulkExport
*/
public function AppendToTmpFile($data)
{
if ($this->sTmpFile == '')
{
if ($this->sTmpFile == '') {
$this->sTmpFile = $this->MakeTmpFile($this->GetFileExtension());
}
$hFile = fopen($this->sTmpFile, 'ab');
if ($hFile !== false)
{
if ($hFile !== false) {
fwrite($hFile, $data);
fclose($hFile);
}
@@ -257,15 +247,13 @@ abstract class BulkExport
* Lists all possible export formats. The output is a hash array in the form: 'format_code' => 'localized format label'
* @return array :string
*/
static public function FindSupportedFormats()
public static function FindSupportedFormats()
{
$aSupportedFormats = array();
foreach(get_declared_classes() as $sPHPClass)
{
$aSupportedFormats = [];
foreach (get_declared_classes() as $sPHPClass) {
$oRefClass = new ReflectionClass($sPHPClass);
if ($oRefClass->isSubClassOf('BulkExport') && !$oRefClass->isAbstract())
{
$oBulkExporter = new $sPHPClass;
if ($oRefClass->isSubClassOf('BulkExport') && !$oRefClass->isAbstract()) {
$oBulkExporter = new $sPHPClass();
$aFormats = $oBulkExporter->GetSupportedFormats();
$aSupportedFormats = array_merge($aSupportedFormats, $aFormats);
}
@@ -282,13 +270,13 @@ abstract class BulkExport
$this->iChunkSize = $iChunkSize;
}
/**
* @param $bLocalizeOutput
*/
public function SetLocalizeOutput($bLocalizeOutput)
{
$this->bLocalizeOutput = $bLocalizeOutput;
}
/**
* @param $bLocalizeOutput
*/
public function SetLocalizeOutput($bLocalizeOutput)
{
$this->bLocalizeOutput = $bLocalizeOutput;
}
/**
* (non-PHPdoc)
@@ -320,10 +308,9 @@ abstract class BulkExport
*/
public function GetSupportedFormats()
{
return array(); // return array('csv' => Dict::S('UI:ExportFormatCSV'));
return []; // return array('csv' => Dict::S('UI:ExportFormatCSV'));
}
public function SetHttpHeaders(WebPage $oPage)
{
}
@@ -347,14 +334,13 @@ abstract class BulkExport
public function SaveState()
{
if ($this->oBulkExportResult === null)
{
if ($this->oBulkExportResult === null) {
$this->oBulkExportResult = new BulkExportResult();
$this->oBulkExportResult->Set('format', $this->sFormatCode);
$this->oBulkExportResult->Set('search', $this->oSearch->serialize());
$this->oBulkExportResult->Set('chunk_size', $this->iChunkSize);
$this->oBulkExportResult->Set('localize_output', $this->bLocalizeOutput);
}
$this->oBulkExportResult->Set('localize_output', $this->bLocalizeOutput);
}
$this->oBulkExportResult->Set('status_info', json_encode($this->GetStatusInfo()));
$this->oBulkExportResult->Set('temp_file_path', $this->sTmpFile);
utils::PushArchiveMode(false);
@@ -365,11 +351,9 @@ abstract class BulkExport
public function Cleanup()
{
if (($this->oBulkExportResult && (!$this->oBulkExportResult->IsNew())))
{
if (($this->oBulkExportResult && (!$this->oBulkExportResult->IsNew()))) {
$sFilename = $this->oBulkExportResult->Get('temp_file_path');
if ($sFilename != '')
{
if ($sFilename != '') {
@unlink($sFilename);
}
utils::PushArchiveMode(false);
@@ -380,7 +364,7 @@ abstract class BulkExport
public function EnumFormParts()
{
return array();
return [];
}
/**
@@ -464,25 +448,21 @@ abstract class BulkExport
*/
protected function MakeTmpFile($sExtension)
{
if(!is_dir(utils::GetDataPath()."bulk_export"))
{
if (!is_dir(utils::GetDataPath()."bulk_export")) {
@mkdir(utils::GetDataPath()."bulk_export", 0777, true /* recursive */);
clearstatcache();
}
if (!is_writable(utils::GetDataPath()."bulk_export"))
{
if (!is_writable(utils::GetDataPath()."bulk_export")) {
throw new Exception('Data directory "'.utils::GetDataPath().'bulk_export" could not be written.');
}
$iNum = rand();
do
{
do {
$iNum++;
$sToken = sprintf("%08x", $iNum);
$sFileName = utils::GetDataPath()."bulk_export/$sToken.".$sExtension;
$hFile = @fopen($sFileName, 'x');
}
while($hFile === false);
} while ($hFile === false);
fclose($hFile);
return $sFileName;
@@ -492,8 +472,7 @@ abstract class BulkExport
// The built-in exports
require_once(APPROOT.'core/tabularbulkexport.class.inc.php');
require_once(APPROOT.'core/htmlbulkexport.class.inc.php');
if (extension_loaded('gd'))
{
if (extension_loaded('gd')) {
// PDF export - via TCPDF - requires GD
require_once(APPROOT.'core/pdfbulkexport.class.inc.php');
}
@@ -501,4 +480,3 @@ require_once(APPROOT.'core/csvbulkexport.class.inc.php');
require_once(APPROOT.'core/excelbulkexport.class.inc.php');
require_once(APPROOT.'core/spreadsheetbulkexport.class.inc.php');
require_once(APPROOT.'core/xmlbulkexport.class.inc.php');

View File

@@ -1,4 +1,5 @@
<?php
// Copyright (C) 2010-2024 Combodo SAS
//
// This file is part of iTop.
@@ -16,7 +17,6 @@
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Class cmdbObject
*
@@ -24,7 +24,6 @@
* @license http://opensource.org/licenses/AGPL-3.0
*/
/**
* cmdbObjectClass
* the file to include, then the core is yours
@@ -148,8 +147,7 @@ abstract class CMDBObject extends DBObject
*/
public static function GetCurrentChange($bAutoCreate = true)
{
if ($bAutoCreate && is_null(self::$m_oCurrChange))
{
if ($bAutoCreate && is_null(self::$m_oCurrChange)) {
self::CreateChange();
}
return self::$m_oCurrChange;
@@ -214,7 +212,7 @@ abstract class CMDBObject extends DBObject
return CMDBChange::GetCurrentUserName();
} else {
//N°5135 - add impersonation information in activity log/current cmdb change
if (UserRights::IsImpersonated()){
if (UserRights::IsImpersonated()) {
return sprintf("%s (%s)", CMDBChange::GetCurrentUserName(), self::$m_sInfo);
} else {
return self::$m_sInfo;
@@ -234,12 +232,9 @@ abstract class CMDBObject extends DBObject
if (is_null(self::$m_sUserId)
//N°5135 - indicate impersonation inside changelogs
&& (false === UserRights::IsImpersonated())
)
{
) {
return CMDBChange::GetCurrentUserId();
}
else
{
} else {
return self::$m_sUserId;
}
}
@@ -249,12 +244,9 @@ abstract class CMDBObject extends DBObject
*/
protected static function GetTrackOrigin()
{
if (is_null(self::$m_sOrigin))
{
if (is_null(self::$m_sOrigin)) {
return 'interactive';
}
else
{
} else {
return self::$m_sOrigin;
}
}
@@ -382,14 +374,10 @@ abstract class CMDBObject extends DBObject
// $aValues is an array of $sAttCode => $value
//
foreach ($aValues as $sAttCode=> $value)
{
if (array_key_exists($sAttCode, $aOrigValues))
{
foreach ($aValues as $sAttCode => $value) {
if (array_key_exists($sAttCode, $aOrigValues)) {
$original = $aOrigValues[$sAttCode];
}
else
{
} else {
$original = null;
}
$this->RecordAttChange($sAttCode, $original, $value);
@@ -431,8 +419,7 @@ abstract class CMDBObject extends DBObject
$bOriginal = $this->Get('archive_flag');
parent::DBArchive();
if (!$bOriginal)
{
if (!$bOriginal) {
utils::PushArchiveMode(false);
$this->RecordAttChange('archive_flag', false, true);
utils::PopArchiveMode();
@@ -445,8 +432,7 @@ abstract class CMDBObject extends DBObject
$bOriginal = $this->Get('archive_flag');
parent::DBUnarchive();
if ($bOriginal)
{
if ($bOriginal) {
utils::PushArchiveMode(false);
$this->RecordAttChange('archive_flag', true, false);
utils::PopArchiveMode();
@@ -454,8 +440,6 @@ abstract class CMDBObject extends DBObject
}
}
/**
* TODO: investigate how to get rid of this class that was made to workaround some language limitation... or a poor design!
*
@@ -471,7 +455,7 @@ class CMDBObjectSet extends DBObjectSet
// just to get the right object class in return.
// I have to think again to those things: maybe it will work fine if a have a constructor define here (?)
static public function FromScratch($sClass)
public static function FromScratch($sClass)
{
$oFilter = new DBObjectSearch($sClass);
$oFilter->AddConditionExpression(new FalseExpression());
@@ -483,14 +467,14 @@ class CMDBObjectSet extends DBObjectSet
// create an object set ex nihilo
// input = array of objects
static public function FromArray($sClass, $aObjects)
public static function FromArray($sClass, $aObjects)
{
$oRetSet = self::FromScratch($sClass);
$oRetSet->AddObjectArray($aObjects, $sClass);
return $oRetSet;
}
static public function FromArrayAssoc($aClasses, $aObjects)
public static function FromArrayAssoc($aClasses, $aObjects)
{
// In a perfect world, we should create a complete tree of DBObjectSearch,
// but as we lack most of the information related to the objects,
@@ -502,8 +486,7 @@ class CMDBObjectSet extends DBObjectSet
$oRetSet = new CMDBObjectSet($oFilter);
$oRetSet->m_bLoaded = true; // no DB load
foreach($aObjects as $rowIndex => $aObjectsByClassAlias)
{
foreach ($aObjects as $rowIndex => $aObjectsByClassAlias) {
$oRetSet->AddObjectExtended($aObjectsByClassAlias);
}
return $oRetSet;

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (C) 2013-2024 Combodo SAS
*
@@ -19,7 +20,6 @@
*
*/
use Combodo\iTop\Config\Validator\iTopConfigAstValidator;
use Combodo\iTop\Config\Validator\iTopConfigSyntaxValidator;
@@ -68,7 +68,6 @@ define('DEFAULT_LOG_WEB_SERVICE', true);
define('DEFAULT_QUERY_CACHE_ENABLED', true);
define('DEFAULT_MIN_DISPLAY_LIMIT', 20);
define('DEFAULT_MAX_DISPLAY_LIMIT', 30);
define('DEFAULT_STANDARD_RELOAD_INTERVAL', 5 * 60);
@@ -441,14 +440,14 @@ class Config
'show_in_conf_sample' => true,
],
'export_pdf_font' => [ // @since 2.7.0 PR #49 / N°1947
'type' => 'string',
'description' => 'Font used when generating a PDF file',
'default' => 'DejaVuSans', // DejaVuSans is a UTF-8 Unicode font, embedded in the TCPPDF lib we're using
// Standard PDF fonts like helvetica or times newroman are NOT Unicode
// A new DroidSansFallback can be used to improve CJK support (se PR #49)
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
'type' => 'string',
'description' => 'Font used when generating a PDF file',
'default' => 'DejaVuSans', // DejaVuSans is a UTF-8 Unicode font, embedded in the TCPPDF lib we're using
// Standard PDF fonts like helvetica or times newroman are NOT Unicode
// A new DroidSansFallback can be used to improve CJK support (se PR #49)
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'access_mode' => [
'type' => 'integer',
@@ -891,7 +890,7 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
'forgot_password.url' => [
'forgot_password.url' => [
'type' => 'string',
'description' => 'Set this value to your "forgot password" service URL if it should be handled out of '.ITOP_APPLICATION_SHORT.'. Note that it will apply to all users (iTop users, LDAP users, ...)',
'default' => '',
@@ -1803,7 +1802,7 @@ class Config
'default' => ITOP_APPLICATION.'/'.ITOP_VERSION,
'source_of_value' => '',
'show_in_conf_sample' => false,
]
],
];
public function IsProperty($sPropCode)
@@ -1811,7 +1810,6 @@ class Config
return (array_key_exists($sPropCode, $this->m_aSettings));
}
/**
* @return string identifier that can be used for example to name WebStorage/SessionStorage keys (they
* are related to a whole domain, and a domain can host multiple itop)
@@ -1845,8 +1843,7 @@ class Config
$value = $this->oConfigPlaceholdersResolver->Resolve($value);
switch ($sType)
{
switch ($sType) {
case 'bool':
$value = (bool)$value;
break;
@@ -1854,7 +1851,7 @@ class Config
$value = (string)$value;
break;
case 'integer':
$value = (integer)$value;
$value = (int)$value;
break;
case 'float':
$value = (float)$value;
@@ -1862,11 +1859,10 @@ class Config
case 'array':
break;
default:
throw new CoreException('Unknown type for setting', array('property' => $sPropCode, 'type' => $sType));
throw new CoreException('Unknown type for setting', ['property' => $sPropCode, 'type' => $sType]);
}
if ($this->m_aSettings[$sPropCode]['value'] == $value)
{
if ($this->m_aSettings[$sPropCode]['value'] == $value) {
//when you set the exact same value than the previous one, then, you still can preserve the non evaluated version and so on preserve vars/jokers.
$bCanOverride = true;
}
@@ -2008,15 +2004,13 @@ class Config
$this->oConfigPlaceholdersResolver = new ConfigPlaceholdersResolver();
$this->m_sFile = $sConfigFile;
if (is_null($sConfigFile))
{
if (is_null($sConfigFile)) {
$bLoadConfig = false;
}
$this->m_aAddons = [];
foreach ($this->m_aSettings as $sPropCode => $aSettingInfo)
{
foreach ($this->m_aSettings as $sPropCode => $aSettingInfo) {
$this->m_aSettings[$sPropCode]['value'] = $aSettingInfo['default'];
}
@@ -2032,7 +2026,7 @@ class Config
$this->m_sDefaultLanguage = 'EN US';
$this->m_sAllowedLoginTypes = DEFAULT_ALLOWED_LOGIN_TYPES;
$this->m_sExtAuthVariable = DEFAULT_EXT_AUTH_VARIABLE;
$this->m_aCharsets = array();
$this->m_aCharsets = [];
$this->m_bQueryCacheEnabled = DEFAULT_QUERY_CACHE_ENABLED;
$this->m_iPasswordHashAlgo = DEFAULT_HASH_ALGO;
$this->m_sAppSecret = bin2hex(random_bytes(16));
@@ -2042,10 +2036,9 @@ class Config
$this->m_sEncryptionLibrary = isset($aEncryptParams['lib']) ? $aEncryptParams['lib'] : DEFAULT_ENCRYPTION_LIB;
$this->m_sEncryptionKey = isset($aEncryptParams['key']) ? $aEncryptParams['key'] : DEFAULT_ENCRYPTION_KEY;
$this->m_aModuleSettings = array();
$this->m_aModuleSettings = [];
if ($bLoadConfig)
{
if ($bLoadConfig) {
$this->Load($sConfigFile);
$this->Verify();
}
@@ -2074,14 +2067,14 @@ class Config
*/
protected function CheckFile($sPurpose, $sFileName)
{
if (!file_exists($sFileName))
{
throw new ConfigException("Could not find $sPurpose file", array('file' => $sFileName));
if (!file_exists($sFileName)) {
throw new ConfigException("Could not find $sPurpose file", ['file' => $sFileName]);
}
if (!is_readable($sFileName))
{
throw new ConfigException("Could not read $sPurpose file (the file exists but cannot be read). Do you have the rights to access this file?",
array('file' => $sFileName));
if (!is_readable($sFileName)) {
throw new ConfigException(
"Could not read $sPurpose file (the file exists but cannot be read). Do you have the rights to access this file?",
['file' => $sFileName]
);
}
}
@@ -2108,64 +2101,58 @@ class Config
// This does not work on several lines
// preg_match('/^<\\?php(.*)\\?'.'>$/', $sConfigCode, $aMatches)...
// So, I've implemented a solution suggested in the PHP doc (search for phpWrapper)
try
{
try {
ob_start();
eval('?'.'>'.trim($sConfigCode));
$sNoise = trim(ob_get_contents());
ob_end_clean();
}
catch (Error $e)
{
} catch (Error $e) {
// PHP 7
throw new ConfigException('Error in configuration file',
array('file' => $sConfigFile, 'error' => $e->getMessage().' at line '.$e->getLine()));
}
catch (Exception $e)
{
throw new ConfigException(
'Error in configuration file',
['file' => $sConfigFile, 'error' => $e->getMessage().' at line '.$e->getLine()]
);
} catch (Exception $e) {
// well, never reach in case of parsing error :-(
// will be improved in PHP 6 ?
throw new ConfigException('Error in configuration file',
array('file' => $sConfigFile, 'error' => $e->getMessage()));
throw new ConfigException(
'Error in configuration file',
['file' => $sConfigFile, 'error' => $e->getMessage()]
);
}
if (strlen($sNoise) > 0)
{
if (strlen($sNoise) > 0) {
// Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack)
throw new ConfigException('Syntax error in configuration file',
array('file' => $sConfigFile, 'error' => '<tt>'.utils::EscapeHtml($sNoise, ENT_QUOTES).'</tt>'));
throw new ConfigException(
'Syntax error in configuration file',
['file' => $sConfigFile, 'error' => '<tt>'.utils::EscapeHtml($sNoise, ENT_QUOTES).'</tt>']
);
}
if (!isset($MySettings) || !is_array($MySettings))
{
throw new ConfigException('Missing array in configuration file',
array('file' => $sConfigFile, 'expected' => '$MySettings'));
if (!isset($MySettings) || !is_array($MySettings)) {
throw new ConfigException(
'Missing array in configuration file',
['file' => $sConfigFile, 'expected' => '$MySettings']
);
}
if (!array_key_exists('addons', $MyModules) || !array_key_exists('user rights', $MyModules['addons']))
{
if (!array_key_exists('addons', $MyModules) || !array_key_exists('user rights', $MyModules['addons'])) {
// Add one, by default
$MyModules['addons']['user rights'] = 'addons/userrights/userrightsprofile.class.inc.php';
$this->m_aAddons = $MyModules['addons'];
}
foreach ($MySettings as $sPropCode => $rawvalue)
{
if ($this->IsProperty($sPropCode))
{
if (is_string($rawvalue))
{
foreach ($MySettings as $sPropCode => $rawvalue) {
if ($this->IsProperty($sPropCode)) {
if (is_string($rawvalue)) {
$value = trim($rawvalue);
}
else
{
} else {
$value = $rawvalue;
}
$this->Set($sPropCode, $value, $sConfigFile, true);
}
}
if (file_exists(READONLY_MODE_FILE))
{
if (file_exists(READONLY_MODE_FILE)) {
$this->Set('access_mode', ACCESS_READONLY, READONLY_MODE_FILE);
}
@@ -2181,14 +2168,14 @@ class Config
$this->m_iFastReloadInterval = isset($MySettings['fast_reload_interval']) ? trim($MySettings['fast_reload_interval']) : DEFAULT_FAST_RELOAD_INTERVAL;
$this->m_bSecureConnectionRequired = isset($MySettings['secure_connection_required']) ? (bool)trim($MySettings['secure_connection_required']) : DEFAULT_SECURE_CONNECTION_REQUIRED;
$this->m_aModuleSettings = isset($MyModuleSettings) ? $MyModuleSettings : array();
$this->m_aModuleSettings = isset($MyModuleSettings) ? $MyModuleSettings : [];
$this->m_sDefaultLanguage = isset($MySettings['default_language']) ? trim($MySettings['default_language']) : 'EN US';
$this->m_sAllowedLoginTypes = isset($MySettings['allowed_login_types']) ? trim($MySettings['allowed_login_types']) : DEFAULT_ALLOWED_LOGIN_TYPES;
$this->m_sExtAuthVariable = isset($MySettings['ext_auth_variable']) ? trim($MySettings['ext_auth_variable']) : DEFAULT_EXT_AUTH_VARIABLE;
$this->m_sEncryptionKey = isset($MySettings['encryption_key']) ? trim($MySettings['encryption_key']) : $this->m_sEncryptionKey;
$this->m_sEncryptionLibrary = isset($MySettings['encryption_library']) ? trim($MySettings['encryption_library']) : $this->m_sEncryptionLibrary;
$this->m_aCharsets = isset($MySettings['csv_import_charsets']) ? $MySettings['csv_import_charsets'] : array();
$this->m_aCharsets = isset($MySettings['csv_import_charsets']) ? $MySettings['csv_import_charsets'] : [];
$this->m_iPasswordHashAlgo = isset($MySettings['password_hash_algo']) ? $MySettings['password_hash_algo'] : $this->m_iPasswordHashAlgo;
}
@@ -2210,8 +2197,7 @@ class Config
*/
public function GetModuleSetting($sModule, $sProperty, $defaultvalue = null)
{
if (isset($this->m_aModuleSettings[$sModule][$sProperty]))
{
if (isset($this->m_aModuleSettings[$sModule][$sProperty])) {
return $this->m_aModuleSettings[$sModule][$sProperty];
}
@@ -2233,11 +2219,9 @@ class Config
public function GetModuleParameter($sModule, $sProperty, $defaultvalue = null)
{
$ret = $defaultvalue;
if (class_exists('ModulesXMLParameters'))
{
if (class_exists('ModulesXMLParameters')) {
$aAllParams = ModulesXMLParameters::GetData($sModule);
if (array_key_exists($sProperty, $aAllParams))
{
if (array_key_exists($sProperty, $aAllParams)) {
$ret = $aAllParams[$sProperty];
}
}
@@ -2255,10 +2239,10 @@ class Config
*/
public function GetAddons()
{
if (array_key_exists("user rights", $this->m_aAddons)) {
if (array_key_exists("user rights", $this->m_aAddons)) {
return $this->m_aAddons;
} else {
return array_merge($this->m_aAddons,['user rights' => 'addons/userrights/userrightsprofile.class.inc.php']);
return array_merge($this->m_aAddons, ['user rights' => 'addons/userrights/userrightsprofile.class.inc.php']);
}
}
@@ -2438,7 +2422,7 @@ class Config
public function AddAllowedLoginTypes($sLoginMode)
{
$aAllowedLoginTypes = $this->GetAllowedLoginTypes();
if (in_array($sLoginMode, $aAllowedLoginTypes)){
if (in_array($sLoginMode, $aAllowedLoginTypes)) {
return;
}
@@ -2461,7 +2445,6 @@ class Config
$this->m_sAppSecret = $sKey;
}
public function SetCSVImportCharsets($aCharsets)
{
$this->m_aCharsets = $aCharsets;
@@ -2474,12 +2457,9 @@ class Config
public function GetLoadedFile()
{
if (is_null($this->m_sFile))
{
if (is_null($this->m_sFile)) {
return '';
}
else
{
} else {
return $this->m_sFile;
}
}
@@ -2491,9 +2471,8 @@ class Config
*/
public function ToArray()
{
$aSettings = array();
foreach ($this->m_aSettings as $sPropCode => $aSettingInfo)
{
$aSettings = [];
foreach ($this->m_aSettings as $sPropCode => $aSettingInfo) {
$aSettings[$sPropCode] = $aSettingInfo['value'];
}
$aSettings['log_global'] = $this->m_bLogGlobal;
@@ -2514,15 +2493,12 @@ class Config
$aSettings['csv_import_charsets'] = $this->m_aCharsets;
$aSettings['password_hash_algo'] = $this->m_iPasswordHashAlgo;
foreach ($this->m_aModuleSettings as $sModule => $aProperties)
{
foreach ($aProperties as $sProperty => $value)
{
foreach ($this->m_aModuleSettings as $sModule => $aProperties) {
foreach ($aProperties as $sProperty => $value) {
$aSettings['module_settings'][$sModule][$sProperty] = $value;
}
}
foreach ($this->m_aAddons as $sKey => $sFile)
{
foreach ($this->m_aAddons as $sKey => $sFile) {
$aSettings['addon_list'][] = $sFile;
}
@@ -2541,22 +2517,18 @@ class Config
*/
public function WriteToFile($sFileName = '')
{
if (empty($sFileName))
{
if (empty($sFileName)) {
$sFileName = $this->m_sFile;
}
$oHandle = null;
$sConfig = null;
if ($this->m_sFile !== null && is_file($this->m_sFile))
{
if ($this->m_sFile !== null && is_file($this->m_sFile)) {
$oHandle = fopen($this->m_sFile, 'r');
$index = 0;
while (!flock($oHandle, LOCK_SH))
{
if ($index > 50)
{
throw new ConfigException("Could not read to configuration file", array('file' => $this->m_sFile));
while (!flock($oHandle, LOCK_SH)) {
if ($index > 50) {
throw new ConfigException("Could not read to configuration file", ['file' => $this->m_sFile]);
}
usleep(100000);
$index++;
@@ -2564,61 +2536,59 @@ class Config
$sConfig = file_get_contents($this->m_sFile);
}
$this->oItopConfigParser = new iTopConfigParser($sConfig);
if ($oHandle !==null)
{
if ($oHandle !== null) {
flock($oHandle, LOCK_UN);
}
$hFile = @fopen($sFileName, 'w');
if ($hFile !== false)
{
if ($hFile !== false) {
fwrite($hFile, "<?php\n");
fwrite($hFile, "\n/**\n");
fwrite($hFile, " *\n");
fwrite($hFile, " * Configuration file, generated by the ".ITOP_APPLICATION." configuration wizard\n");
fwrite($hFile, " *\n");
fwrite($hFile,
" * The file is used in MetaModel::LoadConfig() which does all the necessary initialization job\n");
fwrite(
$hFile,
" * The file is used in MetaModel::LoadConfig() which does all the necessary initialization job\n"
);
fwrite($hFile, " *\n");
fwrite($hFile, " */\n");
$aConfigSettings = $this->m_aSettings;
// Old fashioned boolean settings
$aBoolValues = array(
$aBoolValues = [
'log_global' => $this->m_bLogGlobal,
'log_notification' => $this->m_bLogNotification,
'log_issue' => $this->m_bLogIssue,
'log_web_service' => $this->m_bLogWebService,
'secure_connection_required' => $this->m_bSecureConnectionRequired,
);
foreach ($aBoolValues as $sKey => $bValue)
{
$aConfigSettings[$sKey] = array(
];
foreach ($aBoolValues as $sKey => $bValue) {
$aConfigSettings[$sKey] = [
'show_in_conf_sample' => true,
'type' => 'bool',
'value' => $bValue,
);
];
}
// Old fashioned integer settings
$aIntValues = array(
$aIntValues = [
'fast_reload_interval' => $this->m_iFastReloadInterval,
'max_display_limit' => $this->m_iMaxDisplayLimit,
'min_display_limit' => $this->m_iMinDisplayLimit,
'standard_reload_interval' => $this->m_iStandardReloadInterval,
);
foreach ($aIntValues as $sKey => $iValue)
{
$aConfigSettings[$sKey] = array(
];
foreach ($aIntValues as $sKey => $iValue) {
$aConfigSettings[$sKey] = [
'show_in_conf_sample' => true,
'type' => 'integer',
'value' => $iValue,
);
];
}
// Old fashioned remaining values
$aOtherValues = array(
$aOtherValues = [
'default_language' => $this->m_sDefaultLanguage,
'allowed_login_types' => $this->m_sAllowedLoginTypes,
'ext_auth_variable' => $this->m_sExtAuthVariable,
@@ -2626,45 +2596,37 @@ class Config
'encryption_library' => $this->m_sEncryptionLibrary,
'csv_import_charsets' => $this->m_aCharsets,
'password_hash_algo' => $this->m_iPasswordHashAlgo,
);
foreach ($aOtherValues as $sKey => $value)
{
$aConfigSettings[$sKey] = array(
];
foreach ($aOtherValues as $sKey => $value) {
$aConfigSettings[$sKey] = [
'show_in_conf_sample' => true,
'type' => is_string($value) ? 'string' : 'mixed',
'value' => $value,
);
];
}
ksort($aConfigSettings);
fwrite($hFile, "\$MySettings = array(\n");
foreach ($aConfigSettings as $sPropCode => $aSettingInfo)
{
foreach ($aConfigSettings as $sPropCode => $aSettingInfo) {
// Write all values that are either always visible or present in the cloned config file
if ($aSettingInfo['show_in_conf_sample'] || (!empty($aSettingInfo['source_of_value']) && ($aSettingInfo['source_of_value'] != 'unknown')))
{
if ($aSettingInfo['show_in_conf_sample'] || (!empty($aSettingInfo['source_of_value']) && ($aSettingInfo['source_of_value'] != 'unknown'))) {
fwrite($hFile, "\n");
if (isset($aSettingInfo['description']))
{
if (isset($aSettingInfo['description'])) {
fwrite($hFile, "\t// $sPropCode: {$aSettingInfo['description']}\n");
}
if (isset($aSettingInfo['default']))
{
$sComment = self::PrettyVarExport(null,$aSettingInfo['default'], "\t//\t\t", true);
fwrite($hFile,"\t//\tdefault: {$sComment}\n");
if (isset($aSettingInfo['default'])) {
$sComment = self::PrettyVarExport(null, $aSettingInfo['default'], "\t//\t\t", true);
fwrite($hFile, "\t//\tdefault: {$sComment}\n");
}
if (isset($this->m_aCanOverrideSettings[$sPropCode]) && $this->m_aCanOverrideSettings[$sPropCode])
{
if (isset($this->m_aCanOverrideSettings[$sPropCode]) && $this->m_aCanOverrideSettings[$sPropCode]) {
$aParserValue = $this->oItopConfigParser->GetVarValue('MySettings', $sPropCode);
}
else
{
} else {
$aParserValue = null;
}
$sSeenAs = self::PrettyVarExport($aParserValue,$aSettingInfo['value'], "\t");
$sSeenAs = self::PrettyVarExport($aParserValue, $aSettingInfo['value'], "\t");
fwrite($hFile, "\t'$sPropCode' => $sSeenAs,\n");
}
}
@@ -2673,11 +2635,9 @@ class Config
fwrite($hFile, "\n");
fwrite($hFile, "/**\n *\n * Modules specific settings\n *\n */\n");
fwrite($hFile, "\$MyModuleSettings = array(\n");
foreach ($this->m_aModuleSettings as $sModule => $aProperties)
{
foreach ($this->m_aModuleSettings as $sModule => $aProperties) {
fwrite($hFile, "\t'$sModule' => array (\n");
foreach ($aProperties as $sProperty => $value)
{
foreach ($aProperties as $sProperty => $value) {
$sNiceExport = self::PrettyVarExport($this->oItopConfigParser->GetVarValue('MyModuleSettings', $sProperty), $value, "\t\t");
fwrite($hFile, "\t\t'$sProperty' => $sNiceExport,\n");
}
@@ -2692,8 +2652,7 @@ class Config
fwrite($hFile, " */\n");
fwrite($hFile, "\$MyModules = array(\n");
$aParserValue = $this->oItopConfigParser->GetVarValue('MyModules', 'addons');
if ($aParserValue['found'])
{
if ($aParserValue['found']) {
fwrite($hFile, "\t'addons' => {$aParserValue['value']},\n");
}
fwrite($hFile, ");\n");
@@ -2704,10 +2663,8 @@ class Config
utils::SetConfig($this);
return $bReturn;
}
else
{
throw new ConfigException("Could not write to configuration file", array('file' => $sFileName));
} else {
throw new ConfigException("Could not write to configuration file", ['file' => $sFileName]);
}
}
@@ -2728,32 +2685,25 @@ class Config
*/
public function UpdateFromParams($aParamValues, $sModulesDir = null, $bPreserveModuleSettings = false)
{
if (isset($aParamValues['application_path']))
{
if (isset($aParamValues['application_path'])) {
$this->Set('app_root_url', $aParamValues['application_path']);
}
if (isset($aParamValues['graphviz_path']))
{
if (isset($aParamValues['graphviz_path'])) {
$this->Set('graphviz_path', $aParamValues['graphviz_path']);
}
if (isset($aParamValues['mode']) && isset($aParamValues['language']))
{
if (($aParamValues['mode'] == 'install') || $this->GetDefaultLanguage() == '')
{
if (isset($aParamValues['mode']) && isset($aParamValues['language'])) {
if (($aParamValues['mode'] == 'install') || $this->GetDefaultLanguage() == '') {
$this->SetDefaultLanguage($aParamValues['language']);
}
}
if (isset($aParamValues['db_server']))
{
if (isset($aParamValues['db_server'])) {
$this->Set('db_host', $aParamValues['db_server']);
$this->Set('db_user', $aParamValues['db_user']);
$this->Set('db_pwd', $aParamValues['db_pwd']);
$sDBName = $aParamValues['db_name'];
if ($sDBName == '')
{
if ($sDBName == '') {
// Todo - obsolete after the transition to the new setup (2.0) is complete (WARNING: used by the designer)
if (isset($aParamValues['new_db_name']))
{
if (isset($aParamValues['new_db_name'])) {
$sDBName = $aParamValues['new_db_name'];
}
}
@@ -2761,39 +2711,29 @@ class Config
$this->Set('db_subname', $aParamValues['db_prefix']);
$bDbTlsEnabled = (bool)$aParamValues['db_tls_enabled'];
if ($bDbTlsEnabled)
{
if ($bDbTlsEnabled) {
$this->Set('db_tls.enabled', $bDbTlsEnabled, 'UpdateFromParams');
}
else
{
} else {
// disabled : we don't want parameter in the file
$this->Set('db_tls.enabled', $bDbTlsEnabled, null);
}
$sDbTlsCa = $bDbTlsEnabled ? $aParamValues['db_tls_ca'] : null;
if (isset($sDbTlsCa) && !empty($sDbTlsCa))
{
if (isset($sDbTlsCa) && !empty($sDbTlsCa)) {
$this->Set('db_tls.ca', $sDbTlsCa, 'UpdateFromParams');
}
else
{
} else {
// empty parameter : we don't want it in the file
$this->Set('db_tls.ca', null, null);
}
}
if (isset($aParamValues['selected_modules']))
{
if (isset($aParamValues['selected_modules'])) {
$aSelectedModules = explode(',', $aParamValues['selected_modules']);
}
else
{
} else {
$aSelectedModules = null;
}
$this->UpdateIncludes($sModulesDir, $aSelectedModules);
if (isset($aParamValues['source_dir']))
{
if (isset($aParamValues['source_dir'])) {
$this->Set('source_dir', $aParamValues['source_dir']);
}
}
@@ -2811,8 +2751,7 @@ class Config
*/
public function UpdateIncludes($sModulesDir, $aSelectedModules = null)
{
if ($sModulesDir === null)
{
if ($sModulesDir === null) {
return;
}
@@ -2820,23 +2759,16 @@ class Config
$oEmptyConfig = new Config('dummy_file', false); // Do NOT load any config file, just set the default values
$aAddOns = $oEmptyConfig->GetAddOns();
$aModules = ModuleDiscovery::GetAvailableModules(array(APPROOT.$sModulesDir));
foreach ($aModules as $sModuleId => $aModuleInfo)
{
list ($sModuleName, $sModuleVersion) = ModuleDiscovery::GetModuleName($sModuleId);
if (is_null($aSelectedModules) || in_array($sModuleName, $aSelectedModules))
{
if (isset($aModuleInfo['settings']))
{
list ($sName, $sVersion) = ModuleDiscovery::GetModuleName($sModuleId);
foreach ($aModuleInfo['settings'] as $sProperty => $value)
{
if (isset($this->m_aModuleSettings[$sName][$sProperty]))
{
$aModules = ModuleDiscovery::GetAvailableModules([APPROOT.$sModulesDir]);
foreach ($aModules as $sModuleId => $aModuleInfo) {
list($sModuleName, $sModuleVersion) = ModuleDiscovery::GetModuleName($sModuleId);
if (is_null($aSelectedModules) || in_array($sModuleName, $aSelectedModules)) {
if (isset($aModuleInfo['settings'])) {
list($sName, $sVersion) = ModuleDiscovery::GetModuleName($sModuleId);
foreach ($aModuleInfo['settings'] as $sProperty => $value) {
if (isset($this->m_aModuleSettings[$sName][$sProperty])) {
// Do nothing keep the original value
}
else
{
} else {
$this->SetModuleSetting($sName, $sProperty, $value);
}
}
@@ -2857,10 +2789,8 @@ class Config
*/
protected static function ChangePrefix(&$aStrings, $sSearchPrefix, $sNewPrefix)
{
foreach ($aStrings as &$sFile)
{
if (substr($sFile, 0, strlen($sSearchPrefix)) == $sSearchPrefix)
{
foreach ($aStrings as &$sFile) {
if (substr($sFile, 0, strlen($sSearchPrefix)) == $sSearchPrefix) {
$sFile = $sNewPrefix.substr($sFile, strlen($sSearchPrefix));
}
}
@@ -2891,22 +2821,19 @@ class Config
*/
protected static function PrettyVarExport($aParserValue, $value, $sIndentation, $bForceIndentation = false)
{
if (is_array($aParserValue) && $aParserValue['found'])
{
if (is_array($aParserValue) && $aParserValue['found']) {
return $aParserValue['value'];
}
$sExport = var_export($value, true);
$sNiceExport = str_replace(array("\r\n", "\n", "\r"), "\n".$sIndentation, trim($sExport));
if (!$bForceIndentation)
{
$sNiceExport = str_replace(["\r\n", "\n", "\r"], "\n".$sIndentation, trim($sExport));
if (!$bForceIndentation) {
/** @var array $aImported */
$aImported = null;
eval('$aImported='.$sNiceExport.';');
// Check if adding the identations at the beginning of each line
// did not modify the values (in case of a string containing a line break)
if ($aImported != $value)
{
if ($aImported != $value) {
$sNiceExport = $sExport;
}
}
@@ -2935,37 +2862,31 @@ class ConfigPlaceholdersResolver
public function Resolve($rawValue)
{
if (empty($this->aEnv['ITOP_CONFIG_PLACEHOLDERS']) && empty($this->aServer['ITOP_CONFIG_PLACEHOLDERS']))
{
if (empty($this->aEnv['ITOP_CONFIG_PLACEHOLDERS']) && empty($this->aServer['ITOP_CONFIG_PLACEHOLDERS'])) {
return $rawValue;
}
if (is_array($rawValue))
{
$aResolvedRawValue = array();
foreach ($rawValue as $key => $value)
{
if (is_array($rawValue)) {
$aResolvedRawValue = [];
foreach ($rawValue as $key => $value) {
$aResolvedRawValue[$key] = $this->Resolve($value);
}
return $aResolvedRawValue;
}
if (!is_string($rawValue))
{
if (!is_string($rawValue)) {
return $rawValue;
}
$sPattern = '/\%(env|server)\((\w+)\)(?:\?:(\w*))?\%/'; //3 capturing groups, ie `%env(HTTP_PORT)?:8080%` produce: `env` `HTTP_PORT` and `8080`.
if (! preg_match_all($sPattern, $rawValue, $aMatchesCollection, PREG_SET_ORDER))
{
if (! preg_match_all($sPattern, $rawValue, $aMatchesCollection, PREG_SET_ORDER)) {
return $rawValue;
}
$sValue = $rawValue;
foreach ($aMatchesCollection as $aMatches)
{
foreach ($aMatchesCollection as $aMatches) {
$sWholeMask = $aMatches[0];
$sSource = $aMatches[1];
$sKey = $aMatches[2];
@@ -2981,35 +2902,27 @@ class ConfigPlaceholdersResolver
private function Get($sSourceName, $sKey, $sDefault, $sWholeMask)
{
if ('env' == $sSourceName)
{
if ('env' == $sSourceName) {
$aSource = $this->aEnv;
}
else if ('server' == $sSourceName)
{
} elseif ('server' == $sSourceName) {
$aSource = $this->aServer;
}
else
{
} else {
$sErrorMessage = sprintf('unsupported source name "%s" into "%s"', $sSourceName, $sWholeMask);
IssueLog::Error($sErrorMessage, self::class, array($sSourceName, $sKey, $sDefault, $sWholeMask));
IssueLog::Error($sErrorMessage, self::class, [$sSourceName, $sKey, $sDefault, $sWholeMask]);
throw new ConfigException($sErrorMessage);
}
if (array_key_exists($sKey, $aSource))
{
if (array_key_exists($sKey, $aSource)) {
return $aSource[$sKey];
}
if (null !== $sDefault)
{
if (null !== $sDefault) {
return $sDefault;
}
$sErrorMessage = sprintf('key "%s" not found into "%s" while expanding', $sSourceName, $sWholeMask);
IssueLog::Error($sErrorMessage, self::class, array($sSourceName, $sKey, $sDefault, $sWholeMask));
IssueLog::Error($sErrorMessage, self::class, [$sSourceName, $sKey, $sDefault, $sWholeMask]);
throw new ConfigException($sErrorMessage);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
<?php
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
@@ -26,29 +27,25 @@ class DBUnionSearch extends DBSearch
protected $aSearches; // source queries
protected $aSelectedClasses; // alias => classes (lowest common ancestors) computed at construction
protected $aColumnToAliases;
/**
* DBUnionSearch constructor.
*
* @api
*
* @param $aSearches
*
* @throws CoreException
*/
/**
* DBUnionSearch constructor.
*
* @api
*
* @param $aSearches
*
* @throws CoreException
*/
public function __construct($aSearches)
{
if (count ($aSearches) == 0)
{
if (count($aSearches) == 0) {
throw new CoreException('A DBUnionSearch must be made of at least one search');
}
$this->aSearches = array();
foreach ($aSearches as $oSearch)
{
if ($oSearch instanceof DBUnionSearch)
{
foreach ($oSearch->aSearches as $oSubSearch)
{
$this->aSearches = [];
foreach ($aSearches as $oSearch) {
if ($oSearch instanceof DBUnionSearch) {
foreach ($oSearch->aSearches as $oSubSearch) {
$this->aSearches[] = $oSubSearch->DeepClone();
}
} else {
@@ -69,15 +66,16 @@ class DBUnionSearch extends DBSearch
public function IsAllDataAllowed()
{
foreach ($this->aSearches as $oSearch) {
if ($oSearch->IsAllDataAllowed() === false) return false;
if ($oSearch->IsAllDataAllowed() === false) {
return false;
}
}
return true;
}
public function SetArchiveMode($bEnable)
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->SetArchiveMode($bEnable);
}
parent::SetArchiveMode($bEnable);
@@ -85,8 +83,7 @@ class DBUnionSearch extends DBSearch
public function SetShowObsoleteData($bShow)
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->SetShowObsoleteData($bShow);
}
parent::SetShowObsoleteData($bShow);
@@ -102,31 +99,25 @@ class DBUnionSearch extends DBSearch
// 1 - Collect all the column/classes
$aColumnToClasses = [];
$this->aColumnToAliases = [];
foreach ($this->aSearches as $iPos => $oSearch)
{
foreach ($this->aSearches as $iPos => $oSearch) {
$aSelected = array_values($oSearch->GetSelectedClasses());
if ($iPos != 0)
{
if (count($aSelected) < count($aColumnToClasses))
{
throw new Exception('Too few selected classes in the subquery #'.($iPos+1));
if ($iPos != 0) {
if (count($aSelected) < count($aColumnToClasses)) {
throw new Exception('Too few selected classes in the subquery #'.($iPos + 1));
}
if (count($aSelected) > count($aColumnToClasses))
{
throw new Exception('Too many selected classes in the subquery #'.($iPos+1));
if (count($aSelected) > count($aColumnToClasses)) {
throw new Exception('Too many selected classes in the subquery #'.($iPos + 1));
}
}
foreach ($aSelected as $iColumn => $sClass)
{
foreach ($aSelected as $iColumn => $sClass) {
$aColumnToClasses[$iColumn][$iPos] = $sClass;
}
// Store the aliases by column to map them later (the first query impose the aliases)
$aAliases = array_keys($oSearch->GetSelectedClasses());
foreach ($aAliases as $iColumn => $sAlias)
{
foreach ($aAliases as $iColumn => $sAlias) {
$this->aColumnToAliases[$iColumn][$iPos] = $sAlias;
}
}
@@ -137,13 +128,11 @@ class DBUnionSearch extends DBSearch
// 3 - Compute alias => lowest common ancestor
$this->aSelectedClasses = [];
foreach ($aColumnToClasses as $iColumn => $aClasses)
{
foreach ($aColumnToClasses as $iColumn => $aClasses) {
$sAlias = $aColumnToAlias[$iColumn];
$sAncestor = MetaModel::GetLowestCommonAncestor($aClasses);
if (is_null($sAncestor))
{
throw new Exception('Could not find a common ancestor for the column '.($iColumn+1).' (Classes: '.implode(', ', $aClasses).')');
if (is_null($sAncestor)) {
throw new Exception('Could not find a common ancestor for the column '.($iColumn + 1).' (Classes: '.implode(', ', $aClasses).')');
}
$this->aSelectedClasses[$sAlias] = $sAncestor;
}
@@ -164,12 +153,9 @@ class DBUnionSearch extends DBSearch
*/
public function GetClassName($sAlias)
{
if (array_key_exists($sAlias, $this->aSelectedClasses))
{
if (array_key_exists($sAlias, $this->aSelectedClasses)) {
return $this->aSelectedClasses[$sAlias];
}
else
{
} else {
throw new CoreException("Invalid class alias '$sAlias'");
}
}
@@ -185,20 +171,16 @@ class DBUnionSearch extends DBSearch
return key($this->aSelectedClasses);
}
/**
* Change the class (only subclasses are supported as of now, because the conditions must fit the new class)
* Defaults to the first selected class
* Only the selected classes can be changed
*/
*/
public function ChangeClass($sNewClass, $sAlias = null)
{
if (is_null($sAlias))
{
if (is_null($sAlias)) {
$sAlias = $this->GetClassAlias();
}
elseif (!array_key_exists($sAlias, $this->aSelectedClasses))
{
} elseif (!array_key_exists($sAlias, $this->aSelectedClasses)) {
// discard silently - necessary when recursing (??? copied from DBObjectSearch)
return;
}
@@ -207,8 +189,7 @@ class DBUnionSearch extends DBSearch
$iColumn = array_search($sAlias, array_keys($this->aSelectedClasses));
// 2 - change for each search
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$aSearchAliases = array_keys($oSearch->GetSelectedClasses());
$sSearchAlias = $aSearchAliases[$iColumn];
$oSearch->ChangeClass($sNewClass, $sSearchAlias);
@@ -279,38 +260,31 @@ class DBUnionSearch extends DBSearch
public function RenameAlias($sOldName, $sNewName)
{
$bRet = false;
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$bRet = $oSearch->RenameAlias($sOldName, $sNewName) || $bRet;
}
return $bRet;
}
public function RenameAliasesInNameSpace($aClassAliases, $aAliasTranslation = array())
public function RenameAliasesInNameSpace($aClassAliases, $aAliasTranslation = [])
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->RenameAliasesInNameSpace($aClassAliases, $aAliasTranslation);
}
}
public function TranslateConditions($aTranslationData, $bMatchAll = true, $bMarkFieldsAsResolved = true)
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->TranslateConditions($aTranslationData, $bMatchAll, $bMarkFieldsAsResolved);
}
}
public function IsAny()
{
$bIsAny = true;
foreach ($this->aSearches as $oSearch)
{
if (!$oSearch->IsAny())
{
foreach ($this->aSearches as $oSearch) {
if (!$oSearch->IsAny()) {
$bIsAny = false;
break;
}
@@ -320,8 +294,7 @@ class DBUnionSearch extends DBSearch
public function ResetCondition()
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->ResetCondition();
}
}
@@ -329,13 +302,10 @@ class DBUnionSearch extends DBSearch
public function MergeConditionExpression($oExpression)
{
$aAliases = array_keys($this->aSelectedClasses);
foreach ($this->aSearches as $iSearchIndex => $oSearch)
{
foreach ($this->aSearches as $iSearchIndex => $oSearch) {
$oClonedExpression = $oExpression->DeepClone();
if ($iSearchIndex != 0)
{
foreach (array_keys($oSearch->GetSelectedClasses()) as $iColumn => $sSearchAlias)
{
if ($iSearchIndex != 0) {
foreach (array_keys($oSearch->GetSelectedClasses()) as $iColumn => $sSearchAlias) {
$oClonedExpression->RenameAlias($aAliases[$iColumn], $sSearchAlias);
}
}
@@ -346,13 +316,10 @@ class DBUnionSearch extends DBSearch
public function AddConditionExpression($oExpression)
{
$aAliases = array_keys($this->aSelectedClasses);
foreach ($this->aSearches as $iSearchIndex => $oSearch)
{
foreach ($this->aSearches as $iSearchIndex => $oSearch) {
$oClonedExpression = $oExpression->DeepClone();
if ($iSearchIndex != 0)
{
foreach (array_keys($oSearch->GetSelectedClasses()) as $iColumn => $sSearchAlias)
{
if ($iSearchIndex != 0) {
foreach (array_keys($oSearch->GetSelectedClasses()) as $iColumn => $sSearchAlias) {
$oClonedExpression->RenameAlias($aAliases[$iColumn], $sSearchAlias);
}
}
@@ -360,18 +327,16 @@ class DBUnionSearch extends DBSearch
}
}
public function AddNameCondition($sName)
public function AddNameCondition($sName)
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->AddNameCondition($sName);
}
}
public function AddCondition($sFilterCode, $value, $sOpCode = null)
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->AddCondition($sFilterCode, $value, $sOpCode);
}
}
@@ -379,35 +344,32 @@ class DBUnionSearch extends DBSearch
/**
* Specify a condition on external keys or link sets
* @param String sAttSpec Can be either an attribute code or extkey->[sAttSpec] or linkset->[sAttSpec] and so on, recursively
* Example: infra_list->ci_id->location_id->country
* Example: infra_list->ci_id->location_id->country
* @param Object value The value to match (can be an array => IN(val1, val2...)
* @return void
*/
public function AddConditionAdvanced($sAttSpec, $value)
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->AddConditionAdvanced($sAttSpec, $value);
}
}
public function AddCondition_FullText($sFullText)
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->AddCondition_FullText($sFullText);
}
}
public function AddCondition_FullTextOnAttributes(array $aAttCodes, $sNeedle)
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->AddCondition_FullTextOnAttributes($aAttCodes, $sNeedle);
}
}
/**
/**
* @param DBObjectSearch $oFilter
* @param $sExtKeyAttCode
* @param int $iOperatorCode
@@ -415,8 +377,7 @@ class DBUnionSearch extends DBSearch
*/
public function AddCondition_PointingTo(DBObjectSearch $oFilter, $sExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null)
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oConditionFilter = $oFilter->DeepClone();
$oSearch->AddCondition_PointingTo($oConditionFilter, $sExtKeyAttCode, $iOperatorCode, $aRealiasingMap);
}
@@ -430,8 +391,7 @@ class DBUnionSearch extends DBSearch
*/
public function AddCondition_ReferencedBy(DBObjectSearch $oFilter, $sForeignExtKeyAttCode, $iOperatorCode = TREE_OPERATOR_EQUALS, &$aRealiasingMap = null)
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oConditionFilter = $oFilter->DeepClone();
$oSearch->AddCondition_ReferencedBy($oConditionFilter, $sForeignExtKeyAttCode, $iOperatorCode, $aRealiasingMap);
}
@@ -439,9 +399,8 @@ class DBUnionSearch extends DBSearch
public function Filter($sClassAlias, DBSearch $oFilter)
{
$aSearches = array();
foreach ($this->aSearches as $oSearch)
{
$aSearches = [];
foreach ($this->aSearches as $oSearch) {
if (!$oSearch->IsAllDataAllowed()) {
$aSearches[] = $oSearch->Filter($sClassAlias, $oFilter);
} else {
@@ -453,9 +412,8 @@ class DBUnionSearch extends DBSearch
public function Intersect(DBSearch $oFilter)
{
$aSearches = array();
foreach ($this->aSearches as $oSearch)
{
$aSearches = [];
foreach ($this->aSearches as $oSearch) {
$aSearches[] = $oSearch->Intersect($oFilter);
}
return new DBUnionSearch($aSearches);
@@ -463,17 +421,15 @@ class DBUnionSearch extends DBSearch
public function SetInternalParams($aParams)
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->SetInternalParams($aParams);
}
}
public function GetInternalParams()
{
$aParams = array();
foreach ($this->aSearches as $oSearch)
{
$aParams = [];
foreach ($this->aSearches as $oSearch) {
$aParams = array_merge($oSearch->GetInternalParams(), $aParams);
}
return $aParams;
@@ -481,9 +437,8 @@ class DBUnionSearch extends DBSearch
public function GetQueryParams()
{
$aParams = array();
foreach ($this->aSearches as $oSearch)
{
$aParams = [];
foreach ($this->aSearches as $oSearch) {
$aParams = array_merge($oSearch->GetQueryParams(), $aParams);
}
return $aParams;
@@ -492,7 +447,7 @@ class DBUnionSearch extends DBSearch
public function ListConstantFields()
{
// Somewhat complex to implement for unions, for a poor benefit
return array();
return [];
}
/**
@@ -501,20 +456,18 @@ class DBUnionSearch extends DBSearch
*/
public function ApplyParameters($aArgs)
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->ApplyParameters($aArgs);
}
}
/**
* Overloads for query building
*/
*/
public function ToOQL($bDevelopParams = false, $aContextParams = null, $bWithAllowAllFlag = false)
{
$aSubQueries = array();
foreach ($this->aSearches as $oSearch)
{
$aSubQueries = [];
foreach ($this->aSearches as $oSearch) {
$aSubQueries[] = $oSearch->ToOQL($bDevelopParams, $aContextParams, $bWithAllowAllFlag);
}
$sRet = implode(' UNION ', $aSubQueries);
@@ -527,9 +480,8 @@ class DBUnionSearch extends DBSearch
*/
public function ToJSON()
{
$sRet = array('unions' => array());
foreach ($this->aSearches as $oSearch)
{
$sRet = ['unions' => []];
foreach ($this->aSearches as $oSearch) {
$sRet['unions'][] = $oSearch->ToJSON();
}
return $sRet;
@@ -543,21 +495,19 @@ class DBUnionSearch extends DBSearch
*/
public function RemoveDuplicateQueries()
{
$aQueries = array();
$aSearches = array();
$aQueries = [];
$aSearches = [];
foreach ($this->GetSearches() as $oTmpSearch)
{
foreach ($this->GetSearches() as $oTmpSearch) {
$sQuery = $oTmpSearch->ToOQL(true);
if (!in_array($sQuery, $aQueries))
{
if (!in_array($sQuery, $aQueries)) {
$aQueries[] = $sQuery;
$aSearches[] = $oTmpSearch;
}
}
$oNewSearch = new DBUnionSearch($aSearches);
return $oNewSearch;
}
@@ -567,60 +517,49 @@ class DBUnionSearch extends DBSearch
//
////////////////////////////////////////////////////////////////////////////
public function MakeDeleteQuery($aArgs = array())
public function MakeDeleteQuery($aArgs = [])
{
throw new Exception('MakeDeleteQuery is not implemented for the unions!');
}
public function MakeUpdateQuery($aValues, $aArgs = array())
public function MakeUpdateQuery($aValues, $aArgs = [])
{
throw new Exception('MakeUpdateQuery is not implemented for the unions!');
}
public function GetSQLQueryStructure($aAttToLoad, $bGetCount, $aGroupByExpr = null, $aSelectedClasses = null, $aSelectExpr = null)
{
if (count($this->aSearches) == 1)
{
if (count($this->aSearches) == 1) {
return $this->aSearches[0]->GetSQLQueryStructure($aAttToLoad, $bGetCount, $aGroupByExpr, $aSelectedClasses, $aSelectExpr);
}
$aSQLQueries = array();
$aSQLQueries = [];
$aAliases = array_keys($this->aSelectedClasses);
$aQueryAttToLoad = null;
$aUnionQuerySelectExpr = array();
foreach ($this->aSearches as $iSearch => $oSearch)
{
$aUnionQuerySelectExpr = [];
foreach ($this->aSearches as $iSearch => $oSearch) {
$aSearchAliases = array_keys($oSearch->GetSelectedClasses());
// The selected classes from the query build perspective are the lowest common ancestors amongst the various queries
// (used when it comes to determine which attributes must be selected)
$aSearchSelectedClasses = array();
foreach ($aSearchAliases as $iColumn => $sSearchAlias)
{
$aSearchSelectedClasses = [];
foreach ($aSearchAliases as $iColumn => $sSearchAlias) {
$sAlias = $aAliases[$iColumn];
$aSearchSelectedClasses[$sSearchAlias] = $this->aSelectedClasses[$sAlias];
}
if ($bGetCount)
{
if ($bGetCount) {
// Select only ids for the count to allow optimization of joins
foreach($aSearchAliases as $sSearchAlias)
{
$aQueryAttToLoad[$sSearchAlias] = array();
foreach ($aSearchAliases as $sSearchAlias) {
$aQueryAttToLoad[$sSearchAlias] = [];
}
}
else
{
if (is_null($aAttToLoad))
{
} else {
if (is_null($aAttToLoad)) {
$aQueryAttToLoad = null;
}
else
{
} else {
// (Eventually) Transform the aliases
$aQueryAttToLoad = array();
foreach($aAttToLoad as $sAlias => $aAttributes)
{
$aQueryAttToLoad = [];
foreach ($aAttToLoad as $sAlias => $aAttributes) {
$iColumn = array_search($sAlias, $aAliases);
$sQueryAlias = ($iColumn === false) ? $sAlias : $aSearchAliases[$iColumn];
$aQueryAttToLoad[$sQueryAlias] = $aAttributes;
@@ -628,66 +567,51 @@ class DBUnionSearch extends DBSearch
}
}
if (is_null($aGroupByExpr))
{
if (is_null($aGroupByExpr)) {
$aQueryGroupByExpr = null;
}
else
{
} else {
// Clone (and eventually transform) the group by expressions
$aQueryGroupByExpr = array();
$aTranslationData = array();
$aQueryGroupByExpr = [];
$aTranslationData = [];
$aQueryColumns = array_keys($oSearch->GetSelectedClasses());
foreach ($aAliases as $iColumn => $sAlias)
{
foreach ($aAliases as $iColumn => $sAlias) {
$sQueryAlias = $aQueryColumns[$iColumn];
$aTranslationData[$sAlias]['*'] = $sQueryAlias;
$aQueryGroupByExpr[$sAlias.'id'] = new FieldExpression('id', $sQueryAlias);
}
foreach ($aGroupByExpr as $sExpressionAlias => $oExpression)
{
foreach ($aGroupByExpr as $sExpressionAlias => $oExpression) {
$aQueryGroupByExpr[$sExpressionAlias] = $oExpression->Translate($aTranslationData, false, false);
}
}
if (is_null($aSelectExpr))
{
if (is_null($aSelectExpr)) {
$aQuerySelectExpr = null;
}
else
{
$aQuerySelectExpr = array();
$aTranslationData = array();
} else {
$aQuerySelectExpr = [];
$aTranslationData = [];
$aQueryColumns = array_keys($oSearch->GetSelectedClasses());
foreach($aAliases as $iColumn => $sAlias)
{
foreach ($aAliases as $iColumn => $sAlias) {
$sQueryAlias = $aQueryColumns[$iColumn];
$aTranslationData[$sAlias]['*'] = $sQueryAlias;
}
foreach($aSelectExpr as $sExpressionAlias => $oExpression)
{
$oExpression->Browse(function ($oNode) use (&$aQuerySelectExpr, &$aTranslationData)
{
if ($oNode instanceof FieldExpression)
{
foreach ($aSelectExpr as $sExpressionAlias => $oExpression) {
$oExpression->Browse(function ($oNode) use (&$aQuerySelectExpr, &$aTranslationData) {
if ($oNode instanceof FieldExpression) {
$sAlias = $oNode->GetParent()."__".$oNode->GetName();
if (!key_exists($sAlias, $aQuerySelectExpr))
{
if (!key_exists($sAlias, $aQuerySelectExpr)) {
$aQuerySelectExpr[$sAlias] = $oNode->Translate($aTranslationData, false, false);
}
$aTranslationData[$oNode->GetParent()][$oNode->GetName()] = new FieldExpression($sAlias);
}
});
// Only done for the first select as aliases are named after the first query
if (!array_key_exists($sExpressionAlias, $aUnionQuerySelectExpr))
{
if (!array_key_exists($sExpressionAlias, $aUnionQuerySelectExpr)) {
$aUnionQuerySelectExpr[$sExpressionAlias] = $oExpression->Translate($aTranslationData, false, false);
}
}
}
$oSubQuery = $oSearch->GetSQLQueryStructure($aQueryAttToLoad, false, $aQueryGroupByExpr, $aSearchSelectedClasses, $aQuerySelectExpr);
if (count($aSearchAliases) > 1)
{
if (count($aSearchAliases) > 1) {
// Necessary to make sure that selected columns will match throughout all the queries
// (default order of selected fields depending on the order of JOINS)
$oSubQuery->SortSelectedFields();
@@ -698,17 +622,17 @@ class DBUnionSearch extends DBSearch
$oSQLQuery = new SQLUnionQuery($aSQLQueries, $aGroupByExpr, $aUnionQuerySelectExpr);
//MyHelpers::var_dump_html($oSQLQuery, true);
//MyHelpers::var_dump_html($oSQLQuery->RenderSelect(), true);
if (self::$m_bDebugQuery) $oSQLQuery->DisplayHtml();
if (self::$m_bDebugQuery) {
$oSQLQuery->DisplayHtml();
}
return $oSQLQuery;
}
protected function IsDataFiltered()
{
$bIsAllDataFiltered = true;
foreach ($this->aSearches as $oSearch)
{
if (!$oSearch->IsDataFiltered())
{
foreach ($this->aSearches as $oSearch) {
if (!$oSearch->IsDataFiltered()) {
$bIsAllDataFiltered = false;
break;
}
@@ -718,19 +642,15 @@ class DBUnionSearch extends DBSearch
protected function SetDataFiltered()
{
foreach ($this->aSearches as $oSearch)
{
foreach ($this->aSearches as $oSearch) {
$oSearch->SetDataFiltered();
}
}
public function AddConditionForInOperatorUsingParam($sFilterCode, $aValues, $bPositiveMatch = true)
{
$sInParamName = $this->GenerateUniqueParamName();
foreach ($this->aSearches as $iSearchIndex => $oSearch)
{
foreach ($this->aSearches as $iSearchIndex => $oSearch) {
$oFieldExpression = new FieldExpression($sFilterCode, $oSearch->GetClassAlias());
$sOperator = $bPositiveMatch ? 'IN' : 'NOT IN';
@@ -738,17 +658,16 @@ class DBUnionSearch extends DBSearch
$oParamExpression = new VariableExpression($sInParamName);
$oSearch->GetInternalParamsByRef()[$sInParamName] = $aValues;
$oListExpression = new ListExpression(array($oParamExpression));
$oListExpression = new ListExpression([$oParamExpression]);
$oInCondition = new BinaryExpression($oFieldExpression, $sOperator, $oListExpression);
$oSearch->AddConditionExpression($oInCondition);
}
}
function GetExpectedArguments(): array
public function GetExpectedArguments(): array
{
$aVariableCriteria = array();
foreach ($this->aSearches as $oSearch)
{
$aVariableCriteria = [];
foreach ($this->aSearches as $oSearch) {
$aVariableCriteria = array_merge($aVariableCriteria, $oSearch->GetExpectedArguments());
}

File diff suppressed because it is too large Load Diff

View File

@@ -24,31 +24,31 @@ class Event extends DBObject implements iDisplay
{
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "core/cmdb,view_in_gui",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",
"reconc_keys" => array(),
"reconc_keys" => [],
"db_table" => "priv_event",
"db_key_field" => "id",
"db_finalclass_field" => "realclass",
"order_by_default" => array('date' => false)
);
"order_by_default" => ['date' => false],
];
MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeText("message", array("allowed_values"=>null, "sql"=>"message", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeDateTime("date", array("allowed_values"=>null, "sql"=>"date", "default_value"=>"NOW()", "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
// MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("message", ["allowed_values" => null, "sql" => "message", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeDateTime("date", ["allowed_values" => null, "sql" => "date", "default_value" => "NOW()", "is_null_allowed" => false, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeString("userinfo", ["allowed_values" => null, "sql" => "userinfo", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
// MetaModel::Init_AddAttribute(new AttributeString("userinfo", array("allowed_values"=>null, "sql"=>"userinfo", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
// Display lists
MetaModel::Init_SetZListItems('details', array('date', 'message', 'userinfo')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('date', 'finalclass', 'message')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['date', 'message', 'userinfo']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['date', 'finalclass', 'message']); // Attributes to be displayed for a list
// Search criteria
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
/**
@@ -58,12 +58,9 @@ class Event extends DBObject implements iDisplay
*/
public static function MapContextParam($sContextParam)
{
if ($sContextParam == 'menu')
{
if ($sContextParam == 'menu') {
return null;
}
else
{
} else {
return $sContextParam;
}
}
@@ -79,7 +76,7 @@ class Event extends DBObject implements iDisplay
public function GetHilightClass()
{
// Possible return values are:
// HILIGHT_CLASS_CRITICAL, HILIGHT_CLASS_WARNING, HILIGHT_CLASS_OK, HILIGHT_CLASS_NONE
// HILIGHT_CLASS_CRITICAL, HILIGHT_CLASS_WARNING, HILIGHT_CLASS_OK, HILIGHT_CLASS_NONE
return HILIGHT_CLASS_NONE; // Not hilighted by default
}
@@ -88,7 +85,7 @@ class Event extends DBObject implements iDisplay
return 'UI.php';
}
function DisplayDetails(WebPage $oPage, $bEditMode = false)
public function DisplayDetails(WebPage $oPage, $bEditMode = false)
{
// Object's details
//$this->DisplayBareHeader($oPage, $bEditMode);
@@ -97,21 +94,23 @@ class Event extends DBObject implements iDisplay
$oPage->SetCurrentTab('UI:PropertiesTab');
$this->DisplayBareProperties($oPage, $bEditMode);
}
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
{
if ($bEditMode) return array(); // Not editable
$aDetails = array();
public function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = [])
{
if ($bEditMode) {
return [];
} // Not editable
$aDetails = [];
$sClass = get_class($this);
$aZList = MetaModel::FlattenZlist(MetaModel::GetZListItems($sClass, 'details'));
foreach ($aZList as $sAttCode) {
$sDisplayValue = $this->GetAsHTML($sAttCode);
$aDetails[] = array('label' => '<span title="'.MetaModel::GetDescription($sClass, $sAttCode).'">'.MetaModel::GetLabel($sClass, $sAttCode).'</span>', 'value' => $sDisplayValue);
$aDetails[] = ['label' => '<span title="'.MetaModel::GetDescription($sClass, $sAttCode).'">'.MetaModel::GetLabel($sClass, $sAttCode).'</span>', 'value' => $sDisplayValue];
}
$oPage->Details($aDetails);
return array();
return [];
}
}
@@ -119,35 +118,35 @@ class EventNotification extends Event
{
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "core/cmdb,view_in_gui",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",
"reconc_keys" => array(),
"reconc_keys" => [],
"db_table" => "priv_event_notification",
"db_key_field" => "id",
"db_finalclass_field" => "",
"order_by_default" => array('date' => false),
'indexes' => array(
array( 'object_class', 'object_id'),
)
);
"order_by_default" => ['date' => false],
'indexes' => [
[ 'object_class', 'object_id'],
],
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeExternalKey("trigger_id", array("targetclass"=>"Trigger", "jointype"=> "", "allowed_values"=>null, "sql"=>"trigger_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_AUTO, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("action_id", array("targetclass" => "Action", "jointype" => "", "allowed_values" => null, "sql" => "action_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeInteger("object_id", array("allowed_values" => null, "sql" => "object_id", "default_value" => 0, "is_null_allowed" => false, "depends_on" => array())));
//@since 3.2.0
MetaModel::Init_AddAttribute(new AttributeClass("object_class", array("class_category"=>"", "more_values"=>"", "sql"=>"object_class", "default_value"=>null, "is_null_allowed"=>true /*to avoid setting AbstractResource as default in database*/, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("trigger_id", ["targetclass" => "Trigger", "jointype" => "", "allowed_values" => null, "sql" => "trigger_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeExternalKey("action_id", ["targetclass" => "Action", "jointype" => "", "allowed_values" => null, "sql" => "action_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeInteger("object_id", ["allowed_values" => null, "sql" => "object_id", "default_value" => 0, "is_null_allowed" => false, "depends_on" => []]));
//@since 3.2.0
MetaModel::Init_AddAttribute(new AttributeClass("object_class", ["class_category" => "", "more_values" => "", "sql" => "object_class", "default_value" => null, "is_null_allowed" => true /*to avoid setting AbstractResource as default in database*/, "depends_on" => []]));
// Display lists
MetaModel::Init_SetZListItems('details', array('date', 'message', 'userinfo', 'trigger_id', 'action_id', 'object_class', 'object_id')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('date', 'message')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['date', 'message', 'userinfo', 'trigger_id', 'action_id', 'object_class', 'object_id']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['date', 'message']); // Attributes to be displayed for a list
// Search criteria
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
}
@@ -155,35 +154,35 @@ class EventNotificationEmail extends EventNotification
{
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "core/cmdb,view_in_gui",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",
"reconc_keys" => array(),
"reconc_keys" => [],
"db_table" => "priv_event_email",
"db_key_field" => "id",
"db_finalclass_field" => "",
"order_by_default" => array('date' => false)
);
"order_by_default" => ['date' => false],
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeText("to", array("allowed_values"=>null, "sql"=>"to", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("cc", array("allowed_values"=>null, "sql"=>"cc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("bcc", array("allowed_values"=>null, "sql"=>"bcc", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("from", array("allowed_values"=>null, "sql"=>"from", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("subject", array("allowed_values"=>null, "sql"=>"subject", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeHTML("body", array("allowed_values"=>null, "sql"=>"body", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeTable("attachments", array("allowed_values"=>null, "sql"=>"attachments", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("to", ["allowed_values" => null, "sql" => "to", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeText("cc", ["allowed_values" => null, "sql" => "cc", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeText("bcc", ["allowed_values" => null, "sql" => "bcc", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeText("from", ["allowed_values" => null, "sql" => "from", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeText("subject", ["allowed_values" => null, "sql" => "subject", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeHTML("body", ["allowed_values" => null, "sql" => "body", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeTable("attachments", ["allowed_values" => null, "sql" => "attachments", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
// Display lists
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'message', 'trigger_id', 'action_id', 'object_class', 'object_id', 'to', 'cc', 'bcc', 'from', 'subject', 'body', 'attachments')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('date', 'message', 'to', 'subject', 'attachments')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['date', 'userinfo', 'message', 'trigger_id', 'action_id', 'object_class', 'object_id', 'to', 'cc', 'bcc', 'from', 'subject', 'body', 'attachments']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['date', 'message', 'to', 'subject', 'attachments']); // Attributes to be displayed for a list
// Search criteria
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
}
@@ -191,34 +190,34 @@ class EventIssue extends Event
{
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "core/cmdb,view_in_gui",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",
"reconc_keys" => array(),
"reconc_keys" => [],
"db_table" => "priv_event_issue",
"db_key_field" => "id",
"db_finalclass_field" => "",
"order_by_default" => array('date' => false)
);
"order_by_default" => ['date' => false],
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeString("issue", array("allowed_values"=>null, "sql"=>"issue", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("impact", array("allowed_values"=>null, "sql"=>"impact", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("page", array("allowed_values"=>null, "sql"=>"page", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributePropertySet("arguments_post", array("allowed_values"=>null, "sql"=>"arguments_post", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributePropertySet("arguments_get", array("allowed_values"=>null, "sql"=>"arguments_get", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeTable("callstack", array("allowed_values"=>null, "sql"=>"callstack", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributePropertySet("data", array("allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("issue", ["allowed_values" => null, "sql" => "issue", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeString("impact", ["allowed_values" => null, "sql" => "impact", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeString("page", ["allowed_values" => null, "sql" => "page", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributePropertySet("arguments_post", ["allowed_values" => null, "sql" => "arguments_post", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributePropertySet("arguments_get", ["allowed_values" => null, "sql" => "arguments_get", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeTable("callstack", ["allowed_values" => null, "sql" => "callstack", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributePropertySet("data", ["allowed_values" => null, "sql" => "data", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
// Display lists
MetaModel::Init_SetZListItems('details', array('date', 'message', 'userinfo', 'issue', 'impact', 'page', 'arguments_post', 'arguments_get', 'callstack', 'data')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'issue', 'impact')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['date', 'message', 'userinfo', 'issue', 'impact', 'page', 'arguments_post', 'arguments_get', 'callstack', 'data']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['date', 'userinfo', 'issue', 'impact']); // Attributes to be displayed for a list
// Search criteria
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
protected function OnInsert()
@@ -231,20 +230,16 @@ class EventIssue extends Event
$this->Set('userinfo', UserRights::GetUserId());
}
if (array_key_exists('_GET', $GLOBALS) && is_array($GLOBALS['_GET']))
{
if (array_key_exists('_GET', $GLOBALS) && is_array($GLOBALS['_GET'])) {
$this->Set('arguments_get', $this->SanitizeRequestParams($GLOBALS['_GET']));
}
else
{
$this->Set('arguments_get', array());
} else {
$this->Set('arguments_get', []);
}
if (array_key_exists('_POST', $GLOBALS) && is_array($GLOBALS['_POST']))
{
if (array_key_exists('_POST', $GLOBALS) && is_array($GLOBALS['_POST'])) {
$this->Set('arguments_post', $this->SanitizeRequestParams($GLOBALS['_POST']));
} else {
$this->Set('arguments_post', array());
$this->Set('arguments_post', []);
}
$sLength = mb_strlen($this->Get('issue'));
if ($sLength > 255) {
@@ -281,44 +276,42 @@ class EventIssue extends Event
}
}
return $aSanitizedParams;
}
}
class EventWebService extends Event
{
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "core/cmdb,view_in_gui",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",
"reconc_keys" => array(),
"reconc_keys" => [],
"db_table" => "priv_event_webservice",
"db_key_field" => "id",
"db_finalclass_field" => "",
"order_by_default" => array('date' => false)
);
"order_by_default" => ['date' => false],
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeString("verb", array("allowed_values"=>null, "sql"=>"verb", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("verb", ["allowed_values" => null, "sql" => "verb", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
//MetaModel::Init_AddAttribute(new AttributeStructure("arguments", array("allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeBoolean("result", array("allowed_values"=>null, "sql"=>"result", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("log_info", array("allowed_values"=>null, "sql"=>"log_info", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("log_warning", array("allowed_values"=>null, "sql"=>"log_warning", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("log_error", array("allowed_values"=>null, "sql"=>"log_error", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("data", array("allowed_values"=>null, "sql"=>"data", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeBoolean("result", ["allowed_values" => null, "sql" => "result", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeText("log_info", ["allowed_values" => null, "sql" => "log_info", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeText("log_warning", ["allowed_values" => null, "sql" => "log_warning", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeText("log_error", ["allowed_values" => null, "sql" => "log_error", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeText("data", ["allowed_values" => null, "sql" => "data", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
// Display lists
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'verb', 'result', 'log_info', 'log_warning', 'log_error', 'data')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'verb', 'result')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['date', 'userinfo', 'verb', 'result', 'log_info', 'log_warning', 'log_error', 'data']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['date', 'userinfo', 'verb', 'result']); // Attributes to be displayed for a list
// Search criteria
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
}
@@ -326,34 +319,34 @@ class EventRestService extends Event
{
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "core/cmdb,view_in_gui",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",
"reconc_keys" => array(),
"reconc_keys" => [],
"db_table" => "priv_event_restservice",
"db_key_field" => "id",
"db_finalclass_field" => "",
"order_by_default" => array('date' => false)
);
"order_by_default" => ['date' => false],
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeString("operation", array("allowed_values"=>null, "sql"=>"operation", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("version", array("allowed_values"=>null, "sql"=>"version", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("json_input", array("allowed_values"=>null, "sql"=>"json_input", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("operation", ["allowed_values" => null, "sql" => "operation", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeString("version", ["allowed_values" => null, "sql" => "version", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeText("json_input", ["allowed_values" => null, "sql" => "json_input", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeInteger("code", array("allowed_values"=>null, "sql"=>"code", "default_value"=>0, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeText("json_output", array("allowed_values"=>null, "sql"=>"json_output", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeString("provider", array("allowed_values"=>null, "sql"=>"provider", "default_value"=>null, "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("code", ["allowed_values" => null, "sql" => "code", "default_value" => 0, "is_null_allowed" => false, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeText("json_output", ["allowed_values" => null, "sql" => "json_output", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeString("provider", ["allowed_values" => null, "sql" => "provider", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
// Display lists
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'operation', 'version', 'json_input', 'message', 'code', 'json_output', 'provider')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'operation', 'message')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['date', 'userinfo', 'operation', 'version', 'json_input', 'message', 'code', 'json_output', 'provider']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['date', 'userinfo', 'operation', 'message']); // Attributes to be displayed for a list
// Search criteria
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
}
@@ -361,66 +354,64 @@ class EventLoginUsage extends Event
{
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "core/cmdb,view_in_gui",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",
"reconc_keys" => array(),
"reconc_keys" => [],
"db_table" => "priv_event_loginusage",
"db_key_field" => "id",
"db_finalclass_field" => "",
"order_by_default" => array('date' => false)
);
"order_by_default" => ['date' => false],
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", array("targetclass"=>"User", "jointype"=> "", "allowed_values"=>null, "sql"=>"user_id", "is_null_allowed"=>false, "on_target_delete"=>DEL_SILENT, "depends_on"=>array())));
$aZList = array('date', 'user_id');
if (MetaModel::IsValidAttCode('Contact', 'name'))
{
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_name", array("allowed_values"=>null, "extkey_attcode"=>"user_id", "target_attcode"=>"contactid", "is_null_allowed"=>true, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("user_id", ["targetclass" => "User", "jointype" => "", "allowed_values" => null, "sql" => "user_id", "is_null_allowed" => false, "on_target_delete" => DEL_SILENT, "depends_on" => []]));
$aZList = ['date', 'user_id'];
if (MetaModel::IsValidAttCode('Contact', 'name')) {
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_name", ["allowed_values" => null, "extkey_attcode" => "user_id", "target_attcode" => "contactid", "is_null_allowed" => true, "depends_on" => []]));
$aZList[] = 'contact_name';
}
if (MetaModel::IsValidAttCode('Contact', 'email'))
{
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_email", array("allowed_values"=>null, "extkey_attcode"=>"user_id", "target_attcode"=>"email", "is_null_allowed"=>true, "depends_on"=>array())));
if (MetaModel::IsValidAttCode('Contact', 'email')) {
MetaModel::Init_AddAttribute(new AttributeExternalField("contact_email", ["allowed_values" => null, "extkey_attcode" => "user_id", "target_attcode" => "email", "is_null_allowed" => true, "depends_on" => []]));
$aZList[] = 'contact_email';
}
// Display lists
MetaModel::Init_SetZListItems('details', array_merge($aZList, array('userinfo', 'message'))); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array_merge($aZList, array('userinfo'))); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', array_merge($aZList, ['userinfo', 'message'])); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array_merge($aZList, ['userinfo'])); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', $aZList); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
}
class EventOnObject extends Event
{
public static function Init()
{
$aParams = array
(
"category" => "core/cmdb,view_in_gui",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",
"reconc_keys" => array(),
"db_table" => "priv_event_onobject",
"db_key_field" => "id",
"db_finalclass_field" => "",
"display_template" => "",
"order_by_default" => array('date' => false)
);
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeString("obj_class", array("allowed_values"=>null, "sql"=>"obj_class", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
MetaModel::Init_AddAttribute(new AttributeInteger("obj_key", array("allowed_values"=>null, "sql"=>"obj_key", "default_value"=>null, "is_null_allowed"=>false, "depends_on"=>array())));
public static function Init()
{
$aParams =
[
"category" => "core/cmdb,view_in_gui",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",
"reconc_keys" => [],
"db_table" => "priv_event_onobject",
"db_key_field" => "id",
"db_finalclass_field" => "",
"display_template" => "",
"order_by_default" => ['date' => false],
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeString("obj_class", ["allowed_values" => null, "sql" => "obj_class", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeInteger("obj_key", ["allowed_values" => null, "sql" => "obj_key", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
// Display lists
MetaModel::Init_SetZListItems('details', array('date', 'userinfo', 'obj_class', 'obj_key', 'message')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('date', 'userinfo', 'obj_class', 'obj_key', 'message')); // Attributes to be displayed for a list
}
// Display lists
MetaModel::Init_SetZListItems('details', ['date', 'userinfo', 'obj_class', 'obj_key', 'message']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['date', 'userinfo', 'obj_class', 'obj_key', 'message']); // Attributes to be displayed for a list
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (C) 2013-2024 Combodo SAS
*
@@ -25,9 +26,9 @@ define('INLINEIMAGE_DOWNLOAD_URL', 'pages/ajax.document.php?operation=download_i
class InlineImage extends DBObject
{
/** @var string attribute to be added to IMG tags to contain ID */
const DOM_ATTR_ID = 'data-img-id';
public const DOM_ATTR_ID = 'data-img-id';
/** @var string attribute to be added to IMG tags to contain secret */
const DOM_ATTR_SECRET = 'data-img-secret';
public const DOM_ATTR_SECRET = 'data-img-secret';
/**
*
@@ -36,39 +37,37 @@ class InlineImage extends DBObject
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
'category' => 'addon',
'key_type' => 'autoincrement',
'name_attcode' => array('item_class', 'temp_id'),
'name_attcode' => ['item_class', 'temp_id'],
'state_attcode' => '',
'reconc_keys' => array(''),
'reconc_keys' => [''],
'db_table' => 'inline_image',
'db_key_field' => 'id',
'db_finalclass_field' => '',
'indexes' => array(
array('temp_id'),
array('item_class', 'item_id'),
array('item_org_id'),
),
);
'indexes' => [
['temp_id'],
['item_class', 'item_id'],
['item_org_id'],
],
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeDateTime("expire", array("allowed_values" => null, "sql" => 'expire', "default_value" => 'DATE_ADD(NOW(), INTERVAL 1 DAY)', "is_null_allowed" => false, "depends_on" => array(), "always_load_in_tables" => false)));
MetaModel::Init_AddAttribute(new AttributeString("temp_id", array("allowed_values"=>null, "sql"=>'temp_id', "default_value"=>'', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false)));
MetaModel::Init_AddAttribute(new AttributeString("item_class", array("allowed_values"=>null, "sql"=>'item_class', "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false)));
MetaModel::Init_AddAttribute(new AttributeObjectKey("item_id", array("class_attcode"=>'item_class', "allowed_values"=>null, "sql"=>'item_id', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false)));
MetaModel::Init_AddAttribute(new AttributeInteger("item_org_id", array("allowed_values"=>null, "sql"=>'item_org_id', "default_value"=>'0', "is_null_allowed"=>true, "depends_on"=>array(), "always_load_in_tables"=>false)));
MetaModel::Init_AddAttribute(new AttributeBlob("contents", array("is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false)));
MetaModel::Init_AddAttribute(new AttributeString("secret", array("allowed_values"=>null, "sql" => "secret", "default_value"=>'', "is_null_allowed"=>false, "depends_on"=>array(), "always_load_in_tables"=>false)));
MetaModel::Init_AddAttribute(new AttributeDateTime("expire", ["allowed_values" => null, "sql" => 'expire', "default_value" => 'DATE_ADD(NOW(), INTERVAL 1 DAY)', "is_null_allowed" => false, "depends_on" => [], "always_load_in_tables" => false]));
MetaModel::Init_AddAttribute(new AttributeString("temp_id", ["allowed_values" => null, "sql" => 'temp_id', "default_value" => '', "is_null_allowed" => true, "depends_on" => [], "always_load_in_tables" => false]));
MetaModel::Init_AddAttribute(new AttributeString("item_class", ["allowed_values" => null, "sql" => 'item_class', "default_value" => '', "is_null_allowed" => false, "depends_on" => [], "always_load_in_tables" => false]));
MetaModel::Init_AddAttribute(new AttributeObjectKey("item_id", ["class_attcode" => 'item_class', "allowed_values" => null, "sql" => 'item_id', "is_null_allowed" => true, "depends_on" => [], "always_load_in_tables" => false]));
MetaModel::Init_AddAttribute(new AttributeInteger("item_org_id", ["allowed_values" => null, "sql" => 'item_org_id', "default_value" => '0', "is_null_allowed" => true, "depends_on" => [], "always_load_in_tables" => false]));
MetaModel::Init_AddAttribute(new AttributeBlob("contents", ["is_null_allowed" => false, "depends_on" => [], "always_load_in_tables" => false]));
MetaModel::Init_AddAttribute(new AttributeString("secret", ["allowed_values" => null, "sql" => "secret", "default_value" => '', "is_null_allowed" => false, "depends_on" => [], "always_load_in_tables" => false]));
MetaModel::Init_SetZListItems('details', array('temp_id', 'item_class', 'item_id', 'item_org_id'));
MetaModel::Init_SetZListItems('standard_search', array('temp_id', 'item_class', 'item_id'));
MetaModel::Init_SetZListItems('list', array('temp_id', 'item_class', 'item_id' ));
MetaModel::Init_SetZListItems('details', ['temp_id', 'item_class', 'item_id', 'item_org_id']);
MetaModel::Init_SetZListItems('standard_search', ['temp_id', 'item_class', 'item_id']);
MetaModel::Init_SetZListItems('list', ['temp_id', 'item_class', 'item_id' ]);
}
/**
* Maps the given context parameter name to the appropriate filter/search code for this class
*
@@ -77,12 +76,9 @@ class InlineImage extends DBObject
*/
public static function MapContextParam($sContextParam)
{
if ($sContextParam == 'org_id')
{
if ($sContextParam == 'org_id') {
return 'item_org_id';
}
else
{
} else {
return null;
}
}
@@ -104,23 +100,18 @@ class InlineImage extends DBObject
$sClass = get_class($oItem);
$iItemId = $oItem->GetKey();
$this->Set('item_class', $sClass);
$this->Set('item_id', $iItemId);
$this->Set('item_class', $sClass);
$this->Set('item_id', $iItemId);
$aCallSpec = array($sClass, 'MapContextParam');
if (is_callable($aCallSpec))
{
$aCallSpec = [$sClass, 'MapContextParam'];
if (is_callable($aCallSpec)) {
$sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter
if (MetaModel::IsValidAttCode($sClass, $sAttCode))
{
if (MetaModel::IsValidAttCode($sClass, $sAttCode)) {
$iOrgId = $oItem->Get($sAttCode);
if ($iOrgId > 0)
{
if ($iOrgId != $this->Get('item_org_id'))
{
if ($iOrgId > 0) {
if ($iOrgId != $this->Get('item_org_id')) {
$this->Set('item_org_id', $iOrgId);
if ($bUpdateOnChange)
{
if ($bUpdateOnChange) {
$this->DBUpdate();
}
}
@@ -143,29 +134,23 @@ class InlineImage extends DBObject
// First check that the organization CAN be fetched from the target class
//
$sClass = $this->Get('item_class');
$aCallSpec = array($sClass, 'MapContextParam');
if (is_callable($aCallSpec))
{
$aCallSpec = [$sClass, 'MapContextParam'];
if (is_callable($aCallSpec)) {
$sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter
if (MetaModel::IsValidAttCode($sClass, $sAttCode))
{
if (MetaModel::IsValidAttCode($sClass, $sAttCode)) {
// Second: check that the organization CAN be fetched from the current user
//
if (MetaModel::IsValidClass('Person'))
{
$aCallSpec = array($sClass, 'MapContextParam');
if (is_callable($aCallSpec))
{
if (MetaModel::IsValidClass('Person')) {
$aCallSpec = [$sClass, 'MapContextParam'];
if (is_callable($aCallSpec)) {
$sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter
if (MetaModel::IsValidAttCode($sClass, $sAttCode))
{
if (MetaModel::IsValidAttCode($sClass, $sAttCode)) {
// OK - try it
//
$oCurrentPerson = MetaModel::GetObject('Person', UserRights::GetContactId(), false);
if ($oCurrentPerson)
{
$this->Set('item_org_id', $oCurrentPerson->Get($sAttCode));
}
if ($oCurrentPerson) {
$this->Set('item_org_id', $oCurrentPerson->Get($sAttCode));
}
}
}
}
@@ -189,39 +174,37 @@ class InlineImage extends DBObject
public static function FinalizeInlineImages(DBObject $oObject)
{
$iTransactionId = utils::ReadParam('transaction_id', null, false, 'transaction_id');
if (!is_null($iTransactionId))
{
if (!is_null($iTransactionId)) {
// Attach new (temporary) inline images
$sTempId = utils::GetUploadTempId($iTransactionId);
// The object is being created from a form, check if there are pending inline images for this object
$sOQL = 'SELECT InlineImage WHERE temp_id = :temp_id';
$oSearch = DBObjectSearch::FromOQL($sOQL);
$oSet = new DBObjectSet($oSearch, array(), array('temp_id' => $sTempId));
$aInlineImagesId = array();
$oSet = new DBObjectSet($oSearch, [], ['temp_id' => $sTempId]);
$aInlineImagesId = [];
while ($oInlineImage = $oSet->Fetch()) {
$aInlineImagesId[] = $oInlineImage->GetKey();
$oInlineImage->SetItem($oObject);
$oInlineImage->Set('temp_id', '');
$oInlineImage->DBUpdate();
}
IssueLog::Trace('FinalizeInlineImages (see $aInlineImagesId for the id list)', LogChannels::INLINE_IMAGE, array(
IssueLog::Trace('FinalizeInlineImages (see $aInlineImagesId for the id list)', LogChannels::INLINE_IMAGE, [
'$sObjectClass' => get_class($oObject),
'$sTransactionId' => $iTransactionId,
'$sTempId' => $sTempId,
'$aInlineImagesId' => $aInlineImagesId,
'$sUser' => UserRights::GetUser(),
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
));
]);
} else {
IssueLog::Trace('FinalizeInlineImages "error" $iTransactionId is null', LogChannels::INLINE_IMAGE, [
'$sObjectClass' => get_class($oObject),
'$sTransactionId' => $iTransactionId,
'$sUser' => UserRights::GetUser(),
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
]);
}
else {
IssueLog::Trace('FinalizeInlineImages "error" $iTransactionId is null', LogChannels::INLINE_IMAGE, array(
'$sObjectClass' => get_class($oObject),
'$sTransactionId' => $iTransactionId,
'$sUser' => UserRights::GetUser(),
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
));
}
}
/**
@@ -243,11 +226,11 @@ class InlineImage extends DBObject
{
// Protection against unfortunate massive delete of inline images when a null temp ID is passed
if (utils::IsNullOrEmptyString($sTempId)) {
IssueLog::Trace('OnFormCancel "error" $sTempId is null or empty', LogChannels::INLINE_IMAGE, array(
IssueLog::Trace('OnFormCancel "error" $sTempId is null or empty', LogChannels::INLINE_IMAGE, [
'$sTempId' => $sTempId,
'$sUser' => UserRights::GetUser(),
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
));
]);
return false;
}
@@ -255,19 +238,18 @@ class InlineImage extends DBObject
// Delete all "pending" InlineImages for this form
$sOQL = 'SELECT InlineImage WHERE temp_id = :temp_id';
$oSearch = DBObjectSearch::FromOQL($sOQL);
$oSet = new DBObjectSet($oSearch, array(), array('temp_id' => $sTempId));
$aInlineImagesId = array();
while($oInlineImage = $oSet->Fetch())
{
$aInlineImagesId[] = $oInlineImage->GetKey();
$oSet = new DBObjectSet($oSearch, [], ['temp_id' => $sTempId]);
$aInlineImagesId = [];
while ($oInlineImage = $oSet->Fetch()) {
$aInlineImagesId[] = $oInlineImage->GetKey();
$oInlineImage->DBDelete();
}
IssueLog::Trace('OnFormCancel', LogChannels::INLINE_IMAGE, array(
IssueLog::Trace('OnFormCancel', LogChannels::INLINE_IMAGE, [
'$sTempId' => $sTempId,
'$aInlineImagesId' => $aInlineImagesId,
'$sUser' => UserRights::GetUser(),
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
));
]);
return true;
}
@@ -284,15 +266,17 @@ class InlineImage extends DBObject
*/
public static function FixUrls($sHtml)
{
$aNeedles = array();
$aReplacements = array();
$aNeedles = [];
$aReplacements = [];
// Find img tags with an attribute data-img-id
if (preg_match_all('/<img ([^>]*)'.self::DOM_ATTR_ID.'="([0-9]+)"([^>]*)>/i',
$sHtml, $aMatches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
{
if (preg_match_all(
'/<img ([^>]*)'.self::DOM_ATTR_ID.'="([0-9]+)"([^>]*)>/i',
$sHtml,
$aMatches,
PREG_SET_ORDER | PREG_OFFSET_CAPTURE
)) {
$sUrl = utils::GetAbsoluteUrlAppRoot().INLINEIMAGE_DOWNLOAD_URL;
foreach($aMatches as $aImgInfo)
{
foreach ($aMatches as $aImgInfo) {
$sImgTag = $aImgInfo[0][0];
$sSecret = '';
if (preg_match('/data-img-secret="([0-9a-f]+)"/', $sImgTag, $aSecretMatches)) {
@@ -321,11 +305,10 @@ class InlineImage extends DBObject
public static function ProcessImageTag(DOMElement $oElement)
{
$sSrc = $oElement->getAttribute('src');
$sDownloadUrl = str_replace(array('.', '?'), array('\.', '\?'), INLINEIMAGE_DOWNLOAD_URL); // Escape . and ?
$sDownloadUrl = str_replace(['.', '?'], ['\.', '\?'], INLINEIMAGE_DOWNLOAD_URL); // Escape . and ?
$sUrlPattern = '|'.$sDownloadUrl.'([0-9]+)&s=([0-9a-f]+)|';
$bIsInlineImage = preg_match($sUrlPattern, $sSrc, $aMatches);
if (!$bIsInlineImage)
{
if (!$bIsInlineImage) {
return;
}
$iInlineImageId = $aMatches[1];
@@ -334,8 +317,7 @@ class InlineImage extends DBObject
$sAppRoot = utils::GetAbsoluteUrlAppRoot();
$sAppRootPattern = '/^'.preg_quote($sAppRoot, '/').'/';
$bIsSameItop = preg_match($sAppRootPattern, $sSrc);
if (!$bIsSameItop)
{
if (!$bIsSameItop) {
// @see N°1921
// image from another iTop should be treated as external images
$oElement->removeAttribute(self::DOM_ATTR_ID);
@@ -357,8 +339,7 @@ class InlineImage extends DBObject
{
$iMaxWidth = (int)MetaModel::GetConfig()->Get('inline_image_max_display_width', 0);
$sJS = '';
if ($iMaxWidth != 0)
{
if ($iMaxWidth != 0) {
$sJS =
<<<JS
CombodoInlineImage.SetMaxWidth('{$iMaxWidth}');
@@ -381,12 +362,13 @@ JS
*/
public static function IsImage($sMimeType)
{
if (!function_exists('gd_info')) return false; // no image processing capability on this system
if (!function_exists('gd_info')) {
return false;
} // no image processing capability on this system
$bRet = false;
$aInfo = gd_info(); // What are the capabilities
switch($sMimeType)
{
switch ($sMimeType) {
case 'image/gif':
return $aInfo['GIF Read Support'];
break;
@@ -422,24 +404,16 @@ JS
public static function GetMaxUpload()
{
$iMaxUpload = ini_get('upload_max_filesize');
if (!$iMaxUpload)
{
if (!$iMaxUpload) {
$sRet = Dict::S('Attachments:UploadNotAllowedOnThisSystem');
}
else
{
} else {
$iMaxUpload = utils::ConvertToBytes($iMaxUpload);
if ($iMaxUpload > 1024*1024*1024)
{
$sRet = Dict::Format('Attachment:Max_Go', sprintf('%0.2f', $iMaxUpload/(1024*1024*1024)));
}
else if ($iMaxUpload > 1024*1024)
{
$sRet = Dict::Format('Attachment:Max_Mo', sprintf('%0.2f', $iMaxUpload/(1024*1024)));
}
else
{
$sRet = Dict::Format('Attachment:Max_Ko', sprintf('%0.2f', $iMaxUpload/(1024)));
if ($iMaxUpload > 1024 * 1024 * 1024) {
$sRet = Dict::Format('Attachment:Max_Go', sprintf('%0.2f', $iMaxUpload / (1024 * 1024 * 1024)));
} elseif ($iMaxUpload > 1024 * 1024) {
$sRet = Dict::Format('Attachment:Max_Mo', sprintf('%0.2f', $iMaxUpload / (1024 * 1024)));
} else {
$sRet = Dict::Format('Attachment:Max_Ko', sprintf('%0.2f', $iMaxUpload / (1024)));
}
}
return $sRet;
@@ -469,73 +443,71 @@ JS
JS;
}
/**
* @inheritDoc
*/
protected function AfterInsert()
{
IssueLog::Trace(__METHOD__, LogChannels::INLINE_IMAGE, [
'id' => $this->GetKey(),
'expire' => $this->Get('expire'),
'temp_id' => $this->Get('temp_id'),
'item_class' => $this->Get('item_class'),
'item_id' => $this->Get('item_id'),
'item_org_id' => $this->Get('item_org_id'),
'secret' => $this->Get('secret'),
'user' => $sUser = UserRights::GetUser(),
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
]);
parent::AfterInsert();
}
/**
* @inheritDoc
*/
protected function AfterInsert()
{
IssueLog::Trace(__METHOD__, LogChannels::INLINE_IMAGE, array(
'id' => $this->GetKey(),
'expire' => $this->Get('expire'),
'temp_id' => $this->Get('temp_id'),
'item_class' => $this->Get('item_class'),
'item_id' => $this->Get('item_id'),
'item_org_id' => $this->Get('item_org_id'),
'secret' => $this->Get('secret'),
'user' => $sUser = UserRights::GetUser(),
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
));
protected function AfterUpdate()
{
IssueLog::Trace(__METHOD__, LogChannels::INLINE_IMAGE, [
'id' => $this->GetKey(),
'expire' => $this->Get('expire'),
'temp_id' => $this->Get('temp_id'),
'item_class' => $this->Get('item_class'),
'item_id' => $this->Get('item_id'),
'item_org_id' => $this->Get('item_org_id'),
'secret' => $this->Get('secret'),
'user' => $sUser = UserRights::GetUser(),
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
]);
parent::AfterInsert();
}
/**
* @inheritDoc
*/
protected function AfterUpdate()
{
IssueLog::Trace(__METHOD__, LogChannels::INLINE_IMAGE, array(
'id' => $this->GetKey(),
'expire' => $this->Get('expire'),
'temp_id' => $this->Get('temp_id'),
'item_class' => $this->Get('item_class'),
'item_id' => $this->Get('item_id'),
'item_org_id' => $this->Get('item_org_id'),
'secret' => $this->Get('secret'),
'user' => $sUser = UserRights::GetUser(),
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
));
parent::AfterUpdate();
}
parent::AfterUpdate();
}
/**
* @inheritDoc
*/
protected function AfterDelete()
{
IssueLog::Trace(__METHOD__, LogChannels::INLINE_IMAGE, array(
'id' => $this->GetKey(),
'expire' => $this->Get('expire'),
'temp_id' => $this->Get('temp_id'),
'item_class' => $this->Get('item_class'),
'item_id' => $this->Get('item_id'),
'item_org_id' => $this->Get('item_org_id'),
'secret' => $this->Get('secret'),
'user' => $sUser = UserRights::GetUser(),
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
));
{
IssueLog::Trace(__METHOD__, LogChannels::INLINE_IMAGE, [
'id' => $this->GetKey(),
'expire' => $this->Get('expire'),
'temp_id' => $this->Get('temp_id'),
'item_class' => $this->Get('item_class'),
'item_id' => $this->Get('item_id'),
'item_org_id' => $this->Get('item_org_id'),
'secret' => $this->Get('secret'),
'user' => $sUser = UserRights::GetUser(),
'HTTP_REFERER' => @$_SERVER['HTTP_REFERER'],
'REQUEST_URI' => @$_SERVER['REQUEST_URI'],
]);
parent::AfterDelete();
}
parent::AfterDelete();
}
}
/**
* Garbage collector for cleaning "old" temporary InlineImages (and Attachments).
*/
@@ -545,9 +517,9 @@ class InlineImageGC implements iBackgroundProcess
* @inheritDoc
*/
public function GetPeriodicity()
{
return 1;
}
{
return 1;
}
/**
* @inheritDoc
@@ -556,13 +528,11 @@ class InlineImageGC implements iBackgroundProcess
{
$sDateLimit = date(AttributeDateTime::GetSQLFormat(), time()); // Every temporary InlineImage/Attachment expired will be deleted
$aResults = array();
$aClasses = array('InlineImage', 'Attachment');
foreach($aClasses as $sClass)
{
$aResults = [];
$aClasses = ['InlineImage', 'Attachment'];
foreach ($aClasses as $sClass) {
$iProcessed = 0;
if(class_exists($sClass))
{
if (class_exists($sClass)) {
$iProcessed = $this->DeleteExpiredDocuments($sClass, $iTimeLimit, $sDateLimit);
}
$aResults[] = "$iProcessed old temporary $sClass(s)";
@@ -591,11 +561,15 @@ class InlineImageGC implements iBackgroundProcess
$iProcessed = 0;
$sOQL = "SELECT $sClass WHERE (item_id = 0) AND (expire < '$sDateLimit')";
// Next one ?
$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL), array('expire' => true) /* order by*/, array(), null,
1 /* limit count */);
$oSet->OptimizeColumnLoad(array());
while ((time() < $iTimeLimit) && ($oResult = $oSet->Fetch()))
{
$oSet = new CMDBObjectSet(
DBObjectSearch::FromOQL($sOQL),
['expire' => true] /* order by*/,
[],
null,
1 /* limit count */
);
$oSet->OptimizeColumnLoad([]);
while ((time() < $iTimeLimit) && ($oResult = $oSet->Fetch())) {
/** @var \ormDocument $oDocument */
$oDocument = $oResult->Get('contents');
IssueLog::Info($sClass.' GC: Removed temp. file '.$oDocument->GetFileName().' on "'.$oResult->Get('item_class').'" #'.$oResult->Get('item_id').' as it has expired.');
@@ -605,4 +579,4 @@ class InlineImageGC implements iBackgroundProcess
return $iProcessed;
}
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
@@ -7,32 +8,31 @@
use Combodo\iTop\Core\Kpi\KpiLogData;
use Combodo\iTop\Service\Module\ModuleService;
/**
* Measures operations duration, memory usage, etc. (and some other KPIs)
*/
class ExecutionKPI
{
static protected $m_bEnabled_Duration = false;
static protected $m_bEnabled_Memory = false;
static protected $m_bBlameCaller = false;
static protected $m_sAllowedUser = '*';
static protected $m_bGenerateLegacyReport = true;
static protected $m_fSlowQueries = 0;
protected static $m_bEnabled_Duration = false;
protected static $m_bEnabled_Memory = false;
protected static $m_bBlameCaller = false;
protected static $m_sAllowedUser = '*';
protected static $m_bGenerateLegacyReport = true;
protected static $m_fSlowQueries = 0;
static protected $m_aStats = []; // Recurrent operations
static protected $m_aExecData = []; // One shot operations
protected static $m_aStats = []; // Recurrent operations
protected static $m_aExecData = []; // One shot operations
/**
* @var array[ExecutionKPI]
*/
static protected $m_aExecutionStack = []; // embedded execution stats
protected static $m_aExecutionStack = []; // embedded execution stats
protected $m_fStarted = null;
protected $m_fChildrenDuration = 0; // Count embedded
protected $m_iInitialMemory = null;
static public function EnableDuration($iLevel)
public static function EnableDuration($iLevel)
{
if ($iLevel > 0) {
self::$m_bEnabled_Duration = true;
@@ -47,7 +47,7 @@ class ExecutionKPI
}
}
static public function EnableMemory($iLevel)
public static function EnableMemory($iLevel)
{
if ($iLevel > 0) {
self::$m_bEnabled_Memory = true;
@@ -57,91 +57,94 @@ class ExecutionKPI
}
/**
* @param string sUser A user login or * for all users
*/
static public function SetAllowedUser($sUser)
* @param string sUser A user login or * for all users
*/
public static function SetAllowedUser($sUser)
{
self::$m_sAllowedUser = $sUser;
}
static public function IsEnabled()
public static function IsEnabled()
{
if (self::$m_bEnabled_Duration || self::$m_bEnabled_Memory)
{
if ((self::$m_sAllowedUser == '*') || (UserRights::GetUser() == trim(self::$m_sAllowedUser)))
{
if (self::$m_bEnabled_Duration || self::$m_bEnabled_Memory) {
if ((self::$m_sAllowedUser == '*') || (UserRights::GetUser() == trim(self::$m_sAllowedUser))) {
return true;
}
}
return false;
}
static public function SetGenerateLegacyReport($bReportExtensionsOnly)
{
self::$m_bGenerateLegacyReport = $bReportExtensionsOnly;
}
static public function SetSlowQueries($fSlowQueries)
{
self::$m_fSlowQueries = $fSlowQueries;
}
static public function GetDescription()
public static function SetGenerateLegacyReport($bReportExtensionsOnly)
{
$aFeatures = array();
if (self::$m_bEnabled_Duration) $aFeatures[] = 'Duration';
if (self::$m_bEnabled_Memory) $aFeatures[] = 'Memory usage';
$sFeatures = 'Measures: '.implode(', ', $aFeatures);
$sFor = self::$m_sAllowedUser == '*' ? 'EVERYBODY' : "'".trim(self::$m_sAllowedUser)."'";
$sSlowQueries = '';
if (self::$m_fSlowQueries > 0) {
$sSlowQueries = ". Slow Queries: ".self::$m_fSlowQueries."s";
}
$aExtensions = [];
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
$aExtensions[] = ModuleService::GetInstance()->GetModuleNameFromObject($oExtensionInstance);
}
$sExtensions = '';
if (count($aExtensions) > 0) {
$sExtensions = '. KPI Extensions: ['.implode(', ', $aExtensions).']';
}
return "KPI logging is active for $sFor. $sFeatures$sSlowQueries$sExtensions";
self::$m_bGenerateLegacyReport = $bReportExtensionsOnly;
}
static public function ReportStats()
public static function SetSlowQueries($fSlowQueries)
{
if (!self::IsEnabled()) return;
self::$m_fSlowQueries = $fSlowQueries;
}
public static function GetDescription()
{
$aFeatures = [];
if (self::$m_bEnabled_Duration) {
$aFeatures[] = 'Duration';
}
if (self::$m_bEnabled_Memory) {
$aFeatures[] = 'Memory usage';
}
$sFeatures = 'Measures: '.implode(', ', $aFeatures);
$sFor = self::$m_sAllowedUser == '*' ? 'EVERYBODY' : "'".trim(self::$m_sAllowedUser)."'";
$sSlowQueries = '';
if (self::$m_fSlowQueries > 0) {
$sSlowQueries = ". Slow Queries: ".self::$m_fSlowQueries."s";
}
$aExtensions = [];
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
$aExtensions[] = ModuleService::GetInstance()->GetModuleNameFromObject($oExtensionInstance);
}
$sExtensions = '';
if (count($aExtensions) > 0) {
$sExtensions = '. KPI Extensions: ['.implode(', ', $aExtensions).']';
}
return "KPI logging is active for $sFor. $sFeatures$sSlowQueries$sExtensions";
}
public static function ReportStats()
{
if (!self::IsEnabled()) {
return;
}
global $fItopStarted;
global $iItopInitialMemory;
global $iItopInitialMemory;
$sExecId = microtime(); // id to differentiate the hrefs!
$sRequest = $_SERVER['REQUEST_URI'].' ('.$_SERVER['REQUEST_METHOD'].')';
if (isset($_POST['operation'])) {
$sRequest .= ' operation: '.$_POST['operation'];
}
$sRequest = $_SERVER['REQUEST_URI'].' ('.$_SERVER['REQUEST_METHOD'].')';
if (isset($_POST['operation'])) {
$sRequest .= ' operation: '.$_POST['operation'];
}
$fStop = MyHelpers::getmicrotime();
if (($fStop - $fItopStarted) > self::$m_fSlowQueries) {
// Invoke extensions to log the KPI operation
/** @var \iKPILoggerExtension $oExtensionInstance */
$iCurrentMemory = self::memory_get_usage();
$iPeakMemory = self::memory_get_peak_usage();
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
$oKPILogData = new KpiLogData(KpiLogData::TYPE_REQUEST, 'Page', $sRequest, $fItopStarted, $fStop, '', $iItopInitialMemory, $iCurrentMemory, $iPeakMemory);
$oExtensionInstance->LogOperation($oKPILogData);
}
}
$fStop = MyHelpers::getmicrotime();
if (($fStop - $fItopStarted) > self::$m_fSlowQueries) {
// Invoke extensions to log the KPI operation
/** @var \iKPILoggerExtension $oExtensionInstance */
$iCurrentMemory = self::memory_get_usage();
$iPeakMemory = self::memory_get_peak_usage();
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
$oKPILogData = new KpiLogData(KpiLogData::TYPE_REQUEST, 'Page', $sRequest, $fItopStarted, $fStop, '', $iItopInitialMemory, $iCurrentMemory, $iPeakMemory);
$oExtensionInstance->LogOperation($oKPILogData);
}
}
if (!self::$m_bGenerateLegacyReport) {
return;
}
if (!self::$m_bGenerateLegacyReport) {
return;
}
$aBeginTimes = array();
foreach (self::$m_aExecData as $aOpStats)
{
$aBeginTimes = [];
foreach (self::$m_aExecData as $aOpStats) {
$aBeginTimes[] = $aOpStats['time_begin'];
}
array_multisort($aBeginTimes, self::$m_aExecData);
@@ -150,7 +153,7 @@ class ExecutionKPI
$sHtml = "<hr/>";
$sHtml .= "<div style=\"background-color: grey; padding: 10px;\">";
$sHtml .= "<h3><a name=\"".md5($sExecId)."\">KPIs</a> - $sRequest</h3>";
$sHtml .= "<h3><a name=\"".md5($sExecId)."\">KPIs</a> - $sRequest</h3>";
$oStarted = DateTime::createFromFormat('U.u', $fItopStarted);
$sHtml .= '<p>'.$oStarted->format('Y-m-d H:i:s.u').'</p>';
$sHtml .= "<p>log_kpi_user_id: ".UserRights::GetUserId()."</p>";
@@ -159,8 +162,7 @@ class ExecutionKPI
$sHtml .= "<thead>";
$sHtml .= " <th>Operation</th><th>Begin</th><th>End</th><th>Duration</th><th>Memory start</th><th>Memory end</th><th>Memory peak</th>";
$sHtml .= "</thead>";
foreach (self::$m_aExecData as $aOpStats)
{
foreach (self::$m_aExecData as $aOpStats) {
$sOperation = $aOpStats['op'];
$sBegin = round($aOpStats['time_begin'], 3);
$sEnd = round($aOpStats['time_end'], 3);
@@ -170,12 +172,10 @@ class ExecutionKPI
$sMemBegin = 'n/a';
$sMemEnd = 'n/a';
$sMemPeak = 'n/a';
if (isset($aOpStats['mem_begin']))
{
if (isset($aOpStats['mem_begin'])) {
$sMemBegin = self::MemStr($aOpStats['mem_begin']);
$sMemEnd = self::MemStr($aOpStats['mem_end']);
if (isset($aOpStats['mem_peak']))
{
if (isset($aOpStats['mem_peak'])) {
$sMemPeak = self::MemStr($aOpStats['mem_peak']);
}
}
@@ -187,38 +187,34 @@ class ExecutionKPI
$sHtml .= "</table>";
$sHtml .= "</div>";
$aConsolidatedStats = array();
foreach (self::$m_aStats as $sOperation => $aOpStats)
{
$aConsolidatedStats = [];
foreach (self::$m_aStats as $sOperation => $aOpStats) {
$fTotalOp = 0;
$iTotalOp = 0;
$fMinOp = null;
$fMaxOp = 0;
$sMaxOpArguments = null;
foreach ($aOpStats as $sArguments => $aEvents)
{
foreach ($aEvents as $aEventData)
{
foreach ($aOpStats as $sArguments => $aEvents) {
foreach ($aEvents as $aEventData) {
$fDuration = $aEventData['time'];
$fTotalOp += $fDuration;
$iTotalOp++;
$fMinOp = is_null($fMinOp) ? $fDuration : min($fMinOp, $fDuration);
if ($fDuration > $fMaxOp)
{
if ($fDuration > $fMaxOp) {
$sMaxOpArguments = $sArguments;
$fMaxOp = $fDuration;
}
}
}
$aConsolidatedStats[$sOperation] = array(
$aConsolidatedStats[$sOperation] = [
'count' => $iTotalOp,
'duration' => $fTotalOp,
'min' => $fMinOp,
'max' => $fMaxOp,
'avg' => $fTotalOp / $iTotalOp,
'max_args' => $sMaxOpArguments
);
'max_args' => $sMaxOpArguments,
];
}
$sHtml .= "<div>";
@@ -226,8 +222,7 @@ class ExecutionKPI
$sHtml .= "<thead>";
$sHtml .= " <th>Operation</th><th>Count</th><th>Duration</th><th>Min</th><th>Max</th><th>Avg</th>";
$sHtml .= "</thead>";
foreach ($aConsolidatedStats as $sOperation => $aOpStats)
{
foreach ($aConsolidatedStats as $sOperation => $aOpStats) {
$sOperation = '<a href="#'.md5($sExecId.$sOperation).'">'.$sOperation.'</a>';
$sCount = $aOpStats['count'];
$sDuration = round($aOpStats['duration'], 3);
@@ -250,25 +245,20 @@ class ExecutionKPI
self::Report($sHtml);
// Report operation details
foreach (self::$m_aStats as $sOperation => $aOpStats)
{
foreach (self::$m_aStats as $sOperation => $aOpStats) {
$sHtml = '';
$bDisplayHeader = true;
foreach ($aOpStats as $sArguments => $aEvents)
{
foreach ($aOpStats as $sArguments => $aEvents) {
$sHtmlArguments = '<a name="'.md5($sExecId.$sArguments).'"><div style="white-space: pre-wrap;">'.$sArguments.'</div></a>';
if ($aConsolidatedStats[$sOperation]['max_args'] == $sArguments)
{
if ($aConsolidatedStats[$sOperation]['max_args'] == $sArguments) {
$sHtmlArguments = '<span style="color: red;">'.$sHtmlArguments.'</span>';
}
if (isset($aEvents[0]['callers']))
{
if (isset($aEvents[0]['callers'])) {
$sHtmlArguments .= '<div style="padding: 10px;">';
$sHtmlArguments .= '<table border="1" bgcolor="#cfc">';
$sHtmlArguments .= '<tr><td colspan="2" bgcolor="#e9b96">Call stack for the <b>FIRST</b> caller</td></tr>';
foreach ($aEvents[0]['callers'] as $aCall)
{
foreach ($aEvents[0]['callers'] as $aCall) {
$sHtmlArguments .= '<tr>';
$sHtmlArguments .= '<td>'.$aCall['Function'].'</td>';
$sHtmlArguments .= '<td>'.$aCall['File'].':'.$aCall['Line'].'</td>';
@@ -281,8 +271,7 @@ class ExecutionKPI
$fTotalInter = 0;
$fMinInter = null;
$fMaxInter = 0;
foreach ($aEvents as $aEventData)
{
foreach ($aEvents as $aEventData) {
$fDuration = $aEventData['time'];
$fTotalInter += $fDuration;
$fMinInter = is_null($fMinInter) ? $fDuration : min($fMinInter, $fDuration);
@@ -293,10 +282,8 @@ class ExecutionKPI
$sTotalInter = round($fTotalInter, 3);
$sMinInter = round($fMinInter, 3);
$sMaxInter = round($fMaxInter, 3);
if (($fTotalInter >= self::$m_fSlowQueries))
{
if ($bDisplayHeader)
{
if (($fTotalInter >= self::$m_fSlowQueries)) {
if ($bDisplayHeader) {
$sOperationHtml = '<a name="'.md5($sExecId.$sOperation).'">'.$sOperation.'</a>';
$sHtml .= "<h4>$sOperationHtml</h4>";
$sHtml .= "<table border=\"1\" style=\"$sTableStyle\">";
@@ -310,8 +297,7 @@ class ExecutionKPI
$sHtml .= "</tr>";
}
}
if (!$bDisplayHeader)
{
if (!$bDisplayHeader) {
$sHtml .= "</table>";
$sHtml .= "<p><a href=\"#".md5($sExecId)."\">Back to page stats</a></p>";
}
@@ -321,19 +307,19 @@ class ExecutionKPI
self::Report($sHtml);
}
public static function InitStats()
{
// Invoke extensions to initialize the KPI statistics
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
$oExtensionInstance->InitStats();
}
}
public static function InitStats()
{
// Invoke extensions to initialize the KPI statistics
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
$oExtensionInstance->InitStats();
}
}
public function __construct()
{
$this->ResetCounters();
}
}
// Get the duration since startup, and reset the counter for the next measure
//
@@ -341,65 +327,62 @@ class ExecutionKPI
{
global $fItopStarted;
if (!self::IsEnabled()) {
return;
}
if (!self::IsEnabled()) {
return;
}
$aNewEntry = null;
$fStarted = $this->m_fStarted;
$fStopped = $this->m_fStarted;
if (self::$m_bEnabled_Duration) {
$fStarted = $this->m_fStarted;
$fStopped = $this->m_fStarted;
if (self::$m_bEnabled_Duration) {
$fStopped = MyHelpers::getmicrotime();
$aNewEntry = array(
$aNewEntry = [
'op' => $sOperationDesc,
'time_begin' => $this->m_fStarted - $fItopStarted,
'time_end' => $fStopped - $fItopStarted,
);
];
// Reset for the next operation (if the object is recycled)
$this->m_fStarted = $fStopped;
}
$iInitialMemory = is_null($this->m_iInitialMemory) ? 0 : $this->m_iInitialMemory;
$iCurrentMemory = 0;
$iPeakMemory = 0;
if (self::$m_bEnabled_Memory)
{
$iInitialMemory = is_null($this->m_iInitialMemory) ? 0 : $this->m_iInitialMemory;
$iCurrentMemory = 0;
$iPeakMemory = 0;
if (self::$m_bEnabled_Memory) {
$iCurrentMemory = self::memory_get_usage();
if (is_null($aNewEntry))
{
$aNewEntry = array('op' => $sOperationDesc);
if (is_null($aNewEntry)) {
$aNewEntry = ['op' => $sOperationDesc];
}
$aNewEntry['mem_begin'] = $this->m_iInitialMemory;
$aNewEntry['mem_end'] = $iCurrentMemory;
$iPeakMemory = self::memory_get_peak_usage();
$aNewEntry['mem_peak'] = $iPeakMemory;
$iPeakMemory = self::memory_get_peak_usage();
$aNewEntry['mem_peak'] = $iPeakMemory;
// Reset for the next operation (if the object is recycled)
$this->m_iInitialMemory = $iCurrentMemory;
}
if (self::$m_bEnabled_Duration || self::$m_bEnabled_Memory) {
// Invoke extensions to log the KPI operation
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance)
{
$sExtension = ModuleService::GetInstance()->GetModuleNameFromCallStack(1);
$oKPILogData = new KpiLogData(
KpiLogData::TYPE_REPORT,
'Step',
$sOperationDesc,
$fStarted,
$fStopped,
$sExtension,
$iInitialMemory,
$iCurrentMemory,
$iPeakMemory);
$oExtensionInstance->LogOperation($oKPILogData);
}
}
if (self::$m_bEnabled_Duration || self::$m_bEnabled_Memory) {
// Invoke extensions to log the KPI operation
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
$sExtension = ModuleService::GetInstance()->GetModuleNameFromCallStack(1);
$oKPILogData = new KpiLogData(
KpiLogData::TYPE_REPORT,
'Step',
$sOperationDesc,
$fStarted,
$fStopped,
$sExtension,
$iInitialMemory,
$iCurrentMemory,
$iPeakMemory
);
$oExtensionInstance->LogOperation($oKPILogData);
}
}
if (!is_null($aNewEntry) && self::$m_bGenerateLegacyReport)
{
if (!is_null($aNewEntry) && self::$m_bGenerateLegacyReport) {
self::$m_aExecData[] = $aNewEntry;
}
$this->ResetCounters();
@@ -417,20 +400,20 @@ class ExecutionKPI
* @throws \ReflectionException
*/
public function ComputeStatsForExtension($object, string $sMethod, string $sMessage = ''): bool
{
if (!self::IsEnabled()) {
return true;
}
{
if (!self::IsEnabled()) {
return true;
}
$sSignature = ModuleService::GetInstance()->GetModuleMethodSignature($object, $sMethod);
if (utils::StartsWith($sSignature, '[')) {
$this->ComputeStats('Extension', "$sSignature $sMessage");
$sSignature = ModuleService::GetInstance()->GetModuleMethodSignature($object, $sMethod);
if (utils::StartsWith($sSignature, '[')) {
$this->ComputeStats('Extension', "$sSignature $sMessage");
return true;
}
}
return false;
}
}
public function ComputeStats($sOperation, $sArguments)
{
@@ -442,85 +425,82 @@ class ExecutionKPI
if (self::$m_bEnabled_Duration) {
$fStopped = MyHelpers::getmicrotime();
$fDuration = $fStopped - $this->m_fStarted;
$aCallstack = [];
if (self::$m_bGenerateLegacyReport) {
if (self::$m_bBlameCaller) {
$aCallstack = MyHelpers::get_callstack(1);
self::$m_aStats[$sOperation][$sArguments][] = [
'time' => $fDuration,
'callers' => $aCallstack,
];
} else {
self::$m_aStats[$sOperation][$sArguments][] = [
'time' => $fDuration
];
}
}
$aCallstack = [];
if (self::$m_bGenerateLegacyReport) {
if (self::$m_bBlameCaller) {
$aCallstack = MyHelpers::get_callstack(1);
self::$m_aStats[$sOperation][$sArguments][] = [
'time' => $fDuration,
'callers' => $aCallstack,
];
} else {
self::$m_aStats[$sOperation][$sArguments][] = [
'time' => $fDuration,
];
}
}
$iInitialMemory = is_null($this->m_iInitialMemory) ? 0 : $this->m_iInitialMemory;
$iCurrentMemory = 0;
$iPeakMemory = 0;
if (self::$m_bEnabled_Memory)
{
$iCurrentMemory = self::memory_get_usage();
$iPeakMemory = self::memory_get_peak_usage();
}
$iInitialMemory = is_null($this->m_iInitialMemory) ? 0 : $this->m_iInitialMemory;
$iCurrentMemory = 0;
$iPeakMemory = 0;
if (self::$m_bEnabled_Memory) {
$iCurrentMemory = self::memory_get_usage();
$iPeakMemory = self::memory_get_peak_usage();
}
// Invoke extensions to log the KPI operation
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
//$sExtension = ModuleService::GetInstance()->GetModuleNameFromCallStack(1);
$sExtension = '';
$oKPILogData = new KpiLogData(
KpiLogData::TYPE_STATS,
$sOperation,
$sArguments,
$this->m_fStarted,
$fStopped,
$sExtension,
$iInitialMemory,
$iCurrentMemory,
$iPeakMemory,
$aCallstack);
$oExtensionInstance->LogOperation($oKPILogData);
}
}
// Invoke extensions to log the KPI operation
/** @var \iKPILoggerExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins('iKPILoggerExtension') as $oExtensionInstance) {
//$sExtension = ModuleService::GetInstance()->GetModuleNameFromCallStack(1);
$sExtension = '';
$oKPILogData = new KpiLogData(
KpiLogData::TYPE_STATS,
$sOperation,
$sArguments,
$this->m_fStarted,
$fStopped,
$sExtension,
$iInitialMemory,
$iCurrentMemory,
$iPeakMemory,
$aCallstack
);
$oExtensionInstance->LogOperation($oKPILogData);
}
}
}
protected function ResetCounters()
{
if (self::$m_bEnabled_Duration)
{
if (self::$m_bEnabled_Duration) {
$this->m_fStarted = microtime(true);
}
if (self::$m_bEnabled_Memory)
{
if (self::$m_bEnabled_Memory) {
$this->m_iInitialMemory = self::memory_get_usage();
}
}
const HTML_REPORT_FILE = 'log/kpi.html';
public const HTML_REPORT_FILE = 'log/kpi.html';
static protected function Report($sText)
protected static function Report($sText)
{
file_put_contents(APPROOT.self::HTML_REPORT_FILE, "$sText\n", FILE_APPEND | LOCK_EX);
}
static protected function MemStr($iMemory)
protected static function MemStr($iMemory)
{
return round($iMemory / 1024).' Kb';
}
static protected function memory_get_usage()
protected static function memory_get_usage()
{
return memory_get_usage(true);
return memory_get_usage(true);
}
static public function memory_get_peak_usage($bRealUsage = false)
public static function memory_get_peak_usage($bRealUsage = false)
{
if (function_exists('memory_get_peak_usage'))
{
if (function_exists('memory_get_peak_usage')) {
return memory_get_peak_usage($bRealUsage);
}
// PHP > 5.2.1 - this verb depends on a compilation option

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,10 @@
<?php
/**
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
class OQLActualClassTreeResolver
{
/** @var OQLClassNode */
@@ -38,67 +38,54 @@ class OQLActualClassTreeResolver
$sClass = $this->oOQLClassNode->GetNodeClass();
$sClassAlias = $this->oOQLClassNode->GetNodeClassAlias();
$aExpectedAttributes = $this->oBuild->m_oQBExpressions->GetUnresolvedFields($sClassAlias);
if (!is_null($sIncomingKeyAttCode) && !isset($aExpectedAttributes[$sIncomingKeyAttCode]))
{
if (!is_null($sIncomingKeyAttCode) && !isset($aExpectedAttributes[$sIncomingKeyAttCode])) {
// Add entry point as expected attribute
$aExpectedAttributes[$sIncomingKeyAttCode] = new FieldExpression($sIncomingKeyAttCode, $sClassAlias);
}
$aClasses = MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL, false);
/** @var OQLClassNode[] $aClassAndAncestorsNodes */
$aClassAndAncestorsNodes = array();
foreach ($aClasses as $sFamilyClass)
{
$aClassAndAncestorsNodes = [];
foreach ($aClasses as $sFamilyClass) {
// Remove unnecessary classes
if (MetaModel::HasTable($sFamilyClass))
{
if (MetaModel::HasTable($sFamilyClass)) {
$aClassAndAncestorsNodes[$sFamilyClass] = null;
}
}
if (empty($aClassAndAncestorsNodes))
{
if (empty($aClassAndAncestorsNodes)) {
throw new CoreException("Impossible to query the class $sClass");
}
$oBaseNode = null;
$aTranslateFields = array();
foreach ($aExpectedAttributes as $sAttCode => $oExpression)
{
$aTranslateFields = [];
foreach ($aExpectedAttributes as $sAttCode => $oExpression) {
// 'id' is managed later
if ($sAttCode == 'id')
{
if ($sAttCode == 'id') {
continue;
}
// Attributes can be stored in attributes list or for magic ones into filter codes list.
$sOriginClass = null;
if (MetaModel::IsValidAttCode($sClass, $sAttCode)) {
$sOriginClass = MetaModel::GetAttributeOrigin($sClass, $sAttCode);
} else if ($sAttCode == 'id') {
} elseif ($sAttCode == 'id') {
$sOriginClass = $sClass;
} else {
continue;
}
if (!isset($aClassAndAncestorsNodes[$sOriginClass]) || is_null($aClassAndAncestorsNodes[$sOriginClass]))
{
if ($sOriginClass == $sClass)
{
if (!isset($aClassAndAncestorsNodes[$sOriginClass]) || is_null($aClassAndAncestorsNodes[$sOriginClass])) {
if ($sOriginClass == $sClass) {
$sOriginClassAlias = $sClassAlias;
}
else
{
} else {
$sOriginClassAlias = $this->oBuild->GenerateTableAlias($sClassAlias.'_'.$sOriginClass, $sClass);
}
$oOriginClassNode = new OQLClassNode($this->oBuild, $sOriginClass, $sOriginClassAlias, $sClassAlias);
$aClassAndAncestorsNodes[$sOriginClass] = $oOriginClassNode;
}
else
{
} else {
$oOriginClassNode = $aClassAndAncestorsNodes[$sOriginClass];
}
if ($sOriginClass != $sClass)
{
if ($sOriginClass != $sClass) {
// Alias changed, set a new translation
$sOriginClassAlias = $oOriginClassNode->GetNodeClassAlias();
$aTranslateFields[$sClassAlias][$sAttCode] = new FieldExpression($sAttCode, $sOriginClassAlias);
@@ -107,8 +94,7 @@ class OQLActualClassTreeResolver
// Add Joins corresponding to external keys
$this->ResolveJoins($sAttCode, $oOriginClassNode);
if ($sAttCode === $sIncomingKeyAttCode)
{
if ($sAttCode === $sIncomingKeyAttCode) {
// This is the entry point of the class
$oBaseNode = $oOriginClassNode;
}
@@ -117,47 +103,37 @@ class OQLActualClassTreeResolver
// Create joins for ancestor classes
/** @var \OQLClassNode $oBaseNode */
$sFirstValidAncestor = null;
foreach ($aClassAndAncestorsNodes as $sOriginClass => $oOriginClassNode)
{
if (is_null($sFirstValidAncestor))
{
foreach ($aClassAndAncestorsNodes as $sOriginClass => $oOriginClassNode) {
if (is_null($sFirstValidAncestor)) {
$sFirstValidAncestor = $sOriginClass;
}
if (is_null($oOriginClassNode))
{
if (is_null($oOriginClassNode)) {
continue;
}
if (is_null($oBaseNode))
{
if (is_null($oBaseNode)) {
$oBaseNode = $oOriginClassNode;
continue;
}
if ($oBaseNode === $oOriginClassNode)
{
if ($oBaseNode === $oOriginClassNode) {
// Don't link to itself
continue;
}
$oBaseNode->AddInnerJoin($oOriginClassNode, 'id', 'id');
}
if (is_null($oBaseNode))
{
if (is_null($oBaseNode)) {
// If no class was generated above, keep the first valid ancestor
if (is_null($sFirstValidAncestor) || ($sFirstValidAncestor == $sClass))
{
if (is_null($sFirstValidAncestor) || ($sFirstValidAncestor == $sClass)) {
// take current node
$oBaseNode = $this->oOQLClassNode->CloneNode();
}
else
{
} else {
// Use the first valid class to build a default node
$sDefaultClassAlias = $this->oBuild->GenerateTableAlias($sClassAlias.'_'.$sFirstValidAncestor, $sClass);
$oBaseNode = new OQLClassNode($this->oBuild, $sFirstValidAncestor, $sDefaultClassAlias);
}
}
if (isset($aExpectedAttributes['id']) && !isset($aClassAndAncestorsNodes[$sClass]))
{
if (isset($aExpectedAttributes['id']) && !isset($aClassAndAncestorsNodes[$sClass])) {
$sFirstClassAlias = $oBaseNode->GetNodeClassAlias();
$aTranslateFields[$sClassAlias]['id'] = new FieldExpression('id', $sFirstClassAlias);
}
@@ -167,12 +143,11 @@ class OQLActualClassTreeResolver
$this->ResolveJoins('id', $oBaseNode);
// Add finalclass condition if not the requested class
if ($oBaseNode->GetNodeClass() != $sClass)
{
if ($oBaseNode->GetNodeClass() != $sClass) {
$sExpectedClasses = implode("', '", MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL));
$oInExpression = Expression::FromOQL("`".$oBaseNode->GetNodeClassAlias()."`.finalclass IN ('$sExpectedClasses')");
$oTrueExpression = new TrueExpression();
$aCoalesceAttr = array($oInExpression, $oTrueExpression);
$aCoalesceAttr = [$oInExpression, $oTrueExpression];
$oFinalClassRestriction = new FunctionExpression("COALESCE", $aCoalesceAttr);
$this->oBuild->m_oQBExpressions->AddCondition($oFinalClassRestriction);
}
@@ -194,10 +169,8 @@ class OQLActualClassTreeResolver
// Joins on the selected class
$aJoins = $this->oOQLClassNode->GetJoins();
if (isset($aJoins[$sAttCode]))
{
foreach ($aJoins[$sAttCode] as $oBaseOQLJoin)
{
if (isset($aJoins[$sAttCode])) {
foreach ($aJoins[$sAttCode] as $oBaseOQLJoin) {
// transfer the join from OQL class tree to actual class tree
$oBaseJoinedClassNode = $oBaseOQLJoin->GetOOQLClassNode();
$oOQLActualClassTreeResolver = new OQLActualClassTreeResolver($oBaseJoinedClassNode, $this->oBuild);

View File

@@ -407,16 +407,16 @@ class ormDocument
* @return ormDocument The resampled image
*
*/
public function ResizeImageToFit(int $iMaxWidth, int $iMaxHeight, array|null &$aFinalDimensions = null) : static
public function ResizeImageToFit(int $iMaxWidth, int $iMaxHeight, array|null &$aFinalDimensions = null): static
{
$aFinalDimensions = null;
// If gd extension is not loaded, we put a warning in the log and return the image as is
if (extension_loaded('gd') === false) {
IssueLog::Warning('Image could not be resized as the "gd" extension does not seem to be loaded. Its dimensions will remain the same instead of ' . $iMaxWidth . 'x' . $iMaxHeight);
IssueLog::Warning('Image could not be resized as the "gd" extension does not seem to be loaded. Its dimensions will remain the same instead of '.$iMaxWidth.'x'.$iMaxHeight);
return $this;
}
$oGdImage = false;
switch($this->GetMimeType()) {
switch ($this->GetMimeType()) {
case 'image/gif':
case 'image/jpeg':
case 'image/png':
@@ -428,18 +428,18 @@ class ormDocument
}
if ($oGdImage === false) {
IssueLog::Warning('Image could not be resized as . It will remain as imagecreatefromstring could not read its data.Its dimensions will remain the same instead of ' . $iMaxWidth . 'x' . $iMaxHeight);
IssueLog::Warning('Image could not be resized as . It will remain as imagecreatefromstring could not read its data.Its dimensions will remain the same instead of '.$iMaxWidth.'x'.$iMaxHeight);
return $this;
}
$iWidth = imagesx($oGdImage);
$iHeight = imagesy($oGdImage);
if ( ($iMaxWidth === 0 || $iWidth <= $iMaxWidth) && ($iMaxHeight === 0 || $iHeight <= $iMaxHeight)) {
if (($iMaxWidth === 0 || $iWidth <= $iMaxWidth) && ($iMaxHeight === 0 || $iHeight <= $iMaxHeight)) {
// No need to resize
$aFinalDimensions = [
'width' => $iWidth,
'height' =>$iHeight
'height' => $iHeight,
];
return $this;
}
@@ -456,14 +456,13 @@ class ormDocument
$oNewGdImage = imagecreatetruecolor($iNewWidth, $iNewHeight);
$aFinalDimensions = [
'width' => $iNewWidth,
'height' =>$iNewHeight
'height' => $iNewHeight,
];
// Preserve transparency
if($this->GetMimeType() == "image/gif" || $this->GetMimeType() == "image/png") {
if ($this->GetMimeType() == "image/gif" || $this->GetMimeType() == "image/png") {
imagecolortransparent($oNewGdImage, imagecolorallocatealpha($oNewGdImage, 0, 0, 0, 127));
imagealphablending($oNewGdImage, false);
imagesavealpha($oNewGdImage, true);
@@ -473,16 +472,16 @@ class ormDocument
ob_start();
switch ($this->GetMimeType()) {
case 'image/gif':
imagegif($oNewGdImage); // send image to output buffer
break;
imagegif($oNewGdImage); // send image to output buffer
break;
case 'image/jpeg':
imagejpeg($oNewGdImage, null, 80); // null = send image to output buffer, 80 = good quality
break;
imagejpeg($oNewGdImage, null, 80); // null = send image to output buffer, 80 = good quality
break;
case 'image/png':
imagepng($oNewGdImage, null, 5); // null = send image to output buffer, 5 = medium compression
break;
imagepng($oNewGdImage, null, 5); // null = send image to output buffer, 5 = medium compression
break;
}
$oResampledImage = new ormDocument(ob_get_contents(), $this->GetMimeType(), $this->GetFileName());
@ob_end_clean();
@@ -502,5 +501,4 @@ class ormDocument
return md5($this->GetData() ?? '');
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (C) 2013-2024 Combodo SAS
*
@@ -19,7 +20,6 @@
require_once('dbobjectiterator.php');
/**
* The value for an attribute representing a set of links between the host object and "remote" objects
*
@@ -56,22 +56,22 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
* Object from the original set, minus the removed objects
* @var DBObject[] array of iObjectId => DBObject
*/
protected $aPreserved = array();
protected $aPreserved = [];
/**
* @var DBObject[] New items
*/
protected $aAdded = array();
protected $aAdded = [];
/**
* @var DBObject[] Modified items (could also be found in aPreserved)
*/
protected $aModified = array();
protected $aModified = [];
/**
* @var int[] Removed items
*/
protected $aRemoved = array();
protected $aRemoved = [];
/**
* @var int Position in the collection
@@ -100,13 +100,11 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
$this->oOriginalSet = $oOriginalSet ? clone $oOriginalSet : null;
$oAttDef = MetaModel::GetAttributeDef($sHostClass, $sAttCode);
if (!$oAttDef instanceof AttributeLinkedSet)
{
if (!$oAttDef instanceof AttributeLinkedSet) {
throw new Exception("ormLinkSet: $sAttCode is not a link set");
}
$this->sClass = $oAttDef->GetLinkedClass();
if ($oOriginalSet && ($oOriginalSet->GetClass() != $this->sClass))
{
if ($oOriginalSet && ($oOriginalSet->GetClass() != $this->sClass)) {
throw new Exception("ormLinkSet: wrong class for the original set, found {$oOriginalSet->GetClass()} while expecting {$oAttDef->GetLinkedClass()}");
}
}
@@ -140,7 +138,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
{
assert($oLink instanceof $this->sClass);
// No impact on the iteration algorithm
$iObjectId = $oLink->GetKey();
$iObjectId = $oLink->GetKey();
$this->aAdded[$iObjectId] = $oLink;
$this->bHasDelta = true;
}
@@ -150,19 +148,15 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
*/
public function RemoveItem($iObjectId)
{
if (array_key_exists($iObjectId, $this->aPreserved))
{
if (array_key_exists($iObjectId, $this->aPreserved)) {
unset($this->aPreserved[$iObjectId]);
$this->aRemoved[$iObjectId] = $iObjectId;
$this->bHasDelta = true;
} else {
if (array_key_exists($iObjectId, $this->aAdded)) {
unset($this->aAdded[$iObjectId]);
}
}
else
{
if (array_key_exists($iObjectId, $this->aAdded))
{
unset($this->aAdded[$iObjectId]);
}
}
}
/**
@@ -173,12 +167,11 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
assert($oLink instanceof $this->sClass);
$iObjectId = $oLink->GetKey();
if (array_key_exists($iObjectId, $this->aPreserved))
{
unset($this->aPreserved[$iObjectId]);
$this->aModified[$iObjectId] = $oLink;
$this->bHasDelta = true;
}
if (array_key_exists($iObjectId, $this->aPreserved)) {
unset($this->aPreserved[$iObjectId]);
$this->aModified[$iObjectId] = $oLink;
$this->bHasDelta = true;
}
}
/**
@@ -188,33 +181,25 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
*/
protected function LoadOriginalIds()
{
if ($this->aOriginalObjects === null)
{
if ($this->oOriginalSet)
{
if ($this->aOriginalObjects === null) {
if ($this->oOriginalSet) {
$this->aOriginalObjects = $this->GetArrayOfIndex();
$this->aPreserved = $this->aOriginalObjects; // Copy (not effective until aPreserved gets modified)
foreach ($this->aRemoved as $iObjectId)
{
if (array_key_exists($iObjectId, $this->aPreserved))
{
unset($this->aPreserved[$iObjectId]);
}
}
foreach ($this->aModified as $iObjectId => $oLink)
{
if (array_key_exists($iObjectId, $this->aPreserved))
{
unset($this->aPreserved[$iObjectId]);
}
}
}
else
{
foreach ($this->aRemoved as $iObjectId) {
if (array_key_exists($iObjectId, $this->aPreserved)) {
unset($this->aPreserved[$iObjectId]);
}
}
foreach ($this->aModified as $iObjectId => $oLink) {
if (array_key_exists($iObjectId, $this->aPreserved)) {
unset($this->aPreserved[$iObjectId]);
}
}
} else {
// Nothing to load
$this->aOriginalObjects = array();
$this->aPreserved = array();
$this->aOriginalObjects = [];
$this->aPreserved = [];
}
}
}
@@ -230,39 +215,34 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
*/
protected function GetArrayOfIndex()
{
$aRet = array();
$aRet = [];
$this->oOriginalSet->Rewind();
$iRow = 0;
while ($oObject = $this->oOriginalSet->Fetch())
{
while ($oObject = $this->oOriginalSet->Fetch()) {
$aRet[$oObject->GetKey()] = $iRow++;
}
return $aRet;
}
/**
* @param string $sAttCode
* @param bool $bWithId
* @return array
*/
public function GetColumnAsArray($sAttCode, $bWithId = true)
{
$aRet = array();
foreach($this as $oItem)
{
if ($bWithId)
{
$aRet[$oItem->GetKey()] = $oItem->Get($sAttCode);
}
else
{
$aRet[] = $oItem->Get($sAttCode);
}
}
return $aRet;
}
/**
* @param string $sAttCode
* @param bool $bWithId
* @return array
*/
public function GetColumnAsArray($sAttCode, $bWithId = true)
{
$aRet = [];
foreach ($this as $oItem) {
if ($bWithId) {
$aRet[$oItem->GetKey()] = $oItem->Get($sAttCode);
} else {
$aRet[] = $oItem->Get($sAttCode);
}
}
return $aRet;
}
/**
/**
* The class of the objects of the collection (at least a common ancestor)
*
* @return string
@@ -300,13 +280,11 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
$this->LoadOriginalIds();
$iCount = $this->Count();
if ($iPosition >= $iCount)
{
if ($iPosition >= $iCount) {
throw new Exception("Invalid position $iPosition: the link set is made of $iCount items.");
}
$this->rewind();
for($iPos = 0 ; $iPos < $iPosition ; $iPos++)
{
for ($iPos = 0 ; $iPos < $iPosition ; $iPos++) {
$this->next();
}
}
@@ -324,8 +302,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
$this->LoadOriginalIds();
$ret = $this->current();
if ($ret === false)
{
if ($ret === false) {
$ret = null;
}
$this->next();
@@ -350,22 +327,16 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
$this->LoadOriginalIds();
$iPreservedCount = count($this->aPreserved);
if ($this->iCursor < $iPreservedCount)
{
if ($this->iCursor < $iPreservedCount) {
$sId = key($this->aPreserved);
$oRet = MetaModel::GetObject($this->sClass, $sId);
}
else
{
$iModifiedCount = count($this->aModified);
if($this->iCursor < $iPreservedCount + $iModifiedCount)
{
$oRet = current($this->aModified);
}
else
{
$oRet = current($this->aAdded);
}
} else {
$iModifiedCount = count($this->aModified);
if ($this->iCursor < $iPreservedCount + $iModifiedCount) {
$oRet = current($this->aModified);
} else {
$oRet = current($this->aAdded);
}
}
return $oRet;
}
@@ -384,21 +355,15 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
$this->LoadOriginalIds();
$iPreservedCount = count($this->aPreserved);
if ($this->iCursor < $iPreservedCount)
{
if ($this->iCursor < $iPreservedCount) {
next($this->aPreserved);
}
else
{
$iModifiedCount = count($this->aModified);
if($this->iCursor < $iPreservedCount + $iModifiedCount)
{
next($this->aModified);
}
else
{
next($this->aAdded);
}
} else {
$iModifiedCount = count($this->aModified);
if ($this->iCursor < $iPreservedCount + $iModifiedCount) {
next($this->aModified);
} else {
next($this->aAdded);
}
}
// Increment AFTER moving the internal cursors because when starting aModified / aAdded, we must leave it intact
$this->iCursor++;
@@ -446,12 +411,12 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
*/
public function rewind(): void
{
$this->LoadOriginalIds();
$this->LoadOriginalIds();
$this->iCursor = 0;
$this->iCursor = 0;
reset($this->aPreserved);
reset($this->aAdded);
reset($this->aModified);
reset($this->aAdded);
reset($this->aModified);
}
/**
@@ -473,19 +438,14 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
public function Equals(ormLinkSet $oFellow)
{
$bRet = null;
if ($this === $oFellow)
{
if ($this === $oFellow) {
$bRet = true;
}
else
{
if ( ($this->oOriginalSet !== $oFellow->oOriginalSet)
&& ($this->oOriginalSet->GetFilter()->ToOQL() != $oFellow->oOriginalSet->GetFilter()->ToOQL()) )
{
} else {
if (($this->oOriginalSet !== $oFellow->oOriginalSet)
&& ($this->oOriginalSet->GetFilter()->ToOQL() != $oFellow->oOriginalSet->GetFilter()->ToOQL())) {
throw new Exception('ormLinkSet::Equals assumes that compared link sets have the same original scope');
}
if ($this->HasDelta())
{
if ($this->HasDelta()) {
throw new Exception('ormLinkSet::Equals assumes that left link set had no delta');
}
$bRet = !$oFellow->HasDelta();
@@ -501,16 +461,13 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
*/
public function UpdateFromCompleteList(iDBObjectSetIterator $oFellow)
{
if ($oFellow === $this)
{
if ($oFellow === $this) {
throw new Exception('ormLinkSet::UpdateFromCompleteList assumes that the passed link set is at least a clone of the current one');
}
$bUpdateFromDelta = false;
if ($oFellow instanceof ormLinkSet)
{
if ( ($this->oOriginalSet === $oFellow->oOriginalSet)
|| ($this->oOriginalSet->GetFilter()->ToOQL() == $oFellow->oOriginalSet->GetFilter()->ToOQL()) )
{
if ($oFellow instanceof ormLinkSet) {
if (($this->oOriginalSet === $oFellow->oOriginalSet)
|| ($this->oOriginalSet->GetFilter()->ToOQL() == $oFellow->oOriginalSet->GetFilter()->ToOQL())) {
$bUpdateFromDelta = true;
}
} else {
@@ -526,8 +483,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
}
}
if ($bUpdateFromDelta)
{
if ($bUpdateFromDelta) {
// Same original set -> simply update the delta
$this->iCursor = 0;
$this->aAdded = $oFellow->aAdded;
@@ -535,42 +491,36 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
$this->aModified = $oFellow->aModified;
$this->aPreserved = $oFellow->aPreserved;
$this->bHasDelta = $oFellow->bHasDelta;
}
else
{
} else {
// For backward compatibility reasons, let's rebuild a delta...
// Reset the delta
$this->iCursor = 0;
$this->aAdded = array();
$this->aRemoved = array();
$this->aModified = array();
$this->aPreserved = ($this->aOriginalObjects === null) ? array() : $this->aOriginalObjects;
$this->aAdded = [];
$this->aRemoved = [];
$this->aModified = [];
$this->aPreserved = ($this->aOriginalObjects === null) ? [] : $this->aOriginalObjects;
$this->bHasDelta = false;
/** @var \AttributeLinkedSet|\AttributeLinkedSetIndirect $oAttDef */
$oAttDef = MetaModel::GetAttributeDef($this->sHostClass, $this->sAttCode);
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
$sAdditionalKey = null;
if ($oAttDef->IsIndirect() && !$oAttDef->DuplicatesAllowed())
{
if ($oAttDef->IsIndirect() && !$oAttDef->DuplicatesAllowed()) {
$sAdditionalKey = $oAttDef->GetExtKeyToRemote();
}
// Compare both collections by iterating the whole sets, order them, a build a fingerprint based on meaningful data (what make the difference)
/** @var \DBObject $oLink */
$oComparator = new DBObjectSetComparator($this, $oFellow, array($sExtKeyToMe), $sAdditionalKey);
$oComparator = new DBObjectSetComparator($this, $oFellow, [$sExtKeyToMe], $sAdditionalKey);
$aChanges = $oComparator->GetDifferences();
foreach ($aChanges['added'] as $oLink)
{
foreach ($aChanges['added'] as $oLink) {
$this->AddItem($oLink);
}
foreach ($aChanges['modified'] as $oLink)
{
foreach ($aChanges['modified'] as $oLink) {
$this->ModifyItem($oLink);
}
foreach ($aChanges['removed'] as $oLink)
{
foreach ($aChanges['removed'] as $oLink) {
$this->RemoveItem($oLink->GetKey());
}
}
@@ -586,9 +536,8 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
{
$aAdded = $this->aAdded;
$aModified = $this->aModified;
$aRemoved = array();
if (count($this->aRemoved) > 0)
{
$aRemoved = [];
if (count($this->aRemoved) > 0) {
$oSearch = new DBObjectSearch($this->sClass);
$oSearch->AddCondition('id', $this->aRemoved, 'IN');
$oSet = new DBObjectSet($oSearch);
@@ -618,30 +567,23 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
$sExtKeyToMe = $oAttDef->GetExtKeyToMe();
$sExtKeyToRemote = $oAttDef->IsIndirect() ? $oAttDef->GetExtKeyToRemote() : 'n/a';
$aCheckLinks = array();
$aCheckRemote = array();
foreach ($this->aAdded as $oLink)
{
if ($oLink->IsNew())
{
if ($oAttDef->IsIndirect() && !$oAttDef->DuplicatesAllowed())
{
$aCheckLinks = [];
$aCheckRemote = [];
foreach ($this->aAdded as $oLink) {
if ($oLink->IsNew()) {
if ($oAttDef->IsIndirect() && !$oAttDef->DuplicatesAllowed()) {
//todo: faire un test qui passe dans cette branche !
$aCheckRemote[] = $oLink->Get($sExtKeyToRemote);
}
}
else
{
} else {
//todo: faire un test qui passe dans cette branche !
$aCheckLinks[] = $oLink->GetKey();
}
}
foreach ($this->aRemoved as $iLinkId)
{
foreach ($this->aRemoved as $iLinkId) {
$aCheckLinks[] = $iLinkId;
}
foreach ($this->aModified as $iLinkId => $oLink)
{
foreach ($this->aModified as $iLinkId => $oLink) {
$aCheckLinks[] = $oLink->GetKey();
}
@@ -653,11 +595,10 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
// Check for the existing links
//
/** @var DBObject[] $aExistingLinks */
$aExistingLinks = array();
$aExistingLinks = [];
/** @var Int[] $aExistingRemote */
$aExistingRemote = array();
if (count($aCheckLinks) > 0)
{
$aExistingRemote = [];
if (count($aCheckLinks) > 0) {
$oSearch = new DBObjectSearch($this->sClass);
$oSearch->AddCondition('id', $aCheckLinks, 'IN');
$oSet = new DBObjectSet($oSearch);
@@ -666,8 +607,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
// Check for the existing remote objects
//
if (count($aCheckRemote) > 0)
{
if (count($aCheckRemote) > 0) {
$oSearch = new DBObjectSearch($this->sClass);
$oSearch->AddCondition($sExtKeyToMe, $oHostObject->GetKey(), '=');
$oSearch->AddCondition($sExtKeyToRemote, $aCheckRemote, 'IN');
@@ -677,33 +617,27 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
// Write the links according to the existing links
//
foreach ($this->aAdded as $oLink)
{
foreach ($this->aAdded as $oLink) {
// Make sure that the objects in the set point to "this"
$oLink->Set($sExtKeyToMe, $oHostObject->GetKey());
if ($oLink->IsNew())
{
if (count($aCheckRemote) > 0)
{
$bIsDuplicate = false;
foreach($aExistingRemote as $sLinkKey => $sExtKey)
{
if ($sExtKey == $oLink->Get($sExtKeyToRemote))
{
// Do not create a duplicate
// + In the case of a remove action followed by an add action
// of an existing link,
// the final state to consider is add action,
// so suppress the entry in the removed list.
if (array_key_exists($sLinkKey, $this->aRemoved))
{
unset($this->aRemoved[$sLinkKey]);
}
$bIsDuplicate = true;
break;
}
}
if ($oLink->IsNew()) {
if (count($aCheckRemote) > 0) {
$bIsDuplicate = false;
foreach ($aExistingRemote as $sLinkKey => $sExtKey) {
if ($sExtKey == $oLink->Get($sExtKeyToRemote)) {
// Do not create a duplicate
// + In the case of a remove action followed by an add action
// of an existing link,
// the final state to consider is add action,
// so suppress the entry in the removed list.
if (array_key_exists($sLinkKey, $this->aRemoved)) {
unset($this->aRemoved[$sLinkKey]);
}
$bIsDuplicate = true;
break;
}
}
if ($bIsDuplicate) {
continue;
}
@@ -781,8 +715,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
/** @var \AttributeLinkedSet|\AttributeLinkedSetIndirect $oAttDef */
$oAttDef = MetaModel::GetAttributeDef($this->sHostClass, $this->sAttCode);
$oLinkSearch = $this->GetFilter();
if ($oAttDef->IsIndirect())
{
if ($oAttDef->IsIndirect()) {
$oLinkSearch->RenameAlias($oLinkSearch->GetClassAlias(), self::LINK_ALIAS);
$sExtKeyToRemote = $oAttDef->GetExtKeyToRemote();
/** @var \AttributeExternalKey $oLinkingAttDef */
@@ -793,8 +726,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
$sTargetClass = $oLinkingAttDef->GetTargetClass();
$oRemoteClassSearch = new DBObjectSearch($sTargetClass, self::REMOTE_ALIAS);
if (!$bShowObsolete && MetaModel::IsObsoletable($sTargetClass))
{
if (!$bShowObsolete && MetaModel::IsObsoletable($sTargetClass)) {
$oNotObsolete = new BinaryExpression(
new FieldExpression('obsolescence_flag', self::REMOTE_ALIAS),
'=',
@@ -803,8 +735,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
$oRemoteClassSearch->AddConditionExpression($oNotObsolete);
}
if (!utils::IsArchiveMode() && MetaModel::IsArchivable($sTargetClass))
{
if (!utils::IsArchiveMode() && MetaModel::IsArchivable($sTargetClass)) {
$oNotArchived = new BinaryExpression(
new FieldExpression('archive_flag', self::REMOTE_ALIAS),
'=',
@@ -845,7 +776,7 @@ class ormLinkSet implements iDBObjectSetIterator, Iterator, SeekableIterator
*/
public function GetValues()
{
$aValues = array();
$aValues = [];
foreach ($this->aPreserved as $sTagCode => $oTag) {
$aValues[] = $sTagCode;
}

View File

@@ -1,9 +1,10 @@
<?php
// Copyright (C) 2010-2024 Combodo SAS
//
// This file is part of iTop.
//
// iTop is free software; you can redistribute it and/or modify
// iTop is free software; you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
@@ -20,16 +21,15 @@ require_once('backgroundprocess.inc.php');
/**
* ormStopWatch
* encapsulate the behavior of a stop watch that will be stored as an attribute of class AttributeStopWatch
* encapsulate the behavior of a stop watch that will be stored as an attribute of class AttributeStopWatch
*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
/**
* ormStopWatch
* encapsulate the behavior of a stop watch that will be stored as an attribute of class AttributeStopWatch
* encapsulate the behavior of a stop watch that will be stored as an attribute of class AttributeStopWatch
*
* @package itopORM
*/
@@ -40,7 +40,7 @@ class ormStopWatch
protected $iLastStart; // unix time (seconds)
protected $iStopped; // unix time (seconds)
protected $aThresholds;
/**
* Constructor
*/
@@ -51,12 +51,12 @@ class ormStopWatch
$this->iLastStart = $iLastStart;
$this->iStopped = $iStopped;
$this->aThresholds = array();
$this->aThresholds = [];
}
/**
* Necessary for the triggers
*/
*/
public function __toString()
{
return (string) $this->iTimeSpent;
@@ -64,12 +64,12 @@ class ormStopWatch
public function DefineThreshold($iPercent, $tDeadline = null, $bPassed = false, $bTriggered = false, $iOverrun = null, $aHighlightDef = null)
{
$this->aThresholds[$iPercent] = array(
$this->aThresholds[$iPercent] = [
'deadline' => $tDeadline, // unix time (seconds)
'triggered' => $bTriggered,
'overrun' => $iOverrun,
'highlight' => $aHighlightDef, // array('code' => string, 'persistent' => boolean)
);
];
}
public function MarkThresholdAsTriggered($iPercent)
@@ -94,18 +94,14 @@ class ormStopWatch
*/
public function GetElapsedTime($oAttDef, $oObject)
{
if (is_null($this->iLastStart))
{
if (is_null($this->iLastStart)) {
return $this->GetTimeSpent();
}
else
{
} else {
$iElapsed = $this->ComputeDuration($oObject, $oAttDef, $this->iLastStart, time());
return $this->iTimeSpent + $iElapsed;
}
}
public function GetStartDate()
{
return $this->iStarted;
@@ -123,39 +119,30 @@ class ormStopWatch
public function GetThresholdDate($iPercent)
{
if (array_key_exists($iPercent, $this->aThresholds))
{
if (array_key_exists($iPercent, $this->aThresholds)) {
return $this->aThresholds[$iPercent]['deadline'];
}
else
{
} else {
return null;
}
}
public function GetOverrun($iPercent)
{
if (array_key_exists($iPercent, $this->aThresholds))
{
if (array_key_exists($iPercent, $this->aThresholds)) {
return $this->aThresholds[$iPercent]['overrun'];
}
else
{
} else {
return null;
}
}
public function IsThresholdPassed($iPercent)
{
$bRet = false;
if (array_key_exists($iPercent, $this->aThresholds))
{
if (array_key_exists($iPercent, $this->aThresholds)) {
$aThresholdData = $this->aThresholds[$iPercent];
if (!is_null($aThresholdData['deadline']) && ($aThresholdData['deadline'] <= time()))
{
if (!is_null($aThresholdData['deadline']) && ($aThresholdData['deadline'] <= time())) {
$bRet = true;
}
if (isset($aThresholdData['overrun']) && ($aThresholdData['overrun'] > 0))
{
if (isset($aThresholdData['overrun']) && ($aThresholdData['overrun'] > 0)) {
$bRet = true;
}
}
@@ -163,34 +150,27 @@ class ormStopWatch
}
public function IsThresholdTriggered($iPercent)
{
if (array_key_exists($iPercent, $this->aThresholds))
{
if (array_key_exists($iPercent, $this->aThresholds)) {
return $this->aThresholds[$iPercent]['triggered'];
}
else
{
} else {
return false;
}
}
public function GetHighlightCode()
{
$sCode = '';
// Process the thresholds in ascending order
$aPercents = array();
foreach($this->aThresholds as $iPercent => $aDefs)
{
$aPercents = [];
foreach ($this->aThresholds as $iPercent => $aDefs) {
$aPercents[] = $iPercent;
}
sort($aPercents, SORT_NUMERIC);
foreach($aPercents as $iPercent)
{
foreach ($aPercents as $iPercent) {
$aDefs = $this->aThresholds[$iPercent];
if (array_key_exists('highlight', $aDefs) && is_array($aDefs['highlight']) && $this->IsThresholdPassed($iPercent))
{
if (array_key_exists('highlight', $aDefs) && is_array($aDefs['highlight']) && $this->IsThresholdPassed($iPercent)) {
// If persistant or SW running...
if (($aDefs['highlight']['persistent'] == true) || (($aDefs['highlight']['persistent'] == false) && !is_null($this->iLastStart)))
{
if (($aDefs['highlight']['persistent'] == true) || (($aDefs['highlight']['persistent'] == false) && !is_null($this->iLastStart))) {
$sCode = $aDefs['highlight']['code'];
}
}
@@ -200,47 +180,37 @@ class ormStopWatch
public function GetAsHTML($oAttDef, $oHostObject = null)
{
$aProperties = array();
$aProperties = [];
$aProperties['States'] = implode(', ', $oAttDef->GetStates());
if (is_null($this->iLastStart))
{
if (is_null($this->iStarted))
{
if (is_null($this->iLastStart)) {
if (is_null($this->iStarted)) {
$aProperties['Elapsed'] = 'never started';
}
else
{
} else {
$aProperties['Elapsed'] = $this->iTimeSpent.' s';
}
}
else
{
$aProperties['Elapsed'] = 'running <img src="' . utils::GetAbsoluteUrlAppRoot() . 'images/indicator.gif">';
} else {
$aProperties['Elapsed'] = 'running <img src="'.utils::GetAbsoluteUrlAppRoot().'images/indicator.gif">';
}
$aProperties['Started'] = $oAttDef->SecondsToDate($this->iStarted);
$aProperties['LastStart'] = $oAttDef->SecondsToDate($this->iLastStart);
$aProperties['Stopped'] = $oAttDef->SecondsToDate($this->iStopped);
foreach ($this->aThresholds as $iPercent => $aThresholdData)
{
foreach ($this->aThresholds as $iPercent => $aThresholdData) {
$sThresholdDesc = $oAttDef->SecondsToDate($aThresholdData['deadline']);
if ($aThresholdData['triggered'])
{
if ($aThresholdData['triggered']) {
$sThresholdDesc .= " <b>TRIGGERED</b>";
}
if ($aThresholdData['overrun'])
{
if ($aThresholdData['overrun']) {
$sThresholdDesc .= " Overrun:".(int) $aThresholdData['overrun']." sec.";
}
$aProperties[$iPercent.'%'] = $sThresholdDesc;
}
$sRes = "<TABLE>";
$sRes .= "<TBODY>";
foreach ($aProperties as $sProperty => $sValue)
{
foreach ($aProperties as $sProperty => $sValue) {
$sRes .= "<TR>";
$sCell = str_replace("\n", "<br>\n", $sValue ?? '');
$sRes .= "<TD class=\"label\">$sProperty</TD><TD>$sCell</TD>";
@@ -265,9 +235,8 @@ class ormStopWatch
/** @var \iMetricComputer $oComputer */
$oComputer = new $sMetricComputer();
$aCallSpec = array($oComputer, 'ComputeMetric');
if (!is_callable($aCallSpec))
{
$aCallSpec = [$oComputer, 'ComputeMetric'];
if (!is_callable($aCallSpec)) {
throw new CoreException("Unknown class/verb '$sMetricComputer/ComputeMetric'");
}
@@ -287,14 +256,12 @@ class ormStopWatch
protected function ComputeDeadline($oObject, $oAttDef, $iPercent, $iStartTime, $iDurationSec)
{
$sWorkingTimeComputer = $oAttDef->Get('working_time_computing');
if ($sWorkingTimeComputer == '')
{
if ($sWorkingTimeComputer == '') {
$sWorkingTimeComputer = MetaModel::GetWorkingTime(get_class($oObject));
}
$oComputer = new $sWorkingTimeComputer();
$aCallSpec = array($oComputer, 'GetDeadline');
if (!is_callable($aCallSpec))
{
$aCallSpec = [$oComputer, 'GetDeadline'];
if (!is_callable($aCallSpec)) {
throw new CoreException("Unknown class/verb '$sWorkingTimeComputer/GetDeadline'");
}
// GetDeadline($oObject, $iDuration, DateTime $oStartDate)
@@ -316,14 +283,12 @@ class ormStopWatch
protected function ComputeDuration($oObject, $oAttDef, $iStartTime, $iEndTime)
{
$sWorkingTimeComputer = $oAttDef->Get('working_time_computing');
if ($sWorkingTimeComputer == '')
{
if ($sWorkingTimeComputer == '') {
$sWorkingTimeComputer = MetaModel::GetWorkingTime(get_class($oObject));
}
$oComputer = new $sWorkingTimeComputer();
$aCallSpec = array($oComputer, 'GetOpenDuration');
if (!is_callable($aCallSpec))
{
$aCallSpec = [$oComputer, 'GetOpenDuration'];
if (!is_callable($aCallSpec)) {
throw new CoreException("Unknown class/verb '$sWorkingTimeComputer/GetOpenDuration'");
}
// GetOpenDuration($oObject, DateTime $oStartDate, DateTime $oEndDate)
@@ -339,14 +304,12 @@ class ormStopWatch
$this->iStopped = null;
$this->iStarted = null;
foreach ($this->aThresholds as $iPercent => &$aThresholdData)
{
foreach ($this->aThresholds as $iPercent => &$aThresholdData) {
$aThresholdData['triggered'] = false;
$aThresholdData['overrun'] = null;
}
if (!is_null($this->iLastStart))
{
if (!is_null($this->iLastStart)) {
// Currently running... starting again from now!
$this->iStarted = time();
$this->iLastStart = time();
@@ -357,23 +320,20 @@ class ormStopWatch
/**
* Start or continue
* It is the responsibility of the caller to compute the deadlines
* (to avoid computing twice for the same result)
*/
* (to avoid computing twice for the same result)
*/
public function Start($oObject, $oAttDef, $iNow = null)
{
if (!is_null($this->iLastStart))
{
if (!is_null($this->iLastStart)) {
// Already started
return false;
}
if (is_null($iNow))
{
if (is_null($iNow)) {
$iNow = time();
}
if (is_null($this->iStarted))
{
if (is_null($this->iStarted)) {
$this->iStarted = $iNow;
}
$this->iLastStart = $iNow;
@@ -384,39 +344,31 @@ class ormStopWatch
/**
* Compute or recompute the goal and threshold deadlines
*/
*/
public function ComputeDeadlines($oObject, $oAttDef)
{
if (is_null($this->iLastStart))
{
if (is_null($this->iLastStart)) {
// Currently stopped - do nothing
return false;
}
$iDurationGoal = $this->ComputeGoal($oObject, $oAttDef);
$iComputationRefTime = time();
foreach ($this->aThresholds as $iPercent => &$aThresholdData)
{
if (is_null($iDurationGoal))
{
foreach ($this->aThresholds as $iPercent => &$aThresholdData) {
if (is_null($iDurationGoal)) {
// No limit: leave null thresholds
$aThresholdData['deadline'] = null;
}
else
{
} else {
$iThresholdDuration = round($iPercent * $iDurationGoal / 100);
if (class_exists('WorkingTimeRecorder'))
{
if (class_exists('WorkingTimeRecorder')) {
$sClass = get_class($oObject);
$sAttCode = $oAttDef->GetCode();
WorkingTimeRecorder::Start($oObject, $iComputationRefTime, "ormStopWatch-Deadline-$iPercent-$sAttCode", 'Core:ExplainWTC:StopWatch-Deadline', array("Class:$sClass/Attribute:$sAttCode", $iPercent));
WorkingTimeRecorder::Start($oObject, $iComputationRefTime, "ormStopWatch-Deadline-$iPercent-$sAttCode", 'Core:ExplainWTC:StopWatch-Deadline', ["Class:$sClass/Attribute:$sAttCode", $iPercent]);
}
$iRemaining = $iThresholdDuration - $this->iTimeSpent;
if ($iRemaining < 0)
{
if (class_exists('WorkingTimeRecorder'))
{
if ($iRemaining < 0) {
if (class_exists('WorkingTimeRecorder')) {
$sClass = get_class($oObject);
$sKey = $oObject->GetKey();
$sAttCode = $oAttDef->GetCode();
@@ -428,13 +380,11 @@ class ormStopWatch
$aThresholdData['deadline'] = $this->ComputeDeadline($oObject, $oAttDef, $iPercent, $this->iLastStart, $iRemaining);
// OR $aThresholdData['deadline'] = $this->ComputeDeadline($oObject, $oAttDef, $iPercent, $this->iStarted, $iThresholdDuration);
if (class_exists('WorkingTimeRecorder'))
{
if (class_exists('WorkingTimeRecorder')) {
WorkingTimeRecorder::End();
}
}
if (is_null($aThresholdData['deadline']) || ($aThresholdData['deadline'] > time()))
{
if (is_null($aThresholdData['deadline']) || ($aThresholdData['deadline'] > time())) {
// The threshold is in the future, reset
$aThresholdData['triggered'] = false;
$aThresholdData['overrun'] = null;
@@ -452,51 +402,41 @@ class ormStopWatch
/**
* Stop counting if not already done
*/
*/
public function Stop($oObject, $oAttDef, $iNow = null)
{
if (is_null($this->iLastStart))
{
if (is_null($this->iLastStart)) {
// Already stopped
return false;
}
if (is_null($iNow))
{
if (is_null($iNow)) {
$iNow = time();
}
if (class_exists('WorkingTimeRecorder'))
{
if (class_exists('WorkingTimeRecorder')) {
$sClass = get_class($oObject);
$sAttCode = $oAttDef->GetCode();
WorkingTimeRecorder::Start($oObject, $iNow, "ormStopWatch-TimeSpent-$sAttCode", 'Core:ExplainWTC:StopWatch-TimeSpent', array("Class:$sClass/Attribute:$sAttCode"), true /*cumulative*/);
WorkingTimeRecorder::Start($oObject, $iNow, "ormStopWatch-TimeSpent-$sAttCode", 'Core:ExplainWTC:StopWatch-TimeSpent', ["Class:$sClass/Attribute:$sAttCode"], true /*cumulative*/);
}
$iElapsed = $this->ComputeDuration($oObject, $oAttDef, $this->iLastStart, $iNow);
$this->iTimeSpent = $this->iTimeSpent + $iElapsed;
if (class_exists('WorkingTimeRecorder'))
{
if (class_exists('WorkingTimeRecorder')) {
WorkingTimeRecorder::End();
}
foreach ($this->aThresholds as $iPercent => &$aThresholdData)
{
if (!is_null($aThresholdData['deadline']) && ($iNow > $aThresholdData['deadline']))
{
if ($aThresholdData['overrun'] > 0)
{
foreach ($this->aThresholds as $iPercent => &$aThresholdData) {
if (!is_null($aThresholdData['deadline']) && ($iNow > $aThresholdData['deadline'])) {
if ($aThresholdData['overrun'] > 0) {
// Accumulate from last start
$aThresholdData['overrun'] += $iElapsed;
}
else
{
} else {
// First stop after the deadline has been passed
$iOverrun = $this->ComputeDuration($oObject, $oAttDef, $aThresholdData['deadline'], $iNow);
$aThresholdData['overrun'] = $iOverrun;
}
}
if ($aThresholdData['overrun'] == 0)
{
if ($aThresholdData['overrun'] == 0) {
$aThresholdData['deadline'] = null;
}
}
@@ -510,76 +450,65 @@ class ormStopWatch
/**
* CheckStopWatchThresholds
* Implements the automatic actions
* Implements the automatic actions
*
* @package itopORM
*/
class CheckStopWatchThresholds implements iBackgroundProcess
{
public function GetPeriodicity()
{
{
return 10; // seconds
}
public function Process($iTimeLimit)
{
$aList = array();
foreach (MetaModel::GetClasses() as $sClass)
{
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef)
{
if ($oAttDef instanceof AttributeStopWatch)
{
foreach ($oAttDef->ListThresholds() as $iThreshold => $aThresholdData)
{
$aList = [];
foreach (MetaModel::GetClasses() as $sClass) {
foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
if ($oAttDef instanceof AttributeStopWatch) {
foreach ($oAttDef->ListThresholds() as $iThreshold => $aThresholdData) {
$iPercent = $aThresholdData['percent']; // could be different than the index !
$sNow = date(AttributeDateTime::GetSQLFormat());
$sExpression = "SELECT $sClass WHERE {$sAttCode}_laststart AND {$sAttCode}_{$iThreshold}_triggered = 0 AND {$sAttCode}_{$iThreshold}_deadline < :now";
$oFilter = DBObjectSearch::FromOQL($sExpression);
$oSet = new DBObjectSet($oFilter, array(), array('now' => $sNow));
$oSet->OptimizeColumnLoad(array($sClass => array($sAttCode)));
while ((time() < $iTimeLimit) && ($oObj = $oSet->Fetch()))
{
$oSet = new DBObjectSet($oFilter, [], ['now' => $sNow]);
$oSet->OptimizeColumnLoad([$sClass => [$sAttCode]]);
while ((time() < $iTimeLimit) && ($oObj = $oSet->Fetch())) {
$sClass = get_class($oObj);
$aList[] = $sClass.'::'.$oObj->GetKey().' '.$sAttCode.' '.$iThreshold;
// Execute planned actions
//
foreach ($aThresholdData['actions'] as $aActionData)
{
foreach ($aThresholdData['actions'] as $aActionData) {
$sVerb = $aActionData['verb'];
$aParams = $aActionData['params'];
$aValues = array();
foreach($aParams as $def)
{
if (is_string($def))
{
$aValues = [];
foreach ($aParams as $def) {
if (is_string($def)) {
// Old method (pre-2.1.0) non typed parameters
$aValues[] = $def;
}
else // if(is_array($def))
{
} else { // if(is_array($def))
$sParamType = array_key_exists('type', $def) ? $def['type'] : 'string';
switch($sParamType)
{
switch ($sParamType) {
case 'int':
$value = (int)$def['value'];
break;
case 'float':
$value = (float)$def['value'];
break;
case 'bool':
$value = (bool)$def['value'];
break;
case 'reference':
$value = ${$def['value']};
break;
case 'string':
default:
$value = (string)$def['value'];
@@ -587,7 +516,7 @@ class CheckStopWatchThresholds implements iBackgroundProcess
$aValues[] = $value;
}
}
$aCallSpec = array($oObj, $sVerb);
$aCallSpec = [$oObj, $sVerb];
call_user_func_array($aCallSpec, $aValues);
}
@@ -604,22 +533,18 @@ class CheckStopWatchThresholds implements iBackgroundProcess
}
// Activate any existing trigger
//
//
$sClassList = implode("', '", MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL));
$oTriggerSet = new DBObjectSet(
DBObjectSearch::FromOQL("SELECT TriggerOnThresholdReached AS t WHERE t.target_class IN ('$sClassList') AND stop_watch_code MATCHES :stop_watch_code AND threshold_index = :threshold_index"),
array(), // order by
array('stop_watch_code' => $sAttCode, 'threshold_index' => $iThreshold)
[], // order by
['stop_watch_code' => $sAttCode, 'threshold_index' => $iThreshold]
);
while ($oTrigger = $oTriggerSet->Fetch())
{
try
{
while ($oTrigger = $oTriggerSet->Fetch()) {
try {
$oTrigger->DoActivate($oObj->ToArgs('this'));
}
catch(Exception $e)
{
} catch (Exception $e) {
utils::EnrichRaisedException($oTrigger, $e);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -412,4 +412,4 @@ class SimpleCryptOpenSSLMcryptCompatibilityEngine implements CryptEngine
return trim($plaintext);
}
}
}

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (C) 2013-2024 Combodo SAS
*
@@ -22,7 +23,6 @@
*/
class SimpleGraphException extends Exception
{
}
/**
@@ -32,7 +32,7 @@ class GraphElement
{
protected $sId;
protected $aProperties;
/**
* Constructor
* @param string $sId The identifier of the object in the graph
@@ -40,9 +40,9 @@ class GraphElement
public function __construct($sId)
{
$this->sId = $sId;
$this->aProperties = array();
$this->aProperties = [];
}
/**
* Get the identifier of the object in the graph
* @return string
@@ -51,7 +51,7 @@ class GraphElement
{
return $this->sId;
}
/**
* Get the value of the given named property for the object
* @param string $sPropName The name of the property to get
@@ -73,7 +73,7 @@ class GraphElement
{
$this->aProperties[$sPropName] = $value;
}
/**
* Get all the known properties of the object
* @return Ambigous <multitype:, mixed>
@@ -91,7 +91,7 @@ class GraphNode extends GraphElement
{
protected $aIncomingEdges;
protected $aOutgoingEdges;
/**
* Create a new node inside a graph
* @param SimpleGraph $oGraph
@@ -100,16 +100,15 @@ class GraphNode extends GraphElement
public function __construct(SimpleGraph $oGraph, $sId)
{
parent::__construct($sId);
$this->aIncomingEdges = array();
$this->aOutgoingEdges = array();
$this->aIncomingEdges = [];
$this->aOutgoingEdges = [];
$oGraph->_AddNode($this);
}
public function GetDotAttributes($bNoLabel = false)
{
$sDot = '';
if (!$bNoLabel)
{
if (!$bNoLabel) {
$sLabel = addslashes($this->GetProperty('label', $this->GetId()));
$sDot = 'label="'.$sLabel.'"';
}
@@ -133,7 +132,7 @@ class GraphNode extends GraphElement
{
$this->aOutgoingEdges[$oEdge->GetId()] = $oEdge;
}
/**
* INTERNAL USE ONLY
* @param GraphEdge $oEdge
@@ -151,7 +150,7 @@ class GraphNode extends GraphElement
{
unset($this->aOutgoingEdges[$oEdge->GetId()]);
}
/**
* Get the list of all incoming edges on the current node
* @return Ambigous <multitype:, GraphEdge>
@@ -160,7 +159,7 @@ class GraphNode extends GraphElement
{
return $this->aIncomingEdges;
}
/**
* Get the list of all outgoing edges from the current node
* @return Ambigous <multitype:, GraphEdge>
@@ -169,7 +168,7 @@ class GraphNode extends GraphElement
{
return $this->aOutgoingEdges;
}
/**
* Flood fill the chart with the given value for the specified property
* @param string $sPropName The name of the property to set
@@ -179,29 +178,24 @@ class GraphNode extends GraphElement
*/
public function FloodProperty($sPropName, $value, $bFloodDown, $bFloodUp)
{
if ($this->GetProperty($sPropName, null) == null)
{
if ($this->GetProperty($sPropName, null) == null) {
// Property not already set, let's do it
$this->SetProperty($sPropName, $value);
if ($bFloodDown)
{
foreach($this->GetOutgoingEdges() as $oEdge)
{
if ($bFloodDown) {
foreach ($this->GetOutgoingEdges() as $oEdge) {
$oEdge->SetProperty($sPropName, $value);
$oEdge->GetSinkNode()->FloodProperty($sPropName, $value, $bFloodDown, $bFloodUp);
}
}
if ($bFloodUp)
{
foreach($this->GetIncomingEdges() as $oEdge)
{
if ($bFloodUp) {
foreach ($this->GetIncomingEdges() as $oEdge) {
$oEdge->SetProperty($sPropName, $value);
$oEdge->GetSourceNode()->FloodProperty($sPropName, $value, $bFloodDown, $bFloodUp);
}
}
}
}
}
/**
@@ -237,7 +231,7 @@ class GraphEdge extends GraphElement
{
return $this->oSourceNode;
}
/**
* Get the "sink" node for this edge
* @return GraphNode
@@ -250,8 +244,7 @@ class GraphEdge extends GraphElement
public function GetDotAttributes($bNoLabel = false)
{
$sDot = '';
if (!$bNoLabel)
{
if (!$bNoLabel) {
$sLabel = addslashes($this->GetProperty('label', ''));
$sDot = 'label="'.$sLabel.'"';
}
@@ -266,16 +259,16 @@ class SimpleGraph
{
protected $aNodes;
protected $aEdges;
/**
* Creates a new empty graph
*/
public function __construct()
{
$this->aNodes = array();
$this->aEdges = array();
$this->aNodes = [];
$this->aEdges = [];
}
/**
* INTERNAL USE ONLY
* @return Ambigous <multitype:, GraphNode>
@@ -284,7 +277,7 @@ class SimpleGraph
{
return $this->aNodes;
}
/**
* INTERNAL USE ONLY
* @return Ambigous <multitype:, GraphNode>
@@ -293,32 +286,34 @@ class SimpleGraph
{
return $this->aEdges;
}
/**
* INTERNAL USE ONLY
* @return Ambigous <multitype:, GraphNode>
*/
public function _AddNode(GraphNode $oNode)
{
if (array_key_exists($oNode->GetId(), $this->aNodes)) throw new SimpleGraphException('Cannot add node (id='.$oNode->GetId().') to the graph. A node with the same id already exists in the graph.');
if (array_key_exists($oNode->GetId(), $this->aNodes)) {
throw new SimpleGraphException('Cannot add node (id='.$oNode->GetId().') to the graph. A node with the same id already exists in the graph.');
}
$this->aNodes[$oNode->GetId()] = $oNode;
}
/**
* INTERNAL USE ONLY
* @return Ambigous <multitype:, GraphNode>
*/
public function _RemoveNode(GraphNode $oNode)
{
if (!array_key_exists($oNode->GetId(), $this->aNodes)) throw new SimpleGraphException('Cannot remove the node (id='.$oNode->GetId().') from the graph. The node was not found in the graph.');
foreach($oNode->GetOutgoingEdges() as $oEdge)
{
if (!array_key_exists($oNode->GetId(), $this->aNodes)) {
throw new SimpleGraphException('Cannot remove the node (id='.$oNode->GetId().') from the graph. The node was not found in the graph.');
}
foreach ($oNode->GetOutgoingEdges() as $oEdge) {
$this->_RemoveEdge($oEdge);
}
foreach($oNode->GetIncomingEdges() as $oEdge)
{
foreach ($oNode->GetIncomingEdges() as $oEdge) {
$this->_RemoveEdge($oEdge);
}
unset($this->aNodes[$oNode->GetId()]);
@@ -333,42 +328,37 @@ class SimpleGraph
*/
public function FilterNode(GraphNode $oNode, $bAllowLoopingEdge = false)
{
if (!array_key_exists($oNode->GetId(), $this->aNodes)) throw new SimpleGraphException('Cannot filter the node (id='.$oNode->GetId().') from the graph. The node was not found in the graph.');
$aSourceNodes = array();
$aSinkNodes = array();
foreach($oNode->GetOutgoingEdges() as $oEdge)
{
if (!array_key_exists($oNode->GetId(), $this->aNodes)) {
throw new SimpleGraphException('Cannot filter the node (id='.$oNode->GetId().') from the graph. The node was not found in the graph.');
}
$aSourceNodes = [];
$aSinkNodes = [];
foreach ($oNode->GetOutgoingEdges() as $oEdge) {
$sSinkId = $oEdge->GetSinkNode()->GetId();
if ($sSinkId != $oNode->GetId())
{
if ($sSinkId != $oNode->GetId()) {
$aSinkNodes[$sSinkId] = $oEdge->GetSinkNode();
}
$this->_RemoveEdge($oEdge);
}
foreach($oNode->GetIncomingEdges() as $oEdge)
{
foreach ($oNode->GetIncomingEdges() as $oEdge) {
$sSourceId = $oEdge->GetSourceNode()->GetId();
if ($sSourceId != $oNode->GetId())
{
if ($sSourceId != $oNode->GetId()) {
$aSourceNodes[$sSourceId] = $oEdge->GetSourceNode();
}
$this->_RemoveEdge($oEdge);
}
unset($this->aNodes[$oNode->GetId()]);
foreach($aSourceNodes as $sSourceId => $oSourceNode)
{
foreach($aSinkNodes as $sSinkId => $oSinkNode)
{
if ($bAllowLoopingEdge || ($oSourceNode->GetId() != $oSinkNode->GetId()))
{
foreach ($aSourceNodes as $sSourceId => $oSourceNode) {
foreach ($aSinkNodes as $sSinkId => $oSinkNode) {
if ($bAllowLoopingEdge || ($oSourceNode->GetId() != $oSinkNode->GetId())) {
$oEdge = new RelationEdge($this, $oSourceNode, $oSinkNode);
}
}
}
}
/**
* Get the node identified by $sId or null if not found
* @param string $sId
@@ -376,7 +366,7 @@ class SimpleGraph
*/
public function GetNode($sId)
{
return array_key_exists($sId, $this->aNodes) ? $this->aNodes[$sId] : null;
return array_key_exists($sId, $this->aNodes) ? $this->aNodes[$sId] : null;
}
/**
@@ -386,7 +376,7 @@ class SimpleGraph
*/
public function HasNode($sId)
{
return array_key_exists($sId, $this->aNodes);
return array_key_exists($sId, $this->aNodes);
}
/**
@@ -397,23 +387,19 @@ class SimpleGraph
*/
public function _AddEdge(GraphEdge $oEdge, $bMustBeUnique = false)
{
if (array_key_exists($oEdge->GetId(), $this->aEdges))
{
if ($bMustBeUnique)
{
throw new SimpleGraphException('Cannot add edge (id=' . $oEdge->GetId() . ') to the graph. An edge with the same id already exists in the graph.');
}
else
{
if (array_key_exists($oEdge->GetId(), $this->aEdges)) {
if ($bMustBeUnique) {
throw new SimpleGraphException('Cannot add edge (id='.$oEdge->GetId().') to the graph. An edge with the same id already exists in the graph.');
} else {
return;
}
}
$this->aEdges[$oEdge->GetId()] = $oEdge;
$oEdge->GetSourceNode()->_AddOutgoingEdge($oEdge);
$oEdge->GetSinkNode()->_AddIncomingEdge($oEdge);
}
/**
* INTERNAL USE ONLY
* @param GraphEdge $oEdge
@@ -421,14 +407,16 @@ class SimpleGraph
*/
public function _RemoveEdge(GraphEdge $oEdge)
{
if (!array_key_exists($oEdge->GetId(), $this->aEdges)) throw new SimpleGraphException('Cannot remove edge (id='.$oEdge->GetId().') from the graph. The edge was not found.');
if (!array_key_exists($oEdge->GetId(), $this->aEdges)) {
throw new SimpleGraphException('Cannot remove edge (id='.$oEdge->GetId().') from the graph. The edge was not found.');
}
$oEdge->GetSourceNode()->_RemoveOutgoingEdge($oEdge);
$oEdge->GetSinkNode()->_RemoveIncomingEdge($oEdge);
unset($this->aEdges[$oEdge->GetId()]);
}
/**
* Get the edge indentified by $sId or null if not found
* @param string $sId
@@ -438,7 +426,7 @@ class SimpleGraph
{
return array_key_exists($sId, $this->aEdges) ? $this->aEdges[$sId] : null;
}
/**
* Determine if the id already exists in amongst the existing edges
* @param string $sId
@@ -446,7 +434,7 @@ class SimpleGraph
*/
public function HasEdge($sId)
{
return array_key_exists($sId, $this->aEdges);
return array_key_exists($sId, $this->aEdges);
}
/**
@@ -470,23 +458,20 @@ EOF
;
$oIterator = new RelationTypeIterator($this, 'Node');
foreach($oIterator as $key => $oNode)
{
foreach ($oIterator as $key => $oNode) {
$sDot .= "\t\"".$oNode->GetId()."\" [ ".$oNode->GetDotAttributes($bNoLabel)." ];\n";
if (count($oNode->GetOutgoingEdges()) > 0)
{
foreach($oNode->GetOutgoingEdges() as $oEdge)
{
if (count($oNode->GetOutgoingEdges()) > 0) {
foreach ($oNode->GetOutgoingEdges() as $oEdge) {
$sDot .= "\t\"".$oNode->GetId()."\" -> \"".$oEdge->GetSinkNode()->GetId()."\" [ ".$oEdge->GetDotAttributes($bNoLabel)." ];\n";
}
}
}
$sDot .= "}\n";
return $sDot;
return $sDot;
}
/**
* Get the description of the graph as an embedded PNG image (using a data: url) as
* generated by graphviz (requires graphviz to be installed on the machine and the path to
@@ -497,51 +482,43 @@ EOF
public function DumpAsHtmlImage()
{
$sDotExecutable = MetaModel::GetConfig()->Get('graphviz_path');
if (file_exists($sDotExecutable))
{
if (file_exists($sDotExecutable)) {
// create the file with Graphviz
if (!is_dir(utils::GetDataPath()))
{
if (!is_dir(utils::GetDataPath())) {
@mkdir(utils::GetDataPath());
}
if (!is_dir(utils::GetDataPath()."tmp"))
{
if (!is_dir(utils::GetDataPath()."tmp")) {
@mkdir(utils::GetDataPath()."tmp");
}
$sImageFilePath = tempnam(utils::GetDataPath()."tmp", 'png-');
$sDotDescription = $this->GetDotDescription();
$sDotFilePath = tempnam(utils::GetDataPath()."tmp", 'dot-');
$rFile = @fopen($sDotFilePath, "w");
@fwrite($rFile, $sDotDescription);
@fclose($rFile);
$aOutput = array();
$aOutput = [];
$CommandLine = "\"$sDotExecutable\" -v -Tpng < \"$sDotFilePath\" -o\"$sImageFilePath\" 2>&1";
exec($CommandLine, $aOutput, $iRetCode);
if ($iRetCode != 0)
{
if ($iRetCode != 0) {
$sHtml = '';
$sHtml .= "<p><b>Error:</b></p>";
$sHtml .= "<p>The command: <pre>$CommandLine</pre> returned $iRetCode</p>";
$sHtml .= "<p>The output of the command is:<pre>\n".implode("\n", $aOutput)."</pre></p>";
$sHtml .= "<hr>";
$sHtml .= "<p>Content of the '".basename($sDotFilePath)."' file:<pre>\n$sDotDescription</pre>";
}
else
{
} else {
$sHtml = '<img src="data:image/png;base64,'.base64_encode(file_get_contents($sImageFilePath)).'">';
@unlink($sImageFilePath);
}
@unlink($sDotFilePath);
}
else
{
throw new Exception('graphviz not found');
} else {
throw new Exception('graphviz not found');
}
return $sHtml;
}
/**
* Get the description of the graph as text string in the XDot format
* including the positions of the nodes and egdes (requires graphviz
@@ -553,51 +530,42 @@ EOF
public function DumpAsXDot()
{
$sDotExecutable = MetaModel::GetConfig()->Get('graphviz_path');
if (file_exists($sDotExecutable))
{
if (file_exists($sDotExecutable)) {
// create the file with Graphviz
if (!is_dir(utils::GetDataPath()))
{
if (!is_dir(utils::GetDataPath())) {
@mkdir(utils::GetDataPath());
}
if (!is_dir(utils::GetDataPath()."tmp"))
{
if (!is_dir(utils::GetDataPath()."tmp")) {
@mkdir(utils::GetDataPath()."tmp");
}
$sXdotFilePath = tempnam(utils::GetDataPath()."tmp", 'xdot-');
$sDotDescription = $this->GetDotDescription(true); // true => don't put (localized) labels in the file, since it makes it harder to parse
$sDotFilePath = tempnam(utils::GetDataPath()."tmp", 'dot-');
$rFile = @fopen($sDotFilePath, "w");
@fwrite($rFile, $sDotDescription);
@fclose($rFile);
$aOutput = array();
$aOutput = [];
$CommandLine = "\"$sDotExecutable\" -v -Tdot < \"$sDotFilePath\" -o\"$sXdotFilePath\" 2>&1";
exec($CommandLine, $aOutput, $iRetCode);
if ($iRetCode != 0)
{
if ($iRetCode != 0) {
$sHtml = '';
$sHtml .= "<p><b>Error:</b></p>";
$sHtml .= "<p>The command: <pre>$CommandLine</pre> returned $iRetCode</p>";
$sHtml .= "<p>The output of the command is:<pre>\n".implode("\n", $aOutput)."</pre></p>";
IssueLog::Error($sHtml);
}
else
{
} else {
$sHtml = '<pre>'.file_get_contents($sXdotFilePath).'</pre>';
@unlink($sXdotFilePath);
}
@unlink($sDotFilePath);
}
else
{
throw new Exception('graphviz not found');
} else {
throw new Exception('graphviz not found');
}
return $sHtml;
}
/**
* Get the description of the graph as some HTML text
* @return string
@@ -606,42 +574,36 @@ EOF
{
$sHtml = '';
$oIterator = new RelationTypeIterator($this);
foreach($oIterator as $key => $oElement)
{
foreach ($oIterator as $key => $oElement) {
$sHtml .= "<p>$key: ".get_class($oElement)."::".$oElement->GetId()."</p>";
switch(get_class($oElement))
{
switch (get_class($oElement)) {
case 'GraphNode':
if (count($oElement->GetIncomingEdges()) > 0)
{
if (count($oElement->GetIncomingEdges()) > 0) {
$sHtml .= "<ul>Incoming edges:\n";
foreach($oElement->GetIncomingEdges() as $oEdge)
{
foreach ($oElement->GetIncomingEdges() as $oEdge) {
$sHtml .= "<li>From: ".$oEdge->GetSourceNode()->GetId()."</li>\n";
}
$sHtml .= "</ul>\n";
}
if (count($oElement->GetOutgoingEdges()) > 0)
{
if (count($oElement->GetOutgoingEdges()) > 0) {
$sHtml .= "<ul>Outgoing edges:\n";
foreach($oElement->GetOutgoingEdges() as $oEdge)
{
foreach ($oElement->GetOutgoingEdges() as $oEdge) {
$sHtml .= "<li>To: ".$oEdge->GetSinkNode()->GetId()."</li>\n";
}
$sHtml .= "</ul>\n";
}
break;
case 'GraphEdge':
$sHtml .= "<p>From: ".$oElement->GetSourceNode()->GetId().", to:".$oElement->GetSinkNode()->GetId()."</p>\n";
break;
}
}
return $sHtml;
return $sHtml;
}
/**
* Split the graph in a array of non connected subgraphs
* @return multitype:SimpleGraph unknown
@@ -649,48 +611,40 @@ EOF
public function GetSubgraphs()
{
$iNbColors = 0;
$aResult = array();
$aResult = [];
$oIterator = new RelationTypeIterator($this, 'Node');
foreach($oIterator as $oNode)
{
foreach ($oIterator as $oNode) {
$iPrevColor = $oNode->GetProperty('color', null);
if ($iPrevColor == null)
{
if ($iPrevColor == null) {
$iNbColors++; // Start a new color
$oNode->FloodProperty('color', $iNbColors, true, true);
}
}
if ($iNbColors == 1)
{
if ($iNbColors == 1) {
// Everything is connected together, only one subgraph
$aResult[] = $this;
}
else
{
} else {
// Let's reconstruct each separate graph
$sClass = get_class($this);
for($i = 1; $i <= $iNbColors; $i++)
{
for ($i = 1; $i <= $iNbColors; $i++) {
$aResult[$i] = new $sClass();
}
foreach($oIterator as $oNode)
{
foreach ($oIterator as $oNode) {
$iNodeColor = $oNode->GetProperty('color');
$aResult[$iNodeColor]->_AddNode($oNode);
}
$oIter2 = new RelationTypeIterator($this, 'Edge');
foreach($oIter2 as $oEdge)
{
foreach ($oIter2 as $oEdge) {
$iEdgeColor = $oEdge->GetProperty('color');
$aResult[$iEdgeColor]->_AddEdge($oEdge);
}
}
return $aResult;
return $aResult;
}
/**
* Merge back two subgraphs into one
* @param SimpleGraph $oGraph
@@ -698,13 +652,11 @@ EOF
public function Merge(SimpleGraph $oGraph)
{
$oIter1 = new RelationTypeIterator($oGraph, 'Node');
foreach($oIter1 as $oNode)
{
foreach ($oIter1 as $oNode) {
$this->_AddNode($oNode);
}
$oIter2 = new RelationTypeIterator($oGraph, 'Edge');
foreach($oIter2 as $oEdge)
{
foreach ($oIter2 as $oEdge) {
$this->_AddEdge($oEdge);
}
}
@@ -718,7 +670,7 @@ class RelationTypeIterator implements Iterator
{
protected $iCurrentIdx;
protected $aList;
/**
* Constructor
* @param SimpleGraph $oGraph The graph to browse
@@ -727,46 +679,53 @@ class RelationTypeIterator implements Iterator
public function __construct(SimpleGraph $oGraph, $sType = null)
{
$this->iCurrentIdx = -1;
$this->aList = array();
switch($sType)
{
$this->aList = [];
switch ($sType) {
case 'Node':
foreach($oGraph->_GetNodes() as $oNode) $this->aList[] = $oNode;
break;
foreach ($oGraph->_GetNodes() as $oNode) {
$this->aList[] = $oNode;
}
break;
case 'Edge':
foreach($oGraph->_GetEdges() as $oEdge) $this->aList[] = $oEdge;
break;
foreach ($oGraph->_GetEdges() as $oEdge) {
$this->aList[] = $oEdge;
}
break;
default:
foreach($oGraph->_GetNodes() as $oNode) $this->aList[] = $oNode;
foreach($oGraph->_GetEdges() as $oEdge) $this->aList[] = $oEdge;
foreach ($oGraph->_GetNodes() as $oNode) {
$this->aList[] = $oNode;
}
foreach ($oGraph->_GetEdges() as $oEdge) {
$this->aList[] = $oEdge;
}
}
}
public function rewind(): void
{
$this->iCurrentIdx = 0;
}
public function valid(): bool
{
return array_key_exists($this->iCurrentIdx, $this->aList);
}
public function next(): void
{
$this->iCurrentIdx++;
}
// Return type mixed is not supported by PHP 7.4, we can remove the following PHP attribute and add the return type once iTop min PHP version is PHP 8.0+
#[\ReturnTypeWillChange]
public function current()
{
return $this->aList[$this->iCurrentIdx];
}
// Return type mixed is not supported by PHP 7.4, we can remove the following PHP attribute and add the return type once iTop min PHP version is PHP 8.0+
#[\ReturnTypeWillChange]
public function key()

View File

@@ -1,4 +1,5 @@
<?php
/**
* Copyright (C) 2013-2024 Combodo SAS
*
@@ -33,8 +34,8 @@ abstract class Trigger extends cmdbAbstractObject
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "grant_by_profile,core/cmdb",
"key_type" => "autoincrement",
"name_attcode" => "description",
@@ -45,21 +46,23 @@ abstract class Trigger extends cmdbAbstractObject
"db_key_field" => "id",
"db_finalclass_field" => "realclass",
'style' => new ormStyle(null, null, null, null, null, '../images/icons/icons8-conflict.svg'),
);
];
MetaModel::Init_Params($aParams);
//MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeString("description", array("allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect("action_list",
array("linked_class" => "lnkTriggerAction", "ext_key_to_me" => "trigger_id", "ext_key_to_remote" => "action_id", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("description", ["allowed_values" => null, "sql" => "description", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeLinkedSetIndirect(
"action_list",
["linked_class" => "lnkTriggerAction", "ext_key_to_me" => "trigger_id", "ext_key_to_remote" => "action_id", "allowed_values" => null, "count_min" => 1, "count_max" => 0, "depends_on" => []]
));
$aTags = ContextTag::GetTags();
MetaModel::Init_AddAttribute(new AttributeEnumSet("context", array("allowed_values" => null, "possible_values" => new ValueSetEnumPadded($aTags, true), "sql" => "context", "depends_on" => array(), "is_null_allowed" => true, "max_items" => 12)));
MetaModel::Init_AddAttribute(new AttributeEnumSet("context", ["allowed_values" => null, "possible_values" => new ValueSetEnumPadded($aTags, true), "sql" => "context", "depends_on" => [], "is_null_allowed" => true, "max_items" => 12]));
// "complement" is a computed field, fed by Trigger sub-classes, in general in ComputeValues method, for eg. the TriggerOnObject fed it with target_class info
MetaModel::Init_AddAttribute(new AttributeString("complement", array("allowed_values" => null, "sql" => "complement", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeEnum("subscription_policy", array("allowed_values" => new ValueSetEnum(Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::cases()), "sql" => "subscription_policy", "default_value" => \Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::AllowNoChannel->value, "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeString("complement", ["allowed_values" => null, "sql" => "complement", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeEnum("subscription_policy", ["allowed_values" => new ValueSetEnum(Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::cases()), "sql" => "subscription_policy", "default_value" => \Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::AllowNoChannel->value, "is_null_allowed" => false, "depends_on" => []]));
// Display lists
MetaModel::Init_SetZListItems('details', array('finalclass', 'description', 'context', 'subscription_policy', 'action_list', 'complement')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'complement')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['finalclass', 'description', 'context', 'subscription_policy', 'action_list', 'complement']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['finalclass', 'complement']); // Attributes to be displayed for a list
// Search criteria
// MetaModel::Init_SetZListItems('standard_search', array('name')); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
@@ -78,17 +81,14 @@ abstract class Trigger extends cmdbAbstractObject
$oContext = $this->Get('context');
$bChecked = false;
$bValid = false;
foreach ($oContext->GetValues() as $sValue)
{
foreach ($oContext->GetValues() as $sValue) {
$bChecked = true;
if (ContextTag::Check($sValue))
{
if (ContextTag::Check($sValue)) {
$bValid = true;
break;
}
}
if ($bChecked && !$bValid)
{
if ($bChecked && !$bValid) {
// Trigger does not match the current context
return false;
}
@@ -105,8 +105,7 @@ abstract class Trigger extends cmdbAbstractObject
public function DoActivate($aContextArgs)
{
// Check the context
if (!$this->IsContextValid())
{
if (!$this->IsContextValid()) {
// Trigger does not match the current context
$sClass = get_class($this);
$sName = $this->Get('friendlyname');
@@ -128,7 +127,7 @@ abstract class Trigger extends cmdbAbstractObject
// Execute actions
foreach ($aActionListOrdered as $aActionSubList) {
foreach ($aActionSubList as $oLink) /** @var \DBObject $oLink */ {
foreach ($aActionSubList as $oLink) { /** @var \DBObject $oLink */
/** @var \DBObject $oLink */
$iActionId = $oLink->Get('action_id');
/** @var \Action $oAction */
@@ -170,8 +169,8 @@ abstract class TriggerOnObject extends Trigger
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "grant_by_profile,core/cmdb",
"key_type" => "autoincrement",
"name_attcode" => "description",
@@ -181,18 +180,20 @@ abstract class TriggerOnObject extends Trigger
"db_table" => "priv_trigger_onobject",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeClass("target_class",
array("class_category" => "bizmodel", "more_values" => "User,UserExternal,UserInternal,UserLDAP,UserLocal", "sql" => "target_class", "default_value" => null, "is_null_allowed" => false, "depends_on" => array(), "class_exclusion_list" => "Attachment")));
MetaModel::Init_AddAttribute(new AttributeOQL("filter", array("allowed_values" => null, "sql" => "filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeClass(
"target_class",
["class_category" => "bizmodel", "more_values" => "User,UserExternal,UserInternal,UserLDAP,UserLocal", "sql" => "target_class", "default_value" => null, "is_null_allowed" => false, "depends_on" => [], "class_exclusion_list" => "Attachment"]
));
MetaModel::Init_AddAttribute(new AttributeOQL("filter", ["allowed_values" => null, "sql" => "filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['finalclass', 'target_class', 'description']); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('default_search', array('description', 'target_class')); // Default criteria of the search banner
MetaModel::Init_SetZListItems('default_search', ['description', 'target_class']); // Default criteria of the search banner
// MetaModel::Init_SetZListItems('standard_search', array('name', 'target_class', 'description')); // Criteria of the search form
}
@@ -204,18 +205,14 @@ abstract class TriggerOnObject extends Trigger
parent::DoCheckToWrite();
$sFilter = trim($this->Get('filter') ?? '');
if (strlen($sFilter) > 0)
{
try
{
if (strlen($sFilter) > 0) {
try {
$oSearch = DBObjectSearch::FromOQL($sFilter);
if (!MetaModel::IsParentClass($this->Get('target_class'), $oSearch->GetClass()))
{
if (!MetaModel::IsParentClass($this->Get('target_class'), $oSearch->GetClass())) {
$this->m_aCheckIssues[] = Dict::Format('TriggerOnObject:WrongFilterClass', $this->Get('target_class'));
}
} catch (OqlException $e)
{
} catch (OqlException $e) {
$this->m_aCheckIssues[] = Dict::Format('TriggerOnObject:WrongFilterQuery', $e->getMessage());
}
}
@@ -235,7 +232,6 @@ abstract class TriggerOnObject extends Trigger
$this->Set('complement', 'class restriction: '.$this->Get('target_class'));
}
/**
* Check whether the given object is in the scope of this trigger
* and can potentially be the subject of notifications
@@ -261,47 +257,44 @@ abstract class TriggerOnObject extends Trigger
public function DoActivate($aContextArgs)
{
$bGo = true;
if (isset($aContextArgs['this->object()']))
{
if (isset($aContextArgs['this->object()'])) {
/** @var \DBObject $oObject */
$oObject = $aContextArgs['this->object()'];
$bGo = $this->IsTargetObject($oObject->GetKey(), $oObject->ListPreviousValuesForUpdatedAttributes());
}
if ($bGo)
{
if ($bGo) {
parent::DoActivate($aContextArgs);
}
}
/**
* if the target class is Attachment, then the trigger is read-only
* @param $sAttCode
* @param $aReasons
* @param $sTargetState
* @return int
* @throws ArchivedObjectException
* @throws CoreException
*/
public function GetAttributeFlags($sAttCode, &$aReasons = array(), $sTargetState='')
/**
* if the target class is Attachment, then the trigger is read-only
* @param $sAttCode
* @param $aReasons
* @param $sTargetState
* @return int
* @throws ArchivedObjectException
* @throws CoreException
*/
public function GetAttributeFlags($sAttCode, &$aReasons = [], $sTargetState = '')
{
// Force the computed field to be read-only, preventing it to be written
if ($this->Get('target_class') == 'Attachment' ) {
return OPT_ATT_READONLY;
}
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
// Force the computed field to be read-only, preventing it to be written
if ($this->Get('target_class') == 'Attachment') {
return OPT_ATT_READONLY;
}
return parent::GetAttributeFlags($sAttCode, $aReasons, $sTargetState);
}
public function DisplayBareHeader(WebPage $oPage, $bEditMode = false)
{
$aHeaderBlocks = parent::DisplayBareHeader($oPage, $bEditMode);
if ($this->Get('target_class') == 'Attachment') {
$oPage->AddUiBlock(AlertUIBlockFactory::MakeForWarning('', Dict::S('Class:TriggerOnObject:TriggerClassAttachment/ReadOnlyMessage')));
$oPage->add_ready_script("$('#UIMenuModify').hide();");
}
public function DisplayBareHeader(WebPage $oPage, $bEditMode = false)
{
$aHeaderBlocks = parent::DisplayBareHeader($oPage, $bEditMode);
if ($this->Get('target_class') == 'Attachment' ) {
$oPage->AddUiBlock(AlertUIBlockFactory::MakeForWarning('', Dict::S('Class:TriggerOnObject:TriggerClassAttachment/ReadOnlyMessage')));
$oPage->add_ready_script("$('#UIMenuModify').hide();");
}
return $aHeaderBlocks;
}
return $aHeaderBlocks;
}
/**
* Activate trigger based on attribute list given instead of changed attributes
@@ -319,8 +312,7 @@ abstract class TriggerOnObject extends Trigger
*/
public function DoActivateForSpecificAttributes(array $aContextArgs, ?array $aAttributes)
{
if (isset($aContextArgs['this->object()']))
{
if (isset($aContextArgs['this->object()'])) {
/** @var \DBObject $oObject */
$oObject = $aContextArgs['this->object()'];
if (is_null($aAttributes)) {
@@ -347,7 +339,7 @@ abstract class TriggerOnObject extends Trigger
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
*/
public function IsTargetObject($iObjectId, $aChanges = array())
public function IsTargetObject($iObjectId, $aChanges = [])
{
$sFilter = trim($this->Get('filter') ?? '');
if (strlen($sFilter) > 0) {
@@ -404,8 +396,8 @@ class TriggerOnPortalUpdate extends TriggerOnObject
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
@@ -415,13 +407,13 @@ class TriggerOnPortalUpdate extends TriggerOnObject
"db_table" => "priv_trigger_onportalupdate",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'description')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['finalclass', 'target_class', 'description']); // Attributes to be displayed for a list
// Search criteria
}
}
@@ -437,8 +429,8 @@ abstract class TriggerOnStateChange extends TriggerOnObject
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "grant_by_profile,core/cmdb",
"key_type" => "autoincrement",
"name_attcode" => "description",
@@ -448,16 +440,16 @@ abstract class TriggerOnStateChange extends TriggerOnObject
"db_table" => "priv_trigger_onstatechange",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeClassState("state", array("class_field" => 'target_class', "allowed_values" => null, "sql" => "state", "default_value" => null, "is_null_allowed" => false, "depends_on" => array('target_class'))));
MetaModel::Init_AddAttribute(new AttributeClassState("state", ["class_field" => 'target_class', "allowed_values" => null, "sql" => "state", "default_value" => null, "is_null_allowed" => false, "depends_on" => ['target_class']]));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class', 'state')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['finalclass', 'target_class', 'state']); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
MetaModel::Init_SetZListItems('standard_search', ['description', 'target_class', 'state']); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
}
@@ -472,8 +464,8 @@ class TriggerOnStateEnter extends TriggerOnStateChange
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
@@ -483,15 +475,15 @@ class TriggerOnStateEnter extends TriggerOnStateChange
"db_table" => "priv_trigger_onstateenter",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['target_class', 'state']); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
MetaModel::Init_SetZListItems('standard_search', ['description', 'target_class', 'state']); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
}
@@ -506,8 +498,8 @@ class TriggerOnStateLeave extends TriggerOnStateChange
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
@@ -517,15 +509,15 @@ class TriggerOnStateLeave extends TriggerOnStateChange
"db_table" => "priv_trigger_onstateleave",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('target_class', 'state')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['description', 'context', 'target_class', 'filter', 'state', 'subscription_policy', 'action_list']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['target_class', 'state']); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class', 'state')); // Criteria of the std search form
MetaModel::Init_SetZListItems('standard_search', ['description', 'target_class', 'state']); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('')); // Criteria of the advanced search form
}
}
@@ -540,8 +532,8 @@ class TriggerOnObjectCreate extends TriggerOnObject
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
@@ -551,15 +543,15 @@ class TriggerOnObjectCreate extends TriggerOnObject
"db_table" => "priv_trigger_onobjcreate",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['finalclass', 'target_class']); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
MetaModel::Init_SetZListItems('standard_search', ['description', 'target_class']); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
@@ -575,8 +567,8 @@ class TriggerOnObjectDelete extends TriggerOnObject
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
@@ -586,15 +578,15 @@ class TriggerOnObjectDelete extends TriggerOnObject
"db_table" => "priv_trigger_onobjdelete",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['description', 'context', 'target_class', 'filter', 'subscription_policy', 'action_list']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['finalclass', 'target_class']); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
MetaModel::Init_SetZListItems('standard_search', ['description', 'target_class']); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
}
@@ -610,8 +602,8 @@ class TriggerOnObjectUpdate extends TriggerOnObject
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
@@ -621,37 +613,33 @@ class TriggerOnObjectUpdate extends TriggerOnObject
"db_table" => "priv_trigger_onobjupdate",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeClassAttCodeSet('target_attcodes', array("allowed_values" => null, "class_field" => "target_class", "sql" => "target_attcodes", "default_value" => null, "is_null_allowed" => true, "max_items" => 20, "min_items" => 0, "attribute_definition_exclusion_list" => "AttributeDashboard,AttributeExternalField,AttributeFinalClass,AttributeFriendlyName,AttributeObsolescenceDate,AttributeObsolescenceFlag,AttributeSubItem", "attribute_definition_list" => null, "depends_on" => array('target_class'))));
MetaModel::Init_AddAttribute(new AttributeClassAttCodeSet('target_attcodes', ["allowed_values" => null, "class_field" => "target_class", "sql" => "target_attcodes", "default_value" => null, "is_null_allowed" => true, "max_items" => 20, "min_items" => 0, "attribute_definition_exclusion_list" => "AttributeDashboard,AttributeExternalField,AttributeFinalClass,AttributeFriendlyName,AttributeObsolescenceDate,AttributeObsolescenceFlag,AttributeSubItem", "attribute_definition_list" => null, "depends_on" => ['target_class']]));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'target_attcodes', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['description', 'context', 'target_class', 'filter', 'target_attcodes', 'subscription_policy', 'action_list']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['finalclass', 'target_class']); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
MetaModel::Init_SetZListItems('standard_search', ['description', 'target_class']); // Criteria of the std search form
}
public function IsTargetObject($iObjectId, $aChanges = array())
public function IsTargetObject($iObjectId, $aChanges = [])
{
if (!parent::IsTargetObject($iObjectId, $aChanges))
{
if (!parent::IsTargetObject($iObjectId, $aChanges)) {
return false;
}
// Check the attribute
$oAttCodeSet = $this->Get('target_attcodes');
$aAttCodes = $oAttCodeSet->GetValues();
if (empty($aAttCodes))
{
if (empty($aAttCodes)) {
return true;
}
foreach($aAttCodes as $sAttCode)
{
if (array_key_exists($sAttCode, $aChanges))
{
foreach ($aAttCodes as $sAttCode) {
if (array_key_exists($sAttCode, $aChanges)) {
return true;
}
}
@@ -664,26 +652,22 @@ class TriggerOnObjectUpdate extends TriggerOnObject
// Remove unwanted attribute codes
$aChanges = $this->ListChanges();
if (isset($aChanges['target_attcodes']))
{
if (isset($aChanges['target_attcodes'])) {
$oAttDef = MetaModel::GetAttributeDef(get_class($this), 'target_attcodes');
$aArgs = array('this' => $this);
$aArgs = ['this' => $this];
$aAllowedValues = $oAttDef->GetAllowedValues($aArgs);
/** @var \ormSet $oValue */
$oValue = $this->Get('target_attcodes');
$aValues = $oValue->GetValues();
$bChanged = false;
foreach($aValues as $key => $sValue)
{
if (!isset($aAllowedValues[$sValue]))
{
foreach ($aValues as $key => $sValue) {
if (!isset($aAllowedValues[$sValue])) {
unset($aValues[$key]);
$bChanged = true;
}
}
if ($bChanged)
{
if ($bChanged) {
$oValue->SetValues($aValues);
$this->Set('target_attcodes', $oValue);
}
@@ -706,8 +690,8 @@ class TriggerOnObjectMention extends TriggerOnObject
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
@@ -718,16 +702,16 @@ class TriggerOnObjectMention extends TriggerOnObject
"db_key_field" => "id",
"db_finalclass_field" => "",
"display_template" => "",
);
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeOQL("mentioned_filter", array("allowed_values" => null, "sql" => "mentioned_filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeOQL("mentioned_filter", ["allowed_values" => null, "sql" => "mentioned_filter", "default_value" => null, "is_null_allowed" => true, "depends_on" => []]));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'filter', 'mentioned_filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('finalclass', 'target_class')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['description', 'context', 'target_class', 'filter', 'mentioned_filter', 'subscription_policy', 'action_list']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['finalclass', 'target_class']); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
MetaModel::Init_SetZListItems('standard_search', ['description', 'target_class']); // Criteria of the std search form
}
/**
@@ -745,8 +729,7 @@ class TriggerOnObjectMention extends TriggerOnObject
public function IsMentionedObjectInScope(DBObject $oObject)
{
$sFilter = trim($this->Get('mentioned_filter'));
if (strlen($sFilter) > 0)
{
if (strlen($sFilter) > 0) {
$oSearch = DBObjectSearch::FromOQL($sFilter);
$sSearchClass = $oSearch->GetClass();
@@ -763,9 +746,7 @@ class TriggerOnObjectMention extends TriggerOnObject
$aParams = $oObject->ToArgs('this');
$oSet = new DBObjectSet($oSearch, [], $aParams);
$bRet = $oSet->CountExceeds(0);
}
else
{
} else {
$bRet = true;
}
@@ -787,8 +768,8 @@ class TriggerOnAttributeBlobDownload extends TriggerOnObject
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
@@ -799,7 +780,7 @@ class TriggerOnAttributeBlobDownload extends TriggerOnObject
"db_key_field" => "id",
"db_finalclass_field" => "",
"display_template" => "",
);
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
}
@@ -816,42 +797,42 @@ class lnkTriggerAction extends cmdbAbstractObject
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "",
"state_attcode" => "",
"reconc_keys" => array('action_id', 'trigger_id'),
"reconc_keys" => ['action_id', 'trigger_id'],
"db_table" => "priv_link_action_trigger",
"db_key_field" => "link_id",
"db_finalclass_field" => "",
"is_link" => true,
'uniqueness_rules' => array(
'no_duplicate' => array(
'attributes' => array(
'uniqueness_rules' => [
'no_duplicate' => [
'attributes' => [
0 => 'action_id',
1 => 'trigger_id',
),
],
'filter' => '',
'disabled' => false,
'is_blocking' => true,
),
),
);
],
],
];
MetaModel::Init_Params($aParams);
MetaModel::Init_AddAttribute(new AttributeExternalKey("action_id", array("targetclass" => "Action", "jointype" => '', "allowed_values" => null, "sql" => "action_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("action_name", array("allowed_values" => null, "extkey_attcode" => 'action_id', "target_attcode" => "name")));
MetaModel::Init_AddAttribute(new AttributeExternalKey("trigger_id", array("targetclass" => "Trigger", "jointype" => '', "allowed_values" => null, "sql" => "trigger_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalField("trigger_name", array("allowed_values" => null, "extkey_attcode" => 'trigger_id', "target_attcode" => "description")));
MetaModel::Init_AddAttribute(new AttributeInteger("order", array("allowed_values" => null, "sql" => "order", "default_value" => 0, "is_null_allowed" => true, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeExternalKey("action_id", ["targetclass" => "Action", "jointype" => '', "allowed_values" => null, "sql" => "action_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeExternalField("action_name", ["allowed_values" => null, "extkey_attcode" => 'action_id', "target_attcode" => "name"]));
MetaModel::Init_AddAttribute(new AttributeExternalKey("trigger_id", ["targetclass" => "Trigger", "jointype" => '', "allowed_values" => null, "sql" => "trigger_id", "is_null_allowed" => false, "on_target_delete" => DEL_AUTO, "depends_on" => []]));
MetaModel::Init_AddAttribute(new AttributeExternalField("trigger_name", ["allowed_values" => null, "extkey_attcode" => 'trigger_id', "target_attcode" => "description"]));
MetaModel::Init_AddAttribute(new AttributeInteger("order", ["allowed_values" => null, "sql" => "order", "default_value" => 0, "is_null_allowed" => true, "depends_on" => []]));
// Display lists
MetaModel::Init_SetZListItems('details', array('action_id', 'trigger_id', 'order')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('list', array('action_id', 'trigger_id', 'order')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['action_id', 'trigger_id', 'order']); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('list', ['action_id', 'trigger_id', 'order']); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('action_id', 'trigger_id', 'order')); // Criteria of the std search form
MetaModel::Init_SetZListItems('advanced_search', array('action_id', 'trigger_id', 'order')); // Criteria of the advanced search form
MetaModel::Init_SetZListItems('standard_search', ['action_id', 'trigger_id', 'order']); // Criteria of the std search form
MetaModel::Init_SetZListItems('advanced_search', ['action_id', 'trigger_id', 'order']); // Criteria of the advanced search form
}
}
@@ -866,8 +847,8 @@ class TriggerOnThresholdReached extends TriggerOnObject
*/
public static function Init()
{
$aParams = array
(
$aParams =
[
"category" => "grant_by_profile,core/cmdb,application",
"key_type" => "autoincrement",
"name_attcode" => "description",
@@ -877,18 +858,18 @@ class TriggerOnThresholdReached extends TriggerOnObject
"db_table" => "priv_trigger_threshold",
"db_key_field" => "id",
"db_finalclass_field" => "",
);
];
MetaModel::Init_Params($aParams);
MetaModel::Init_InheritAttributes();
MetaModel::Init_AddAttribute(new AttributeClassAttCodeSet('stop_watch_code', array("allowed_values" => null, "class_field" => "target_class", "sql" => "stop_watch_code", "default_value" => null, "is_null_allowed" => false, "max_items" => 1, "min_items" => 1, "attribute_definition_exclusion_list" => null, "attribute_definition_list" => "AttributeStopWatch", "include_child_classes_attributes" => true, "depends_on" => array('target_class'))));
MetaModel::Init_AddAttribute(new AttributeString("threshold_index", array("allowed_values" => null, "sql" => "threshold_index", "default_value" => null, "is_null_allowed" => false, "depends_on" => array())));
MetaModel::Init_AddAttribute(new AttributeClassAttCodeSet('stop_watch_code', ["allowed_values" => null, "class_field" => "target_class", "sql" => "stop_watch_code", "default_value" => null, "is_null_allowed" => false, "max_items" => 1, "min_items" => 1, "attribute_definition_exclusion_list" => null, "attribute_definition_list" => "AttributeStopWatch", "include_child_classes_attributes" => true, "depends_on" => ['target_class']]));
MetaModel::Init_AddAttribute(new AttributeString("threshold_index", ["allowed_values" => null, "sql" => "threshold_index", "default_value" => null, "is_null_allowed" => false, "depends_on" => []]));
// Display lists
MetaModel::Init_SetZListItems('details', array('description', 'context', 'target_class', 'stop_watch_code', 'threshold_index', 'filter', 'subscription_policy', 'action_list')); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', array('target_class', 'threshold_index', 'threshold_index')); // Attributes to be displayed for a list
MetaModel::Init_SetZListItems('details', ['description', 'context', 'target_class', 'stop_watch_code', 'threshold_index', 'filter', 'subscription_policy', 'action_list']); // Attributes to be displayed for the complete details
MetaModel::Init_SetZListItems('list', ['target_class', 'threshold_index', 'threshold_index']); // Attributes to be displayed for a list
// Search criteria
MetaModel::Init_SetZListItems('standard_search', array('description', 'target_class')); // Criteria of the std search form
MetaModel::Init_SetZListItems('standard_search', ['description', 'target_class']); // Criteria of the std search form
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
}

View File

@@ -1,4 +1,5 @@
<?php
// Copyright (C) 2010-2024 Combodo SAS
//
// This file is part of iTop.
@@ -16,7 +17,6 @@
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see <http://www.gnu.org/licenses/>
/**
* Value set definitions (from a fixed list or from a query, etc.)
*
@@ -37,16 +37,14 @@ require_once('MyHelpers.class.inc.php');
abstract class ValueSetDefinition
{
protected $m_bIsLoaded = false;
protected $m_aValues = array();
protected $m_aValues = [];
// Displayable description that could be computed out of the std usage context
public function GetValuesDescription()
{
$aValues = $this->GetValues(array(), '');
$aDisplayedValues = array();
foreach($aValues as $key => $value)
{
$aValues = $this->GetValues([], '');
$aDisplayedValues = [];
foreach ($aValues as $key => $value) {
$aDisplayedValues[] = "$key => $value";
}
$sAllowedValues = implode(', ', $aDisplayedValues);
@@ -62,24 +60,18 @@ abstract class ValueSetDefinition
*/
public function GetValues($aArgs, $sContains = '', $sOperation = 'contains')
{
if (!$this->m_bIsLoaded)
{
if (!$this->m_bIsLoaded) {
$this->LoadValues($aArgs);
$this->m_bIsLoaded = true;
}
if (strlen($sContains) == 0)
{
if (strlen($sContains) == 0) {
// No filtering
$aRet = $this->m_aValues;
}
else
{
} else {
// Filter on results containing the needle <sContain>
$aRet = array();
foreach ($this->m_aValues as $sKey=>$sValue)
{
if (stripos($sValue, $sContains) !== false)
{
$aRet = [];
foreach ($this->m_aValues as $sKey => $sValue) {
if (stripos($sValue, $sContains) !== false) {
$aRet[$sKey] = $sValue;
}
}
@@ -103,7 +95,6 @@ abstract class ValueSetDefinition
abstract protected function LoadValues($aArgs);
}
/**
* Set of existing values for an attribute, given a search filter
*
@@ -122,11 +113,10 @@ class ValueSetObjects extends ValueSetDefinition
private $m_bSort;
private $m_iLimit;
/**
* @param hash $aOrderBy Array of '[<classalias>.]attcode' => bAscending
*/
public function __construct($sFilterExp, $sValueAttCode = '', $aOrderBy = array(), $bAllowAllData = false, $aModifierProperties = array())
public function __construct($sFilterExp, $sValueAttCode = '', $aOrderBy = [], $bAllowAllData = false, $aModifierProperties = [])
{
$this->m_sContains = '';
$this->m_sOperation = '';
@@ -155,54 +145,48 @@ class ValueSetObjects extends ValueSetDefinition
{
$this->m_aOrderBy = $aOrderBy;
}
public function ToObjectSet($aArgs = array(), $sContains = '', $iAdditionalValue = null)
public function ToObjectSet($aArgs = [], $sContains = '', $iAdditionalValue = null)
{
if ($this->m_bAllowAllData)
{
if ($this->m_bAllowAllData) {
$oFilter = DBObjectSearch::FromOQL_AllData($this->m_sFilterExpr);
}
else
{
} else {
$oFilter = DBObjectSearch::FromOQL($this->m_sFilterExpr);
}
if (!is_null($this->m_oExtraCondition))
{
if (!is_null($this->m_oExtraCondition)) {
$oFilter = $oFilter->Intersect($this->m_oExtraCondition);
}
foreach($this->m_aModifierProperties as $sPluginClass => $aProperties)
{
foreach ($aProperties as $sProperty => $value)
{
foreach ($this->m_aModifierProperties as $sPluginClass => $aProperties) {
foreach ($aProperties as $sProperty => $value) {
$oFilter->SetModifierProperty($sPluginClass, $sProperty, $value);
}
}
if ($iAdditionalValue > 0)
{
if ($iAdditionalValue > 0) {
$oSearchAdditionalValue = new DBObjectSearch($oFilter->GetClass());
$oSearchAdditionalValue->AddConditionExpression( new BinaryExpression(
new FieldExpression('id', $oSearchAdditionalValue->GetClassAlias()),
'=',
new VariableExpression('current_extkey_id'))
);
$oSearchAdditionalValue->AddConditionExpression(
new BinaryExpression(
new FieldExpression('id', $oSearchAdditionalValue->GetClassAlias()),
'=',
new VariableExpression('current_extkey_id')
)
);
$oSearchAdditionalValue->AllowAllData();
$oSearchAdditionalValue->SetArchiveMode(true);
$oSearchAdditionalValue->SetInternalParams( array('current_extkey_id' => $iAdditionalValue) );
$oSearchAdditionalValue->SetInternalParams(['current_extkey_id' => $iAdditionalValue]);
$oFilter = new DBUnionSearch(array($oFilter, $oSearchAdditionalValue));
$oFilter = new DBUnionSearch([$oFilter, $oSearchAdditionalValue]);
}
return new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs);
}
/**
* @inheritDoc
* @throws CoreException
* @throws OQLException
*/
public function GetValues($aArgs, $sContains = '', $sOperation = 'contains')
/**
* @inheritDoc
* @throws CoreException
* @throws OQLException
*/
public function GetValues($aArgs, $sContains = '', $sOperation = 'contains')
{
if (!$this->m_bIsLoaded || ($sContains != $this->m_sContains) || ($sOperation != $this->m_sOperation))
{
if (!$this->m_bIsLoaded || ($sContains != $this->m_sContains) || ($sOperation != $this->m_sOperation)) {
$this->LoadValues($aArgs, $sContains, $sOperation);
$this->m_bIsLoaded = true;
}
@@ -225,15 +209,15 @@ class ValueSetObjects extends ValueSetDefinition
$this->m_sContains = $sContains;
$this->m_sOperation = $sOperation;
$this->m_aValues = array();
$this->m_aValues = [];
$oFilter = $this->GetFilter($sOperation, $sContains);
$oObjects = new DBObjectSet($oFilter, $this->m_aOrderBy, $aArgs, null, $this->m_iLimit, 0, $this->m_bSort);
if (empty($this->m_sValueAttCode)) {
$aAttToLoad = array($oFilter->GetClassAlias() => array('friendlyname'));
$aAttToLoad = [$oFilter->GetClassAlias() => ['friendlyname']];
} else {
$aAttToLoad = array($oFilter->GetClassAlias() => array($this->m_sValueAttCode));
$aAttToLoad = [$oFilter->GetClassAlias() => [$this->m_sValueAttCode]];
}
$oObjects->OptimizeColumnLoad($aAttToLoad);
while ($oObject = $oObjects->Fetch()) {
@@ -247,7 +231,6 @@ class ValueSetObjects extends ValueSetDefinition
return true;
}
/**
* Get filter for functions LoadValues and LoadValuesForAutocomplete
*
@@ -297,7 +280,7 @@ class ValueSetObjects extends ValueSetDefinition
$aAttributes = MetaModel::GetFriendlyNameAttributeCodeList($sClass);
if (count($aAttributes) > 0) {
$sClassAlias = $oFilter->GetClassAlias();
$aFilters = array();
$aFilters = [];
$oValueExpr = new ScalarExpression($this->m_sContains);
foreach ($aAttributes as $sAttribute) {
$oNewFilter = $oFilter->DeepClone();
@@ -355,8 +338,7 @@ class ValueSetObjects extends ValueSetDefinition
public function GetValuesForAutocomplete($aArgs, $sContains = '', $sOperation = 'contains')
{
if (!$this->m_bIsLoaded || ($sContains != $this->m_sContains) || ($sOperation != $this->m_sOperation))
{
if (!$this->m_bIsLoaded || ($sContains != $this->m_sContains) || ($sOperation != $this->m_sOperation)) {
$this->LoadValuesForAutocomplete($aArgs, $sContains, $sOperation);
$this->m_bIsLoaded = true;
}
@@ -376,7 +358,7 @@ class ValueSetObjects extends ValueSetDefinition
*/
protected function LoadValuesForAutocomplete($aArgs, $sContains = '', $sOperation = 'contains')
{
$this->m_aValues = array();
$this->m_aValues = [];
$oFilter = $this->GetFilter($sOperation, $sContains);
$sClass = $oFilter->GetClass();
@@ -444,7 +426,6 @@ class ValueSetObjects extends ValueSetDefinition
}
}
/**
* Fixed set values (could be hardcoded in the business model)
*
@@ -514,8 +495,7 @@ class ValueSetEnum extends ValueSetDefinition
protected function LoadValues($aArgs)
{
$aValues = [];
if (is_array($this->m_values))
{
if (is_array($this->m_values)) {
foreach ($this->m_values as $key => $value) {
// Handle backed-enum case
if (is_object($value) && enum_exists(get_class($value))) {
@@ -525,18 +505,13 @@ class ValueSetEnum extends ValueSetDefinition
$aValues[$key] = $value;
}
}
elseif (is_string($this->m_values) && strlen($this->m_values) > 0)
{
foreach (explode(",", $this->m_values) as $sVal)
{
} elseif (is_string($this->m_values) && strlen($this->m_values) > 0) {
foreach (explode(",", $this->m_values) as $sVal) {
$sVal = trim($sVal);
$sKey = $sVal;
$aValues[$sKey] = $sVal;
}
}
else
{
} else {
$aValues = [];
}
$this->m_aValues = $aValues;
@@ -553,17 +528,13 @@ class ValueSetEnumPadded extends ValueSetEnum
public function __construct($Values, bool $bSortByValues = false)
{
parent::__construct($Values, $bSortByValues);
if (is_string($Values))
{
if (is_string($Values)) {
$this->LoadValues(null);
}
else
{
} else {
$this->m_aValues = $Values;
}
$aPaddedValues = array();
foreach ($this->m_aValues as $sKey => $sVal)
{
$aPaddedValues = [];
foreach ($this->m_aValues as $sKey => $sVal) {
// Pad keys to the min. length required by the \AttributeSet
$sKey = str_pad($sKey, 3, '_', STR_PAD_LEFT);
$aPaddedValues[$sKey] = $sVal;
@@ -592,15 +563,13 @@ class ValueSetRange extends ValueSetDefinition
protected function LoadValues($aArgs)
{
$iValue = $this->m_iStart;
for($iValue = $this->m_iStart; $iValue <= $this->m_iEnd; $iValue += $this->m_iStep)
{
for ($iValue = $this->m_iStart; $iValue <= $this->m_iEnd; $iValue += $this->m_iStep) {
$this->m_aValues[$iValue] = $iValue;
}
return true;
}
}
/**
* Data model classes
*
@@ -622,27 +591,19 @@ class ValueSetEnumClasses extends ValueSetEnum
parent::LoadValues($aArgs);
// Translate the labels of the additional values
foreach($this->m_aValues as $sClass => $void)
{
if (MetaModel::IsValidClass($sClass))
{
foreach ($this->m_aValues as $sClass => $void) {
if (MetaModel::IsValidClass($sClass)) {
$this->m_aValues[$sClass] = MetaModel::GetName($sClass);
}
else
{
} else {
unset($this->m_aValues[$sClass]);
}
}
// Then, add the classes from the category definition
foreach (MetaModel::GetClasses($this->m_sCategories) as $sClass)
{
if (MetaModel::IsValidClass($sClass))
{
foreach (MetaModel::GetClasses($this->m_sCategories) as $sClass) {
if (MetaModel::IsValidClass($sClass)) {
$this->m_aValues[$sClass] = MetaModel::GetName($sClass);
}
else
{
} else {
unset($this->m_aValues[$sClass]);
}
}