PluginProbe
WP Debugging / 2.11.13
WP Debugging v2.11.13
2.12.6 2.12.5 trunk 2.10.0 2.10.1 2.10.2 2.11.0 2.11.1 2.11.10 2.11.11 2.11.12 2.11.13 2.11.14 2.11.15 2.11.16 2.11.17 2.11.18 2.11.19 2.11.2 2.11.20 2.11.21 2.11.22 2.11.23 2.11.24 2.11.3 All 59 releases
wp-debugging / vendor / norcross / debug-quick-look / includes / formatting.php

formatting.php in WP Debugging 2.11.13, at vendor/norcross/debug-quick-look/includes/formatting.php

392 lines 10.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Our various formatting functions.
4 *
5 * @package DebugQuickLook
6 */
7
8 // Call our namepsace.
9 namespace DebugQuickLook\Formatting;
10
11 // Set our alias items.
12 use DebugQuickLook as Core;
13 use DebugQuickLook\Helpers as Helpers;
14
15 /**
16 * Format each line of our log data array.
17 *
18 * @param array $lines The log file lines.
19 *
20 * @return array
21 */
22 function format_parsed_lines( $lines ) {
23
24 // Filter the lines.
25 $lines = apply_filters( Core\HOOK_PREFIX . 'before_line_parse', $lines );
26
27 // Now return the lines.
28 return array_map( __NAMESPACE__ . '\format_single_line', $lines );
29 }
30
31 /**
32 * Format the single parsed line.
33 *
34 * @param string $single The single line.
35 *
36 * @return string The formatted line.
37 */
38 function format_single_line( $single ) {
39
40 // Set our block class before we start manupulating.
41 $div_class = set_parse_block_class( $single );
42
43 // Get our formatting args.
44 $formatting = Helpers\get_formatting_args();
45
46 // Do something if we have no formatting.
47 if ( ! $formatting ) {
48 return wrap_final_return( $single, $div_class );
49 }
50
51 // Loop our formatting functions.
52 foreach ( $formatting as $format => $source ) {
53
54 // Check which formatting callback is setup.
55 $format = 'native' !== sanitize_text_field( $source ) ? $format : __NAMESPACE__ . $format;
56
57 // Run each function individually.
58 $single = call_user_func( $format, $single );
59 }
60
61 // Now return the whole thing.
62 return wrap_final_return( $single, $div_class );
63 }
64
65 /**
66 * Create a class for log file block.
67 *
68 * @param string $single The single line from the log file.
69 *
70 * @return string $class The resulting class.
71 */
72 function set_parse_block_class( $single ) {
73
74 // Set the notice types we want.
75 $types = array(
76 'notice' => 'PHP Notice:',
77 'warning' => 'PHP Warning:',
78 'fatal' => 'PHP Fatal error:',
79 'wordpress-db' => 'WordPress database error',
80 'stack-trace' => 'Stack trace:',
81 'wp-community' => 'WP_Community_Events',
82 );
83
84 // Filter the available types.
85 $types = apply_filters( Core\HOOK_PREFIX . 'block_class_types', $types );
86
87 // Set our default class.
88 $data[] = 'log-entry-block';
89
90 // Now loop them and check each one.
91 foreach ( $types as $key => $text ) {
92
93 // Bail if we don't have it.
94 if ( strpos( $single, $text ) === false ) {
95 continue;
96 }
97
98 // Add the key to our class data array.
99 $data[] = 'log-entry-block-' . esc_attr( $key );
100 }
101
102 // Filter the array of classes.
103 $items = apply_filters( Core\HOOK_PREFIX . 'block_classes', $data );
104
105 // Make sure each one is sanitized.
106 $setup = array_map( 'sanitize_html_class', $items );
107
108 // Return the whole thing.
109 return implode( ' ', $setup );
110 }
111
112 /**
113 * Set up the date block.
114 *
115 * @param string $single The single line.
116 *
117 * @return string The formatted line.
118 */
119 function wrap_dateblock( $single ) {
120
121 // Set up our formatting rules.
122 $format = "~
123 \[( # open outer square brackets and capturing group
124 (?: # open subpattern for optional inner square brackets
125 [^[\]]* # non-square-bracket characters
126 \[ # open inner square bracket
127 [^[\]]* # non-square-bracket characters
128 ] # close inner square bracket
129 )* # end subpattern and repeat it 0 or more times
130 [^[\]]* # non-square-bracket characters
131 )] # end capturing group and outer square brackets
132 (?: # open subpattern for optional parentheses
133 \(( # open parentheses and capturing group
134 [a-z]+ # letters
135 )\) # close capturing group and parentheses
136 )? # end subpattern and make it optional
137 ~isx";
138
139 // Run the big match for the date bracket.
140 preg_match( $format, $single, $matches );
141
142 // If we don't have the dateblock, return what we had.
143 if ( empty( $matches[0] ) ) {
144 return $single;
145 }
146
147 // Format our date.
148 $fdate = date( 'c', strtotime( $matches[1] ) );
149
150 // Set the markup.
151 $markup = '<span class="log-entry-date"><time datetime="' . esc_attr( $fdate ) . '">' . $matches[0] . '</time></span>';
152
153 // Wrap the dateblock itself in a time.
154 $setup = str_replace( $matches[0], $markup, $single );
155
156 // Return it.
157 return apply_filters( Core\HOOK_PREFIX . 'dateblock_wrap', $setup, $single );
158 }
159
160 /**
161 * Set up the stack trace list.
162 *
163 * @param string $single The single line.
164 *
165 * @return string The formatted line.
166 */
167 function wrap_stacktrace( $single ) {
168
169 // Set up our formatting rules.
170 $format = "/Stack trace:\n((?:#\d*.+\n*)+)/m";
171
172 // Run the match check.
173 preg_match( $format, $single, $matches );
174
175 // If we don't have the list, return what we had.
176 if ( empty( $matches[1] ) ) {
177 return $single;
178 }
179
180 // Set our string to be modified.
181 $setup = $single;
182
183 // Create an array of the stack data.
184 $items = explode( PHP_EOL, $matches[1] );
185
186 // Set the empty list tagged items.
187 $ltags = '';
188
189 // Wrap each one with a list tag.
190 foreach ( $items as $line_item ) {
191 $ltags .= '<li class="log-entry-stack-trace-list-item">' . trim( $line_item ) . '</li>';
192 }
193
194 // Wrap the list with the ul tag.
195 $ulwrap = '<ul class="log-entry-stack-trace-list-wrap">' . $ltags . '</ul>';
196
197 // Now merge in the list.
198 $merged = str_replace( $matches[1], $ulwrap, $setup );
199
200 // Set my title.
201 $twrap = '<p class="log-entry-stack-trace-title">Stack trace:</p>';
202
203 // Wrap the stack trace word in a paragraph.
204 $setup = str_replace( 'Stack trace:', $twrap, $merged );
205
206 // Return it.
207 return apply_filters( Core\HOOK_PREFIX . 'stacktrace_wrap', $setup, $single );
208 }
209
210 /**
211 * Wrap any warning types with markup.
212 *
213 * @param string $single The single line from the log file.
214 *
215 * @return string $single The formatted line from the log file.
216 */
217 function wrap_warning_types( $single ) {
218
219 // Set the notice types we want.
220 $types = array(
221 'notice' => 'PHP Notice: ',
222 'warning' => 'PHP Warning: ',
223 'fatal' => 'PHP Fatal error: ',
224 'wordpress-db' => 'WordPress database error ',
225 'wp-community' => 'WP_Community_Events::maybe_log_events_response: ',
226 );
227
228 // Filter the available types.
229 $types = apply_filters( Core\HOOK_PREFIX . 'warning_types', $types );
230
231 // Set our string to be modified.
232 $setup = $single;
233
234 // Now loop them and check each one.
235 foreach ( $types as $key => $text ) {
236
237 // Bail if we don't have it.
238 if ( strpos( $single, $text ) === false ) {
239 continue;
240 }
241
242 // Set the notice class.
243 $nclass = 'log-entry-error-label log-entry-error-' . esc_attr( $key ) . '-label';
244
245 // Set up the wrapped item.
246 $markup = '<span class="' . esc_attr( $nclass ) . '">' . esc_html( rtrim( $text, ': ' ) ) . '</span>' . PHP_EOL;
247
248 // Now wrap it in some markup.
249 $setup = str_replace( $text, $markup, $setup );
250 }
251
252 // Return it with our filter.
253 return apply_filters( Core\HOOK_PREFIX . 'warning_types_wrap', $setup, $single );
254 }
255
256 /**
257 * Wrap any JSON that may exist.
258 *
259 * @param string $single The single line from the log file.
260 *
261 * @return string $single The formatted line from the log file.
262 */
263 function wrap_json_bits( $single ) {
264
265 // Set my format for finding JSON.
266 $format = '/\{(?:[^{}]|(?R))*\}/x';
267
268 // Attempt the preg_match.
269 preg_match_all( $format, $single, $matches );
270
271 // Bail if we have none.
272 if ( empty( $matches[0] ) ) {
273 return $single;
274 }
275
276 // Set our string to be modified.
277 $setup = $single;
278
279 // Loop each bit of JSON and attempt to format it.
280 foreach ( $matches[0] as $found_json ) {
281
282 // Now attempt to decode it.
283 $maybe_json = json_decode( $found_json, true );
284
285 // If we threw an error, return the single line.
286 if ( json_last_error() !== JSON_ERROR_NONE ) {
287 continue;
288 }
289
290 // Get my markup and wrap it in a div.
291 $markup = '<div class="log-entry-json-array-section">' . format_json_array( $maybe_json ) . '</div>';
292
293 // Now wrap it in some markup.
294 $setup = str_replace( $found_json, $markup, $setup );
295 }
296
297 // Return it with our filter.
298 return apply_filters( Core\HOOK_PREFIX . 'json_bits_wrap', $setup, $single );
299 }
300
301 /**************************************
302 Set the various callback formatting.
303 ***************************************/
304
305 /**
306 * Take the JSON array and make it fancy.
307 *
308 * @param array $maybe_json The array parsed from the JSON.
309 *
310 * @return HTML
311 */
312 function format_json_array( $maybe_json ) {
313
314 // Set my empty build.
315 $build = '';
316
317 // Wrap the whole thing in a list.
318 $build .= '<ul class="log-entry-json-array-wrap">';
319
320 // Loop my array and start checking.
321 foreach ( $maybe_json as $key => $value ) {
322
323 // Open it as a list.
324 $build .= '<li class="log-entry-json-array-item">';
325
326 // Set the key as our first label.
327 $build .= '<span class="log-entry-json-array-piece">' . esc_html( $key ) . '</span>';
328
329 // Add our splitter.
330 $build .= '<span class="log-entry-json-array-piece log-entry-json-array-splitter">&nbsp;&equals;&gt;&nbsp;</span>';
331
332 // If the value isn't an array, make a basic list item.
333 if ( ! is_array( $value ) ) {
334
335 // Make boolean a string for display.
336 $value = is_bool( $value ) ? var_export( $value, true ) : $value;
337
338 // Just wrap the piece as per usual.
339 $build .= '<span class="log-entry-json-array-piece">' . esc_html( $value ) . '</span>';
340
341 } else {
342
343 // Set the "array" holder text.
344 $build .= '<span class="log-entry-json-array-piece"><em>' . esc_html__( '(array)', 'debug-quick-look' ) . '</em></span>';
345
346 // And get recursive with it.
347 $build .= format_json_array( $value );
348 }
349
350 // Close the item inside.
351 $build .= '</li>';
352 }
353
354 // Close my list.
355 $build .= '</ul>';
356
357 // Return the entire thing.
358 return $build;
359 }
360
361 /**
362 * Handle the final markup adding.
363 *
364 * @param string $single The formatted line from the log file.
365 * @param string $class What class to include on the div.
366 *
367 * @return string $build The line wrapped in some divs.
368 */
369 function wrap_final_return( $single, $class = '' ) {
370
371 // Now set our display.
372 $build = '';
373
374 // Set the div wrapper.
375 $build .= '<div class="' . esc_attr( $class ) . '">';
376
377 // Add a second div wrapper to mimic the <pre> tag stuff.
378 $build .= '<div class="log-entry-block-pre-wrap">';
379
380 // Output to handle the text remaining.
381 $build .= wpautop( $single, false ); // . "\n";
382
383 // Close the div wrapper.
384 $build .= '</div>';
385
386 // Close the div wrapper.
387 $build .= '</div>';
388
389 // Now return the whole thing.
390 return $build;
391 }
392