PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.8.2
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.8.2
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / vendor / prefixed / symfony / error-handler / Exception / FlattenException.php
matomo / app / vendor / prefixed / symfony / error-handler / Exception Last commit date
FlattenException.php 1 year ago SilencedErrorContext.php 2 years ago
FlattenException.php
332 lines
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 namespace Matomo\Dependencies\Symfony\Component\ErrorHandler\Exception;
12
13 use Matomo\Dependencies\Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface;
14 use Matomo\Dependencies\Symfony\Component\HttpFoundation\Response;
15 use Matomo\Dependencies\Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
16 /**
17 * FlattenException wraps a PHP Error or Exception to be able to serialize it.
18 *
19 * Basically, this class removes all objects from the trace.
20 *
21 * @author Fabien Potencier <fabien@symfony.com>
22 */
23 class FlattenException
24 {
25 /** @var string */
26 private $message;
27 /** @var int|string */
28 private $code;
29 /** @var self|null */
30 private $previous;
31 /** @var array */
32 private $trace;
33 /** @var string */
34 private $traceAsString;
35 /** @var string */
36 private $class;
37 /** @var int */
38 private $statusCode;
39 /** @var string */
40 private $statusText;
41 /** @var array */
42 private $headers;
43 /** @var string */
44 private $file;
45 /** @var int */
46 private $line;
47 /** @var string|null */
48 private $asString;
49 /**
50 * @return static
51 */
52 public static function create(\Exception $exception, ?int $statusCode = null, array $headers = []) : self
53 {
54 return static::createFromThrowable($exception, $statusCode, $headers);
55 }
56 /**
57 * @return static
58 */
59 public static function createFromThrowable(\Throwable $exception, ?int $statusCode = null, array $headers = []) : self
60 {
61 $e = new static();
62 $e->setMessage($exception->getMessage());
63 $e->setCode($exception->getCode());
64 if ($exception instanceof HttpExceptionInterface) {
65 $statusCode = $exception->getStatusCode();
66 $headers = array_merge($headers, $exception->getHeaders());
67 } elseif ($exception instanceof RequestExceptionInterface) {
68 $statusCode = 400;
69 }
70 if (null === $statusCode) {
71 $statusCode = 500;
72 }
73 if (class_exists(Response::class) && isset(Response::$statusTexts[$statusCode])) {
74 $statusText = Response::$statusTexts[$statusCode];
75 } else {
76 $statusText = 'Whoops, looks like something went wrong.';
77 }
78 $e->setStatusText($statusText);
79 $e->setStatusCode($statusCode);
80 $e->setHeaders($headers);
81 $e->setTraceFromThrowable($exception);
82 $e->setClass(\get_class($exception));
83 $e->setFile($exception->getFile());
84 $e->setLine($exception->getLine());
85 $previous = $exception->getPrevious();
86 if ($previous instanceof \Throwable) {
87 $e->setPrevious(static::createFromThrowable($previous));
88 }
89 return $e;
90 }
91 public function toArray() : array
92 {
93 $exceptions = [];
94 foreach (array_merge([$this], $this->getAllPrevious()) as $exception) {
95 $exceptions[] = ['message' => $exception->getMessage(), 'class' => $exception->getClass(), 'trace' => $exception->getTrace()];
96 }
97 return $exceptions;
98 }
99 public function getStatusCode() : int
100 {
101 return $this->statusCode;
102 }
103 /**
104 * @return $this
105 */
106 public function setStatusCode(int $code) : self
107 {
108 $this->statusCode = $code;
109 return $this;
110 }
111 public function getHeaders() : array
112 {
113 return $this->headers;
114 }
115 /**
116 * @return $this
117 */
118 public function setHeaders(array $headers) : self
119 {
120 $this->headers = $headers;
121 return $this;
122 }
123 public function getClass() : string
124 {
125 return $this->class;
126 }
127 /**
128 * @return $this
129 */
130 public function setClass(string $class) : self
131 {
132 $this->class = \false !== strpos($class, "@anonymous\x00") ? ((get_parent_class($class) ?: key(class_implements($class))) ?: 'class') . '@anonymous' : $class;
133 return $this;
134 }
135 public function getFile() : string
136 {
137 return $this->file;
138 }
139 /**
140 * @return $this
141 */
142 public function setFile(string $file) : self
143 {
144 $this->file = $file;
145 return $this;
146 }
147 public function getLine() : int
148 {
149 return $this->line;
150 }
151 /**
152 * @return $this
153 */
154 public function setLine(int $line) : self
155 {
156 $this->line = $line;
157 return $this;
158 }
159 public function getStatusText() : string
160 {
161 return $this->statusText;
162 }
163 /**
164 * @return $this
165 */
166 public function setStatusText(string $statusText) : self
167 {
168 $this->statusText = $statusText;
169 return $this;
170 }
171 public function getMessage() : string
172 {
173 return $this->message;
174 }
175 /**
176 * @return $this
177 */
178 public function setMessage(string $message) : self
179 {
180 if (\false !== strpos($message, "@anonymous\x00")) {
181 $message = preg_replace_callback('/[a-zA-Z_\\x7f-\\xff][\\\\a-zA-Z0-9_\\x7f-\\xff]*+@anonymous\\x00.*?\\.php(?:0x?|:[0-9]++\\$)?[0-9a-fA-F]++/', function ($m) {
182 return class_exists($m[0], \false) ? ((get_parent_class($m[0]) ?: key(class_implements($m[0]))) ?: 'class') . '@anonymous' : $m[0];
183 }, $message);
184 }
185 $this->message = $message;
186 return $this;
187 }
188 /**
189 * @return int|string int most of the time (might be a string with PDOException)
190 */
191 public function getCode()
192 {
193 return $this->code;
194 }
195 /**
196 * @param int|string $code
197 *
198 * @return $this
199 */
200 public function setCode($code) : self
201 {
202 $this->code = $code;
203 return $this;
204 }
205 public function getPrevious() : ?self
206 {
207 return $this->previous;
208 }
209 /**
210 * @return $this
211 */
212 public function setPrevious(?self $previous) : self
213 {
214 $this->previous = $previous;
215 return $this;
216 }
217 /**
218 * @return self[]
219 */
220 public function getAllPrevious() : array
221 {
222 $exceptions = [];
223 $e = $this;
224 while ($e = $e->getPrevious()) {
225 $exceptions[] = $e;
226 }
227 return $exceptions;
228 }
229 public function getTrace() : array
230 {
231 return $this->trace;
232 }
233 /**
234 * @return $this
235 */
236 public function setTraceFromThrowable(\Throwable $throwable) : self
237 {
238 $this->traceAsString = $throwable->getTraceAsString();
239 return $this->setTrace($throwable->getTrace(), $throwable->getFile(), $throwable->getLine());
240 }
241 /**
242 * @return $this
243 */
244 public function setTrace(array $trace, ?string $file, ?int $line) : self
245 {
246 $this->trace = [];
247 $this->trace[] = ['namespace' => '', 'short_class' => '', 'class' => '', 'type' => '', 'function' => '', 'file' => $file, 'line' => $line, 'args' => []];
248 foreach ($trace as $entry) {
249 $class = '';
250 $namespace = '';
251 if (isset($entry['class'])) {
252 $parts = explode('\\', $entry['class']);
253 $class = array_pop($parts);
254 $namespace = implode('\\', $parts);
255 }
256 $this->trace[] = ['namespace' => $namespace, 'short_class' => $class, 'class' => $entry['class'] ?? '', 'type' => $entry['type'] ?? '', 'function' => $entry['function'] ?? null, 'file' => $entry['file'] ?? null, 'line' => $entry['line'] ?? null, 'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : []];
257 }
258 return $this;
259 }
260 private function flattenArgs(array $args, int $level = 0, int &$count = 0) : array
261 {
262 $result = [];
263 foreach ($args as $key => $value) {
264 if (++$count > 10000.0) {
265 return ['array', '*SKIPPED over 10000 entries*'];
266 }
267 if ($value instanceof \__PHP_Incomplete_Class) {
268 $result[$key] = ['incomplete-object', $this->getClassNameFromIncomplete($value)];
269 } elseif (\is_object($value)) {
270 $result[$key] = ['object', \get_class($value)];
271 } elseif (\is_array($value)) {
272 if ($level > 10) {
273 $result[$key] = ['array', '*DEEP NESTED ARRAY*'];
274 } else {
275 $result[$key] = ['array', $this->flattenArgs($value, $level + 1, $count)];
276 }
277 } elseif (null === $value) {
278 $result[$key] = ['null', null];
279 } elseif (\is_bool($value)) {
280 $result[$key] = ['boolean', $value];
281 } elseif (\is_int($value)) {
282 $result[$key] = ['integer', $value];
283 } elseif (\is_float($value)) {
284 $result[$key] = ['float', $value];
285 } elseif (\is_resource($value)) {
286 $result[$key] = ['resource', get_resource_type($value)];
287 } else {
288 $result[$key] = ['string', (string) $value];
289 }
290 }
291 return $result;
292 }
293 private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value) : string
294 {
295 $array = new \ArrayObject($value);
296 return $array['__PHP_Incomplete_Class_Name'];
297 }
298 public function getTraceAsString() : string
299 {
300 return $this->traceAsString;
301 }
302 /**
303 * @return $this
304 */
305 public function setAsString(?string $asString) : self
306 {
307 $this->asString = $asString;
308 return $this;
309 }
310 public function getAsString() : string
311 {
312 if (null !== $this->asString) {
313 return $this->asString;
314 }
315 $message = '';
316 $next = \false;
317 foreach (array_reverse(array_merge([$this], $this->getAllPrevious())) as $exception) {
318 if ($next) {
319 $message .= 'Next ';
320 } else {
321 $next = \true;
322 }
323 $message .= $exception->getClass();
324 if ('' != $exception->getMessage()) {
325 $message .= ': ' . $exception->getMessage();
326 }
327 $message .= ' in ' . $exception->getFile() . ':' . $exception->getLine() . "\nStack trace:\n" . $exception->getTraceAsString() . "\n\n";
328 }
329 return rtrim($message);
330 }
331 }
332