Yaffs site version 1.1
[yaffs-website] / vendor / symfony / var-dumper / Caster / ExceptionCaster.php
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\VarDumper\Caster;
13
14 use Symfony\Component\VarDumper\Exception\ThrowingCasterException;
15 use Symfony\Component\VarDumper\Cloner\Stub;
16
17 /**
18  * Casts common Exception classes to array representation.
19  *
20  * @author Nicolas Grekas <p@tchwork.com>
21  */
22 class ExceptionCaster
23 {
24     public static $srcContext = 1;
25     public static $traceArgs = true;
26     public static $errorTypes = array(
27         E_DEPRECATED => 'E_DEPRECATED',
28         E_USER_DEPRECATED => 'E_USER_DEPRECATED',
29         E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
30         E_ERROR => 'E_ERROR',
31         E_WARNING => 'E_WARNING',
32         E_PARSE => 'E_PARSE',
33         E_NOTICE => 'E_NOTICE',
34         E_CORE_ERROR => 'E_CORE_ERROR',
35         E_CORE_WARNING => 'E_CORE_WARNING',
36         E_COMPILE_ERROR => 'E_COMPILE_ERROR',
37         E_COMPILE_WARNING => 'E_COMPILE_WARNING',
38         E_USER_ERROR => 'E_USER_ERROR',
39         E_USER_WARNING => 'E_USER_WARNING',
40         E_USER_NOTICE => 'E_USER_NOTICE',
41         E_STRICT => 'E_STRICT',
42     );
43
44     public static function castError(\Error $e, array $a, Stub $stub, $isNested, $filter = 0)
45     {
46         return self::filterExceptionArray($stub->class, $a, "\0Error\0", $filter);
47     }
48
49     public static function castException(\Exception $e, array $a, Stub $stub, $isNested, $filter = 0)
50     {
51         return self::filterExceptionArray($stub->class, $a, "\0Exception\0", $filter);
52     }
53
54     public static function castErrorException(\ErrorException $e, array $a, Stub $stub, $isNested)
55     {
56         if (isset($a[$s = Caster::PREFIX_PROTECTED.'severity'], self::$errorTypes[$a[$s]])) {
57             $a[$s] = new ConstStub(self::$errorTypes[$a[$s]], $a[$s]);
58         }
59
60         return $a;
61     }
62
63     public static function castThrowingCasterException(ThrowingCasterException $e, array $a, Stub $stub, $isNested)
64     {
65         $prefix = Caster::PREFIX_PROTECTED;
66         $xPrefix = "\0Exception\0";
67
68         if (isset($a[$xPrefix.'previous'], $a[$xPrefix.'trace']) && $a[$xPrefix.'previous'] instanceof \Exception) {
69             $b = (array) $a[$xPrefix.'previous'];
70             array_unshift($b[$xPrefix.'trace'], array(
71                 'function' => 'new '.get_class($a[$xPrefix.'previous']),
72                 'file' => $b[$prefix.'file'],
73                 'line' => $b[$prefix.'line'],
74             ));
75             $a[$xPrefix.'trace'] = new TraceStub($b[$xPrefix.'trace'], false, 0, -1 - count($a[$xPrefix.'trace']->value));
76         }
77
78         unset($a[$xPrefix.'previous'], $a[$prefix.'code'], $a[$prefix.'file'], $a[$prefix.'line']);
79
80         return $a;
81     }
82
83     public static function castTraceStub(TraceStub $trace, array $a, Stub $stub, $isNested)
84     {
85         if (!$isNested) {
86             return $a;
87         }
88         $stub->class = '';
89         $stub->handle = 0;
90         $frames = $trace->value;
91
92         $a = array();
93         $j = count($frames);
94         if (0 > $i = $trace->sliceOffset) {
95             $i = max(0, $j + $i);
96         }
97         if (!isset($trace->value[$i])) {
98             return array();
99         }
100         $lastCall = isset($frames[$i]['function']) ? ' ==> '.(isset($frames[$i]['class']) ? $frames[0]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : '';
101
102         for ($j += $trace->numberingOffset - $i++; isset($frames[$i]); ++$i, --$j) {
103             $call = isset($frames[$i]['function']) ? (isset($frames[$i]['class']) ? $frames[$i]['class'].$frames[$i]['type'] : '').$frames[$i]['function'].'()' : '???';
104
105             $a[Caster::PREFIX_VIRTUAL.$j.'. '.$call.$lastCall] = new FrameStub(
106                 array(
107                     'object' => isset($frames[$i]['object']) ? $frames[$i]['object'] : null,
108                     'class' => isset($frames[$i]['class']) ? $frames[$i]['class'] : null,
109                     'type' => isset($frames[$i]['type']) ? $frames[$i]['type'] : null,
110                     'function' => isset($frames[$i]['function']) ? $frames[$i]['function'] : null,
111                 ) + $frames[$i - 1],
112                 $trace->keepArgs,
113                 true
114             );
115
116             $lastCall = ' ==> '.$call;
117         }
118         $a[Caster::PREFIX_VIRTUAL.$j.'. {main}'.$lastCall] = new FrameStub(
119             array(
120                 'object' => null,
121                 'class' => null,
122                 'type' => null,
123                 'function' => '{main}',
124             ) + $frames[$i - 1],
125             $trace->keepArgs,
126             true
127         );
128         if (null !== $trace->sliceLength) {
129             $a = array_slice($a, 0, $trace->sliceLength, true);
130         }
131
132         return $a;
133     }
134
135     public static function castFrameStub(FrameStub $frame, array $a, Stub $stub, $isNested)
136     {
137         if (!$isNested) {
138             return $a;
139         }
140         $f = $frame->value;
141         $prefix = Caster::PREFIX_VIRTUAL;
142
143         if (isset($f['file'], $f['line'])) {
144             if (preg_match('/\((\d+)\)(?:\([\da-f]{32}\))? : (?:eval\(\)\'d code|runtime-created function)$/', $f['file'], $match)) {
145                 $f['file'] = substr($f['file'], 0, -strlen($match[0]));
146                 $f['line'] = (int) $match[1];
147             }
148             if (file_exists($f['file']) && 0 <= self::$srcContext) {
149                 $src[$f['file'].':'.$f['line']] = self::extractSource(explode("\n", file_get_contents($f['file'])), $f['line'], self::$srcContext);
150
151                 if (!empty($f['class']) && (is_subclass_of($f['class'], 'Twig\Template') || is_subclass_of($f['class'], 'Twig_Template')) && method_exists($f['class'], 'getDebugInfo')) {
152                     $template = isset($f['object']) ? $f['object'] : unserialize(sprintf('O:%d:"%s":0:{}', strlen($f['class']), $f['class']));
153
154                     $templateName = $template->getTemplateName();
155                     $templateSrc = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : '');
156                     $templateInfo = $template->getDebugInfo();
157                     if (isset($templateInfo[$f['line']])) {
158                         if (method_exists($template, 'getSourceContext')) {
159                             $templateName = $template->getSourceContext()->getPath() ?: $templateName;
160                         }
161                         if ($templateSrc) {
162                             $templateSrc = explode("\n", $templateSrc);
163                             $src[$templateName.':'.$templateInfo[$f['line']]] = self::extractSource($templateSrc, $templateInfo[$f['line']], self::$srcContext);
164                         } else {
165                             $src[$templateName] = $templateInfo[$f['line']];
166                         }
167                     }
168                 }
169             } else {
170                 $src[$f['file']] = $f['line'];
171             }
172             $a[$prefix.'src'] = new EnumStub($src);
173         }
174
175         unset($a[$prefix.'args'], $a[$prefix.'line'], $a[$prefix.'file']);
176         if ($frame->inTraceStub) {
177             unset($a[$prefix.'class'], $a[$prefix.'type'], $a[$prefix.'function']);
178         }
179         foreach ($a as $k => $v) {
180             if (!$v) {
181                 unset($a[$k]);
182             }
183         }
184         if ($frame->keepArgs && isset($f['args'])) {
185             $a[$prefix.'args'] = $f['args'];
186         }
187
188         return $a;
189     }
190
191     /**
192      * @deprecated since 2.8, to be removed in 3.0. Use the castTraceStub method instead.
193      */
194     public static function filterTrace(&$trace, $dumpArgs, $offset = 0)
195     {
196         @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0. Use the castTraceStub method instead.', E_USER_DEPRECATED);
197
198         if (0 > $offset || empty($trace[$offset])) {
199             return $trace = null;
200         }
201
202         $t = $trace[$offset];
203
204         if (empty($t['class']) && isset($t['function'])) {
205             if ('user_error' === $t['function'] || 'trigger_error' === $t['function']) {
206                 ++$offset;
207             }
208         }
209
210         if ($offset) {
211             array_splice($trace, 0, $offset);
212         }
213
214         foreach ($trace as &$t) {
215             $t = array(
216                 'call' => (isset($t['class']) ? $t['class'].$t['type'] : '').$t['function'].'()',
217                 'file' => isset($t['line']) ? "{$t['file']}:{$t['line']}" : '',
218                 'args' => &$t['args'],
219             );
220
221             if (!isset($t['args']) || !$dumpArgs) {
222                 unset($t['args']);
223             }
224         }
225     }
226
227     private static function filterExceptionArray($xClass, array $a, $xPrefix, $filter)
228     {
229         if (isset($a[$xPrefix.'trace'])) {
230             $trace = $a[$xPrefix.'trace'];
231             unset($a[$xPrefix.'trace']); // Ensures the trace is always last
232         } else {
233             $trace = array();
234         }
235
236         if (!($filter & Caster::EXCLUDE_VERBOSE)) {
237             if (isset($a[Caster::PREFIX_PROTECTED.'file'], $a[Caster::PREFIX_PROTECTED.'line'])) {
238                 array_unshift($trace, array(
239                     'function' => $xClass ? 'new '.$xClass : null,
240                     'file' => $a[Caster::PREFIX_PROTECTED.'file'],
241                     'line' => $a[Caster::PREFIX_PROTECTED.'line'],
242                 ));
243             }
244             $a[$xPrefix.'trace'] = new TraceStub($trace, self::$traceArgs);
245         }
246         if (empty($a[$xPrefix.'previous'])) {
247             unset($a[$xPrefix.'previous']);
248         }
249         unset($a[$xPrefix.'string'], $a[Caster::PREFIX_DYNAMIC.'xdebug_message'], $a[Caster::PREFIX_DYNAMIC.'__destructorException']);
250
251         return $a;
252     }
253
254     private static function extractSource(array $srcArray, $line, $srcContext)
255     {
256         $src = array();
257
258         for ($i = $line - 1 - $srcContext; $i <= $line - 1 + $srcContext; ++$i) {
259             $src[] = (isset($srcArray[$i]) ? $srcArray[$i] : '')."\n";
260         }
261
262         $ltrim = 0;
263         do {
264             $pad = null;
265             for ($i = $srcContext << 1; $i >= 0; --$i) {
266                 if (isset($src[$i][$ltrim]) && "\r" !== ($c = $src[$i][$ltrim]) && "\n" !== $c) {
267                     if (null === $pad) {
268                         $pad = $c;
269                     }
270                     if ((' ' !== $c && "\t" !== $c) || $pad !== $c) {
271                         break;
272                     }
273                 }
274             }
275             ++$ltrim;
276         } while (0 > $i && null !== $pad);
277
278         if (--$ltrim) {
279             foreach ($src as $i => $line) {
280                 $src[$i] = isset($line[$ltrim]) && "\r" !== $line[$ltrim] ? substr($line, $ltrim) : ltrim($line, " \t");
281             }
282         }
283
284         return implode('', $src);
285     }
286 }