@@ -42,12 +42,12 @@ class ExceptionCaster
42
42
43
43
public static function castError (\Error $ e , array $ a , Stub $ stub , $ isNested , $ filter = 0 )
44
44
{
45
- return self ::filterExceptionArray ($ a , "\0Error \0" , $ filter );
45
+ return self ::filterExceptionArray ($ stub -> class , $ a , "\0Error \0" , $ filter );
46
46
}
47
47
48
48
public static function castException (\Exception $ e , array $ a , Stub $ stub , $ isNested , $ filter = 0 )
49
49
{
50
- return self ::filterExceptionArray ($ a , "\0Exception \0" , $ filter );
50
+ return self ::filterExceptionArray ($ stub -> class , $ a , "\0Exception \0" , $ filter );
51
51
}
52
52
53
53
public static function castErrorException (\ErrorException $ e , array $ a , Stub $ stub , $ isNested )
@@ -64,24 +64,133 @@ public static function castThrowingCasterException(ThrowingCasterException $e, a
64
64
$ prefix = Caster::PREFIX_PROTECTED ;
65
65
$ xPrefix = "\0Exception \0" ;
66
66
67
- if (isset ($ a [$ xPrefix .'previous ' ], $ a [$ xPrefix .'trace ' ][ 0 ] )) {
67
+ if (isset ($ a [$ xPrefix .'previous ' ], $ a [$ xPrefix .'trace ' ])) {
68
68
$ b = (array ) $ a [$ xPrefix .'previous ' ];
69
- $ b [$ xPrefix .'trace ' ][0 ] += array (
69
+ array_unshift ($ b [$ xPrefix .'trace ' ], array (
70
+ 'function ' => 'new ' .get_class ($ a [$ xPrefix .'previous ' ]),
70
71
'file ' => $ b [$ prefix .'file ' ],
71
72
'line ' => $ b [$ prefix .'line ' ],
73
+ ));
74
+ $ a [$ xPrefix .'trace ' ] = new TraceStub ($ b [$ xPrefix .'trace ' ], 1 , false , 0 , -1 - count ($ a [$ xPrefix .'trace ' ]->value ));
75
+ }
76
+
77
+ unset($ a [$ xPrefix .'previous ' ], $ a [$ prefix .'code ' ], $ a [$ prefix .'file ' ], $ a [$ prefix .'line ' ]);
78
+
79
+ return $ a ;
80
+ }
81
+
82
+ public static function castTraceStub (TraceStub $ trace , array $ a , Stub $ stub , $ isNested )
83
+ {
84
+ if (!$ isNested ) {
85
+ return $ a ;
86
+ }
87
+ $ stub ->class = '' ;
88
+ $ stub ->handle = 0 ;
89
+ $ frames = $ trace ->value ;
90
+
91
+ $ a = array ();
92
+ $ j = count ($ frames );
93
+ if (0 > $ i = $ trace ->offset ) {
94
+ $ i = max (0 , $ j + $ i );
95
+ }
96
+ if (!isset ($ trace ->value [$ i ])) {
97
+ return array ();
98
+ }
99
+ $ lastCall = isset ($ frames [$ i ]['function ' ]) ? ' ==> ' .(isset ($ frames [$ i ]['class ' ]) ? $ frames [0 ]['class ' ].$ frames [$ i ]['type ' ] : '' ).$ frames [$ i ]['function ' ].'() ' : '' ;
100
+
101
+ for ($ j -= $ i ++; isset ($ frames [$ i ]); ++$ i , --$ j ) {
102
+ $ call = isset ($ frames [$ i ]['function ' ]) ? (isset ($ frames [$ i ]['class ' ]) ? $ frames [$ i ]['class ' ].$ frames [$ i ]['type ' ] : '' ).$ frames [$ i ]['function ' ].'() ' : '??? ' ;
103
+
104
+ $ a [Caster::PREFIX_VIRTUAL .$ j .'. ' .$ call .$ lastCall ] = new FrameStub (
105
+ array (
106
+ 'object ' => isset ($ frames [$ i ]['object ' ]) ? $ frames [$ i ]['object ' ] : null ,
107
+ 'class ' => isset ($ frames [$ i ]['class ' ]) ? $ frames [$ i ]['class ' ] : null ,
108
+ 'type ' => isset ($ frames [$ i ]['type ' ]) ? $ frames [$ i ]['type ' ] : null ,
109
+ 'function ' => isset ($ frames [$ i ]['function ' ]) ? $ frames [$ i ]['function ' ] : null ,
110
+ ) + $ frames [$ i - 1 ],
111
+ $ trace ->srcContext ,
112
+ $ trace ->keepArgs ,
113
+ true
72
114
);
73
- array_splice ($ b [$ xPrefix .'trace ' ], -1 - count ($ a [$ xPrefix .'trace ' ]));
74
- static ::filterTrace ($ b [$ xPrefix .'trace ' ], false );
75
- $ a [Caster::PREFIX_VIRTUAL .'trace ' ] = $ b [$ xPrefix .'trace ' ];
115
+
116
+ $ lastCall = ' ==> ' .$ call ;
76
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 ->srcContext ,
126
+ $ trace ->keepArgs ,
127
+ true
128
+ );
129
+ if (null !== $ trace ->length ) {
130
+ $ a = array_slice ($ a , 0 , $ trace ->length , true );
131
+ }
132
+
133
+ return $ a ;
134
+ }
77
135
78
- unset($ a [$ xPrefix .'trace ' ], $ a [$ xPrefix .'previous ' ], $ a [$ prefix .'code ' ], $ a [$ prefix .'file ' ], $ a [$ prefix .'line ' ]);
136
+ public static function castFrameStub (FrameStub $ frame , array $ a , Stub $ stub , $ isNested )
137
+ {
138
+ if (!$ isNested ) {
139
+ return $ a ;
140
+ }
141
+ $ f = $ frame ->value ;
142
+ $ prefix = Caster::PREFIX_VIRTUAL ;
143
+
144
+ if (isset ($ f ['file ' ], $ f ['line ' ])) {
145
+ if (preg_match ('/\((\d+)\)(?:\([\da-f]{32}\))? : (?:eval\(\) \'d code|runtime-created function)$/ ' , $ f ['file ' ], $ match )) {
146
+ $ f ['file ' ] = substr ($ f ['file ' ], 0 , -strlen ($ match [0 ]));
147
+ $ f ['line ' ] = (int ) $ match [1 ];
148
+ }
149
+ if (file_exists ($ f ['file ' ]) && 0 <= $ frame ->srcContext ) {
150
+ $ src [$ f ['file ' ].': ' .$ f ['line ' ]] = self ::extractSource (explode ("\n" , file_get_contents ($ f ['file ' ])), $ f ['line ' ], $ frame ->srcContext );
151
+
152
+ if (!empty ($ f ['class ' ]) && is_subclass_of ($ f ['class ' ], 'Twig_Template ' ) && method_exists ($ f ['class ' ], 'getDebugInfo ' )) {
153
+ $ template = isset ($ f ['object ' ]) ? $ f ['object ' ] : new $ f ['class ' ](new \Twig_Environment (new \Twig_Loader_Filesystem ()));
154
+
155
+ try {
156
+ $ templateName = $ template ->getTemplateName ();
157
+ $ templateSrc = explode ("\n" , method_exists ($ template , 'getSource ' ) ? $ template ->getSource () : $ template ->getEnvironment ()->getLoader ()->getSource ($ templateName ));
158
+ $ templateInfo = $ template ->getDebugInfo ();
159
+ if (isset ($ templateInfo [$ f ['line ' ]])) {
160
+ $ src [$ templateName .': ' .$ templateInfo [$ f ['line ' ]]] = self ::extractSource ($ templateSrc , $ templateInfo [$ f ['line ' ]], $ frame ->srcContext );
161
+ }
162
+ } catch (\Twig_Error_Loader $ e ) {
163
+ }
164
+ }
165
+ } else {
166
+ $ src [$ f ['file ' ]] = $ f ['line ' ];
167
+ }
168
+ $ a [$ prefix .'src ' ] = new EnumStub ($ src );
169
+ }
170
+
171
+ unset($ a [$ prefix .'args ' ], $ a [$ prefix .'line ' ], $ a [$ prefix .'file ' ]);
172
+ if ($ frame ->inTraceStub ) {
173
+ unset($ a [$ prefix .'class ' ], $ a [$ prefix .'type ' ], $ a [$ prefix .'function ' ]);
174
+ }
175
+ foreach ($ a as $ k => $ v ) {
176
+ if (!$ v ) {
177
+ unset($ a [$ k ]);
178
+ }
179
+ }
180
+ if ($ frame ->keepArgs && isset ($ f ['args ' ])) {
181
+ $ a [$ prefix .'args ' ] = $ f ['args ' ];
182
+ }
79
183
80
184
return $ a ;
81
185
}
82
186
187
+ /**
188
+ * @deprecated since 2.8, to be removed in 3.0. Use the castTraceStub method instead.
189
+ */
83
190
public static function filterTrace (&$ trace , $ dumpArgs , $ offset = 0 )
84
191
{
192
+ @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 );
193
+
85
194
if (0 > $ offset || empty ($ trace [$ offset ])) {
86
195
return $ trace = null ;
87
196
}
@@ -111,7 +220,7 @@ public static function filterTrace(&$trace, $dumpArgs, $offset = 0)
111
220
}
112
221
}
113
222
114
- private static function filterExceptionArray (array $ a , $ xPrefix , $ filter )
223
+ private static function filterExceptionArray ($ xClass , array $ a , $ xPrefix , $ filter )
115
224
{
116
225
if (isset ($ a [$ xPrefix .'trace ' ])) {
117
226
$ trace = $ a [$ xPrefix .'trace ' ];
@@ -121,11 +230,12 @@ private static function filterExceptionArray(array $a, $xPrefix, $filter)
121
230
}
122
231
123
232
if (!($ filter & Caster::EXCLUDE_VERBOSE )) {
124
- static ::filterTrace ($ trace , static ::$ traceArgs );
125
-
126
- if (null !== $ trace ) {
127
- $ a [$ xPrefix .'trace ' ] = $ trace ;
128
- }
233
+ array_unshift ($ trace , array (
234
+ 'function ' => $ xClass ? 'new ' .$ xClass : null ,
235
+ 'file ' => $ a [Caster::PREFIX_PROTECTED .'file ' ],
236
+ 'line ' => $ a [Caster::PREFIX_PROTECTED .'line ' ],
237
+ ));
238
+ $ a [$ xPrefix .'trace ' ] = new TraceStub ($ trace );
129
239
}
130
240
if (empty ($ a [$ xPrefix .'previous ' ])) {
131
241
unset($ a [$ xPrefix .'previous ' ]);
@@ -134,4 +244,18 @@ private static function filterExceptionArray(array $a, $xPrefix, $filter)
134
244
135
245
return $ a ;
136
246
}
247
+
248
+ private static function extractSource (array $ srcArray , $ line , $ srcContext )
249
+ {
250
+ $ src = '' ;
251
+
252
+ for ($ i = $ line - 1 - $ srcContext ; $ i <= $ line - 1 + $ srcContext ; ++$ i ) {
253
+ $ src .= (isset ($ srcArray [$ i ]) ? $ srcArray [$ i ] : '' )."\n" ;
254
+ }
255
+ if (!$ srcContext ) {
256
+ $ src = trim ($ src );
257
+ }
258
+
259
+ return $ src ;
260
+ }
137
261
}
0 commit comments