1 <?php
2
3 class Kint_Decorators_Rich
4 {
5
6 private static $_usedColors = array();
7
8 public static function decorate( kintVariableData $kintVar )
9 {
10 $output = '<dl>';
11
12 $extendedPresent = $kintVar->extendedValue !== null || $kintVar->_alternatives !== null;
13
14 if ( $extendedPresent ) {
15 $class = 'kint-parent';
16 if ( Kint::$expandedByDefault ) {
17 $class .= ' kint-show';
18 }
19 $output .= '<dt class="' . $class . '">';
20 } else {
21 $output .= '<dt>';
22 }
23
24 if ( $extendedPresent ) {
25 $output .= '<span class="kint-popup-trigger" title="Open in new window">→</span><nav></nav>';
26 }
27
28 $output .= self::_drawHeader( $kintVar ) . $kintVar->value . '</dt>';
29
30
31 if ( $extendedPresent ) {
32 $output .= '<dd>';
33 }
34
35 if ( isset( $kintVar->extendedValue ) ) {
36
37 if ( is_array( $kintVar->extendedValue ) ) {
38 foreach ( $kintVar->extendedValue as $v ) {
39 $output .= self::decorate( $v );
40 }
41 } elseif ( is_string( $kintVar->extendedValue ) ) {
42 $output .= '<pre>' . $kintVar->extendedValue . '</pre>';
43 } else {
44 $output .= self::decorate( $kintVar->extendedValue );
45 }
46
47 } elseif ( isset( $kintVar->_alternatives ) ) {
48 $output .= "<ul class=\"kint-tabs\">";
49
50 foreach ( $kintVar->_alternatives as $k => $var ) {
51 $active = $k === 0 ? ' class="kint-active-tab"' : '';
52 $output .= "<li{$active}>" . self::_drawHeader( $var, false ) . '</li>';
53 }
54
55 $output .= "</ul><ul>";
56
57 foreach ( $kintVar->_alternatives as $var ) {
58 $output .= "<li>";
59
60 $var = $var->value;
61
62 if ( is_array( $var ) ) {
63 foreach ( $var as $v ) {
64 $output .= is_string( $v )
65 ? '<pre>' . $v . '</pre>'
66 : self::decorate( $v );
67 }
68 } elseif ( is_string( $var ) ) {
69 $output .= '<pre>' . $var . '</pre>';
70 } elseif ( isset( $var ) ) {
71 throw new Exception(
72 'Kint has encountered an error, '
73 . 'please paste this report to https://github.com/raveren/kint/issues<br>'
74 . 'Error encountered at ' . basename( __FILE__ ) . ':' . __LINE__ . '<br>'
75 . ' variables: '
76 . htmlspecialchars( var_export( $kintVar->_alternatives, true ), ENT_QUOTES )
77 );
78 }
79
80 $output .= "</li>";
81 }
82
83 $output .= "</ul>";
84 }
85 if ( $extendedPresent ) {
86 $output .= '</dd>';
87 }
88
89 $output .= '</dl>';
90
91 return $output;
92 }
93
94 public static function decorateTrace( $traceData )
95 {
96 $output = '<dl class="kint-trace">';
97
98 foreach ( $traceData as $i => $step ) {
99 $class = 'kint-parent';
100 if ( Kint::$expandedByDefault ) {
101 $class .= ' kint-show';
102 }
103
104 $output .= '<dt class="' . $class . '">'
105 . '<b>' . ( $i + 1 ) . '</b> '
106 . '<nav></nav>'
107 . '<var>';
108
109 if ( isset( $step['file'] ) ) {
110 $output .= self::_ideLink( $step['file'], $step['line'] );
111 } else {
112 $output .= 'PHP internal call';
113 }
114
115 $output .= '</var>';
116
117 $output .= $step['function'];
118
119 if ( isset( $step['args'] ) ) {
120 $output .= '(' . implode( ', ', array_keys( $step['args'] ) ) . ')';
121 }
122 $output .= '</dt><dd>';
123 $firstTab = ' class="kint-active-tab"';
124 $output .= '<ul class="kint-tabs">';
125
126 if ( !empty( $step['source'] ) ) {
127 $output .= "<li{$firstTab}>Source</li>";
128 $firstTab = '';
129 }
130
131 if ( !empty( $step['args'] ) ) {
132 $output .= "<li{$firstTab}>Arguments</li>";
133 $firstTab = '';
134 }
135
136 if ( !empty( $step['object'] ) ) {
137 kintParser::reset();
138 $calleeDump = kintParser::factory( $step['object'] );
139
140 $output .= "<li{$firstTab}>Callee object [{$calleeDump->type}]</li>";
141 }
142
143
144 $output .= '</ul><ul>';
145
146
147 if ( !empty( $step['source'] ) ) {
148 $output .= "<li><pre class=\"kint-source\">{$step['source']}</pre></li>";
149 }
150
151 if ( !empty( $step['args'] ) ) {
152 $output .= "<li>";
153 foreach ( $step['args'] as $k => $arg ) {
154 kintParser::reset();
155 $output .= self::decorate( kintParser::factory( $arg, $k ) );
156 }
157 $output .= "</li>";
158 }
159 if ( !empty( $step['object'] ) ) {
160 $output .= "<li>" . self::decorate( $calleeDump ) . "</li>";
161 }
162
163 $output .= '</ul></dd>';
164 }
165 $output .= '</dl>';
166
167 return $output;
168 }
169
170
171 172 173 174 175 176 177
178 public static function wrapStart()
179 {
180 return "<div class=\"kint\">";
181 }
182
183
184 185 186 187 188 189 190 191 192
193 public static function wrapEnd( $callee, $miniTrace, $prevCaller )
194 {
195 if ( !Kint::$displayCalledFrom ) {
196 return '</div>';
197 }
198
199 $callingFunction = '';
200 $calleeInfo = '';
201 $traceDisplay = '';
202 if ( isset( $prevCaller['class'] ) ) {
203 $callingFunction = $prevCaller['class'];
204 }
205 if ( isset( $prevCaller['type'] ) ) {
206 $callingFunction .= $prevCaller['type'];
207 }
208 if ( isset( $prevCaller['function'] )
209 && !in_array( $prevCaller['function'], array( 'include', 'include_once', 'require', 'require_once' ) )
210 ) {
211 $callingFunction .= $prevCaller['function'] . '()';
212 }
213 $callingFunction and $callingFunction = " [{$callingFunction}]";
214
215
216 if ( isset( $callee['file'] ) ) {
217 $calleeInfo .= 'Called from ' . self::_ideLink( $callee['file'], $callee['line'] );
218 }
219
220 if ( !empty( $miniTrace ) ) {
221 $traceDisplay = '<ol>';
222 foreach ( $miniTrace as $step ) {
223 $traceDisplay .= '<li>' . self::_ideLink( $step['file'], $step['line'] );
224 if ( isset( $step['function'] )
225 && !in_array( $step['function'], array( 'include', 'include_once', 'require', 'require_once' ) )
226 ) {
227 $classString = ' [';
228 if ( isset( $step['class'] ) ) {
229 $classString .= $step['class'];
230 }
231 if ( isset( $step['type'] ) ) {
232 $classString .= $step['type'];
233 }
234 $classString .= $step['function'] . '()]';
235 $traceDisplay .= $classString;
236 }
237 }
238 $traceDisplay .= '</ol>';
239
240 $calleeInfo = '<nav></nav>' . $calleeInfo;
241 }
242
243
244 return "<footer>"
245 . '<span class="kint-popup-trigger" title="Open in new window">→</span> '
246 . "{$calleeInfo}{$callingFunction}{$traceDisplay}"
247 . "</footer></div>";
248 }
249
250
251 private static function ( kintVariableData $kintVar, $verbose = true )
252 {
253 $output = '';
254 if ( $verbose ) {
255 if ( $kintVar->access !== null ) {
256 $output .= "<var>" . $kintVar->access . "</var> ";
257 }
258
259 if ( $kintVar->name !== null && $kintVar->name !== '' ) {
260 $output .= "<dfn>" . kintParser::escape( $kintVar->name ) . "</dfn> ";
261 }
262
263 if ( $kintVar->operator !== null ) {
264 $output .= $kintVar->operator . " ";
265 }
266 }
267
268 if ( $kintVar->type !== null ) {
269 if ( $verbose ) {
270 $output .= "<var>";
271 }
272
273 $output .= $kintVar->type;
274
275 if ( $verbose ) {
276 $output .= "</var>";
277 } else {
278 $output .= " ";
279 }
280 }
281
282
283 if ( $kintVar->size !== null ) {
284 $output .= "(" . $kintVar->size . ") ";
285 }
286
287 return $output;
288 }
289
290 private static function _ideLink( $file, $line )
291 {
292 $shortenedPath = Kint::shortenPath( $file );
293 if ( !Kint::$fileLinkFormat ) return $shortenedPath . ':' . $line;
294
295 $ideLink = Kint::getIdeLink( $file, $line );
296 $class = ( strpos( $ideLink, 'http://' ) === 0 ) ? 'class="kint-ide-link" ' : '';
297 return "<a {$class}href=\"{$ideLink}\">{$shortenedPath}:{$line}</a>";
298 }
299
300
301 302 303 304 305 306
307 public static function init()
308 {
309 $baseDir = KINT_DIR . 'view/compiled/';
310
311 if ( !is_readable( $cssFile = $baseDir . Kint::$theme . '.css' ) ) {
312 $cssFile = $baseDir . 'original.css';
313 }
314
315 return
316 '<script class="-kint-js">' . file_get_contents( $baseDir . 'kint.js' ) . '</script>'
317 . '<style class="-kint-css">' . file_get_contents( $cssFile ) . "</style>\n";
318 }
319 }