mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-17 01:14:14 +01:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5475b9fbbe | ||
|
|
6f8e7c7002 | ||
|
|
bc7c1b4744 | ||
|
|
4d8246c4d8 | ||
|
|
5c61d725e1 | ||
|
|
2c4cad4dac | ||
|
|
da45651121 | ||
|
|
d388ce9a06 | ||
|
|
47e71d8838 | ||
|
|
2b5973ec67 | ||
|
|
78396d8e4a | ||
|
|
9afc22bd8f | ||
|
|
264a8cd70a | ||
|
|
aa1834170b | ||
|
|
f94d67ab35 | ||
|
|
3048c8c41f | ||
|
|
246e4a9f50 |
@@ -1857,4 +1857,28 @@ class RestUtils
|
||||
interface iModuleExtension
|
||||
{
|
||||
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 */
|
||||
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;
|
||||
@@ -4020,13 +4022,16 @@ EOF
|
||||
|
||||
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.)
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||
{
|
||||
$oKPI = new ExecutionKPI();
|
||||
$oExtensionInstance->OnDBInsert($oNewObj, self::GetCurrentChange());
|
||||
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBInsert');
|
||||
}
|
||||
|
||||
return $oNewObj;
|
||||
@@ -4054,7 +4059,9 @@ EOF
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach (MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||
{
|
||||
$oKPI = new ExecutionKPI();
|
||||
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
|
||||
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBUpdate');
|
||||
}
|
||||
}
|
||||
catch (Exception $e)
|
||||
@@ -4100,7 +4107,9 @@ EOF
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||
{
|
||||
$oKPI = new ExecutionKPI();
|
||||
$oExtensionInstance->OnDBDelete($this, self::GetCurrentChange());
|
||||
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBDelete');
|
||||
}
|
||||
|
||||
return parent::DBDeleteTracked_Internal($oDeletionPlan);
|
||||
@@ -4118,7 +4127,10 @@ EOF
|
||||
/** @var \iApplicationObjectExtension $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;
|
||||
}
|
||||
@@ -4162,7 +4174,9 @@ EOF
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||
{
|
||||
$oKPI = new ExecutionKPI();
|
||||
$aNewIssues = $oExtensionInstance->OnCheckToWrite($this);
|
||||
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnCheckToWrite');
|
||||
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);
|
||||
@@ -4210,7 +4224,9 @@ EOF
|
||||
/** @var \iApplicationObjectExtension $oExtensionInstance */
|
||||
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
|
||||
{
|
||||
$oKPI = new ExecutionKPI();
|
||||
$aNewIssues = $oExtensionInstance->OnCheckToDelete($this);
|
||||
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnCheckToDelete');
|
||||
if (is_array($aNewIssues) && count($aNewIssues) > 0)
|
||||
{
|
||||
$this->m_aDeleteIssues = array_merge($this->m_aDeleteIssues, $aNewIssues);
|
||||
@@ -4722,7 +4738,7 @@ EOF
|
||||
$bResult = (count($aErrors) == 0);
|
||||
if ($bResult)
|
||||
{
|
||||
list($bResult, $aErrors) = $oObj->CheckToWrite();
|
||||
[$bResult, $aErrors] = $oObj->CheckToWrite();
|
||||
}
|
||||
if ($bPreview)
|
||||
{
|
||||
|
||||
@@ -91,4 +91,10 @@ else
|
||||
$_SESSION['itop_env'] = ITOP_DEFAULT_ENV;
|
||||
}
|
||||
$sConfigFile = APPCONF.$sEnv.'/'.ITOP_CONFIG_FILE;
|
||||
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
|
||||
try {
|
||||
MetaModel::Startup($sConfigFile, false /* $bModelOnly */, $bAllowCache, false /* $bTraceSourceFiles */, $sEnv);
|
||||
}
|
||||
catch (MySQLException $e) {
|
||||
IssueLog::Debug($e->getMessage());
|
||||
throw new MySQLException('Could not connect to the DB server', []);
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Service\Module\ModuleService;
|
||||
use ScssPhp\ScssPhp\Compiler;
|
||||
|
||||
|
||||
@@ -1946,24 +1947,7 @@ class utils
|
||||
*/
|
||||
public static function GetCurrentModuleName($iCallDepth = 0)
|
||||
{
|
||||
$sCurrentModuleName = '';
|
||||
$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;
|
||||
return ModuleService::GetInstance()->GetCurrentModuleName($iCallDepth + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1979,24 +1963,7 @@ class utils
|
||||
*/
|
||||
public static function GetCurrentModuleDir($iCallDepth)
|
||||
{
|
||||
$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;
|
||||
return ModuleService::GetInstance()->GetCurrentModuleDir($iCallDepth);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2011,12 +1978,7 @@ class utils
|
||||
*/
|
||||
public static function GetCurrentModuleUrl()
|
||||
{
|
||||
$sDir = static::GetCurrentModuleDir(1);
|
||||
if ( $sDir !== '')
|
||||
{
|
||||
return static::GetAbsoluteUrlModulesRoot().'/'.$sDir;
|
||||
}
|
||||
return '';
|
||||
return ModuleService::GetInstance()->GetCurrentModuleUrl(1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2026,8 +1988,7 @@ class utils
|
||||
*/
|
||||
public static function GetCurrentModuleSetting($sProperty, $defaultvalue = null)
|
||||
{
|
||||
$sModuleName = static::GetCurrentModuleName(1);
|
||||
return MetaModel::GetModuleSetting($sModuleName, $sProperty, $defaultvalue);
|
||||
return ModuleService::GetInstance()->GetCurrentModuleSetting($sProperty, $defaultvalue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2036,12 +1997,7 @@ class utils
|
||||
*/
|
||||
public static function GetCompiledModuleVersion($sModuleName)
|
||||
{
|
||||
$aModulesInfo = GetModulesInfo();
|
||||
if (array_key_exists($sModuleName, $aModulesInfo))
|
||||
{
|
||||
return $aModulesInfo[$sModuleName]['version'];
|
||||
}
|
||||
return null;
|
||||
return ModuleService::GetInstance()->GetCompiledModuleVersion($sModuleName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2505,4 +2461,5 @@ class utils
|
||||
return (substr(PHP_OS,0,3) === 'WIN');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -22,14 +22,8 @@ define('ITOP_DEFAULT_ENV', 'production');
|
||||
define('MAINTENANCE_MODE_FILE', APPROOT.'data/.maintenance');
|
||||
define('READONLY_MODE_FILE', APPROOT.'data/.readonly');
|
||||
|
||||
if (function_exists('microtime'))
|
||||
{
|
||||
$fItopStarted = microtime(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$fItopStarted = 1000 * time();
|
||||
}
|
||||
$fItopStarted = microtime(true);
|
||||
$iItopInitialMemory = memory_get_usage(true);
|
||||
|
||||
if (! isset($GLOBALS['bBypassAutoload']) || $GLOBALS['bBypassAutoload'] == false)
|
||||
{
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
"sources/application",
|
||||
"sources/Composer",
|
||||
"sources/Controller",
|
||||
"sources/Service",
|
||||
"sources/Core"
|
||||
],
|
||||
"exclude-from-classmap": [
|
||||
|
||||
@@ -67,8 +67,7 @@ class MyHelpers
|
||||
// format sss.mmmuuupppnnn
|
||||
public static function getmicrotime()
|
||||
{
|
||||
list($usec, $sec) = explode(" ",microtime());
|
||||
return ((float)$usec + (float)$sec);
|
||||
return microtime(true);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -420,6 +419,7 @@ class MyHelpers
|
||||
//}
|
||||
return $sOutput;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -524,5 +524,3 @@ class Str
|
||||
return (strtolower($sString) == $sString);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -731,8 +731,9 @@ class CMDBSource
|
||||
{
|
||||
self::LogDeadLock($e);
|
||||
throw new MySQLException('Failed to issue SQL query', array('query' => $sSql, $e));
|
||||
}
|
||||
$oKPI->ComputeStats('Query exec (mySQL)', $sSql);
|
||||
} finally {
|
||||
$oKPI->ComputeStats('Query exec (mySQL)', $sSql);
|
||||
}
|
||||
if ($oResult === false)
|
||||
{
|
||||
$aContext = array('query' => $sSql);
|
||||
|
||||
@@ -963,6 +963,14 @@ class Config
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'log_kpi_generate_legacy_report' => array(
|
||||
'type' => 'bool',
|
||||
'description' => 'Generate the legacy KPI report (kpi.html)',
|
||||
'default' => true,
|
||||
'value' => '',
|
||||
'source_of_value' => '',
|
||||
'show_in_conf_sample' => false,
|
||||
),
|
||||
'max_linkset_output' => array(
|
||||
'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.',
|
||||
|
||||
@@ -188,8 +188,8 @@ final class ItopCounter
|
||||
|
||||
if (!$hDBLink)
|
||||
{
|
||||
throw new Exception("Could not connect to the DB server (host=$sDBHost, user=$sDBUser): ".mysqli_connect_error().' (mysql errno: '.mysqli_connect_errno().')');
|
||||
}
|
||||
throw new MySQLException('Could not connect to the DB server '.mysqli_connect_error().' (mysql errno: '.mysqli_connect_errno(), array('host' => $sDBHost, 'user' => $sDBUser));
|
||||
}
|
||||
|
||||
return $hDBLink;
|
||||
}
|
||||
|
||||
@@ -2225,7 +2225,7 @@ abstract class DBObject implements iDisplay
|
||||
|
||||
$oKPI = new ExecutionKPI();
|
||||
$this->DoCheckToWrite();
|
||||
$oKPI->ComputeStats('CheckToWrite', get_class($this));
|
||||
$oKPI->ComputeStatsForExtension($this, 'DoCheckToWrite');
|
||||
if (count($this->m_aCheckIssues) == 0)
|
||||
{
|
||||
$this->m_bCheckStatus = true;
|
||||
@@ -2693,8 +2693,12 @@ abstract class DBObject implements iDisplay
|
||||
$sRootClass = MetaModel::GetRootClass($sClass);
|
||||
|
||||
// Ensure the update of the values (we are accessing the data directly)
|
||||
$oKPI = new ExecutionKPI();
|
||||
$this->DoComputeValues();
|
||||
$oKPI->ComputeStatsForExtension($this, 'DoComputeValues');
|
||||
$oKPI = new ExecutionKPI();
|
||||
$this->OnInsert();
|
||||
$oKPI->ComputeStatsForExtension($this, 'OnInsert');
|
||||
|
||||
if ($this->m_iKey < 0)
|
||||
{
|
||||
@@ -2712,7 +2716,7 @@ abstract class DBObject implements iDisplay
|
||||
}
|
||||
|
||||
// Ultimate check - ensure DB integrity
|
||||
list($bRes, $aIssues) = $this->CheckToWrite();
|
||||
[$bRes, $aIssues] = $this->CheckToWrite();
|
||||
if (!$bRes)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
$oKPI = new ExecutionKPI();
|
||||
$this->AfterInsert();
|
||||
$oKPI->ComputeStatsForExtension($this, 'AfterInsert');
|
||||
|
||||
// Activate any existing trigger
|
||||
$sClass = get_class($this);
|
||||
@@ -3094,8 +3100,11 @@ abstract class DBObject implements iDisplay
|
||||
|
||||
try
|
||||
{
|
||||
$oKPI = new ExecutionKPI();
|
||||
$this->DoComputeValues();
|
||||
// Stop watches
|
||||
$oKPI->ComputeStatsForExtension($this, 'DoComputeValues');
|
||||
|
||||
// Stop watches
|
||||
$sState = $this->GetState();
|
||||
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();
|
||||
if (count($aChanges) == 0)
|
||||
@@ -3126,7 +3137,7 @@ abstract class DBObject implements iDisplay
|
||||
}
|
||||
|
||||
// Ultimate check - ensure DB integrity
|
||||
list($bRes, $aIssues) = $this->CheckToWrite();
|
||||
[$bRes, $aIssues] = $this->CheckToWrite();
|
||||
if (!$bRes)
|
||||
{
|
||||
throw new CoreCannotSaveObjectException(array(
|
||||
@@ -3326,7 +3337,9 @@ abstract class DBObject implements iDisplay
|
||||
|
||||
try
|
||||
{
|
||||
$this->AfterUpdate();
|
||||
$oKPI = new ExecutionKPI();
|
||||
$this->AfterUpdate();
|
||||
$oKPI->ComputeStatsForExtension($this, 'AfterUpdate');
|
||||
|
||||
// Reload to get the external attributes
|
||||
if ($bHasANewExternalKeyValue)
|
||||
|
||||
@@ -763,7 +763,10 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
|
||||
try
|
||||
{
|
||||
$oKPI = new ExecutionKPI();
|
||||
$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)
|
||||
{
|
||||
// 1116 = ER_TOO_MANY_TABLES
|
||||
@@ -843,8 +846,11 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
{
|
||||
if (is_null($this->m_iNumTotalDBRows))
|
||||
{
|
||||
$oKPI = new ExecutionKPI();
|
||||
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, 0, 0, true);
|
||||
$resQuery = CMDBSource::Query($sSQL);
|
||||
$sOQL = $this->GetPseudoOQL($this->m_oFilter, array(), 0, 0, true);
|
||||
$oKPI->ComputeStats('OQL Query Exec', $sOQL);
|
||||
if (!$resQuery) return 0;
|
||||
|
||||
$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 ??
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
@@ -871,8 +913,11 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
{
|
||||
if (is_null($this->m_iNumTotalDBRows))
|
||||
{
|
||||
$oKPI = new ExecutionKPI();
|
||||
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, $iLimit + 2, 0, true);
|
||||
$resQuery = CMDBSource::Query($sSQL);
|
||||
$sOQL = $this->GetPseudoOQL($this->m_oFilter, array(), $iLimit + 2, 0, true);
|
||||
$oKPI->ComputeStats('OQL Query Exec', $sOQL);
|
||||
if ($resQuery)
|
||||
{
|
||||
$aRow = CMDBSource::FetchArray($resQuery);
|
||||
@@ -883,7 +928,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
{
|
||||
$iCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iCount = $this->m_iNumTotalDBRows;
|
||||
@@ -908,8 +953,11 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
{
|
||||
if (is_null($this->m_iNumTotalDBRows))
|
||||
{
|
||||
$oKPI = new ExecutionKPI();
|
||||
$sSQL = $this->m_oFilter->MakeSelectQuery(array(), $this->m_aArgs, null, null, $iLimit + 2, 0, true);
|
||||
$resQuery = CMDBSource::Query($sSQL);
|
||||
$sOQL = $this->GetPseudoOQL($this->m_oFilter, array(), $iLimit + 2, 0, true);
|
||||
$oKPI->ComputeStats('OQL Query Exec', $sOQL);
|
||||
if ($resQuery)
|
||||
{
|
||||
$aRow = CMDBSource::FetchArray($resQuery);
|
||||
@@ -920,7 +968,7 @@ class DBObjectSet implements iDBObjectSetIterator
|
||||
{
|
||||
$iCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$iCount = $this->m_iNumTotalDBRows;
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// 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_bBlameCaller = false;
|
||||
static protected $m_sAllowedUser = '*';
|
||||
static protected $m_bGenerateLegacyReport = true;
|
||||
static protected $m_fSlowQueries = 0;
|
||||
|
||||
static protected $m_aStats = array(); // Recurrent operations
|
||||
static protected $m_aExecData = array(); // One shot operations
|
||||
@@ -77,14 +81,39 @@ class ExecutionKPI
|
||||
return false;
|
||||
}
|
||||
|
||||
static public function SetGenerateLegacyReport($bReportExtensionsOnly)
|
||||
{
|
||||
self::$m_bGenerateLegacyReport = $bReportExtensionsOnly;
|
||||
}
|
||||
|
||||
static public function SetSlowQueries($fSlowQueries)
|
||||
{
|
||||
self::$m_fSlowQueries = $fSlowQueries;
|
||||
}
|
||||
|
||||
static public function GetDescription()
|
||||
{
|
||||
$aFeatures = array();
|
||||
if (self::$m_bEnabled_Duration) $aFeatures[] = 'Duration';
|
||||
if (self::$m_bEnabled_Memory) $aFeatures[] = 'Memory usage';
|
||||
$sFeatures = implode(', ', $aFeatures);
|
||||
$sFeatures = 'Measures: '.implode(', ', $aFeatures);
|
||||
$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()
|
||||
@@ -92,7 +121,28 @@ class ExecutionKPI
|
||||
if (!self::IsEnabled()) return;
|
||||
|
||||
global $fItopStarted;
|
||||
global $iItopInitialMemory;
|
||||
$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_bGenerateLegacyReport) {
|
||||
return;
|
||||
}
|
||||
|
||||
$aBeginTimes = array();
|
||||
foreach (self::$m_aExecData as $aOpStats)
|
||||
@@ -105,7 +155,7 @@ class ExecutionKPI
|
||||
|
||||
self::Report("<hr/>");
|
||||
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>log_kpi_user_id: ".UserRights::GetUserId()."</p>");
|
||||
self::Report("<div>");
|
||||
@@ -200,8 +250,6 @@ class ExecutionKPI
|
||||
|
||||
self::Report("<p><a href=\"#end-".md5($sExecId)."\">Next page stats</a></p>");
|
||||
|
||||
$fSlowQueries = MetaModel::GetConfig()->Get('log_kpi_slow_queries');
|
||||
|
||||
// Report operation details
|
||||
foreach (self::$m_aStats as $sOperation => $aOpStats)
|
||||
{
|
||||
@@ -245,7 +293,7 @@ class ExecutionKPI
|
||||
$sTotalInter = round($fTotalInter, 3);
|
||||
$sMinInter = round($fMinInter, 3);
|
||||
$sMaxInter = round($fMaxInter, 3);
|
||||
if (($fTotalInter >= $fSlowQueries))
|
||||
if (($fTotalInter >= self::$m_fSlowQueries))
|
||||
{
|
||||
if ($bDisplayHeader)
|
||||
{
|
||||
@@ -271,11 +319,19 @@ class ExecutionKPI
|
||||
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()
|
||||
{
|
||||
$this->ResetCounters();
|
||||
}
|
||||
}
|
||||
|
||||
// Get the duration since startup, and reset the counter for the next measure
|
||||
//
|
||||
@@ -283,8 +339,14 @@ class ExecutionKPI
|
||||
{
|
||||
global $fItopStarted;
|
||||
|
||||
if (!self::IsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$aNewEntry = null;
|
||||
|
||||
$fStarted = $this->m_fStarted;
|
||||
$fStopped = $this->m_fStarted;
|
||||
if (self::$m_bEnabled_Duration)
|
||||
{
|
||||
$fStopped = MyHelpers::getmicrotime();
|
||||
@@ -297,6 +359,9 @@ class ExecutionKPI
|
||||
$this->m_fStarted = $fStopped;
|
||||
}
|
||||
|
||||
$iInitialMemory = is_null($this->m_iInitialMemory) ? 0 : $this->m_iInitialMemory;
|
||||
$iCurrentMemory = 0;
|
||||
$iPeakMemory = 0;
|
||||
if (self::$m_bEnabled_Memory)
|
||||
{
|
||||
$iCurrentMemory = self::memory_get_usage();
|
||||
@@ -306,41 +371,102 @@ class ExecutionKPI
|
||||
}
|
||||
$aNewEntry['mem_begin'] = $this->m_iInitialMemory;
|
||||
$aNewEntry['mem_end'] = $iCurrentMemory;
|
||||
if (function_exists('memory_get_peak_usage'))
|
||||
{
|
||||
$aNewEntry['mem_peak'] = memory_get_peak_usage();
|
||||
}
|
||||
$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 (!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_bGenerateLegacyReport)
|
||||
{
|
||||
self::$m_aExecData[] = $aNewEntry;
|
||||
}
|
||||
$this->ResetCounters();
|
||||
}
|
||||
|
||||
public function ComputeStatsForExtension($object, $sMethod)
|
||||
{
|
||||
if (!self::IsEnabled()) {
|
||||
return;
|
||||
}
|
||||
$sSignature = ModuleService::GetInstance()->GetModuleMethodSignature($object, $sMethod);
|
||||
if (utils::StartsWith($sSignature, '[')) {
|
||||
$this->ComputeStats('Extension', $sSignature);
|
||||
}
|
||||
}
|
||||
|
||||
public function ComputeStats($sOperation, $sArguments)
|
||||
{
|
||||
if (!self::IsEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self::$m_bEnabled_Duration)
|
||||
{
|
||||
$fStopped = MyHelpers::getmicrotime();
|
||||
$fDuration = $fStopped - $this->m_fStarted;
|
||||
if (self::$m_bBlameCaller)
|
||||
{
|
||||
self::$m_aStats[$sOperation][$sArguments][] = array(
|
||||
'time' => $fDuration,
|
||||
'callers' => MyHelpers::get_callstack(1),
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
self::$m_aStats[$sOperation][$sArguments][] = array(
|
||||
'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();
|
||||
}
|
||||
|
||||
// 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()
|
||||
@@ -370,35 +496,7 @@ class ExecutionKPI
|
||||
|
||||
static protected function memory_get_usage()
|
||||
{
|
||||
if (function_exists('memory_get_usage'))
|
||||
{
|
||||
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;
|
||||
}
|
||||
return memory_get_usage(true);
|
||||
}
|
||||
|
||||
static public function memory_get_peak_usage($bRealUsage = false)
|
||||
|
||||
@@ -2778,7 +2778,7 @@ abstract class MetaModel
|
||||
|
||||
// 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)
|
||||
{
|
||||
self::$m_aExtensionClasses[$sInterface] = array();
|
||||
@@ -6348,7 +6348,9 @@ abstract class MetaModel
|
||||
|
||||
ExecutionKPI::EnableDuration(self::$m_oConfig->Get('log_kpi_duration'));
|
||||
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::SetGenerateLegacyReport(self::$m_oConfig->Get('log_kpi_generate_legacy_report'));
|
||||
ExecutionKPI::SetSlowQueries(self::$m_oConfig->Get('log_kpi_slow_queries'));
|
||||
|
||||
self::$m_bSkipCheckToWrite = self::$m_oConfig->Get('skip_check_to_write');
|
||||
self::$m_bSkipCheckExtKeys = self::$m_oConfig->Get('skip_check_ext_keys');
|
||||
@@ -6485,6 +6487,7 @@ abstract class MetaModel
|
||||
|
||||
CMDBSource::InitFromConfig(self::$m_oConfig);
|
||||
// Later when timezone implementation is correctly done: CMDBSource::SetTimezone($sDBTimezone);
|
||||
ExecutionKPI::InitStats();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -257,7 +257,7 @@ class iTopMutex
|
||||
$this->hDBLink = CMDBSource::GetMysqliInstance($sServer, $sUser, $sPwd, $sSource, $bTlsEnabled, $sTlsCA, false);
|
||||
|
||||
if (!$this->hDBLink) {
|
||||
throw new Exception("Could not connect to the DB server (host=$sServer, user=$sUser): ".mysqli_connect_error().' (mysql errno: '.mysqli_connect_errno().')');
|
||||
throw new MySQLException('Could not connect to the DB server '.mysqli_connect_error().' (mysql errno: '.mysqli_connect_errno(), array('host' => $sDBHost, 'user' => $sDBUser));
|
||||
}
|
||||
|
||||
// Make sure that the server variable `wait_timeout` is at least 86400 seconds for this connection,
|
||||
|
||||
@@ -126,7 +126,9 @@ abstract class Trigger extends cmdbAbstractObject
|
||||
$oAction = MetaModel::GetObject('Action', $iActionId);
|
||||
if ($oAction->IsActive())
|
||||
{
|
||||
$oKPI = new ExecutionKPI();
|
||||
$oAction->DoExecute($this, $aContextArgs);
|
||||
$oKPI->ComputeStatsForExtension($oAction, 'DoExecute');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,6 +202,7 @@
|
||||
$this->Set('refresh_token', $oAccessToken->getRefreshToken());
|
||||
}
|
||||
$this->Set('status', 'active');
|
||||
$this->AllowWrite();
|
||||
$this->DBUpdate();
|
||||
}
|
||||
]]></code>
|
||||
|
||||
@@ -11,6 +11,7 @@ use Combodo\iTop\Application\TwigBase\Controller\Controller;
|
||||
use Combodo\iTop\Core\Authentication\Client\OAuth\OAuthClientProviderFactory;
|
||||
use Dict;
|
||||
use IssueLog;
|
||||
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
|
||||
use MetaModel;
|
||||
use utils;
|
||||
|
||||
@@ -64,13 +65,15 @@ class AjaxOauthClientController extends Controller
|
||||
}
|
||||
if (isset($aQuery['code'])) {
|
||||
$sCode = $aQuery['code'];
|
||||
$oAccessToken = OAuthClientProviderFactory::GetAccessTokenFromCode($oOAuthClient, $sCode);
|
||||
|
||||
$oOAuthClient->SetAccessToken($oAccessToken);
|
||||
|
||||
|
||||
|
||||
$aResult['status'] = 'success';
|
||||
try {
|
||||
$oAccessToken = OAuthClientProviderFactory::GetAccessTokenFromCode($oOAuthClient, $sCode);
|
||||
$oOAuthClient->SetAccessToken($oAccessToken);
|
||||
$aResult['status'] = 'success';
|
||||
}
|
||||
catch (IdentityProviderException $e) {
|
||||
$aResult['status'] = 'error';
|
||||
$aResult['error_description'] = $e->getMessage();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$aResult['status'] = 'error';
|
||||
|
||||
@@ -2,11 +2,6 @@
|
||||
|
||||
// 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';
|
||||
|
||||
return ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b::getLoader();
|
||||
|
||||
@@ -149,7 +149,7 @@ class ClassLoader
|
||||
|
||||
/**
|
||||
* @return string[] Array of classname => path
|
||||
* @psalm-return array<string, string>
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
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\\Email\\EmailFactory' => $baseDir . '/sources/Core/Email/EmailFactory.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\\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',
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
'Config' => $baseDir . '/core/config.class.inc.php',
|
||||
@@ -2712,6 +2714,7 @@ return array(
|
||||
'iDBObjectSetIterator' => $baseDir . '/core/dbobjectiterator.php',
|
||||
'iDBObjectURLMaker' => $baseDir . '/application/applicationcontext.class.inc.php',
|
||||
'iDisplay' => $baseDir . '/core/dbobject.class.php',
|
||||
'iKPILoggerExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iLogFileNameBuilder' => $baseDir . '/core/log.class.inc.php',
|
||||
'iLoginExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
'iLoginFSMExtension' => $baseDir . '/application/applicationextension.inc.php',
|
||||
|
||||
@@ -2,25 +2,25 @@
|
||||
|
||||
// autoload_files.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.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',
|
||||
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'bd9634f2d41831496de0d3dfe4c94881' => $vendorDir . '/symfony/polyfill-php56/bootstrap.php',
|
||||
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
|
||||
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/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',
|
||||
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
|
||||
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
|
||||
);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
|
||||
@@ -25,20 +25,33 @@ class ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b
|
||||
require __DIR__ . '/platform_check.php';
|
||||
|
||||
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'));
|
||||
|
||||
$includePaths = require __DIR__ . '/include_paths.php';
|
||||
$includePaths[] = get_include_path();
|
||||
set_include_path(implode(PATH_SEPARATOR, $includePaths));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit0018331147de7601e7552f7da8e3bb8b::getInitializer($loader));
|
||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||
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->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) {
|
||||
composerRequire0018331147de7601e7552f7da8e3bb8b($fileIdentifier, $file);
|
||||
}
|
||||
@@ -47,16 +60,11 @@ class ComposerAutoloaderInit0018331147de7601e7552f7da8e3bb8b
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fileIdentifier
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
function composerRequire0018331147de7601e7552f7da8e3bb8b($fileIdentifier, $file)
|
||||
{
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,21 +8,21 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
||||
{
|
||||
public static $files = array (
|
||||
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.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',
|
||||
'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
|
||||
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
|
||||
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
|
||||
'bd9634f2d41831496de0d3dfe4c94881' => __DIR__ . '/..' . '/symfony/polyfill-php56/bootstrap.php',
|
||||
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
|
||||
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/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',
|
||||
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.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\\Email\\EmailFactory' => __DIR__ . '/../..' . '/sources/Core/Email/EmailFactory.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\\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',
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
'Config' => __DIR__ . '/../..' . '/core/config.class.inc.php',
|
||||
@@ -3080,6 +3082,7 @@ class ComposerStaticInit0018331147de7601e7552f7da8e3bb8b
|
||||
'iDBObjectSetIterator' => __DIR__ . '/../..' . '/core/dbobjectiterator.php',
|
||||
'iDBObjectURLMaker' => __DIR__ . '/../..' . '/application/applicationcontext.class.inc.php',
|
||||
'iDisplay' => __DIR__ . '/../..' . '/core/dbobject.class.php',
|
||||
'iKPILoggerExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iLogFileNameBuilder' => __DIR__ . '/../..' . '/core/log.class.inc.php',
|
||||
'iLoginExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
'iLoginFSMExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// include_paths.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?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>
|
||||
<system.web>
|
||||
<authorization>
|
||||
<deny users="*" /> <!-- Denies all users -->
|
||||
</authorization>
|
||||
</system.web>
|
||||
</configuration>
|
||||
@@ -307,6 +307,7 @@ class DBBackup
|
||||
|
||||
$sPortOption = self::GetMysqliCliSingleOption('port', $this->iDBPort);
|
||||
$sTlsOptions = self::GetMysqlCliTlsOptions($this->oConfig);
|
||||
$sProtocolOption = self::GetMysqlCliTransportOption($this->sDBHost);
|
||||
|
||||
$sMysqlVersion = CMDBSource::GetDBVersion();
|
||||
$bIsMysqlSupportUtf8mb4 = (version_compare($sMysqlVersion, self::MYSQL_VERSION_WITH_UTF8MB4_IN_PROGRAMS) === -1);
|
||||
@@ -327,8 +328,8 @@ EOF;
|
||||
|
||||
// Note: opt implicitely sets lock-tables... which cancels the benefit of single-transaction!
|
||||
// skip-lock-tables compensates and allows for writes during a backup
|
||||
$sCommand = "$sMySQLDump --defaults-extra-file=\"$sMySQLDumpCnfFile\" --opt --skip-lock-tables --default-character-set=".$sMysqldumpCharset." --add-drop-database --single-transaction --host=$sHost $sPortOption --user=$sUser $sTlsOptions --result-file=$sTmpFileName $sDBName $sTables 2>&1";
|
||||
$sCommandDisplay = "$sMySQLDump --defaults-extra-file=\"$sMySQLDumpCnfFile\" --opt --skip-lock-tables --default-character-set=".$sMysqldumpCharset." --add-drop-database --single-transaction --host=$sHost $sPortOption --user=xxxxx $sTlsOptions --result-file=$sTmpFileName $sDBName $sTables";
|
||||
$sCommand = "$sMySQLDump --defaults-extra-file=\"$sMySQLDumpCnfFile\" --opt --skip-lock-tables --default-character-set=".$sMysqldumpCharset." --add-drop-database --single-transaction --host=$sHost $sPortOption $sProtocolOption --user=$sUser $sTlsOptions --result-file=$sTmpFileName $sDBName $sTables 2>&1";
|
||||
$sCommandDisplay = "$sMySQLDump --defaults-extra-file=\"$sMySQLDumpCnfFile\" --opt --skip-lock-tables --default-character-set=".$sMysqldumpCharset." --add-drop-database --single-transaction --host=$sHost $sPortOption $sProtocolOption --user=xxxxx $sTlsOptions --result-file=$sTmpFileName $sDBName $sTables";
|
||||
|
||||
// Now run the command for real
|
||||
$this->LogInfo("backup: generate data file with command: $sCommandDisplay");
|
||||
@@ -416,8 +417,8 @@ EOF;
|
||||
if ($oMysqli->connect_errno)
|
||||
{
|
||||
$sHost = is_null($this->iDBPort) ? $this->sDBHost : $this->sDBHost.' on port '.$this->iDBPort;
|
||||
throw new BackupException("Cannot connect to the MySQL server '$sHost' (".$oMysqli->connect_errno.") ".$oMysqli->connect_error);
|
||||
}
|
||||
throw new MySQLException('Could not connect to the DB server '.$oMysqli->connect_errno.' (mysql errno: '.$oMysqli->connect_error, array('host' => $sHost, 'user' => $sUser));
|
||||
}
|
||||
if (!$oMysqli->select_db($this->sDBName))
|
||||
{
|
||||
throw new BackupException("The database '$this->sDBName' does not seem to exist");
|
||||
@@ -521,6 +522,28 @@ EOF;
|
||||
return ' --'.$sCliArgName.'='.self::EscapeShellArg($sData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Define if we should force a transport option
|
||||
*
|
||||
* @param string $sHost
|
||||
*
|
||||
* @return string .
|
||||
|
||||
* @since 2.7.9 3.0.4 3.1.1 N°6123
|
||||
*/
|
||||
public static function GetMysqlCliTransportOption(string $sHost)
|
||||
{
|
||||
$sTransportOptions = '';
|
||||
|
||||
/** N°6123 As we're using a --port option, if we use localhost as host,
|
||||
* MariaDB > 10.6 will implicitly change its protocol from socket to tcp and throw a warning **/
|
||||
if($sHost === 'localhost'){
|
||||
$sTransportOptions = '--protocol=tcp';
|
||||
}
|
||||
|
||||
return $sTransportOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string the command to launch mysqldump (without its params)
|
||||
*/
|
||||
|
||||
@@ -74,6 +74,7 @@ class OAuthClientProviderFactory
|
||||
* @return AccessTokenInterface
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \League\OAuth2\Client\Provider\Exception\IdentityProviderException
|
||||
*/
|
||||
public static function GetAccessTokenFromCode(OAuthClient $oOAuthClient, $sCode)
|
||||
{
|
||||
@@ -109,7 +110,7 @@ class OAuthClientProviderFactory
|
||||
/**
|
||||
* @param \DBObject $oOAuthClient
|
||||
*
|
||||
* @return mixed
|
||||
* @return OAuthClientProviderAbstract
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreException
|
||||
*/
|
||||
|
||||
@@ -181,7 +181,11 @@ class EmailSwiftMailer extends EMail
|
||||
|
||||
case 'PHPMail':
|
||||
default:
|
||||
$oTransport = new Swift_SendmailTransport();
|
||||
// Retrieve sendmail path or select a default one as SwiftMailer is not doing it anymore
|
||||
$sSendmailPath = ini_get('sendmail_path');
|
||||
$sSendmailPath = ($sSendmailPath === false || $sSendmailPath === '') ? '/usr/sbin/sendmail -bs' : $sSendmailPath;
|
||||
|
||||
$oTransport = new Swift_SendmailTransport($sSendmailPath);
|
||||
}
|
||||
|
||||
$oMailer = new Swift_Mailer($oTransport);
|
||||
|
||||
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(int $iCallDepth = 0): string
|
||||
{
|
||||
$sDir = $this->GetCurrentModuleDir(1 + $iCallDepth);
|
||||
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 '';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,6 +18,9 @@ namespace Combodo\iTop\Test\UnitTest\Integration;
|
||||
use Combodo\iTop\Test\UnitTest\ItopTestCase;
|
||||
|
||||
|
||||
/**
|
||||
* @group beforeSetup
|
||||
*/
|
||||
class DictionariesConsistencyTest extends ItopTestCase
|
||||
{
|
||||
/**
|
||||
@@ -29,24 +32,27 @@ class DictionariesConsistencyTest extends ItopTestCase
|
||||
*/
|
||||
public function testDictionariesLanguage($sDictFile)
|
||||
{
|
||||
// In iTop the language available list is dynamically made during setup, depending on the dict files found
|
||||
// Here we are using a fixed list
|
||||
$aPrefixToLanguageData = array(
|
||||
'cs' => array('CS CZ', 'Czech', 'Čeština'),
|
||||
'da' => array('DA DA', 'Danish', 'Dansk'),
|
||||
'de' => array('DE DE', 'German', 'Deutsch'),
|
||||
'en' => array('EN US', 'English', 'English'),
|
||||
'cs' => array('CS CZ', 'Czech', 'Čeština'),
|
||||
'da' => array('DA DA', 'Danish', 'Dansk'),
|
||||
'de' => array('DE DE', 'German', 'Deutsch'),
|
||||
'en' => array('EN US', 'English', 'English'),
|
||||
'es_cr' => array('ES CR', 'Spanish', array(
|
||||
'Español, Castellaño', // old value
|
||||
'Español, Castellano', // new value since N°3635
|
||||
)),
|
||||
'fr' => array('FR FR', 'French', 'Français'),
|
||||
'hu' => array('HU HU', 'Hungarian', 'Magyar'),
|
||||
'it' => array('IT IT', 'Italian', 'Italiano'),
|
||||
'ja' => array('JA JP', 'Japanese', '日本語'),
|
||||
'nl' => array('NL NL', 'Dutch', 'Nederlands'),
|
||||
'fr' => array('FR FR', 'French', 'Français'),
|
||||
'hu' => array('HU HU', 'Hungarian', 'Magyar'),
|
||||
'it' => array('IT IT', 'Italian', 'Italiano'),
|
||||
'ja' => array('JA JP', 'Japanese', '日本語'),
|
||||
'nl' => array('NL NL', 'Dutch', 'Nederlands'),
|
||||
'pl' => array('PL PL', 'Polish', 'Polski'),
|
||||
'pt_br' => array('PT BR', 'Brazilian', 'Brazilian'),
|
||||
'ru' => array('RU RU', 'Russian', 'Русский'),
|
||||
'sk' => array('SK SK', 'Slovak', 'Slovenčina'),
|
||||
'tr' => array('TR TR', 'Turkish', 'Türkçe'),
|
||||
'ru' => array('RU RU', 'Russian', 'Русский'),
|
||||
'sk' => array('SK SK', 'Slovak', 'Slovenčina'),
|
||||
'tr' => array('TR TR', 'Turkish', 'Türkçe'),
|
||||
'zh_cn' => array('ZH CN', 'Chinese', '简体中文'),
|
||||
);
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ use PHPUnit\Exception;
|
||||
*
|
||||
* @package Combodo\iTop\Test\UnitTest\Setup
|
||||
*/
|
||||
class TestForITopDesignFormatClass extends ItopTestCase
|
||||
class iTopDesignFormatChecklistTest extends ItopTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
@@ -47,7 +47,7 @@ class TestForITopDesignFormatClass extends ItopTestCase
|
||||
$aErrors[] = "cannot retrieve itop_design datamodel version in $sDataModelFile:1";
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$aDatamodelCurrentVersions[$sVersion] = $sVersion;
|
||||
}
|
||||
}
|
||||
@@ -159,4 +159,4 @@ class TestForITopDesignFormatClass extends ItopTestCase
|
||||
}
|
||||
return $aDataModelFiles;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
stopOnRisky="false"
|
||||
stopOnSkipped="false"
|
||||
verbose="true"
|
||||
printerClass="Sempro\PHPUnitPrettyPrinter\PrettyPrinter"
|
||||
>
|
||||
|
||||
<php>
|
||||
@@ -23,6 +24,7 @@
|
||||
<ini name="display_errors" value="On"/>
|
||||
<ini name="log_errors" value="On"/>
|
||||
<ini name="html_errors" value="Off"/>
|
||||
<env name="PHPUNIT_PRETTY_PRINT_PROGRESS" value="true"/>
|
||||
</php>
|
||||
|
||||
<testsuites>
|
||||
|
||||
@@ -84,4 +84,31 @@ class DBBackupTest extends ItopTestCase
|
||||
$this->assertStringStartsWith(' --ssl', $sCliArgsCapathCfg);
|
||||
$this->assertStringEndsWith('--ssl-ca='.DBBackup::EscapeShellArg($sTestCa), $sCliArgsCapathCfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Host is localhost, we should be forced into tcp
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetMysqlCliTransportOptionWithLocalhost()
|
||||
{
|
||||
$sHost= 'localhost';
|
||||
$sTransport = DBBackup::GetMysqlCliTransportOption($sHost);
|
||||
|
||||
$this->assertStringStartsWith('--protocol=tcp', $sTransport);
|
||||
$this->assertStringEndsWith('--protocol=tcp', $sTransport);
|
||||
}
|
||||
|
||||
/**
|
||||
* Host is not localhost, we shouldn't be forced into tcp
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function testGetMysqlCliTransportOptionWithoutLocalhost()
|
||||
{
|
||||
$sHost= '127.0.0.1';
|
||||
$sTransport = DBBackup::GetMysqlCliTransportOption($sHost);
|
||||
|
||||
$this->assertEmpty($sTransport);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user