mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Merge remote-tracking branch 'origin/support/3.2' into develop
This commit is contained in:
@@ -706,7 +706,7 @@ class DisplayBlock
|
||||
if ($bDoSearch)
|
||||
{
|
||||
// Keep the table_id identifying this table if we're performing a search
|
||||
$sTableId = utils::ReadParam('_table_id_', null, false, 'raw_data');
|
||||
$sTableId = utils::ReadParam('_table_id_', null, false, utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||
if ($sTableId != null)
|
||||
{
|
||||
$aExtraParams['table_id'] = $sTableId;
|
||||
|
||||
@@ -113,6 +113,11 @@ class utils
|
||||
* @since 2.7.10 3.0.0
|
||||
*/
|
||||
public const ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER = 'element_identifier';
|
||||
/**
|
||||
* @var string For XML / HTML node id/class selector
|
||||
* @since 3.1.2 3.2.1
|
||||
*/
|
||||
public const ENUM_SANITIZATION_FILTER_ELEMENT_SELECTOR = 'element_selector';
|
||||
/**
|
||||
* @var string For variables names
|
||||
* @since 3.0.0
|
||||
@@ -497,8 +502,17 @@ class utils
|
||||
}
|
||||
break;
|
||||
|
||||
// For XML / HTML node identifiers
|
||||
case static::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER:
|
||||
$retValue = preg_replace('/[^a-zA-Z0-9_-]/', '', $value);
|
||||
$retValue = filter_var($retValue, FILTER_VALIDATE_REGEXP,
|
||||
['options' => ['regexp' => '/^[A-Za-z0-9][A-Za-z0-9_-]*$/']]);
|
||||
break;
|
||||
|
||||
// For XML / HTML node id selector
|
||||
case static::ENUM_SANITIZATION_FILTER_ELEMENT_SELECTOR:
|
||||
$retValue = filter_var($value, FILTER_VALIDATE_REGEXP,
|
||||
['options' => ['regexp' => '/^[#\.][A-Za-z0-9][A-Za-z0-9_-]*$/']]);
|
||||
break;
|
||||
|
||||
case static::ENUM_SANITIZATION_FILTER_VARIABLE_NAME:
|
||||
|
||||
@@ -1173,7 +1173,7 @@ class DeprecatedCallsLog extends LogAPI
|
||||
|
||||
/**
|
||||
* This will catch a message for all E_DEPRECATED and E_USER_DEPRECATED errors.
|
||||
* This handler is set in DeprecatedCallsLog::Enable
|
||||
* This handler is set in {@see DeprecatedCallsLog::Enable}
|
||||
*
|
||||
* @param int $errno
|
||||
* @param string $errstr
|
||||
@@ -1193,52 +1193,22 @@ class DeprecatedCallsLog extends LogAPI
|
||||
return false;
|
||||
}
|
||||
|
||||
$aStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 4);
|
||||
if (isset($aStack[2]['function']) && ($aStack[2]['function'] == 'ForwardToTriggerError')) {
|
||||
// Let the notice bubble up
|
||||
return false;
|
||||
}
|
||||
|
||||
if (false === static::IsLogLevelEnabledSafe(self::LEVEL_WARNING, self::ENUM_CHANNEL_PHP_LIBMETHOD)) {
|
||||
// returns true so that nothing is throwned !
|
||||
// returns true so that nothing is thrown!
|
||||
return true;
|
||||
}
|
||||
|
||||
$aStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 4);
|
||||
$iStackDeprecatedMethodLevel = 2; // level 0 = current method, level 1 = @trigger_error, level 2 = method containing the `trigger_error` call (can be either 'trigger_deprecation' or the faulty method), level 3 = In some cases, method containing the 'trigger_deprecation' call
|
||||
// In case current level is actually a 'trigger_deprecation' call, try to go one level further to get the real deprecated method
|
||||
if (array_key_exists($iStackDeprecatedMethodLevel, $aStack) && ($aStack[$iStackDeprecatedMethodLevel]['function'] === 'trigger_deprecation') && array_key_exists($iStackDeprecatedMethodLevel + 1, $aStack)) {
|
||||
$iStackDeprecatedMethodLevel++;
|
||||
}
|
||||
|
||||
$sDeprecatedObject = $aStack[$iStackDeprecatedMethodLevel]['class'];
|
||||
$sDeprecatedMethod = $aStack[$iStackDeprecatedMethodLevel]['function'];
|
||||
if (($sDeprecatedObject === __CLASS__) && ($sDeprecatedMethod === 'Log')) {
|
||||
// We are generating a trigger_error ourselves, we don't want to trace them !
|
||||
return false;
|
||||
}
|
||||
$sCallerFile = $aStack[$iStackDeprecatedMethodLevel]['file'];
|
||||
$sCallerLine = $aStack[$iStackDeprecatedMethodLevel]['line'];
|
||||
$sMessage = "Call to {$sDeprecatedObject}::{$sDeprecatedMethod} in {$sCallerFile}#L{$sCallerLine}";
|
||||
|
||||
$iStackCallerMethodLevel = $iStackDeprecatedMethodLevel + 1; // level 3 = caller of the deprecated method
|
||||
if (array_key_exists($iStackCallerMethodLevel, $aStack)) {
|
||||
$sCallerObject = $aStack[$iStackCallerMethodLevel]['class'] ?? null;
|
||||
$sCallerMethod = $aStack[$iStackCallerMethodLevel]['function'] ?? null;
|
||||
$sMessage .= ' (';
|
||||
if (!is_null($sCallerObject)) {
|
||||
$sMessage .= "{$sCallerObject}::{$sCallerMethod}";
|
||||
} else {
|
||||
$sCallerMethodFile = $aStack[$iStackCallerMethodLevel]['file'];
|
||||
$sCallerMethodLine = $aStack[$iStackCallerMethodLevel]['line'];
|
||||
if (!is_null($sCallerMethod)) {
|
||||
$sMessage .= "call to {$sCallerMethod}() in {$sCallerMethodFile}#L{$sCallerMethodLine}";
|
||||
} else {
|
||||
$sMessage .= "{$sCallerMethodFile}#L{$sCallerMethodLine}";
|
||||
}
|
||||
}
|
||||
$sMessage .= ')';
|
||||
}
|
||||
|
||||
if (!empty($errstr)) {
|
||||
$sMessage .= ' : '.$errstr;
|
||||
}
|
||||
$aStack = static::StripCallStack($aStack);
|
||||
$sMessage = "$errstr, called from ".static::SummarizeCallStack($aStack);
|
||||
|
||||
static::Warning($sMessage, self::ENUM_CHANNEL_PHP_LIBMETHOD);
|
||||
static::ForwardToTriggerError($sMessage);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1264,6 +1234,8 @@ class DeprecatedCallsLog extends LogAPI
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this helper at the beginning of a deprecated file (in its global scope)
|
||||
*
|
||||
* @since 3.0.1 3.1.0 N°4725 silently handles ConfigException
|
||||
* @since 3.0.4 3.1.0 N°4725 remove forgotten throw PHPDoc annotation
|
||||
*
|
||||
@@ -1298,9 +1270,12 @@ class DeprecatedCallsLog extends LogAPI
|
||||
}
|
||||
|
||||
static::Warning($sMessage, static::ENUM_CHANNEL_FILE);
|
||||
static::ForwardToTriggerError($sMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this helper when calling a deprecated extension method
|
||||
*
|
||||
* @param string $sImplementationClass Class implementing the deprecated API
|
||||
* @param string $sDeprecatedApi Class name of the deprecated API
|
||||
* @param string $sDeprecatedMethod Method name of the deprecated API
|
||||
@@ -1327,9 +1302,12 @@ class DeprecatedCallsLog extends LogAPI
|
||||
}
|
||||
|
||||
static::Warning($sMessage, self::ENUM_CHANNEL_PHP_API);
|
||||
static::ForwardToTriggerError($sMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this helper within deprecated methods
|
||||
*
|
||||
* @param string|null $sAdditionalMessage
|
||||
*
|
||||
* @link https://www.php.net/debug_backtrace
|
||||
@@ -1347,52 +1325,24 @@ class DeprecatedCallsLog extends LogAPI
|
||||
}
|
||||
|
||||
$aStack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
|
||||
$sMessage = self::GetMessageFromStack($aStack);
|
||||
|
||||
if (isset($aStack[1]['class'])) {
|
||||
$sFunctionDesc = $aStack[1]['class'].$aStack[1]['type'].$aStack[1]['function'];
|
||||
}
|
||||
else {
|
||||
$sFunctionDesc = $aStack[1]['function'];
|
||||
}
|
||||
|
||||
$sMessage = "Function $sFunctionDesc() is deprecated";
|
||||
if (!is_null($sAdditionalMessage)) {
|
||||
$sMessage .= ': '.$sAdditionalMessage;
|
||||
}
|
||||
|
||||
$sMessage .= '. Caller: '.self::SummarizeCallStack(array_slice($aStack, 1));
|
||||
|
||||
|
||||
static::Warning($sMessage, self::ENUM_CHANNEL_PHP_METHOD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $aDebugBacktrace data from {@see debug_backtrace()}
|
||||
*
|
||||
* @return string message to print to the log
|
||||
*/
|
||||
private static function GetMessageFromStack(array $aDebugBacktrace): string
|
||||
{
|
||||
// level 0 = current method
|
||||
// level 1 = deprecated method, containing the `NotifyDeprecatedPhpMethod` call
|
||||
$sMessage = 'Call'.self::GetMessageForCurrentStackLevel($aDebugBacktrace[1], " to ");
|
||||
|
||||
// level 2 = caller of the deprecated method
|
||||
if (array_key_exists(2, $aDebugBacktrace)) {
|
||||
$sMessage .= ' (from ';
|
||||
$sMessage .= self::GetMessageForCurrentStackLevel($aDebugBacktrace[2]);
|
||||
$sMessage .= ')';
|
||||
}
|
||||
|
||||
return $sMessage;
|
||||
}
|
||||
|
||||
private static function GetMessageForCurrentStackLevel(array $aCurrentLevelDebugTrace, ?string $sPrefix = ""): string
|
||||
{
|
||||
$sMessage = "";
|
||||
if (array_key_exists('class', $aCurrentLevelDebugTrace)) {
|
||||
$sDeprecatedObject = $aCurrentLevelDebugTrace['class'];
|
||||
$sDeprecatedMethod = $aCurrentLevelDebugTrace['function'] ?? "";
|
||||
$sMessage = "{$sPrefix}{$sDeprecatedObject}::{$sDeprecatedMethod} in ";
|
||||
}
|
||||
|
||||
if (array_key_exists('file', $aCurrentLevelDebugTrace)) {
|
||||
$sCallerFile = $aCurrentLevelDebugTrace['file'];
|
||||
$sCallerLine = $aCurrentLevelDebugTrace['line'] ?? "";
|
||||
$sMessage .= "{$sCallerFile}#L{$sCallerLine}";
|
||||
}
|
||||
|
||||
return $sMessage;
|
||||
static::ForwardToTriggerError($sMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1422,14 +1372,11 @@ class DeprecatedCallsLog extends LogAPI
|
||||
}
|
||||
|
||||
static::Warning($sMessage, self::ENUM_CHANNEL_PHP_ENDPOINT);
|
||||
static::ForwardToTriggerError($sMessage);
|
||||
}
|
||||
|
||||
public static function Log($sLevel, $sMessage, $sChannel = null, $aContext = array()): void
|
||||
{
|
||||
if (true === utils::IsDevelopmentEnvironment()) {
|
||||
trigger_error($sMessage, E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
try {
|
||||
parent::Log($sLevel, $sMessage, $sChannel, $aContext);
|
||||
}
|
||||
@@ -1437,6 +1384,61 @@ class DeprecatedCallsLog extends LogAPI
|
||||
// nothing much we can do... and we don't want to crash the caller !
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips some elements from the top of the call stack to skip calls that are not relevant to report the deprecated call
|
||||
* @param array $aCallStack Call stack as returned by {@see debug_backtrace()}
|
||||
*/
|
||||
protected static function StripCallStack($aCallStack): array
|
||||
{
|
||||
if (!isset($aCallStack[0]['line'])) {
|
||||
$aCallStack = array_slice($aCallStack, 1);
|
||||
}
|
||||
if (isset($aCallStack[1]['function']) && $aCallStack[1]['function'] === 'trigger_deprecation') {
|
||||
$aCallStack = array_slice($aCallStack, 1);
|
||||
}
|
||||
|
||||
return $aCallStack;
|
||||
}
|
||||
|
||||
protected static function SummarizeCallStack($aCallStack, $bRecurse = true)
|
||||
{
|
||||
if (count($aCallStack) == 0) {
|
||||
return null;
|
||||
}
|
||||
$sFileLine = $aCallStack[0]['file'].'#'.$aCallStack[0]['line'];
|
||||
$sSummary = $sFileLine;
|
||||
|
||||
// If possible and meaningful, add the class and method
|
||||
if (isset($aCallStack[1]['class'])) {
|
||||
$sSummary = $aCallStack[1]['class'].$aCallStack[1]['type'].$aCallStack[1]['function']." ($sFileLine)";
|
||||
}
|
||||
elseif (isset($aCallStack[1]['function'])) {
|
||||
if (in_array($aCallStack[1]['function'], ['include', 'require', 'include_once', 'require_once'])) {
|
||||
// No need to show the generic mechanism of inclusion
|
||||
$bRecurse = false;
|
||||
}
|
||||
else {
|
||||
$sSummary = $aCallStack[1]['function']." ($sFileLine)";
|
||||
}
|
||||
}
|
||||
|
||||
if ($bRecurse) {
|
||||
$sUpperSummary = static::SummarizeCallStack(array_slice($aCallStack, 1), false);
|
||||
if (!is_null($sUpperSummary)) {
|
||||
$sSummary .= ', itself called from '.$sUpperSummary;
|
||||
}
|
||||
}
|
||||
|
||||
return $sSummary;
|
||||
}
|
||||
|
||||
private static function ForwardToTriggerError(string $sMessage): void
|
||||
{
|
||||
if (true === utils::IsDevelopmentEnvironment()) {
|
||||
trigger_error($sMessage, E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -54,3 +54,11 @@ SetupWebPage::AddModule(
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// ____ _ _ _ __ _ _ _ _ _______
|
||||
// | _ \| | ___ __ _ ___ ___ | |_ __ _| | _____ ___ __ _ _ __ ___ ___ / _| | |_| |__ ___ _ __ ___ _ __| |_ __ _| | / /___ /
|
||||
// | |_) | |/ _ \/ _` / __|/ _ \ | __/ _` | |/ / _ \ / __/ _` | '__/ _ \ / _ \| |_ | __| '_ \ / _ \ | '_ \ / _ \| '__| __/ _` | | / / |_ \
|
||||
// | __/| | __/ (_| \__ \ __/ | || (_| | < __/ | (_| (_| | | | __/ | (_) | _| | |_| | | | __/ | |_) | (_) | | | || (_| | | \ \ ___) |
|
||||
// |_| |_|\___|\__,_|___/\___| \__\__,_|_|\_\___| \___\__,_|_| \___| \___/|_| \__|_| |_|\___| | .__/ \___/|_| \__\__,_|_| \_\____/
|
||||
// |_|
|
||||
|
||||
@@ -782,12 +782,12 @@ try
|
||||
$sClass = utils::ReadParam('className', '', false, 'class');
|
||||
$sRootClass = utils::ReadParam('baseClass', '', false, 'class');
|
||||
$currentId = utils::ReadParam('currentId', '');
|
||||
$sTableId = utils::ReadParam('_table_id_', null, false, 'raw_data');
|
||||
$sTableId = utils::ReadParam('_table_id_', null, false, utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||
$sAction = utils::ReadParam('action', '');
|
||||
$sSelectionMode = utils::ReadParam('selection_mode', null, false, 'raw_data');
|
||||
$sResultListOuterSelector = utils::ReadParam('result_list_outer_selector', null, false, 'raw_data');
|
||||
$scssCount = utils::ReadParam('css_count', null, false, 'raw_data');
|
||||
$sTableInnerId = utils::ReadParam('table_inner_id', $sTableId, false, 'raw_data');
|
||||
$sSelectionMode = utils::ReadParam('selection_mode');
|
||||
$sResultListOuterSelector = utils::ReadParam('result_list_outer_selector', null,false, utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER); // actually an Id not a selector
|
||||
$scssCount = utils::ReadParam('css_count', null,false,utils::ENUM_SANITIZATION_FILTER_ELEMENT_SELECTOR);
|
||||
$sTableInnerId = utils::ReadParam('table_inner_id', null,false, utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||
|
||||
$oFilter = new DBObjectSearch($sClass);
|
||||
$oSet = new CMDBObjectSet($oFilter);
|
||||
|
||||
@@ -13,143 +13,256 @@ use DeprecatedCallsLog;
|
||||
class DeprecatedCallsLogTest extends ItopTestCase
|
||||
{
|
||||
/**
|
||||
* We are testing for a undefined offset error. This was throwing a Notice, but starting with PHP 8.0 it was converted to a Warning ! Also the message was changed :(
|
||||
*
|
||||
* @link https://www.php.net/manual/en/migration80.incompatible.php check "A number of notices have been converted into warnings:"
|
||||
* @dataProvider StripCallStackProvider
|
||||
*/
|
||||
private function SetUndefinedOffsetExceptionToExpect(): void
|
||||
public function testStripCallStack($sInputStack, $sExpectedStack)
|
||||
{
|
||||
/** @noinspection ConstantCanBeUsedInspection Preferring the function call as it is easier to read and won't cost that much in this PHPUnit context */
|
||||
if (version_compare(PHP_VERSION, '8.0', '>=')) {
|
||||
$this->expectWarning();
|
||||
$sUndefinedOffsetExceptionMessage = 'Undefined array key "tutu"';
|
||||
} else {
|
||||
$this->expectNotice();
|
||||
$sUndefinedOffsetExceptionMessage = 'Undefined index: tutu';
|
||||
}
|
||||
$this->expectExceptionMessage($sUndefinedOffsetExceptionMessage);
|
||||
$this->assertEquals(
|
||||
$sExpectedStack,
|
||||
$this->InvokeNonPublicStaticMethod(DeprecatedCallsLog::class, 'StripCallStack', [$sInputStack]),
|
||||
'The top item of the call stack should be the first item meaningful to track deprecated calls, not the intermediate layers of the PHP engine'
|
||||
);
|
||||
}
|
||||
|
||||
public function testPhpNoticeWithoutDeprecatedCallsLog(): void
|
||||
{
|
||||
$this->SetUndefinedOffsetExceptionToExpect();
|
||||
|
||||
$aArray = [];
|
||||
if ('toto' === $aArray['tutu']) {
|
||||
//Do nothing, just raising a undefined offset warning
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @runInSeparateProcess Necessary, due to the DeprecatedCallsLog being enabled (no mean to reset)
|
||||
*
|
||||
* The error handler set by DeprecatedCallsLog during startup was causing PHPUnit to miss PHP notices like "undefined offset"
|
||||
*
|
||||
* The error handler is now disabled when running PHPUnit
|
||||
*
|
||||
* @since 3.0.4 N°6274
|
||||
* @covers DeprecatedCallsLog::DeprecatedNoticesErrorHandler
|
||||
*/
|
||||
public function testPhpNoticeWithDeprecatedCallsLog(): void
|
||||
{
|
||||
$this->RequireOnceItopFile('core/log.class.inc.php');
|
||||
DeprecatedCallsLog::Enable(); // will set error handler
|
||||
$this->SetUndefinedOffsetExceptionToExpect();
|
||||
|
||||
$aArray = [];
|
||||
if ('toto' === $aArray['tutu']) {
|
||||
//Do nothing, just raising a undefined offset warning
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider GetMessageFromStackProvider
|
||||
*/
|
||||
public function testGetMessageFromStack($aDebugBacktrace, $sExpectedMessage): void
|
||||
{
|
||||
$sActualMessage = $this->InvokeNonPublicStaticMethod(DeprecatedCallsLog::class, 'GetMessageFromStack', [$aDebugBacktrace]);
|
||||
$this->assertEquals($sExpectedMessage, $sActualMessage);
|
||||
}
|
||||
|
||||
public function GetMessageFromStackProvider()
|
||||
public function StripCallStackProvider()
|
||||
{
|
||||
return [
|
||||
'Call in a file outside of a function or class' => [
|
||||
/* A deprecated PHP method is invoked from scratch.php, at line 25 (note: the name of the method is not present in the callstack) */
|
||||
'Should preserve the handler when the notice is fired by PHP itself' => [
|
||||
'in' => [
|
||||
[
|
||||
'file' => 'whateverfolder/scratch.php',
|
||||
'line' => 25,
|
||||
'function' => 'DeprecatedNoticesErrorHandler',
|
||||
'class' => 'DeprecatedCallsLog',
|
||||
'type' => '::',
|
||||
],
|
||||
],
|
||||
'out' => [
|
||||
[
|
||||
'file' => 'C:\Dev\wamp64\www\itop-32\sources\Application\WebPage\WebPage.php',
|
||||
'line' => '866',
|
||||
'function' => 'NotifyDeprecatedPhpMethod',
|
||||
'file' => 'whateverfolder/scratch.php',
|
||||
'line' => 25,
|
||||
'function' => 'DeprecatedNoticesErrorHandler',
|
||||
'class' => 'DeprecatedCallsLog',
|
||||
'type' => '::',
|
||||
],
|
||||
],
|
||||
],
|
||||
'Should skip the handler when the notice is fired by a call to trigger_error' => [
|
||||
'in' => [
|
||||
[
|
||||
'function' => 'DeprecatedNoticesErrorHandler',
|
||||
'class' => 'DeprecatedCallsLog',
|
||||
'type' => '::',
|
||||
],
|
||||
[
|
||||
'file' => 'C:\Dev\wamp64\www\itop-32\extensions\itop-object-copier\copy.php',
|
||||
'line' => '130',
|
||||
'function' => 'add_linked_script',
|
||||
'class' => 'Combodo\iTop\Application\WebPage\WebPage',
|
||||
'type' => '->',
|
||||
'file' => 'whateverfolder/scratch.php',
|
||||
'line' => 25,
|
||||
'function' => 'trigger_error',
|
||||
],
|
||||
],
|
||||
'out' => [
|
||||
[
|
||||
'file' => 'whateverfolder/scratch.php',
|
||||
'line' => 25,
|
||||
'function' => 'trigger_error',
|
||||
],
|
||||
],
|
||||
],
|
||||
'Should skip two levels when the notice is fired by trigger_deprecation (Symfony helper)' => [
|
||||
'in' => [
|
||||
[
|
||||
'function' => 'DeprecatedNoticesErrorHandler',
|
||||
'class' => 'DeprecatedCallsLog',
|
||||
'type' => '::',
|
||||
],
|
||||
[
|
||||
'file' => 'C:\Dev\wamp64\www\itop-32\pages\exec.php',
|
||||
'line' => '102',
|
||||
'args' => ['C:\Dev\wamp64\www\itop-32\extensions\itop-object-copier\copy.php'],
|
||||
'file' => 'symfony/deprecation.php',
|
||||
'line' => 12,
|
||||
'function' => 'trigger_error',
|
||||
],
|
||||
[
|
||||
'file' => 'symfony/service.php',
|
||||
'line' => 25,
|
||||
'function' => 'trigger_deprecation',
|
||||
],
|
||||
],
|
||||
'out' => [
|
||||
[
|
||||
'file' => 'symfony/service.php',
|
||||
'line' => 25,
|
||||
'function' => 'trigger_deprecation',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider SummarizeCallStackProvider
|
||||
*/
|
||||
public function testSummarizeCallStack($sInputStackStripped, $sExpectedSummary)
|
||||
{
|
||||
$this->assertEquals(
|
||||
$sExpectedSummary,
|
||||
$this->InvokeNonPublicStaticMethod(DeprecatedCallsLog::class, 'SummarizeCallStack', [$sInputStackStripped])
|
||||
);
|
||||
}
|
||||
|
||||
public function SummarizeCallStackProvider()
|
||||
{
|
||||
// All tests are based on a call stack issued from a deprecated PHP function
|
||||
// Other cases are similar: what counts on the top level item is the file and line number of the deprecated call
|
||||
return [
|
||||
'From the main page (deprecated PHP function)' => [
|
||||
'in:stripped call stack' => [
|
||||
[
|
||||
'file' => 'whateverfolder/scratch.php',
|
||||
'line' => 25,
|
||||
'function' => 'DeprecatedNoticesErrorHandler',
|
||||
'class' => 'DeprecatedCallsLog',
|
||||
'type' => '::',
|
||||
],
|
||||
],
|
||||
'out' => 'whateverfolder/scratch.php#25',
|
||||
],
|
||||
'From an iTop method (deprecated PHP function)' => [
|
||||
'in:stripped call stack' => [
|
||||
[
|
||||
'file' => 'whateverfolder/someclass.php',
|
||||
'line' => 18,
|
||||
'function' => 'DeprecatedNoticesErrorHandler',
|
||||
'class' => 'DeprecatedCallsLog',
|
||||
'type' => '::',
|
||||
],
|
||||
[
|
||||
'file' => 'whateverfolder/index.php',
|
||||
'line' => 25,
|
||||
'function' => 'SomeMethod',
|
||||
'class' => 'SomeClass',
|
||||
'type' => '->',
|
||||
],
|
||||
],
|
||||
'out' => 'SomeClass->SomeMethod (whateverfolder/someclass.php#18), itself called from whateverfolder/index.php#25',
|
||||
],
|
||||
'From an iTop static method (deprecated PHP function)' => [
|
||||
'in:stripped call stack' => [
|
||||
[
|
||||
'file' => 'whateverfolder/someclass.php',
|
||||
'line' => 18,
|
||||
'function' => 'DeprecatedNoticesErrorHandler',
|
||||
'class' => 'DeprecatedCallsLog',
|
||||
'type' => '::',
|
||||
],
|
||||
[
|
||||
'file' => 'whateverfolder/index.php',
|
||||
'line' => 25,
|
||||
'function' => 'SomeMethod',
|
||||
'class' => 'SomeClass',
|
||||
'type' => '::',
|
||||
],
|
||||
],
|
||||
'out' => 'SomeClass::SomeMethod (whateverfolder/someclass.php#18), itself called from whateverfolder/index.php#25',
|
||||
],
|
||||
'From an iTop function (deprecated PHP function)' => [
|
||||
'in:stripped call stack' => [
|
||||
[
|
||||
'file' => 'whateverfolder/someclass.php',
|
||||
'line' => 18,
|
||||
'function' => 'DeprecatedNoticesErrorHandler',
|
||||
'class' => 'DeprecatedCallsLog',
|
||||
'type' => '::',
|
||||
],
|
||||
[
|
||||
'file' => 'whateverfolder/index.php',
|
||||
'line' => 25,
|
||||
'function' => 'SomeFunction',
|
||||
],
|
||||
],
|
||||
'out' => 'SomeFunction (whateverfolder/someclass.php#18), itself called from whateverfolder/index.php#25',
|
||||
],
|
||||
'From a code snippet (deprecated PHP function)' => [
|
||||
'in:stripped call stack' => [
|
||||
[
|
||||
'file' => 'itop-root/env-production/core/main.php',
|
||||
'line' => 1290,
|
||||
'function' => 'DeprecatedNoticesErrorHandler',
|
||||
'class' => 'DeprecatedCallsLog',
|
||||
'type' => '::',
|
||||
],
|
||||
[
|
||||
'file' => 'itop-root/core/metamodel.class.php',
|
||||
'line' => 6698,
|
||||
'function' => 'require_once',
|
||||
],
|
||||
[
|
||||
'file' => 'itop-root/env-production/autoload.php',
|
||||
'line' => 6,
|
||||
'function' => 'IncludeModule',
|
||||
'class' => 'MetaModel',
|
||||
'type' => '::',
|
||||
],
|
||||
[
|
||||
'file' => 'itop-root/core/metamodel.class.php',
|
||||
'line' => 6487,
|
||||
'function' => 'require_once',
|
||||
],
|
||||
],
|
||||
'Call to Combodo\iTop\Application\WebPage\WebPage::add_linked_script in C:\Dev\wamp64\www\itop-32\extensions\itop-object-copier\copy.php#L130 (from C:\Dev\wamp64\www\itop-32\pages\exec.php#L102)',
|
||||
'out' => 'itop-root/env-production/core/main.php#1290'
|
||||
],
|
||||
|
||||
'Call in a file function, outside of a class' => [
|
||||
'From a persistent object method (deprecated PHP function)' => [
|
||||
'in:stripped call stack' => [
|
||||
[
|
||||
[
|
||||
'file' => 'C:\\Dev\\wamp64\\www\\itop-32\\sources\\Application\\WebPage\\WebPage.php',
|
||||
'line' => 866,
|
||||
'function' => 'NotifyDeprecatedPhpMethod',
|
||||
'file' => 'itop-root/env-production/itop-tickets/model.itop-tickets.php',
|
||||
'line' => 165,
|
||||
'function' => 'DeprecatedNoticesErrorHandler',
|
||||
'class' => 'DeprecatedCallsLog',
|
||||
'type' => '::',
|
||||
],
|
||||
[
|
||||
'file' => 'C:\\Dev\\wamp64\\www\\itop-32\\extensions\\itop-object-copier\\copy.php',
|
||||
'line' => 81,
|
||||
'function' => 'add_linked_script',
|
||||
'class' => 'Combodo\\iTop\\Application\\WebPage\\WebPage',
|
||||
'file' => 'itop-root/core/dbobject.class.php',
|
||||
'line' => 6575,
|
||||
'function' => 'OnBeforeWriteTicket',
|
||||
'class' => 'Ticket',
|
||||
'type' => '->',
|
||||
],
|
||||
[
|
||||
'file' => 'C:\\Dev\\wamp64\\www\\itop-32\\extensions\\itop-object-copier\\copy.php',
|
||||
'line' => 123,
|
||||
'function' => 'myFunction',
|
||||
],
|
||||
],
|
||||
'Call to Combodo\iTop\Application\WebPage\WebPage::add_linked_script in C:\Dev\wamp64\www\itop-32\extensions\itop-object-copier\copy.php#L81 (from C:\Dev\wamp64\www\itop-32\extensions\itop-object-copier\copy.php#L123)',
|
||||
],
|
||||
|
||||
'Call from a class method' => [
|
||||
[
|
||||
[
|
||||
'file' => 'C:\\Dev\\wamp64\\www\\itop-32\\sources\\Application\\WebPage\\WebPage.php',
|
||||
'line' => 866,
|
||||
'function' => 'NotifyDeprecatedPhpMethod',
|
||||
'class' => 'DeprecatedCallsLog',
|
||||
'type' => '::',
|
||||
],
|
||||
[
|
||||
'file' => 'C:\\Dev\\wamp64\\www\\itop-32\\extensions\\itop-object-copier\\copy.php',
|
||||
'line' => 82,
|
||||
'function' => 'add_linked_script',
|
||||
'class' => 'Combodo\\iTop\\Application\\WebPage\\WebPage',
|
||||
'file' => 'itop-root/application/cmdbabstract.class.inc.php',
|
||||
'line' => 5933,
|
||||
'function' => 'FireEvent',
|
||||
'class' => 'DBObject',
|
||||
'type' => '->',
|
||||
],
|
||||
[
|
||||
'file' => 'C:\\Dev\\wamp64\\www\\itop-32\\extensions\\itop-object-copier\\copy.php',
|
||||
'line' => 125,
|
||||
'function' => 'MyMethod',
|
||||
'class' => 'MyClass',
|
||||
'type' => '::',
|
||||
'file' => 'itop-root/core/dbobject.class.php',
|
||||
'line' => 3643,
|
||||
'function' => 'FireEventBeforeWrite',
|
||||
'class' => 'cmdbAbstractObject',
|
||||
'type' => '->',
|
||||
],
|
||||
[
|
||||
'file' => 'itop-root/application/cmdbabstract.class.inc.php',
|
||||
'line' => 4593,
|
||||
'function' => 'DBUpdate',
|
||||
'class' => 'DBObject',
|
||||
'type' => '->',
|
||||
],
|
||||
[
|
||||
'file' => 'itop-root/sources/Controller/Base/Layout/ObjectController.php',
|
||||
'line' => 649,
|
||||
'function' => 'DBUpdate',
|
||||
'class' => 'cmdbAbstractObject',
|
||||
'type' => '->',
|
||||
],
|
||||
[
|
||||
'file' => 'itop-root/pages/UI.php',
|
||||
'line' => 720,
|
||||
'function' => 'OperationApplyModify',
|
||||
'class' => 'Combodo\\iTop\\Controller\\Base\\Layout\\ObjectController',
|
||||
'type' => '->',
|
||||
],
|
||||
],
|
||||
'Call to Combodo\iTop\Application\WebPage\WebPage::add_linked_script in C:\Dev\wamp64\www\itop-32\extensions\itop-object-copier\copy.php#L82 (from MyClass::MyMethod in C:\Dev\wamp64\www\itop-32\extensions\itop-object-copier\copy.php#L125)',
|
||||
'out' => 'Ticket->OnBeforeWriteTicket (itop-root/env-production/itop-tickets/model.itop-tickets.php#165), itself called from DBObject->FireEvent (itop-root/core/dbobject.class.php#6575)'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user