mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
N°8796 - Add PHP code style validation in iTop and extensions - format whole code base
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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
@@ -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');
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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() ?? '');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -412,4 +412,4 @@ class SimpleCryptOpenSSLMcryptCompatibilityEngine implements CryptEngine
|
||||
return trim($plaintext);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user