comparison vendor/symfony/debug/Exception/FlattenException.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 7a779792577d
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
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
12 namespace Symfony\Component\Debug\Exception;
13
14 use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
15
16 /**
17 * FlattenException wraps a PHP 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 private $message;
26 private $code;
27 private $previous;
28 private $trace;
29 private $class;
30 private $statusCode;
31 private $headers;
32 private $file;
33 private $line;
34
35 public static function create(\Exception $exception, $statusCode = null, array $headers = array())
36 {
37 $e = new static();
38 $e->setMessage($exception->getMessage());
39 $e->setCode($exception->getCode());
40
41 if ($exception instanceof HttpExceptionInterface) {
42 $statusCode = $exception->getStatusCode();
43 $headers = array_merge($headers, $exception->getHeaders());
44 }
45
46 if (null === $statusCode) {
47 $statusCode = 500;
48 }
49
50 $e->setStatusCode($statusCode);
51 $e->setHeaders($headers);
52 $e->setTraceFromException($exception);
53 $e->setClass(get_class($exception));
54 $e->setFile($exception->getFile());
55 $e->setLine($exception->getLine());
56
57 $previous = $exception->getPrevious();
58
59 if ($previous instanceof \Exception) {
60 $e->setPrevious(static::create($previous));
61 } elseif ($previous instanceof \Throwable) {
62 $e->setPrevious(static::create(new FatalThrowableError($previous)));
63 }
64
65 return $e;
66 }
67
68 public function toArray()
69 {
70 $exceptions = array();
71 foreach (array_merge(array($this), $this->getAllPrevious()) as $exception) {
72 $exceptions[] = array(
73 'message' => $exception->getMessage(),
74 'class' => $exception->getClass(),
75 'trace' => $exception->getTrace(),
76 );
77 }
78
79 return $exceptions;
80 }
81
82 public function getStatusCode()
83 {
84 return $this->statusCode;
85 }
86
87 public function setStatusCode($code)
88 {
89 $this->statusCode = $code;
90 }
91
92 public function getHeaders()
93 {
94 return $this->headers;
95 }
96
97 public function setHeaders(array $headers)
98 {
99 $this->headers = $headers;
100 }
101
102 public function getClass()
103 {
104 return $this->class;
105 }
106
107 public function setClass($class)
108 {
109 $this->class = $class;
110 }
111
112 public function getFile()
113 {
114 return $this->file;
115 }
116
117 public function setFile($file)
118 {
119 $this->file = $file;
120 }
121
122 public function getLine()
123 {
124 return $this->line;
125 }
126
127 public function setLine($line)
128 {
129 $this->line = $line;
130 }
131
132 public function getMessage()
133 {
134 return $this->message;
135 }
136
137 public function setMessage($message)
138 {
139 $this->message = $message;
140 }
141
142 public function getCode()
143 {
144 return $this->code;
145 }
146
147 public function setCode($code)
148 {
149 $this->code = $code;
150 }
151
152 public function getPrevious()
153 {
154 return $this->previous;
155 }
156
157 public function setPrevious(FlattenException $previous)
158 {
159 $this->previous = $previous;
160 }
161
162 public function getAllPrevious()
163 {
164 $exceptions = array();
165 $e = $this;
166 while ($e = $e->getPrevious()) {
167 $exceptions[] = $e;
168 }
169
170 return $exceptions;
171 }
172
173 public function getTrace()
174 {
175 return $this->trace;
176 }
177
178 public function setTraceFromException(\Exception $exception)
179 {
180 $this->setTrace($exception->getTrace(), $exception->getFile(), $exception->getLine());
181 }
182
183 public function setTrace($trace, $file, $line)
184 {
185 $this->trace = array();
186 $this->trace[] = array(
187 'namespace' => '',
188 'short_class' => '',
189 'class' => '',
190 'type' => '',
191 'function' => '',
192 'file' => $file,
193 'line' => $line,
194 'args' => array(),
195 );
196 foreach ($trace as $entry) {
197 $class = '';
198 $namespace = '';
199 if (isset($entry['class'])) {
200 $parts = explode('\\', $entry['class']);
201 $class = array_pop($parts);
202 $namespace = implode('\\', $parts);
203 }
204
205 $this->trace[] = array(
206 'namespace' => $namespace,
207 'short_class' => $class,
208 'class' => isset($entry['class']) ? $entry['class'] : '',
209 'type' => isset($entry['type']) ? $entry['type'] : '',
210 'function' => isset($entry['function']) ? $entry['function'] : null,
211 'file' => isset($entry['file']) ? $entry['file'] : null,
212 'line' => isset($entry['line']) ? $entry['line'] : null,
213 'args' => isset($entry['args']) ? $this->flattenArgs($entry['args']) : array(),
214 );
215 }
216 }
217
218 private function flattenArgs($args, $level = 0, &$count = 0)
219 {
220 $result = array();
221 foreach ($args as $key => $value) {
222 if (++$count > 1e4) {
223 return array('array', '*SKIPPED over 10000 entries*');
224 }
225 if ($value instanceof \__PHP_Incomplete_Class) {
226 // is_object() returns false on PHP<=7.1
227 $result[$key] = array('incomplete-object', $this->getClassNameFromIncomplete($value));
228 } elseif (is_object($value)) {
229 $result[$key] = array('object', get_class($value));
230 } elseif (is_array($value)) {
231 if ($level > 10) {
232 $result[$key] = array('array', '*DEEP NESTED ARRAY*');
233 } else {
234 $result[$key] = array('array', $this->flattenArgs($value, $level + 1, $count));
235 }
236 } elseif (null === $value) {
237 $result[$key] = array('null', null);
238 } elseif (is_bool($value)) {
239 $result[$key] = array('boolean', $value);
240 } elseif (is_int($value)) {
241 $result[$key] = array('integer', $value);
242 } elseif (is_float($value)) {
243 $result[$key] = array('float', $value);
244 } elseif (is_resource($value)) {
245 $result[$key] = array('resource', get_resource_type($value));
246 } else {
247 $result[$key] = array('string', (string) $value);
248 }
249 }
250
251 return $result;
252 }
253
254 private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value)
255 {
256 $array = new \ArrayObject($value);
257
258 return $array['__PHP_Incomplete_Class_Name'];
259 }
260 }