]> git.mxchange.org Git - friendica.git/blob - src/Core/Logger/Util/Introspection.php
Merge branch 'api-direct-messages' of github.com:annando/friendica into api-direct...
[friendica.git] / src / Core / Logger / Util / Introspection.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2021, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Core\Logger\Util;
23
24 /**
25  * Get Introspection information about the current call
26  */
27 class Introspection
28 {
29         /** @var int  */
30         private $skipStackFramesCount;
31
32         /** @var string[] */
33         private $skipClassesPartials;
34
35         private $skipFunctions = [
36                 'call_user_func',
37                 'call_user_func_array',
38         ];
39
40         /**
41          * @param string[] $skipClassesPartials  An array of classes to skip during logging
42          * @param int      $skipStackFramesCount If the logger should use information from other hierarchy levels of the call
43          */
44         public function __construct(array $skipClassesPartials = [], int $skipStackFramesCount = 0)
45         {
46                 $this->skipClassesPartials  = $skipClassesPartials;
47                 $this->skipStackFramesCount = $skipStackFramesCount;
48         }
49
50         /**
51          * Adds new classes to get skipped
52          *
53          * @param array $classNames
54          */
55         public function addClasses(array $classNames)
56         {
57                 $this->skipClassesPartials = array_merge($this->skipClassesPartials, $classNames);
58         }
59
60         /**
61          * Returns the introspection record of the current call
62          *
63          * @return array
64          */
65         public function getRecord(): array
66         {
67                 $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
68
69                 $i = 1;
70
71                 while ($this->isTraceClassOrSkippedFunction($trace, $i)) {
72                         $i++;
73                 }
74
75                 $i += $this->skipStackFramesCount;
76
77                 return [
78                         'file'     => isset($trace[$i - 1]['file']) ? basename($trace[$i - 1]['file']) : null,
79                         'line'     => $trace[$i - 1]['line'] ?? null,
80                         'function' => $trace[$i]['function'] ?? null,
81                 ];
82         }
83
84         /**
85          * Checks if the current trace class or function has to be skipped
86          *
87          * @param array $trace The current trace array
88          * @param int   $index The index of the current hierarchy level
89          *
90          * @return bool True if the class or function should get skipped, otherwise false
91          */
92         private function isTraceClassOrSkippedFunction(array $trace, int $index): bool
93         {
94                 if (!isset($trace[$index])) {
95                         return false;
96                 }
97
98                 if (isset($trace[$index]['class'])) {
99                         foreach ($this->skipClassesPartials as $part) {
100                                 if (strpos($trace[$index]['class'], $part) !== false) {
101                                         return true;
102                                 }
103                         }
104                 } elseif (in_array($trace[$index]['function'], $this->skipFunctions)) {
105                         return true;
106                 }
107
108                 return false;
109         }
110 }