mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°6436 - Integrate Performance Audit pre requisite in iTop Pro 2.7.9
This commit is contained in:
committed by
Eric Espie
parent
9afc22bd8f
commit
2b5973ec67
@@ -1857,4 +1857,28 @@ class RestUtils
|
|||||||
interface iModuleExtension
|
interface iModuleExtension
|
||||||
{
|
{
|
||||||
public function __construct();
|
public function __construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* KPI logging extensibility point
|
||||||
|
*
|
||||||
|
* KPI Logger extension
|
||||||
|
*/
|
||||||
|
interface iKPILoggerExtension
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Init the statistics collected
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function InitStats();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new KPI to the stats
|
||||||
|
*
|
||||||
|
* @param \Combodo\iTop\Core\Kpi\KpiLogData $oKPILogData
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function LogOperation($oKPILogData);
|
||||||
}
|
}
|
||||||
@@ -4003,7 +4003,9 @@ EOF
|
|||||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||||
{
|
{
|
||||||
$oExtensionInstance->OnDBInsert($this, self::GetCurrentChange());
|
$oKPI = new ExecutionKPI();
|
||||||
|
$oExtensionInstance->OnDBInsert($this, self::GetCurrentChange());
|
||||||
|
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBInsert');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $res;
|
return $res;
|
||||||
@@ -4020,13 +4022,16 @@ EOF
|
|||||||
|
|
||||||
protected function DBCloneTracked_Internal($newKey = null)
|
protected function DBCloneTracked_Internal($newKey = null)
|
||||||
{
|
{
|
||||||
$oNewObj = parent::DBCloneTracked_Internal($newKey);
|
/** @var cmdbAbstractObject $oNewObj */
|
||||||
|
$oNewObj = MetaModel::GetObject(get_class($this), parent::DBCloneTracked_Internal($newKey));
|
||||||
|
|
||||||
// Invoke extensions after insertion (the object must exist, have an id, etc.)
|
// Invoke extensions after insertion (the object must exist, have an id, etc.)
|
||||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||||
{
|
{
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$oExtensionInstance->OnDBInsert($oNewObj, self::GetCurrentChange());
|
$oExtensionInstance->OnDBInsert($oNewObj, self::GetCurrentChange());
|
||||||
|
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBInsert');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $oNewObj;
|
return $oNewObj;
|
||||||
@@ -4054,7 +4059,9 @@ EOF
|
|||||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||||
foreach (MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
foreach (MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||||
{
|
{
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
|
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
|
||||||
|
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBUpdate');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception $e)
|
catch (Exception $e)
|
||||||
@@ -4100,7 +4107,9 @@ EOF
|
|||||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||||
{
|
{
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$oExtensionInstance->OnDBDelete($this, self::GetCurrentChange());
|
$oExtensionInstance->OnDBDelete($this, self::GetCurrentChange());
|
||||||
|
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBDelete');
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::DBDeleteTracked_Internal($oDeletionPlan);
|
return parent::DBDeleteTracked_Internal($oDeletionPlan);
|
||||||
@@ -4118,7 +4127,10 @@ EOF
|
|||||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||||
{
|
{
|
||||||
if ($oExtensionInstance->OnIsModified($this))
|
$oKPI = new ExecutionKPI();
|
||||||
|
$bIsModified = $oExtensionInstance->OnIsModified($this);
|
||||||
|
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnIsModified');
|
||||||
|
if ($bIsModified)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -4162,7 +4174,9 @@ EOF
|
|||||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||||
{
|
{
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$aNewIssues = $oExtensionInstance->OnCheckToWrite($this);
|
$aNewIssues = $oExtensionInstance->OnCheckToWrite($this);
|
||||||
|
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnCheckToWrite');
|
||||||
if (is_array($aNewIssues) && (count($aNewIssues) > 0)) // Some extensions return null instead of an empty array
|
if (is_array($aNewIssues) && (count($aNewIssues) > 0)) // Some extensions return null instead of an empty array
|
||||||
{
|
{
|
||||||
$this->m_aCheckIssues = array_merge($this->m_aCheckIssues, $aNewIssues);
|
$this->m_aCheckIssues = array_merge($this->m_aCheckIssues, $aNewIssues);
|
||||||
@@ -4210,7 +4224,9 @@ EOF
|
|||||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||||
{
|
{
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$aNewIssues = $oExtensionInstance->OnCheckToDelete($this);
|
$aNewIssues = $oExtensionInstance->OnCheckToDelete($this);
|
||||||
|
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnCheckToDelete');
|
||||||
if (is_array($aNewIssues) && count($aNewIssues) > 0)
|
if (is_array($aNewIssues) && count($aNewIssues) > 0)
|
||||||
{
|
{
|
||||||
$this->m_aDeleteIssues = array_merge($this->m_aDeleteIssues, $aNewIssues);
|
$this->m_aDeleteIssues = array_merge($this->m_aDeleteIssues, $aNewIssues);
|
||||||
@@ -4722,7 +4738,7 @@ EOF
|
|||||||
$bResult = (count($aErrors) == 0);
|
$bResult = (count($aErrors) == 0);
|
||||||
if ($bResult)
|
if ($bResult)
|
||||||
{
|
{
|
||||||
list($bResult, $aErrors) = $oObj->CheckToWrite();
|
[$bResult, $aErrors] = $oObj->CheckToWrite();
|
||||||
}
|
}
|
||||||
if ($bPreview)
|
if ($bPreview)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Combodo\iTop\Service\Module\ModuleService;
|
||||||
use ScssPhp\ScssPhp\Compiler;
|
use ScssPhp\ScssPhp\Compiler;
|
||||||
|
|
||||||
|
|
||||||
@@ -1946,24 +1947,7 @@ class utils
|
|||||||
*/
|
*/
|
||||||
public static function GetCurrentModuleName($iCallDepth = 0)
|
public static function GetCurrentModuleName($iCallDepth = 0)
|
||||||
{
|
{
|
||||||
$sCurrentModuleName = '';
|
return ModuleService::GetInstance()->GetCurrentModuleName($iCallDepth = 0);
|
||||||
$aCallStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
|
||||||
$sCallerFile = realpath($aCallStack[$iCallDepth]['file']);
|
|
||||||
|
|
||||||
foreach(GetModulesInfo() as $sModuleName => $aInfo)
|
|
||||||
{
|
|
||||||
if ($aInfo['root_dir'] !== '')
|
|
||||||
{
|
|
||||||
$sRootDir = realpath(APPROOT.$aInfo['root_dir']);
|
|
||||||
|
|
||||||
if(substr($sCallerFile, 0, strlen($sRootDir)) === $sRootDir)
|
|
||||||
{
|
|
||||||
$sCurrentModuleName = $sModuleName;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $sCurrentModuleName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1979,24 +1963,7 @@ class utils
|
|||||||
*/
|
*/
|
||||||
public static function GetCurrentModuleDir($iCallDepth)
|
public static function GetCurrentModuleDir($iCallDepth)
|
||||||
{
|
{
|
||||||
$sCurrentModuleDir = '';
|
return ModuleService::GetInstance()->GetCurrentModuleDir($iCallDepth);
|
||||||
$aCallStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
|
||||||
$sCallerFile = realpath($aCallStack[$iCallDepth]['file']);
|
|
||||||
|
|
||||||
foreach(GetModulesInfo() as $sModuleName => $aInfo)
|
|
||||||
{
|
|
||||||
if ($aInfo['root_dir'] !== '')
|
|
||||||
{
|
|
||||||
$sRootDir = realpath(APPROOT.$aInfo['root_dir']);
|
|
||||||
|
|
||||||
if(substr($sCallerFile, 0, strlen($sRootDir)) === $sRootDir)
|
|
||||||
{
|
|
||||||
$sCurrentModuleDir = basename($sRootDir);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $sCurrentModuleDir;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2011,12 +1978,7 @@ class utils
|
|||||||
*/
|
*/
|
||||||
public static function GetCurrentModuleUrl()
|
public static function GetCurrentModuleUrl()
|
||||||
{
|
{
|
||||||
$sDir = static::GetCurrentModuleDir(1);
|
return ModuleService::GetInstance()->GetCurrentModuleUrl();
|
||||||
if ( $sDir !== '')
|
|
||||||
{
|
|
||||||
return static::GetAbsoluteUrlModulesRoot().'/'.$sDir;
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2026,8 +1988,7 @@ class utils
|
|||||||
*/
|
*/
|
||||||
public static function GetCurrentModuleSetting($sProperty, $defaultvalue = null)
|
public static function GetCurrentModuleSetting($sProperty, $defaultvalue = null)
|
||||||
{
|
{
|
||||||
$sModuleName = static::GetCurrentModuleName(1);
|
return ModuleService::GetInstance()->GetCurrentModuleSetting($sProperty, $defaultvalue);
|
||||||
return MetaModel::GetModuleSetting($sModuleName, $sProperty, $defaultvalue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2036,12 +1997,7 @@ class utils
|
|||||||
*/
|
*/
|
||||||
public static function GetCompiledModuleVersion($sModuleName)
|
public static function GetCompiledModuleVersion($sModuleName)
|
||||||
{
|
{
|
||||||
$aModulesInfo = GetModulesInfo();
|
return ModuleService::GetInstance()->GetCompiledModuleVersion($sModuleName);
|
||||||
if (array_key_exists($sModuleName, $aModulesInfo))
|
|
||||||
{
|
|
||||||
return $aModulesInfo[$sModuleName]['version'];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2505,4 +2461,5 @@ class utils
|
|||||||
return (substr(PHP_OS,0,3) === 'WIN');
|
return (substr(PHP_OS,0,3) === 'WIN');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,14 +22,8 @@ define('ITOP_DEFAULT_ENV', 'production');
|
|||||||
define('MAINTENANCE_MODE_FILE', APPROOT.'data/.maintenance');
|
define('MAINTENANCE_MODE_FILE', APPROOT.'data/.maintenance');
|
||||||
define('READONLY_MODE_FILE', APPROOT.'data/.readonly');
|
define('READONLY_MODE_FILE', APPROOT.'data/.readonly');
|
||||||
|
|
||||||
if (function_exists('microtime'))
|
$fItopStarted = microtime(true);
|
||||||
{
|
$iItopInitialMemory = memory_get_usage(true);
|
||||||
$fItopStarted = microtime(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$fItopStarted = 1000 * time();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! isset($GLOBALS['bBypassAutoload']) || $GLOBALS['bBypassAutoload'] == false)
|
if (! isset($GLOBALS['bBypassAutoload']) || $GLOBALS['bBypassAutoload'] == false)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
"sources/application",
|
"sources/application",
|
||||||
"sources/Composer",
|
"sources/Composer",
|
||||||
"sources/Controller",
|
"sources/Controller",
|
||||||
|
"sources/Service",
|
||||||
"sources/Core"
|
"sources/Core"
|
||||||
],
|
],
|
||||||
"exclude-from-classmap": [
|
"exclude-from-classmap": [
|
||||||
|
|||||||
@@ -67,8 +67,7 @@ class MyHelpers
|
|||||||
// format sss.mmmuuupppnnn
|
// format sss.mmmuuupppnnn
|
||||||
public static function getmicrotime()
|
public static function getmicrotime()
|
||||||
{
|
{
|
||||||
list($usec, $sec) = explode(" ",microtime());
|
return microtime(true);
|
||||||
return ((float)$usec + (float)$sec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -420,6 +419,7 @@ class MyHelpers
|
|||||||
//}
|
//}
|
||||||
return $sOutput;
|
return $sOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -524,5 +524,3 @@ class Str
|
|||||||
return (strtolower($sString) == $sString);
|
return (strtolower($sString) == $sString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
||||||
|
|||||||
@@ -731,8 +731,9 @@ class CMDBSource
|
|||||||
{
|
{
|
||||||
self::LogDeadLock($e);
|
self::LogDeadLock($e);
|
||||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql, $e));
|
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql, $e));
|
||||||
}
|
} finally {
|
||||||
$oKPI->ComputeStats('Query exec (mySQL)', $sSql);
|
$oKPI->ComputeStats('Query exec (mySQL)', $sSql);
|
||||||
|
}
|
||||||
if ($oResult === false)
|
if ($oResult === false)
|
||||||
{
|
{
|
||||||
$aContext = array('query' => $sSql);
|
$aContext = array('query' => $sSql);
|
||||||
|
|||||||
@@ -963,6 +963,14 @@ class Config
|
|||||||
'source_of_value' => '',
|
'source_of_value' => '',
|
||||||
'show_in_conf_sample' => false,
|
'show_in_conf_sample' => false,
|
||||||
),
|
),
|
||||||
|
'log_kpi_report_to_extensions_only' => array(
|
||||||
|
'type' => 'bool',
|
||||||
|
'description' => 'Report only the KPI logging extensions',
|
||||||
|
'default' => false,
|
||||||
|
'value' => '',
|
||||||
|
'source_of_value' => '',
|
||||||
|
'show_in_conf_sample' => false,
|
||||||
|
),
|
||||||
'max_linkset_output' => array(
|
'max_linkset_output' => array(
|
||||||
'type' => 'integer',
|
'type' => 'integer',
|
||||||
'description' => 'Maximum number of items shown when getting a list of related items in an email, using the form $this->some_list$. 0 means no limit.',
|
'description' => 'Maximum number of items shown when getting a list of related items in an email, using the form $this->some_list$. 0 means no limit.',
|
||||||
|
|||||||
@@ -2225,7 +2225,7 @@ abstract class DBObject implements iDisplay
|
|||||||
|
|
||||||
$oKPI = new ExecutionKPI();
|
$oKPI = new ExecutionKPI();
|
||||||
$this->DoCheckToWrite();
|
$this->DoCheckToWrite();
|
||||||
$oKPI->ComputeStats('CheckToWrite', get_class($this));
|
$oKPI->ComputeStatsForExtension($this, 'DoCheckToWrite');
|
||||||
if (count($this->m_aCheckIssues) == 0)
|
if (count($this->m_aCheckIssues) == 0)
|
||||||
{
|
{
|
||||||
$this->m_bCheckStatus = true;
|
$this->m_bCheckStatus = true;
|
||||||
@@ -2693,8 +2693,12 @@ abstract class DBObject implements iDisplay
|
|||||||
$sRootClass = MetaModel::GetRootClass($sClass);
|
$sRootClass = MetaModel::GetRootClass($sClass);
|
||||||
|
|
||||||
// Ensure the update of the values (we are accessing the data directly)
|
// Ensure the update of the values (we are accessing the data directly)
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$this->DoComputeValues();
|
$this->DoComputeValues();
|
||||||
|
$oKPI->ComputeStatsForExtension($this, 'DoComputeValues');
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$this->OnInsert();
|
$this->OnInsert();
|
||||||
|
$oKPI->ComputeStatsForExtension($this, 'OnInsert');
|
||||||
|
|
||||||
if ($this->m_iKey < 0)
|
if ($this->m_iKey < 0)
|
||||||
{
|
{
|
||||||
@@ -2712,7 +2716,7 @@ abstract class DBObject implements iDisplay
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ultimate check - ensure DB integrity
|
// Ultimate check - ensure DB integrity
|
||||||
list($bRes, $aIssues) = $this->CheckToWrite();
|
[$bRes, $aIssues] = $this->CheckToWrite();
|
||||||
if (!$bRes)
|
if (!$bRes)
|
||||||
{
|
{
|
||||||
throw new CoreCannotSaveObjectException(array('issues' => $aIssues, 'class' => get_class($this), 'id' => $this->GetKey()));
|
throw new CoreCannotSaveObjectException(array('issues' => $aIssues, 'class' => get_class($this), 'id' => $this->GetKey()));
|
||||||
@@ -2818,7 +2822,9 @@ abstract class DBObject implements iDisplay
|
|||||||
$this->m_aOrigValues[$sAttCode] = $value;
|
$this->m_aOrigValues[$sAttCode] = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$this->AfterInsert();
|
$this->AfterInsert();
|
||||||
|
$oKPI->ComputeStatsForExtension($this, 'AfterInsert');
|
||||||
|
|
||||||
// Activate any existing trigger
|
// Activate any existing trigger
|
||||||
$sClass = get_class($this);
|
$sClass = get_class($this);
|
||||||
@@ -3094,8 +3100,11 @@ abstract class DBObject implements iDisplay
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$this->DoComputeValues();
|
$this->DoComputeValues();
|
||||||
// Stop watches
|
$oKPI->ComputeStatsForExtension($this, 'DoComputeValues');
|
||||||
|
|
||||||
|
// Stop watches
|
||||||
$sState = $this->GetState();
|
$sState = $this->GetState();
|
||||||
if ($sState != '')
|
if ($sState != '')
|
||||||
{
|
{
|
||||||
@@ -3114,7 +3123,9 @@ abstract class DBObject implements iDisplay
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->OnUpdate();
|
$oKPI = new ExecutionKPI();
|
||||||
|
$this->OnUpdate();
|
||||||
|
$oKPI->ComputeStatsForExtension($this, 'OnUpdate');
|
||||||
|
|
||||||
$aChanges = $this->ListChanges();
|
$aChanges = $this->ListChanges();
|
||||||
if (count($aChanges) == 0)
|
if (count($aChanges) == 0)
|
||||||
@@ -3126,7 +3137,7 @@ abstract class DBObject implements iDisplay
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ultimate check - ensure DB integrity
|
// Ultimate check - ensure DB integrity
|
||||||
list($bRes, $aIssues) = $this->CheckToWrite();
|
[$bRes, $aIssues] = $this->CheckToWrite();
|
||||||
if (!$bRes)
|
if (!$bRes)
|
||||||
{
|
{
|
||||||
throw new CoreCannotSaveObjectException(array(
|
throw new CoreCannotSaveObjectException(array(
|
||||||
@@ -3326,7 +3337,9 @@ abstract class DBObject implements iDisplay
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
$this->AfterUpdate();
|
$oKPI = new ExecutionKPI();
|
||||||
|
$this->AfterUpdate();
|
||||||
|
$oKPI->ComputeStatsForExtension($this, 'AfterUpdate');
|
||||||
|
|
||||||
// Reload to get the external attributes
|
// Reload to get the external attributes
|
||||||
if ($bHasANewExternalKeyValue)
|
if ($bHasANewExternalKeyValue)
|
||||||
|
|||||||
@@ -763,7 +763,10 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$this->m_oSQLResult = CMDBSource::Query($sSQL);
|
$this->m_oSQLResult = CMDBSource::Query($sSQL);
|
||||||
|
$sOQL = $this->GetPseudoOQL($this->m_oFilter, $this->GetRealSortOrder(), $this->m_iLimitCount, $this->m_iLimitStart, false);
|
||||||
|
$oKPI->ComputeStats('OQL Query Exec', $sOQL);
|
||||||
} catch (MySQLException $e)
|
} catch (MySQLException $e)
|
||||||
{
|
{
|
||||||
// 1116 = ER_TOO_MANY_TABLES
|
// 1116 = ER_TOO_MANY_TABLES
|
||||||
@@ -843,8 +846,11 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
{
|
{
|
||||||
if (is_null($this->m_iNumTotalDBRows))
|
if (is_null($this->m_iNumTotalDBRows))
|
||||||
{
|
{
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, 0, 0, true);
|
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, 0, 0, true);
|
||||||
$resQuery = CMDBSource::Query($sSQL);
|
$resQuery = CMDBSource::Query($sSQL);
|
||||||
|
$sOQL = $this->GetPseudoOQL($this->m_oFilter, array(), 0, 0, true);
|
||||||
|
$oKPI->ComputeStats('OQL Query Exec', $sOQL);
|
||||||
if (!$resQuery) return 0;
|
if (!$resQuery) return 0;
|
||||||
|
|
||||||
$aRow = CMDBSource::FetchArray($resQuery);
|
$aRow = CMDBSource::FetchArray($resQuery);
|
||||||
@@ -855,6 +861,42 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
return $this->m_iNumTotalDBRows + count($this->m_aAddedObjects); // Does it fix Trac #887 ??
|
return $this->m_iNumTotalDBRows + count($this->m_aAddedObjects); // Does it fix Trac #887 ??
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \DBSearch $oFilter
|
||||||
|
* @param array $aOrder
|
||||||
|
* @param int $iLimitCount
|
||||||
|
* @param int $iLimitStart
|
||||||
|
* @param bool $bCount
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function GetPseudoOQL($oFilter, $aOrder, $iLimitCount, $iLimitStart, $bCount)
|
||||||
|
{
|
||||||
|
$sOQL = '';
|
||||||
|
if ($bCount) {
|
||||||
|
$sOQL .= 'COUNT ';
|
||||||
|
}
|
||||||
|
$sOQL .= $oFilter->ToOQL();
|
||||||
|
|
||||||
|
if ($iLimitCount > 0) {
|
||||||
|
$sOQL .= ' LIMIT ';
|
||||||
|
if ($iLimitStart > 0) {
|
||||||
|
$sOQL .= "$iLimitStart, ";
|
||||||
|
}
|
||||||
|
$sOQL .= "$iLimitCount";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count($aOrder) > 0) {
|
||||||
|
$sOQL .= ' ORDER BY ';
|
||||||
|
$aOrderBy = [];
|
||||||
|
foreach ($aOrder as $sAttCode => $bAsc) {
|
||||||
|
$aOrderBy[] = $sAttCode.' '.($bAsc ? 'ASC' : 'DESC');
|
||||||
|
}
|
||||||
|
$sOQL .= implode(', ', $aOrderBy);
|
||||||
|
}
|
||||||
|
return $sOQL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the count exceeds a given limit
|
* Check if the count exceeds a given limit
|
||||||
*
|
*
|
||||||
@@ -871,8 +913,11 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
{
|
{
|
||||||
if (is_null($this->m_iNumTotalDBRows))
|
if (is_null($this->m_iNumTotalDBRows))
|
||||||
{
|
{
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, $iLimit + 2, 0, true);
|
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, $iLimit + 2, 0, true);
|
||||||
$resQuery = CMDBSource::Query($sSQL);
|
$resQuery = CMDBSource::Query($sSQL);
|
||||||
|
$sOQL = $this->GetPseudoOQL($this->m_oFilter, array(), $iLimit + 2, 0, true);
|
||||||
|
$oKPI->ComputeStats('OQL Query Exec', $sOQL);
|
||||||
if ($resQuery)
|
if ($resQuery)
|
||||||
{
|
{
|
||||||
$aRow = CMDBSource::FetchArray($resQuery);
|
$aRow = CMDBSource::FetchArray($resQuery);
|
||||||
@@ -883,7 +928,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
{
|
{
|
||||||
$iCount = 0;
|
$iCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$iCount = $this->m_iNumTotalDBRows;
|
$iCount = $this->m_iNumTotalDBRows;
|
||||||
@@ -908,8 +953,11 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
{
|
{
|
||||||
if (is_null($this->m_iNumTotalDBRows))
|
if (is_null($this->m_iNumTotalDBRows))
|
||||||
{
|
{
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, $iLimit + 2, 0, true);
|
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, $iLimit + 2, 0, true);
|
||||||
$resQuery = CMDBSource::Query($sSQL);
|
$resQuery = CMDBSource::Query($sSQL);
|
||||||
|
$sOQL = $this->GetPseudoOQL($this->m_oFilter, array(), $iLimit + 2, 0, true);
|
||||||
|
$oKPI->ComputeStats('OQL Query Exec', $sOQL);
|
||||||
if ($resQuery)
|
if ($resQuery)
|
||||||
{
|
{
|
||||||
$aRow = CMDBSource::FetchArray($resQuery);
|
$aRow = CMDBSource::FetchArray($resQuery);
|
||||||
@@ -920,7 +968,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
|||||||
{
|
{
|
||||||
$iCount = 0;
|
$iCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$iCount = $this->m_iNumTotalDBRows;
|
$iCount = $this->m_iNumTotalDBRows;
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
use Combodo\iTop\Core\Kpi\KpiLogData;
|
||||||
|
use Combodo\iTop\Service\Module\ModuleService;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,6 +32,8 @@ class ExecutionKPI
|
|||||||
static protected $m_bEnabled_Memory = false;
|
static protected $m_bEnabled_Memory = false;
|
||||||
static protected $m_bBlameCaller = false;
|
static protected $m_bBlameCaller = false;
|
||||||
static protected $m_sAllowedUser = '*';
|
static protected $m_sAllowedUser = '*';
|
||||||
|
static protected $m_bReportExtensionsOnly = false;
|
||||||
|
static protected $m_fSlowQueries = 0;
|
||||||
|
|
||||||
static protected $m_aStats = array(); // Recurrent operations
|
static protected $m_aStats = array(); // Recurrent operations
|
||||||
static protected $m_aExecData = array(); // One shot operations
|
static protected $m_aExecData = array(); // One shot operations
|
||||||
@@ -77,14 +81,39 @@ class ExecutionKPI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public function SetReportExtensionsOnly($bReportExtensionsOnly)
|
||||||
|
{
|
||||||
|
self::$m_bReportExtensionsOnly = $bReportExtensionsOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
static public function SetSlowQueries($fSlowQueries)
|
||||||
|
{
|
||||||
|
self::$m_fSlowQueries = $fSlowQueries;
|
||||||
|
}
|
||||||
|
|
||||||
static public function GetDescription()
|
static public function GetDescription()
|
||||||
{
|
{
|
||||||
$aFeatures = array();
|
$aFeatures = array();
|
||||||
if (self::$m_bEnabled_Duration) $aFeatures[] = 'Duration';
|
if (self::$m_bEnabled_Duration) $aFeatures[] = 'Duration';
|
||||||
if (self::$m_bEnabled_Memory) $aFeatures[] = 'Memory usage';
|
if (self::$m_bEnabled_Memory) $aFeatures[] = 'Memory usage';
|
||||||
$sFeatures = implode(', ', $aFeatures);
|
$sFeatures = 'Measures: '.implode(', ', $aFeatures);
|
||||||
$sFor = self::$m_sAllowedUser == '*' ? 'EVERYBODY' : "'".trim(self::$m_sAllowedUser)."'";
|
$sFor = self::$m_sAllowedUser == '*' ? 'EVERYBODY' : "'".trim(self::$m_sAllowedUser)."'";
|
||||||
return "KPI logging is active for $sFor. Measures: $sFeatures";
|
$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";
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function ReportStats()
|
static public function ReportStats()
|
||||||
@@ -92,7 +121,28 @@ class ExecutionKPI
|
|||||||
if (!self::IsEnabled()) return;
|
if (!self::IsEnabled()) return;
|
||||||
|
|
||||||
global $fItopStarted;
|
global $fItopStarted;
|
||||||
|
global $iItopInitialMemory;
|
||||||
$sExecId = microtime(); // id to differentiate the hrefs!
|
$sExecId = microtime(); // id to differentiate the hrefs!
|
||||||
|
$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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self::$m_bReportExtensionsOnly) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$aBeginTimes = array();
|
$aBeginTimes = array();
|
||||||
foreach (self::$m_aExecData as $aOpStats)
|
foreach (self::$m_aExecData as $aOpStats)
|
||||||
@@ -105,7 +155,7 @@ class ExecutionKPI
|
|||||||
|
|
||||||
self::Report("<hr/>");
|
self::Report("<hr/>");
|
||||||
self::Report("<div style=\"background-color: grey; padding: 10px;\">");
|
self::Report("<div style=\"background-color: grey; padding: 10px;\">");
|
||||||
self::Report("<h3><a name=\"".md5($sExecId)."\">KPIs</a> - ".$_SERVER['REQUEST_URI']." (".$_SERVER['REQUEST_METHOD'].")</h3>");
|
self::Report("<h3><a name=\"".md5($sExecId)."\">KPIs</a> - $sRequest</h3>");
|
||||||
self::Report("<p>".date('Y-m-d H:i:s', $fItopStarted)."</p>");
|
self::Report("<p>".date('Y-m-d H:i:s', $fItopStarted)."</p>");
|
||||||
self::Report("<p>log_kpi_user_id: ".UserRights::GetUserId()."</p>");
|
self::Report("<p>log_kpi_user_id: ".UserRights::GetUserId()."</p>");
|
||||||
self::Report("<div>");
|
self::Report("<div>");
|
||||||
@@ -200,8 +250,6 @@ class ExecutionKPI
|
|||||||
|
|
||||||
self::Report("<p><a href=\"#end-".md5($sExecId)."\">Next page stats</a></p>");
|
self::Report("<p><a href=\"#end-".md5($sExecId)."\">Next page stats</a></p>");
|
||||||
|
|
||||||
$fSlowQueries = MetaModel::GetConfig()->Get('log_kpi_slow_queries');
|
|
||||||
|
|
||||||
// Report operation details
|
// Report operation details
|
||||||
foreach (self::$m_aStats as $sOperation => $aOpStats)
|
foreach (self::$m_aStats as $sOperation => $aOpStats)
|
||||||
{
|
{
|
||||||
@@ -245,7 +293,7 @@ class ExecutionKPI
|
|||||||
$sTotalInter = round($fTotalInter, 3);
|
$sTotalInter = round($fTotalInter, 3);
|
||||||
$sMinInter = round($fMinInter, 3);
|
$sMinInter = round($fMinInter, 3);
|
||||||
$sMaxInter = round($fMaxInter, 3);
|
$sMaxInter = round($fMaxInter, 3);
|
||||||
if (($fTotalInter >= $fSlowQueries))
|
if (($fTotalInter >= self::$m_fSlowQueries))
|
||||||
{
|
{
|
||||||
if ($bDisplayHeader)
|
if ($bDisplayHeader)
|
||||||
{
|
{
|
||||||
@@ -271,11 +319,19 @@ class ExecutionKPI
|
|||||||
self::Report('<a name="end-'.md5($sExecId).'"> </a>');
|
self::Report('<a name="end-'.md5($sExecId).'"> </a>');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->ResetCounters();
|
$this->ResetCounters();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the duration since startup, and reset the counter for the next measure
|
// Get the duration since startup, and reset the counter for the next measure
|
||||||
//
|
//
|
||||||
@@ -285,6 +341,8 @@ class ExecutionKPI
|
|||||||
|
|
||||||
$aNewEntry = null;
|
$aNewEntry = null;
|
||||||
|
|
||||||
|
$fStarted = $this->m_fStarted;
|
||||||
|
$fStopped = $this->m_fStarted;
|
||||||
if (self::$m_bEnabled_Duration)
|
if (self::$m_bEnabled_Duration)
|
||||||
{
|
{
|
||||||
$fStopped = MyHelpers::getmicrotime();
|
$fStopped = MyHelpers::getmicrotime();
|
||||||
@@ -297,6 +355,9 @@ class ExecutionKPI
|
|||||||
$this->m_fStarted = $fStopped;
|
$this->m_fStarted = $fStopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$iInitialMemory = is_null($this->m_iInitialMemory) ? 0 : $this->m_iInitialMemory;
|
||||||
|
$iCurrentMemory = 0;
|
||||||
|
$iPeakMemory = 0;
|
||||||
if (self::$m_bEnabled_Memory)
|
if (self::$m_bEnabled_Memory)
|
||||||
{
|
{
|
||||||
$iCurrentMemory = self::memory_get_usage();
|
$iCurrentMemory = self::memory_get_usage();
|
||||||
@@ -306,41 +367,95 @@ class ExecutionKPI
|
|||||||
}
|
}
|
||||||
$aNewEntry['mem_begin'] = $this->m_iInitialMemory;
|
$aNewEntry['mem_begin'] = $this->m_iInitialMemory;
|
||||||
$aNewEntry['mem_end'] = $iCurrentMemory;
|
$aNewEntry['mem_end'] = $iCurrentMemory;
|
||||||
if (function_exists('memory_get_peak_usage'))
|
$iPeakMemory = self::memory_get_peak_usage();
|
||||||
{
|
$aNewEntry['mem_peak'] = $iPeakMemory;
|
||||||
$aNewEntry['mem_peak'] = memory_get_peak_usage();
|
|
||||||
}
|
|
||||||
// Reset for the next operation (if the object is recycled)
|
// Reset for the next operation (if the object is recycled)
|
||||||
$this->m_iInitialMemory = $iCurrentMemory;
|
$this->m_iInitialMemory = $iCurrentMemory;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_null($aNewEntry))
|
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_bReportExtensionsOnly)
|
||||||
{
|
{
|
||||||
self::$m_aExecData[] = $aNewEntry;
|
self::$m_aExecData[] = $aNewEntry;
|
||||||
}
|
}
|
||||||
$this->ResetCounters();
|
$this->ResetCounters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function ComputeStatsForExtension($object, $sMethod)
|
||||||
|
{
|
||||||
|
$sSignature = ModuleService::GetInstance()->GetModuleMethodSignature($object, $sMethod);
|
||||||
|
if (utils::StartsWith($sSignature, '[')) {
|
||||||
|
$this->ComputeStats('Extension', $sSignature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function ComputeStats($sOperation, $sArguments)
|
public function ComputeStats($sOperation, $sArguments)
|
||||||
{
|
{
|
||||||
if (self::$m_bEnabled_Duration)
|
if (self::$m_bEnabled_Duration)
|
||||||
{
|
{
|
||||||
$fStopped = MyHelpers::getmicrotime();
|
$fStopped = MyHelpers::getmicrotime();
|
||||||
$fDuration = $fStopped - $this->m_fStarted;
|
$fDuration = $fStopped - $this->m_fStarted;
|
||||||
if (self::$m_bBlameCaller)
|
$aCallstack = [];
|
||||||
{
|
if (!self::$m_bReportExtensionsOnly) {
|
||||||
self::$m_aStats[$sOperation][$sArguments][] = array(
|
if (self::$m_bBlameCaller) {
|
||||||
'time' => $fDuration,
|
$aCallstack = MyHelpers::get_callstack(1);
|
||||||
'callers' => MyHelpers::get_callstack(1),
|
self::$m_aStats[$sOperation][$sArguments][] = [
|
||||||
);
|
'time' => $fDuration,
|
||||||
}
|
'callers' => $aCallstack,
|
||||||
else
|
];
|
||||||
{
|
} else {
|
||||||
self::$m_aStats[$sOperation][$sArguments][] = array(
|
self::$m_aStats[$sOperation][$sArguments][] = [
|
||||||
'time' => $fDuration
|
'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();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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_STATS,
|
||||||
|
$sOperation,
|
||||||
|
$sArguments,
|
||||||
|
$this->m_fStarted,
|
||||||
|
$fStopped,
|
||||||
|
$sExtension,
|
||||||
|
$iInitialMemory,
|
||||||
|
$iCurrentMemory,
|
||||||
|
$iPeakMemory,
|
||||||
|
$aCallstack);
|
||||||
|
$oExtensionInstance->LogOperation($oKPILogData);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function ResetCounters()
|
protected function ResetCounters()
|
||||||
@@ -370,35 +485,7 @@ class ExecutionKPI
|
|||||||
|
|
||||||
static protected function memory_get_usage()
|
static protected function memory_get_usage()
|
||||||
{
|
{
|
||||||
if (function_exists('memory_get_usage'))
|
return memory_get_usage(true);
|
||||||
{
|
|
||||||
return memory_get_usage(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copied from the PHP manual
|
|
||||||
//
|
|
||||||
//If its Windows
|
|
||||||
//Tested on Win XP Pro SP2. Should work on Win 2003 Server too
|
|
||||||
//Doesn't work for 2000
|
|
||||||
//If you need it to work for 2000 look at http://us2.php.net/manual/en/function.memory-get-usage.php#54642
|
|
||||||
if (substr(PHP_OS,0,3) == 'WIN')
|
|
||||||
{
|
|
||||||
$output = array();
|
|
||||||
exec('tasklist /FI "PID eq ' . getmypid() . '" /FO LIST', $output);
|
|
||||||
|
|
||||||
return preg_replace( '/[\D]/', '', $output[5] ) * 1024;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//We now assume the OS is UNIX
|
|
||||||
//Tested on Mac OS X 10.4.6 and Linux Red Hat Enterprise 4
|
|
||||||
//This should work on most UNIX systems
|
|
||||||
$pid = getmypid();
|
|
||||||
exec("ps -eo%mem,rss,pid | grep $pid", $output);
|
|
||||||
$output = explode(" ", $output[0]);
|
|
||||||
//rss is given in 1024 byte units
|
|
||||||
return $output[1] * 1024;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function memory_get_peak_usage($bRealUsage = false)
|
static public function memory_get_peak_usage($bRealUsage = false)
|
||||||
|
|||||||
@@ -2778,7 +2778,7 @@ abstract class MetaModel
|
|||||||
|
|
||||||
// Build the list of available extensions
|
// Build the list of available extensions
|
||||||
//
|
//
|
||||||
$aInterfaces = array('iApplicationUIExtension', 'iPreferencesExtension', 'iApplicationObjectExtension', 'iLoginFSMExtension', 'iLoginUIExtension', 'iLogoutExtension', 'iQueryModifier', 'iOnClassInitialization', 'iPopupMenuExtension', 'iPageUIExtension', 'iPortalUIExtension', 'ModuleHandlerApiInterface', 'iNewsroomProvider', 'iModuleExtension');
|
$aInterfaces = array('iApplicationUIExtension', 'iPreferencesExtension', 'iApplicationObjectExtension', 'iLoginFSMExtension', 'iLoginUIExtension', 'iLogoutExtension', 'iQueryModifier', 'iOnClassInitialization', 'iPopupMenuExtension', 'iPageUIExtension', 'iPortalUIExtension', 'ModuleHandlerApiInterface', 'iNewsroomProvider', 'iModuleExtension', 'iKPILoggerExtension');
|
||||||
foreach($aInterfaces as $sInterface)
|
foreach($aInterfaces as $sInterface)
|
||||||
{
|
{
|
||||||
self::$m_aExtensionClasses[$sInterface] = array();
|
self::$m_aExtensionClasses[$sInterface] = array();
|
||||||
@@ -6348,7 +6348,9 @@ abstract class MetaModel
|
|||||||
|
|
||||||
ExecutionKPI::EnableDuration(self::$m_oConfig->Get('log_kpi_duration'));
|
ExecutionKPI::EnableDuration(self::$m_oConfig->Get('log_kpi_duration'));
|
||||||
ExecutionKPI::EnableMemory(self::$m_oConfig->Get('log_kpi_memory'));
|
ExecutionKPI::EnableMemory(self::$m_oConfig->Get('log_kpi_memory'));
|
||||||
ExecutionKPI::SetAllowedUser(self::$m_oConfig->Get('log_kpi_user_id'));
|
ExecutionKPI::SetAllowedUser(self::$m_oConfig->Get('log_kpi_user_id'));
|
||||||
|
ExecutionKPI::SetReportExtensionsOnly(self::$m_oConfig->Get('log_kpi_report_to_extensions_only'));
|
||||||
|
ExecutionKPI::SetSlowQueries(self::$m_oConfig->Get('log_kpi_slow_queries'));
|
||||||
|
|
||||||
self::$m_bSkipCheckToWrite = self::$m_oConfig->Get('skip_check_to_write');
|
self::$m_bSkipCheckToWrite = self::$m_oConfig->Get('skip_check_to_write');
|
||||||
self::$m_bSkipCheckExtKeys = self::$m_oConfig->Get('skip_check_ext_keys');
|
self::$m_bSkipCheckExtKeys = self::$m_oConfig->Get('skip_check_ext_keys');
|
||||||
@@ -6485,6 +6487,7 @@ abstract class MetaModel
|
|||||||
|
|
||||||
CMDBSource::InitFromConfig(self::$m_oConfig);
|
CMDBSource::InitFromConfig(self::$m_oConfig);
|
||||||
// Later when timezone implementation is correctly done: CMDBSource::SetTimezone($sDBTimezone);
|
// Later when timezone implementation is correctly done: CMDBSource::SetTimezone($sDBTimezone);
|
||||||
|
ExecutionKPI::InitStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -126,7 +126,9 @@ abstract class Trigger extends cmdbAbstractObject
|
|||||||
$oAction = MetaModel::GetObject('Action', $iActionId);
|
$oAction = MetaModel::GetObject('Action', $iActionId);
|
||||||
if ($oAction->IsActive())
|
if ($oAction->IsActive())
|
||||||
{
|
{
|
||||||
|
$oKPI = new ExecutionKPI();
|
||||||
$oAction->DoExecute($this, $aContextArgs);
|
$oAction->DoExecute($this, $aContextArgs);
|
||||||
|
$oKPI->ComputeStatsForExtension($oAction, 'DoExecute');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,6 @@
|
|||||||
|
|
||||||
// autoload.php @generated by Composer
|
// autoload.php @generated by Composer
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 50600) {
|
|
||||||
echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once __DIR__ . '/composer/autoload_real.php';
|
require_once __DIR__ . '/composer/autoload_real.php';
|
||||||
|
|
||||||
return ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b::getLoader();
|
return ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b::getLoader();
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ class ClassLoader
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string[] Array of classname => path
|
* @return string[] Array of classname => path
|
||||||
* @psalm-return array<string, string>
|
* @psalm-var array<string, string>
|
||||||
*/
|
*/
|
||||||
public function getClassMap()
|
public function getClassMap()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// autoload_classmap.php @generated by Composer
|
// autoload_classmap.php @generated by Composer
|
||||||
|
|
||||||
$vendorDir = dirname(__DIR__);
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
@@ -158,8 +158,10 @@ return array(
|
|||||||
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderGoogle' => $baseDir . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderGoogle.php',
|
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderGoogle' => $baseDir . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderGoogle.php',
|
||||||
'Combodo\\iTop\\Core\\Email\\EmailFactory' => $baseDir . '/sources/Core/Email/EmailFactory.php',
|
'Combodo\\iTop\\Core\\Email\\EmailFactory' => $baseDir . '/sources/Core/Email/EmailFactory.php',
|
||||||
'Combodo\\iTop\\Core\\Email\\iEMail' => $baseDir . '/sources/Core/Email/iEMail.php',
|
'Combodo\\iTop\\Core\\Email\\iEMail' => $baseDir . '/sources/Core/Email/iEMail.php',
|
||||||
|
'Combodo\\iTop\\Core\\Kpi\\KpiLogData' => $baseDir . '/sources/Core/Kpi/KpiLogData.php',
|
||||||
'Combodo\\iTop\\DesignDocument' => $baseDir . '/core/designdocument.class.inc.php',
|
'Combodo\\iTop\\DesignDocument' => $baseDir . '/core/designdocument.class.inc.php',
|
||||||
'Combodo\\iTop\\DesignElement' => $baseDir . '/core/designdocument.class.inc.php',
|
'Combodo\\iTop\\DesignElement' => $baseDir . '/core/designdocument.class.inc.php',
|
||||||
|
'Combodo\\iTop\\Service\\Module\\ModuleService' => $baseDir . '/sources/Service/Module/ModuleService.php',
|
||||||
'Combodo\\iTop\\TwigExtension' => $baseDir . '/application/twigextension.class.inc.php',
|
'Combodo\\iTop\\TwigExtension' => $baseDir . '/application/twigextension.class.inc.php',
|
||||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
'Config' => $baseDir . '/core/config.class.inc.php',
|
'Config' => $baseDir . '/core/config.class.inc.php',
|
||||||
@@ -2712,6 +2714,7 @@ return array(
|
|||||||
'iDBObjectSetIterator' => $baseDir . '/core/dbobjectiterator.php',
|
'iDBObjectSetIterator' => $baseDir . '/core/dbobjectiterator.php',
|
||||||
'iDBObjectURLMaker' => $baseDir . '/application/applicationcontext.class.inc.php',
|
'iDBObjectURLMaker' => $baseDir . '/application/applicationcontext.class.inc.php',
|
||||||
'iDisplay' => $baseDir . '/core/dbobject.class.php',
|
'iDisplay' => $baseDir . '/core/dbobject.class.php',
|
||||||
|
'iKPILoggerExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||||
'iLogFileNameBuilder' => $baseDir . '/core/log.class.inc.php',
|
'iLogFileNameBuilder' => $baseDir . '/core/log.class.inc.php',
|
||||||
'iLoginExtension' => $baseDir . '/application/applicationextension.inc.php',
|
'iLoginExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||||
'iLoginFSMExtension' => $baseDir . '/application/applicationextension.inc.php',
|
'iLoginFSMExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||||
|
|||||||
@@ -2,25 +2,25 @@
|
|||||||
|
|
||||||
// autoload_files.php @generated by Composer
|
// autoload_files.php @generated by Composer
|
||||||
|
|
||||||
$vendorDir = dirname(__DIR__);
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
|
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
|
||||||
|
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||||
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
|
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
|
||||||
'023d27dca8066ef29e6739335ea73bad' => $vendorDir . '/symfony/polyfill-php70/bootstrap.php',
|
'023d27dca8066ef29e6739335ea73bad' => $vendorDir . '/symfony/polyfill-php70/bootstrap.php',
|
||||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
'32dcc8afd4335739640db7d200c1971d' => $vendorDir . '/symfony/polyfill-apcu/bootstrap.php',
|
||||||
|
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||||
|
'bd9634f2d41831496de0d3dfe4c94881' => $vendorDir . '/symfony/polyfill-php56/bootstrap.php',
|
||||||
'7e9bd612cc444b3eed788ebbe46263a0' => $vendorDir . '/laminas/laminas-zendframework-bridge/src/autoload.php',
|
'7e9bd612cc444b3eed788ebbe46263a0' => $vendorDir . '/laminas/laminas-zendframework-bridge/src/autoload.php',
|
||||||
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
|
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
|
||||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
||||||
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
|
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||||
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||||
'bd9634f2d41831496de0d3dfe4c94881' => $vendorDir . '/symfony/polyfill-php56/bootstrap.php',
|
|
||||||
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
|
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
|
||||||
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
|
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
|
||||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
|
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||||
'32dcc8afd4335739640db7d200c1971d' => $vendorDir . '/symfony/polyfill-apcu/bootstrap.php',
|
|
||||||
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
|
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
|
||||||
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
|
||||||
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
|
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// autoload_namespaces.php @generated by Composer
|
// autoload_namespaces.php @generated by Composer
|
||||||
|
|
||||||
$vendorDir = dirname(__DIR__);
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// autoload_psr4.php @generated by Composer
|
// autoload_psr4.php @generated by Composer
|
||||||
|
|
||||||
$vendorDir = dirname(__DIR__);
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
|||||||
@@ -25,20 +25,33 @@ class ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b
|
|||||||
require __DIR__ . '/platform_check.php';
|
require __DIR__ . '/platform_check.php';
|
||||||
|
|
||||||
spl_autoload_register(array('ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b', 'loadClassLoader'), true, true);
|
spl_autoload_register(array('ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b', 'loadClassLoader'), true, true);
|
||||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(\dirname(__FILE__)));
|
||||||
spl_autoload_unregister(array('ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b', 'loadClassLoader'));
|
spl_autoload_unregister(array('ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b', 'loadClassLoader'));
|
||||||
|
|
||||||
$includePaths = require __DIR__ . '/include_paths.php';
|
$includePaths = require __DIR__ . '/include_paths.php';
|
||||||
$includePaths[] = get_include_path();
|
$includePaths[] = get_include_path();
|
||||||
set_include_path(implode(PATH_SEPARATOR, $includePaths));
|
set_include_path(implode(PATH_SEPARATOR, $includePaths));
|
||||||
|
|
||||||
require __DIR__ . '/autoload_static.php';
|
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||||
call_user_func(\Composer\Autoload\ComposerStaticInit0018331147de7601e7552f7da8e3bb8b::getInitializer($loader));
|
if ($useStaticLoader) {
|
||||||
|
require __DIR__ . '/autoload_static.php';
|
||||||
|
|
||||||
|
call_user_func(\Composer\Autoload\ComposerStaticInit0018331147de7601e7552f7da8e3bb8b::getInitializer($loader));
|
||||||
|
} else {
|
||||||
|
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||||
|
if ($classMap) {
|
||||||
|
$loader->addClassMap($classMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$loader->setClassMapAuthoritative(true);
|
$loader->setClassMapAuthoritative(true);
|
||||||
$loader->register(true);
|
$loader->register(true);
|
||||||
|
|
||||||
$includeFiles = \Composer\Autoload\ComposerStaticInit0018331147de7601e7552f7da8e3bb8b::$files;
|
if ($useStaticLoader) {
|
||||||
|
$includeFiles = Composer\Autoload\ComposerStaticInit0018331147de7601e7552f7da8e3bb8b::$files;
|
||||||
|
} else {
|
||||||
|
$includeFiles = require __DIR__ . '/autoload_files.php';
|
||||||
|
}
|
||||||
foreach ($includeFiles as $fileIdentifier => $file) {
|
foreach ($includeFiles as $fileIdentifier => $file) {
|
||||||
composerRequire0018331147de7601e7552f7da8e3bb8b($fileIdentifier, $file);
|
composerRequire0018331147de7601e7552f7da8e3bb8b($fileIdentifier, $file);
|
||||||
}
|
}
|
||||||
@@ -47,16 +60,11 @@ class ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $fileIdentifier
|
|
||||||
* @param string $file
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function composerRequire0018331147de7601e7552f7da8e3bb8b($fileIdentifier, $file)
|
function composerRequire0018331147de7601e7552f7da8e3bb8b($fileIdentifier, $file)
|
||||||
{
|
{
|
||||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
|
||||||
|
|
||||||
require $file;
|
require $file;
|
||||||
|
|
||||||
|
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,21 +8,21 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
|||||||
{
|
{
|
||||||
public static $files = array (
|
public static $files = array (
|
||||||
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
|
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
|
||||||
|
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||||
'5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
|
'5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
|
||||||
'023d27dca8066ef29e6739335ea73bad' => __DIR__ . '/..' . '/symfony/polyfill-php70/bootstrap.php',
|
'023d27dca8066ef29e6739335ea73bad' => __DIR__ . '/..' . '/symfony/polyfill-php70/bootstrap.php',
|
||||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
'32dcc8afd4335739640db7d200c1971d' => __DIR__ . '/..' . '/symfony/polyfill-apcu/bootstrap.php',
|
||||||
|
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||||
|
'bd9634f2d41831496de0d3dfe4c94881' => __DIR__ . '/..' . '/symfony/polyfill-php56/bootstrap.php',
|
||||||
'7e9bd612cc444b3eed788ebbe46263a0' => __DIR__ . '/..' . '/laminas/laminas-zendframework-bridge/src/autoload.php',
|
'7e9bd612cc444b3eed788ebbe46263a0' => __DIR__ . '/..' . '/laminas/laminas-zendframework-bridge/src/autoload.php',
|
||||||
'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
|
'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
|
||||||
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
||||||
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
|
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||||
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||||
'bd9634f2d41831496de0d3dfe4c94881' => __DIR__ . '/..' . '/symfony/polyfill-php56/bootstrap.php',
|
|
||||||
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
|
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
|
||||||
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
|
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
|
||||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
|
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||||
'32dcc8afd4335739640db7d200c1971d' => __DIR__ . '/..' . '/symfony/polyfill-apcu/bootstrap.php',
|
|
||||||
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
|
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
|
||||||
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
|
|
||||||
'2c102faa651ef8ea5874edb585946bce' => __DIR__ . '/..' . '/swiftmailer/swiftmailer/lib/swift_required.php',
|
'2c102faa651ef8ea5874edb585946bce' => __DIR__ . '/..' . '/swiftmailer/swiftmailer/lib/swift_required.php',
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -526,8 +526,10 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
|||||||
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderGoogle' => __DIR__ . '/../..' . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderGoogle.php',
|
'Combodo\\iTop\\Core\\Authentication\\Client\\OAuth\\OAuthClientProviderGoogle' => __DIR__ . '/../..' . '/sources/Core/Authentication/Client/OAuth/OAuthClientProviderGoogle.php',
|
||||||
'Combodo\\iTop\\Core\\Email\\EmailFactory' => __DIR__ . '/../..' . '/sources/Core/Email/EmailFactory.php',
|
'Combodo\\iTop\\Core\\Email\\EmailFactory' => __DIR__ . '/../..' . '/sources/Core/Email/EmailFactory.php',
|
||||||
'Combodo\\iTop\\Core\\Email\\iEMail' => __DIR__ . '/../..' . '/sources/Core/Email/iEMail.php',
|
'Combodo\\iTop\\Core\\Email\\iEMail' => __DIR__ . '/../..' . '/sources/Core/Email/iEMail.php',
|
||||||
|
'Combodo\\iTop\\Core\\Kpi\\KpiLogData' => __DIR__ . '/../..' . '/sources/Core/Kpi/KpiLogData.php',
|
||||||
'Combodo\\iTop\\DesignDocument' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
'Combodo\\iTop\\DesignDocument' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
||||||
'Combodo\\iTop\\DesignElement' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
'Combodo\\iTop\\DesignElement' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
||||||
|
'Combodo\\iTop\\Service\\Module\\ModuleService' => __DIR__ . '/../..' . '/sources/Service/Module/ModuleService.php',
|
||||||
'Combodo\\iTop\\TwigExtension' => __DIR__ . '/../..' . '/application/twigextension.class.inc.php',
|
'Combodo\\iTop\\TwigExtension' => __DIR__ . '/../..' . '/application/twigextension.class.inc.php',
|
||||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
'Config' => __DIR__ . '/../..' . '/core/config.class.inc.php',
|
'Config' => __DIR__ . '/../..' . '/core/config.class.inc.php',
|
||||||
@@ -3080,6 +3082,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
|||||||
'iDBObjectSetIterator' => __DIR__ . '/../..' . '/core/dbobjectiterator.php',
|
'iDBObjectSetIterator' => __DIR__ . '/../..' . '/core/dbobjectiterator.php',
|
||||||
'iDBObjectURLMaker' => __DIR__ . '/../..' . '/application/applicationcontext.class.inc.php',
|
'iDBObjectURLMaker' => __DIR__ . '/../..' . '/application/applicationcontext.class.inc.php',
|
||||||
'iDisplay' => __DIR__ . '/../..' . '/core/dbobject.class.php',
|
'iDisplay' => __DIR__ . '/../..' . '/core/dbobject.class.php',
|
||||||
|
'iKPILoggerExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||||
'iLogFileNameBuilder' => __DIR__ . '/../..' . '/core/log.class.inc.php',
|
'iLogFileNameBuilder' => __DIR__ . '/../..' . '/core/log.class.inc.php',
|
||||||
'iLoginExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
'iLoginExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||||
'iLoginFSMExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
'iLoginFSMExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
// include_paths.php @generated by Composer
|
// include_paths.php @generated by Composer
|
||||||
|
|
||||||
$vendorDir = dirname(__DIR__);
|
$vendorDir = dirname(dirname(__FILE__));
|
||||||
$baseDir = dirname($vendorDir);
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
# Apache 2.4
|
|
||||||
<ifModule mod_authz_core.c>
|
|
||||||
Require all denied
|
|
||||||
</ifModule>
|
|
||||||
|
|
||||||
# Apache 2.2
|
|
||||||
<ifModule !mod_authz_core.c>
|
|
||||||
deny from all
|
|
||||||
Satisfy All
|
|
||||||
</ifModule>
|
|
||||||
|
|
||||||
# Apache 2.2 and 2.4
|
|
||||||
IndexIgnore *
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
<?php
|
|
||||||
echo 'Access denied';
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<configuration>
|
|
||||||
<system.webServer>
|
|
||||||
<security>
|
|
||||||
<requestFiltering>
|
|
||||||
<fileExtensions applyToWebDAV="false" allowUnlisted="false"></fileExtensions>
|
|
||||||
</requestFiltering>
|
|
||||||
<authorization>
|
|
||||||
<deny users="*" /> <!-- Denies all users -->
|
|
||||||
</authorization>
|
|
||||||
</security>
|
|
||||||
</system.webServer>
|
|
||||||
</configuration>
|
|
||||||
125
sources/Core/Kpi/KpiLogData.php
Normal file
125
sources/Core/Kpi/KpiLogData.php
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Core\Kpi;
|
||||||
|
|
||||||
|
class KpiLogData
|
||||||
|
{
|
||||||
|
const TYPE_REPORT = 'report';
|
||||||
|
const TYPE_STATS = 'stats';
|
||||||
|
const TYPE_REQUEST = 'request';
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
public $sType;
|
||||||
|
/** @var string */
|
||||||
|
public $sOperation;
|
||||||
|
/** @var string */
|
||||||
|
public $sArguments;
|
||||||
|
/** @var float */
|
||||||
|
public $fStartTime;
|
||||||
|
/** @var float */
|
||||||
|
public $fStopTime;
|
||||||
|
/** @var string */
|
||||||
|
public $sExtension;
|
||||||
|
/** @var int */
|
||||||
|
public $iInitialMemory;
|
||||||
|
/** @var int */
|
||||||
|
public $iCurrentMemory;
|
||||||
|
/** @var int */
|
||||||
|
public $iPeakMemory;
|
||||||
|
/** @var array */
|
||||||
|
public $aData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sType
|
||||||
|
* @param string $sOperation
|
||||||
|
* @param string $sArguments
|
||||||
|
* @param float $fStartTime
|
||||||
|
* @param float $fStopTime
|
||||||
|
* @param string $sExtension
|
||||||
|
* @param int $iInitialMemory
|
||||||
|
* @param int $iCurrentMemory
|
||||||
|
* @param array $aData
|
||||||
|
*/
|
||||||
|
public function __construct($sType, $sOperation, $sArguments, $fStartTime, $fStopTime, $sExtension, $iInitialMemory = 0, $iCurrentMemory = 0, $iPeakMemory = 0, $aData = [])
|
||||||
|
{
|
||||||
|
$this->sType = $sType;
|
||||||
|
$this->sOperation = $sOperation;
|
||||||
|
$this->sArguments = @iconv(mb_detect_encoding($sArguments, mb_detect_order(), true), 'UTF-8', $sArguments);
|
||||||
|
$this->fStartTime = $fStartTime;
|
||||||
|
$this->fStopTime = $fStopTime;
|
||||||
|
$this->sExtension = $sExtension;
|
||||||
|
$this->iInitialMemory = $iInitialMemory;
|
||||||
|
$this->iCurrentMemory = $iCurrentMemory;
|
||||||
|
$this->iPeakMemory = $iPeakMemory;
|
||||||
|
$this->aData = $aData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the CSV Header
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function GetCSVHeader()
|
||||||
|
{
|
||||||
|
return "Type,Operation,Arguments,StartTime,StopTime,Duration,Extension,InitialMemory,CurrentMemory,PeakMemory";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the CSV line for the values
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetCSV()
|
||||||
|
{
|
||||||
|
$fDuration = sprintf('%01.4f', $this->fStopTime - $this->fStartTime);
|
||||||
|
$sType = $this->RemoveQuotes($this->sType);
|
||||||
|
$sOperation = $this->RemoveQuotes($this->sOperation);
|
||||||
|
$sArguments = $this->RemoveQuotes($this->sArguments);
|
||||||
|
$sExtension = $this->RemoveQuotes($this->sExtension);
|
||||||
|
return "\"$sType\",\"$sOperation\",\"$sArguments\",$this->fStartTime,$this->fStopTime,$fDuration,\"$sExtension\",$this->iInitialMemory,$this->iCurrentMemory,$this->iPeakMemory";
|
||||||
|
}
|
||||||
|
|
||||||
|
private function RemoveQuotes(string $sEntry): string
|
||||||
|
{
|
||||||
|
return str_replace('"', "'", $sEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param \Combodo\iTop\Core\Kpi\KpiLogData $oOther
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*/
|
||||||
|
public function Compare(KpiLogData $oOther): float
|
||||||
|
{
|
||||||
|
if ($oOther->fStartTime > $this->fStartTime) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Contains(KpiLogData $oOther): bool
|
||||||
|
{
|
||||||
|
if ($oOther->fStartTime < $this->fStartTime) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($oOther->fStartTime > $this->fStopTime) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return "$this->sType:$this->sOperation:$this->sArguments";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetUUID(): string
|
||||||
|
{
|
||||||
|
return sha1($this->__toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
214
sources/Service/Module/ModuleService.php
Normal file
214
sources/Service/Module/ModuleService.php
Normal file
@@ -0,0 +1,214 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||||
|
* @license http://opensource.org/licenses/AGPL-3.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Combodo\iTop\Service\Module;
|
||||||
|
|
||||||
|
use MetaModel;
|
||||||
|
use ReflectionClass;
|
||||||
|
use ReflectionMethod;
|
||||||
|
use utils;
|
||||||
|
|
||||||
|
class ModuleService
|
||||||
|
{
|
||||||
|
/** @var ModuleService */
|
||||||
|
private static $oInstance;
|
||||||
|
|
||||||
|
private function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function GetInstance(): ModuleService
|
||||||
|
{
|
||||||
|
if (!isset(static::$oInstance)) {
|
||||||
|
static::$oInstance = new ModuleService();
|
||||||
|
}
|
||||||
|
|
||||||
|
return static::$oInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a "signature" of the method of an extension in the form of: "[module-name] class::method()"
|
||||||
|
*
|
||||||
|
* @param object|string $object Object or class
|
||||||
|
* @param string $sMethod
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws \ReflectionException
|
||||||
|
*/
|
||||||
|
public function GetModuleMethodSignature($object, string $sMethod): string
|
||||||
|
{
|
||||||
|
$sSignature = '';
|
||||||
|
$oReflectionMethod = new ReflectionMethod($object, $sMethod);
|
||||||
|
$oReflectionClass = $oReflectionMethod->getDeclaringClass();
|
||||||
|
$sExtension = $this->GetModuleNameFromObject($oReflectionClass->getName());
|
||||||
|
if (strlen($sExtension) !== 0) {
|
||||||
|
$sSignature .= '['.$sExtension.'] ';
|
||||||
|
}
|
||||||
|
$sSignature .= $oReflectionClass->getShortName().'::'.$sMethod.'()';
|
||||||
|
|
||||||
|
return $sSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the module name from an object or class
|
||||||
|
*
|
||||||
|
* @param object|string $object
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws \ReflectionException
|
||||||
|
*/
|
||||||
|
public function GetModuleNameFromObject($object): string
|
||||||
|
{
|
||||||
|
$oReflectionClass = new ReflectionClass($object);
|
||||||
|
$sPath = str_replace('\\', '/', $oReflectionClass->getFileName());
|
||||||
|
$sPattern = str_replace('\\', '/', '@'.APPROOT.'env-'.utils::GetCurrentEnvironment()).'/(?<ext>.+)/@U';
|
||||||
|
if (preg_match($sPattern, $sPath, $aMatches) !== false) {
|
||||||
|
if (isset($aMatches['ext'])) {
|
||||||
|
return $aMatches['ext'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **Warning** : returned result can be invalid as we're using backtrace to find the module dir name
|
||||||
|
*
|
||||||
|
* @param int $iCallDepth The depth of the module in the callstack. Zero when called directly from within the module
|
||||||
|
*
|
||||||
|
* @return string the relative (to MODULESROOT) path of the root directory of the module containing the file where the call to
|
||||||
|
* this function is made
|
||||||
|
* or an empty string if no such module is found (or not called within a module file)
|
||||||
|
*
|
||||||
|
* @uses \debug_backtrace()
|
||||||
|
*/
|
||||||
|
public function GetCurrentModuleDir(int $iCallDepth): string
|
||||||
|
{
|
||||||
|
$sCurrentModuleDir = '';
|
||||||
|
$aCallStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||||
|
$sCallerFile = realpath($aCallStack[$iCallDepth]['file']);
|
||||||
|
|
||||||
|
foreach(GetModulesInfo() as $sModuleName => $aInfo)
|
||||||
|
{
|
||||||
|
if ($aInfo['root_dir'] !== '')
|
||||||
|
{
|
||||||
|
$sRootDir = realpath(APPROOT.$aInfo['root_dir']);
|
||||||
|
|
||||||
|
if(substr($sCallerFile, 0, strlen($sRootDir)) === $sRootDir)
|
||||||
|
{
|
||||||
|
$sCurrentModuleDir = basename($sRootDir);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $sCurrentModuleDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* **Warning** : as this method uses {@see GetCurrentModuleDir} it produces hazardous results.
|
||||||
|
* You should better uses directly {@see GetAbsoluteUrlModulesRoot} and add the module dir name yourself ! See N°4573
|
||||||
|
*
|
||||||
|
* @return string the base URL for all files in the current module from which this method is called
|
||||||
|
* or an empty string if no such module is found (or not called within a module file)
|
||||||
|
* @throws \Exception
|
||||||
|
*
|
||||||
|
* @uses GetCurrentModuleDir
|
||||||
|
*/
|
||||||
|
public function GetCurrentModuleUrl(): string
|
||||||
|
{
|
||||||
|
$sDir = $this->GetCurrentModuleDir(1);
|
||||||
|
if ( $sDir !== '')
|
||||||
|
{
|
||||||
|
return utils::GetAbsoluteUrlModulesRoot().'/'.$sDir;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sProperty The name of the property to retrieve
|
||||||
|
* @param mixed $defaultValue
|
||||||
|
*
|
||||||
|
* @return mixed the value of a given setting for the current module
|
||||||
|
*/
|
||||||
|
public function GetCurrentModuleSetting(string $sProperty, $defaultValue = null)
|
||||||
|
{
|
||||||
|
$sModuleName = $this->GetCurrentModuleName(1);
|
||||||
|
return MetaModel::GetModuleSetting($sModuleName, $sProperty, $defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sModuleName
|
||||||
|
*
|
||||||
|
* @return string|NULL compiled version of a given module, as it was seen by the compiler
|
||||||
|
*/
|
||||||
|
public function GetCompiledModuleVersion(string $sModuleName): ?string
|
||||||
|
{
|
||||||
|
$aModulesInfo = GetModulesInfo();
|
||||||
|
if (array_key_exists($sModuleName, $aModulesInfo))
|
||||||
|
{
|
||||||
|
return $aModulesInfo[$sModuleName]['version'];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the module containing the file where the call to this function is made
|
||||||
|
* or an empty string if no such module is found (or not called within a module file)
|
||||||
|
*
|
||||||
|
* @param int $iCallDepth The depth of the module in the callstack. Zero when called directly from within the module
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function GetCurrentModuleName(int $iCallDepth = 0): string
|
||||||
|
{
|
||||||
|
$sCurrentModuleName = '';
|
||||||
|
$aCallStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||||
|
$sCallerFile = realpath($aCallStack[$iCallDepth]['file']);
|
||||||
|
|
||||||
|
return $this->GetModuleNameFromPath($sCallerFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function GetModuleNameFromPath($sPath)
|
||||||
|
{
|
||||||
|
foreach (GetModulesInfo() as $sModuleName => $aInfo) {
|
||||||
|
if ($aInfo['root_dir'] !== '') {
|
||||||
|
$sRootDir = realpath(APPROOT.$aInfo['root_dir']);
|
||||||
|
if (substr($sPath, 0, strlen($sRootDir)) === $sRootDir) {
|
||||||
|
|
||||||
|
return $sModuleName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the extension code from the call stack.
|
||||||
|
* Scan the call stack until a module is found.
|
||||||
|
*
|
||||||
|
* @param int $iLevelsToIgnore
|
||||||
|
*
|
||||||
|
* @return string module name
|
||||||
|
*/
|
||||||
|
public function GetModuleNameFromCallStack(int $iLevelsToIgnore = 0): string
|
||||||
|
{
|
||||||
|
$aCallStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||||
|
$aCallStack = array_slice($aCallStack, $iLevelsToIgnore);
|
||||||
|
|
||||||
|
foreach ($aCallStack as $aCallInfo) {
|
||||||
|
$sFile = realpath(empty($aCallInfo['file']) ? '' : $aCallInfo['file']);
|
||||||
|
|
||||||
|
$sModuleName = $this->GetModuleNameFromPath($sFile);
|
||||||
|
if (strlen($sModuleName) > 0) {
|
||||||
|
return $sModuleName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user