1 <?php
2
3 class Kint_Decorators_Plain
4 {
5 private static $_enableColors;
6
7 private static $_cliEffects = array(
8
9 'bold' => '1', 'dark' => '2',
10 'italic' => '3', 'underline' => '4',
11 'blink' => '5', 'reverse' => '7',
12 'concealed' => '8', 'default' => '39',
13
14
15 'black' => '30', 'red' => '31',
16 'green' => '32', 'yellow' => '33',
17 'blue' => '34', 'magenta' => '35',
18 'cyan' => '36', 'light_gray' => '37',
19 'dark_gray' => '90', 'light_red' => '91',
20 'light_green' => '92', 'light_yellow' => '93',
21 'light_blue' => '94', 'light_magenta' => '95',
22 'light_cyan' => '96', 'white' => '97',
23
24
25 'bg_default' => '49', 'bg_black' => '40',
26 'bg_red' => '41', 'bg_green' => '42',
27 'bg_yellow' => '43', 'bg_blue' => '44',
28 'bg_magenta' => '45', 'bg_cyan' => '46',
29 'bg_light_gray' => '47', 'bg_dark_gray' => '100',
30 'bg_light_red' => '101', 'bg_light_green' => '102',
31 'bg_light_yellow' => '103', 'bg_light_blue' => '104',
32 'bg_light_magenta' => '105', 'bg_light_cyan' => '106',
33 'bg_white' => '107',
34 );
35 private static $_utfSymbols = array(
36 '┌', '═', '┐',
37 '│',
38 '└', '─', '┘',
39 );
40 private static $_winShellSymbols = array(
41 "\xda", "\xdc", "\xbf",
42 "\xb3",
43 "\xc0", "\xc4", "\xd9",
44 );
45 private static $_htmlSymbols = array(
46 "┌", "▄", "┐",
47 "│",
48 "└", "─", "┘",
49 );
50
51 public static function decorate( kintVariableData $kintVar, $level = 0 )
52 {
53 $output = '';
54 if ( $level === 0 ) {
55 $name = $kintVar->name ? $kintVar->name : 'literal';
56 $kintVar->name = null;
57
58 $output .= self::_title( $name );
59 }
60
61
62 $space = str_repeat( $s = ' ', $level );
63 $output .= $space . self::_drawHeader( $kintVar );
64
65
66 if ( $kintVar->extendedValue !== null ) {
67 $output .= ' ' . ( $kintVar->type === 'array' ? '[' : '(' ) . PHP_EOL;
68
69
70 if ( is_array( $kintVar->extendedValue ) ) {
71 foreach ( $kintVar->extendedValue as $v ) {
72 $output .= self::decorate( $v, $level + 1 );
73 }
74 } elseif ( is_string( $kintVar->extendedValue ) ) {
75 $output .= $space . $s . $kintVar->extendedValue . PHP_EOL;
76 } else {
77 $output .= self::decorate( $kintVar->extendedValue, $level + 1 );
78 }
79 $output .= $space . ( $kintVar->type === 'array' ? ']' : ')' ) . PHP_EOL;
80 } else {
81 $output .= PHP_EOL;
82 }
83
84 return $output;
85 }
86
87 public static function decorateTrace( $traceData )
88 {
89 $output = self::_title( 'TRACE' );
90 $lastStep = count( $traceData );
91 foreach ( $traceData as $stepNo => $step ) {
92 $title = str_pad( ++$stepNo . ': ', 4, ' ' );
93
94 $title .= self::_colorize(
95 ( isset( $step['file'] ) ? self::_buildCalleeString( $step ) : 'PHP internal call' ),
96 'title'
97 );
98
99 if ( !empty( $step['function'] ) ) {
100 $title .= ' ' . $step['function'];
101 if ( isset( $step['args'] ) ) {
102 $title .= '(';
103 if ( empty( $step['args'] ) ) {
104 $title .= ')';
105 } else {
106 }
107 $title .= PHP_EOL;
108 }
109 }
110
111 $output .= $title;
112
113 if ( !empty( $step['args'] ) ) {
114 $appendDollar = $step['function'] === '{closure}' ? '' : '$';
115
116 $i = 0;
117 foreach ( $step['args'] as $name => $argument ) {
118 $argument = kintParser::factory(
119 $argument,
120 $name ? $appendDollar . $name : '#' . ++$i
121 );
122 $argument->operator = $name ? ' =' : ':';
123 $maxLevels = Kint::$maxLevels;
124 if ( $maxLevels ) {
125 Kint::$maxLevels = $maxLevels + 2;
126 }
127 $output .= self::decorate( $argument, 2 );
128 if ( $maxLevels ) {
129 Kint::$maxLevels = $maxLevels;
130 }
131 }
132 $output .= ' )' . PHP_EOL;
133 }
134
135 if ( !empty( $step['object'] ) ) {
136 $output .= self::_colorize(
137 ' ' . self::_char( '─', 27 ) . ' Callee object ' . self::_char( '─', 34 ),
138 'title'
139 );
140
141 $maxLevels = Kint::$maxLevels;
142 if ( $maxLevels ) {
143
144 Kint::$maxLevels = Kint::enabled() === Kint::MODE_CLI
145 ? 1
146 : $maxLevels + 1;
147 }
148 $output .= self::decorate( kintParser::factory( $step['object'] ), 1 );
149 if ( $maxLevels ) {
150 Kint::$maxLevels = $maxLevels;
151 }
152 }
153
154 if ( $stepNo !== $lastStep ) {
155 $output .= self::_colorize( self::_char( '─', 80 ), 'title' );
156 }
157 }
158
159 return $output;
160 }
161
162
163 private static function _colorize( $text, $type, $nlAfter = true )
164 {
165 $nlAfter = $nlAfter ? PHP_EOL : '';
166
167 switch ( Kint::enabled() ) {
168 case Kint::MODE_PLAIN:
169 if ( !self::$_enableColors ) return $text . $nlAfter;
170
171 switch ( $type ) {
172 case 'value':
173 $text = "<i>{$text}</i>";
174 break;
175 case 'type':
176 $text = "<b>{$text}</b>";
177 break;
178 case 'title':
179 $text = "<u>{$text}</u>";
180 break;
181 }
182
183 return $text . $nlAfter;
184 break;
185 case Kint::MODE_CLI:
186 if ( !self::$_enableColors ) return $text . $nlAfter;
187
188 $optionsMap = array(
189 'title' => "\x1b[36m",
190 'type' => "\x1b[35;1m",
191 'value' => "\x1b[32m",
192 );
193
194 return $optionsMap[ $type ] . $text . "\x1b[0m" . $nlAfter;
195 break;
196 case Kint::MODE_WHITESPACE:
197 default:
198 return $text . $nlAfter;
199 break;
200 }
201 }
202
203
204 private static function _char( $char, $repeat = null )
205 {
206 switch ( Kint::enabled() ) {
207 case Kint::MODE_PLAIN:
208 $char = self::$_htmlSymbols[ array_search( $char, self::$_utfSymbols, true ) ];
209 break;
210 case Kint::MODE_CLI:
211 $inWindowsShell = PHP_SAPI === 'cli' && DIRECTORY_SEPARATOR !== '/';
212 if ( $inWindowsShell ) {
213 $char = self::$_winShellSymbols[ array_search( $char, self::$_utfSymbols, true ) ];
214 }
215 break;
216 case Kint::MODE_WHITESPACE:
217 default:
218 break;
219 }
220
221 return $repeat ? str_repeat( $char, $repeat ) : $char;
222 }
223
224 private static function _title( $text )
225 {
226 $escaped = kintParser::escape( $text );
227 $lengthDifference = strlen( $escaped ) - strlen( $text );
228 return
229 self::_colorize(
230 self::_char( '┌' ) . self::_char( '─', 78 ) . self::_char( '┐' ) . PHP_EOL
231 . self::_char( '│' ),
232 'title',
233 false
234 )
235
236 . self::_colorize( str_pad( $escaped, 78 + $lengthDifference, ' ', STR_PAD_BOTH ), 'title', false )
237
238 . self::_colorize( self::_char( '│' ) . PHP_EOL
239 . self::_char( '└' ) . self::_char( '─', 78 ) . self::_char( '┘' ),
240 'title'
241 );
242 }
243
244 public static function wrapStart()
245 {
246 if ( Kint::enabled() === Kint::MODE_PLAIN ) {
247 return '<pre class="-kint">';
248 }
249 return '';
250 }
251
252 public static function wrapEnd( $callee, $miniTrace, $prevCaller )
253 {
254 $lastLine = self::_colorize( self::_char( "═", 80 ), 'title' );
255 $lastChar = Kint::enabled() === Kint::MODE_PLAIN ? '</pre>' : '';
256
257
258 if ( !Kint::$displayCalledFrom ) return $lastLine . $lastChar;
259
260
261 return $lastLine . self::_colorize( 'Called from ' . self::_buildCalleeString( $callee ), 'title' ) . $lastChar;
262 }
263
264
265 private static function ( kintVariableData $kintVar )
266 {
267 $output = '';
268
269 if ( $kintVar->access ) {
270 $output .= ' ' . $kintVar->access;
271 }
272
273 if ( $kintVar->name !== null && $kintVar->name !== '' ) {
274 $output .= ' ' . kintParser::escape( $kintVar->name );
275 }
276
277 if ( $kintVar->operator ) {
278 $output .= ' ' . $kintVar->operator;
279 }
280
281 $output .= ' ' . self::_colorize( $kintVar->type, 'type', false );
282
283 if ( $kintVar->size !== null ) {
284 $output .= ' (' . $kintVar->size . ')';
285 }
286
287
288 if ( $kintVar->value !== null && $kintVar->value !== '' ) {
289 $output .= ' ' . self::_colorize(
290 $kintVar->value,
291 'value',
292 false
293 );
294 }
295
296 return ltrim( $output );
297 }
298
299 private static function _buildCalleeString( $callee )
300 {
301 if ( Kint::enabled() === Kint::MODE_CLI ) {
302 return "+{$callee['line']} {$callee['file']}";
303 }
304
305 $url = Kint::getIdeLink( $callee['file'], $callee['line'] );
306 $shortenedName = Kint::shortenPath( $callee['file'] ) . ':' . $callee['line'];
307
308 if ( Kint::enabled() === Kint::MODE_PLAIN ) {
309 if ( strpos( $url, 'http://' ) === 0 ) {
310 $calleeInfo = "<a href=\"#\"onclick=\""
311 . "X=new XMLHttpRequest;"
312 . "X.open('GET','{$url}');"
313 . "X.send();"
314 . "return!1\">{$shortenedName}</a>";
315 } else {
316 $calleeInfo = "<a href=\"{$url}\">{$shortenedName}</a>";
317 }
318 } else {
319 $calleeInfo = $shortenedName;
320 }
321
322 return $calleeInfo;
323 }
324
325 public static function init()
326 {
327 self::$_enableColors =
328 Kint::$cliColors
329 && ( DIRECTORY_SEPARATOR === '/' || getenv( 'ANSICON' ) !== false || getenv( 'ConEmuANSI' ) === 'ON' );
330
331 return Kint::enabled() === Kint::MODE_PLAIN
332 ? '<style>.-kint i{color:#d00;font-style:normal}.-kint u{color:#030;text-decoration:none;font-weight:bold}</style>'
333 : '';
334 }
335 }