PluginProbe
WPSSO Core – Complete Schema Markup and Meta Tags / trunk
WPSSO Core – Complete Schema Markup and Meta Tags vtrunk
22.6.1 22.6.0 22.5.3 22.5.2 22.5.1 22.4.0 22.3.0 22.2.1 22.2.0 22.1.3 22.1.2 22.1.1 22.1.0 22.0.0 21.13.3 21.13.2 trunk 21.13.1
wpsso / lib / com / debug.php

debug.php in WPSSO Core – Complete Schema Markup and Meta Tags trunk, at lib/com/debug.php

477 lines 11.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 * License: GPLv3
4 * License URI: https://www.gnu.org/licenses/gpl.txt
5 * Copyright 2012-2026 Jean-Sebastien Morisset (https://surniaulula.com/)
6 */
7
8 if ( ! defined( 'ABSPATH' ) ) {
9
10 die( 'These aren\'t the droids you\'re looking for.' );
11 }
12
13 if ( ! class_exists( 'SucomDebug' ) ) {
14
15 class SucomDebug {
16
17 private $p; // Plugin class object.
18 private $display_name = '';
19 private $log_prefix = '';
20 private $log_buffer = array(); // Accumulate text strings going to html output.
21 private $outputs = array(); // Associative array to enable various outputs.
22 private $const_stats = array();
23 private $begin_stats = array();
24 private $last_stats = array();
25 private $log_fmt_cols = array( '%s ::', '%s :' );
26
27 public $enabled = false; // True if at least one $outputs array element is true.
28
29 public function __construct( &$plugin, array $outputs = array( 'html' => false, 'log' => false ) ) {
30
31 if ( ! class_exists( 'SucomUtil' ) ) { // Just in case.
32
33 require_once trailingslashit( dirname( __FILE__ ) ) . 'util.php';
34 }
35
36 if ( ! class_exists( 'SucomUtilWP' ) ) { // Just in case.
37
38 require_once trailingslashit( dirname( __FILE__ ) ) . 'util-wp.php';
39 }
40
41 $this->p =& $plugin;
42
43 $this->const_stats = $this->last_stats = array( 'mtime' => microtime( $get_float = true ), 'mem' => memory_get_usage() );
44 $this->display_name = isset( $this->p->id ) ? $this->p->id : 'sucom';
45 $this->log_prefix = strtoupper( $this->display_name );
46 $this->outputs = $outputs;
47
48 $this->is_enabled(); // Sets $this->enabled value.
49
50 if ( ! empty( $this->outputs[ 'log' ] ) ) {
51
52 if ( ! isset( $_SESSION ) ) {
53
54 session_start();
55 }
56 }
57
58 if ( $this->enabled ) {
59
60 $this->mark();
61 }
62
63 add_action( 'shutdown', array( $this, 'shutdown_stats' ), -1000, 0 );
64 }
65
66 public function shutdown_stats() {
67
68 if ( $this->enabled ) {
69
70 $cur_stats = array( 'mtime' => microtime( $get_float = true ), 'mem' => memory_get_usage() );
71 $mtime_diff = $cur_stats[ 'mtime' ] - $this->const_stats[ 'mtime' ];
72 $mem_diff = $cur_stats[ 'mem' ] - $this->const_stats[ 'mem' ];
73
74 $this->log( 'time diff = ' . $this->get_time_text( $mtime_diff ) );
75 $this->log( 'mem diff = ' . $this->get_bytes_text( $mem_diff ) );
76 $this->log( 'mem peak = ' . $this->get_bytes_text( memory_get_peak_usage() ) );
77 }
78 }
79
80 public function is_enabled( $name = '' ) {
81
82 if ( ! empty( $name ) ) {
83
84 return isset( $this->outputs[ $name ] ) ? $this->outputs[ $name ] : false;
85 }
86
87 return $this->enabled = in_array( true, $this->outputs ) ? true : false; // True if any sybsys is true.
88 }
89
90 public function enable( $name, $state = true ) {
91
92 $prev_state = $this->is_enabled( $name );
93
94 if ( ! empty( $name ) ) {
95
96 $this->outputs[ $name ] = $state;
97
98 if ( 'log' === $name ) {
99
100 if ( ! isset( $_SESSION ) ) {
101
102 session_start();
103 }
104 }
105 }
106
107 $this->is_enabled(); // Sets $this->enabled value.
108
109 return $prev_state; // Return the previous state to save and restore.
110 }
111
112 public function disable( $name, $state = false ) {
113
114 return $this->enable( $name, $state ); // Return the previous state to save and restore.
115 }
116
117 public function log_args( array $arr, $class_seq = 1, $func_seq = false ) {
118
119 if ( ! $this->enabled ) {
120
121 return;
122 }
123
124 if ( is_int( $class_seq ) ) {
125
126 if ( false === $func_seq ) {
127
128 $func_seq = $class_seq;
129 }
130
131 $class_seq++;
132 }
133
134 if ( is_int( $func_seq ) ) {
135
136 $func_seq++;
137
138 } elseif ( false === $func_seq ) {
139
140 $func_seq = 2;
141 }
142
143 $this->log( 'args ' . SucomUtil::get_array_pretty( $arr, $flatten = true ), $class_seq, $func_seq );
144 }
145
146 public function log_arr( $prefix, $mixed, $class_seq = 1, $func_seq = false ) {
147
148 if ( ! $this->enabled ) {
149
150 return;
151 }
152
153 if ( is_int( $class_seq ) ) {
154
155 if ( false === $func_seq ) {
156
157 $func_seq = $class_seq;
158 }
159
160 $class_seq++;
161 }
162
163 if ( is_int( $func_seq ) ) {
164
165 $func_seq++;
166
167 } elseif ( false === $func_seq ) {
168
169 $func_seq = 2;
170 }
171
172 if ( is_object( $mixed ) ) {
173
174 $prefix = trim( $prefix . ' ' . get_class( $mixed ) . ' object vars' );
175
176 $mixed = get_object_vars( $mixed );
177 }
178
179 if ( is_array( $mixed ) ) {
180
181 $this->log( $prefix . ' = ' . trim( print_r( SucomUtil::get_array_pretty( $mixed, false ), true ) ), $class_seq, $func_seq );
182
183 } else $this->log( $prefix . ' = ' . $mixed, $class_seq, $func_seq );
184 }
185
186 public function log_size( $prefix, $mixed, $class_seq = 1, $func_seq = false ) {
187
188 if ( ! $this->enabled ) {
189
190 return;
191 }
192
193 if ( is_int( $class_seq ) ) {
194
195 if ( false === $func_seq ) {
196
197 $func_seq = $class_seq;
198 }
199
200 $class_seq++;
201 }
202
203 if ( is_int( $func_seq ) ) {
204
205 $func_seq++;
206
207 } elseif ( false === $func_seq ) {
208
209 $func_seq = 2;
210 }
211
212 $this->log( 'serialized size of ' . $prefix . ' is ' . $this->get_bytes_text( mb_strlen( serialize( $mixed ), '8bit' ) ), $class_seq, $func_seq );
213 }
214
215 public function log( $input = '', $class_seq = 1, $func_seq = false ) {
216
217 if ( ! $this->enabled ) {
218
219 return;
220 }
221
222 $log_msg = '';
223 $stack = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
224
225 if ( is_int( $class_seq ) ) {
226
227 if ( false === $func_seq ) {
228
229 $func_seq = $class_seq;
230 }
231
232 $class_name = empty( $stack[ $class_seq ][ 'class' ] ) ? '' : $stack[ $class_seq ][ 'class' ];
233
234 $log_msg .= sprintf( $this->log_fmt_cols[ 0 ], $class_name ) . ' ';
235
236 } else {
237
238 if ( false === $func_seq ) {
239
240 $func_seq = 1;
241 }
242
243 $log_msg .= sprintf( $this->log_fmt_cols[ 0 ], $class_seq ) . ' ';
244 }
245
246 if ( is_int( $func_seq ) ) {
247
248 $func_name = empty( $stack[ $func_seq ][ 'function' ] ) ? '' : $stack[ $func_seq ][ 'function' ];
249
250 $log_msg .= sprintf( $this->log_fmt_cols[ 1 ], $func_name ) . ' ';
251
252 } else $log_msg .= sprintf( $this->log_fmt_cols[ 1 ], $func_seq ) . ' ';
253
254 if ( is_multisite() ) {
255
256 global $blog_id;
257
258 $log_msg .= '[blog ' . $blog_id . '] ';
259 }
260
261 if ( is_array( $input ) ) {
262
263 $log_msg .= trim( print_r( $input, true ) );
264
265 } elseif ( is_object( $input ) ) {
266
267 $log_msg .= print_r( 'object ' . get_class( $input ), true );
268
269 } else $log_msg .= $input;
270
271 if ( $this->outputs[ 'html' ] ) {
272
273 $this->log_buffer[] = $log_msg;
274 }
275
276 if ( $this->outputs[ 'log' ] ) {
277
278 $session_id = session_id();
279
280 $connection_id = $session_id ? $session_id : $_SERVER[ 'REMOTE_ADDR' ];
281 $connection_id = SucomUtilWP::doing_ajax() ? 'ajax ' . $connection_id : $connection_id;
282 $connection_id = SucomUtilWP::doing_cron() ? 'cron ' . $connection_id : $connection_id;
283
284 error_log( $connection_id . ' ' . $this->log_prefix . ' ' . $log_msg );
285 }
286 }
287
288 public function mark( $id = false, $comment = '', $class_seq = 2 ) {
289
290 if ( ! $this->enabled ) {
291
292 return;
293 }
294
295 $cur_stats = array( 'mtime' => microtime( $get_float = true ), 'mem' => memory_get_usage() );
296 $comment = $comment ? ' ' . $comment : '';
297 $sep_text = '';
298
299 if ( false !== $id ) {
300
301 $sep_text .= "\n\t" . '- - - - - - ' . $id;
302
303 if ( isset( $this->begin_stats[ $id ] ) ) {
304
305 $mtime_diff = $cur_stats[ 'mtime' ] - $this->begin_stats[ $id ][ 'mtime' ];
306 $mem_diff = $cur_stats[ 'mem' ] - $this->begin_stats[ $id ][ 'mem' ];
307 $stats_text = '+' . $this->get_time_text( $mtime_diff ) . ' / +' . $this->get_bytes_text( $mem_diff );
308
309 $sep_text .= ' end diff (' . $stats_text . ')';
310
311 unset( $this->begin_stats[ $id ] );
312
313 } else {
314
315 $this->begin_stats[ $id ] = array( 'mtime' => $cur_stats[ 'mtime' ], 'mem' => $cur_stats[ 'mem' ] );
316
317 $sep_text .= ' begin';
318 }
319 }
320
321 /*
322 * $this->const_stats is defined in the class __construct().
323 */
324 $mtime_diff = $cur_stats[ 'mtime' ] - $this->const_stats[ 'mtime' ];
325 $mem_diff = $cur_stats[ 'mem' ] - $this->const_stats[ 'mem' ];
326 $stats_text = $this->get_time_text( $mtime_diff ) . ' / ' . $this->get_bytes_text( $mem_diff );
327
328 $this->log( 'mark (' . $stats_text . ')' . $comment . $sep_text, $class_seq );
329 }
330
331 /*
332 * See WpssoComment->get_mod().
333 * See WpssoComment->get_options().
334 * See WpssoPost->get_mod().
335 * See WpssoPost->get_options().
336 * See WpssoTerm->get_mod().
337 * See WpssoTerm->get_options().
338 * See WpssoUser->get_mod().
339 * See WpssoUser->get_options().
340 */
341 public function mark_caller( $comment = '' ) {
342
343 $stack = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
344 $class_seq = 2;
345 $class_name = empty( $stack[ $class_seq ][ 'class' ] ) ? '' : $stack[ $class_seq ][ 'class' ];
346
347 $this->log( trim( 'called by ' . $class_name . ' ' . $comment ), $class_seq );
348 }
349
350 public function mark_diff( $comment = '', $class_seq = 2 ) {
351
352 if ( ! $this->enabled ) {
353
354 return;
355 }
356
357 $comment = $comment ? ' ' . $comment : '';
358 $cur_stats = array( 'mtime' => microtime( $get_float = true ), 'mem' => memory_get_usage() );
359 $mtime_diff = $cur_stats[ 'mtime' ] - $this->last_stats[ 'mtime' ];
360 $mem_diff = $cur_stats[ 'mem' ] - $this->last_stats[ 'mem' ];
361 $stats_text = '+' . $this->get_time_text( $mtime_diff ) . ' / +' . $this->get_bytes_text( $mem_diff );
362
363 $this->last_stats = $cur_stats;
364
365 $this->log( 'mark diff (' . $stats_text . ')' . $comment, $class_seq );
366 }
367
368 private function get_time_text( $time ) {
369
370 return sprintf( '%f secs', $time );
371 }
372
373 private function get_bytes_text( $mem ) {
374
375 return SucomUtil::format_human_bytes( $mem, $dec = 2 );
376 }
377
378 /*
379 * See Wpsso->debug_hooks().
380 */
381 public function show_html( $data = null, $title = null ) {
382
383 if ( ! $this->is_enabled( 'html' ) ) return;
384
385 echo $this->get_html( $data, $title, 2 );
386 }
387
388 public function get_html( $data = null, $title = null, $class_seq = 1, $func_seq = false ) {
389
390 if ( ! $this->is_enabled( 'html' ) ) return;
391
392 if ( false === $func_seq ) {
393
394 $func_seq = $class_seq;
395 }
396
397 $html = '<!-- ' . $this->display_name . ' debug';
398 $stack = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
399 $from = '';
400
401 if ( ! empty( $stack[ $class_seq ][ 'class' ] ) ) {
402
403 $from .= $stack[ $class_seq ][ 'class' ] . '::';
404 }
405
406 if ( ! empty( $stack[ $func_seq ][ 'function' ] ) ) {
407
408 $from .= $stack[ $func_seq ][ 'function' ];
409 }
410
411 if ( null === $data ) {
412
413 $data = $this->log_buffer;
414
415 $this->log_buffer = array(); // Truncate the buffer.
416 }
417
418 if ( ! empty( $from ) ) {
419
420 $html .= ' from ' . $from . '()';
421 }
422
423 if ( ! empty( $title ) ) {
424
425 $html .= ' ' . $title;
426 }
427
428 if ( ! empty( $data ) ) {
429
430 $html .= ' : ';
431
432 if ( is_array( $data ) ) {
433
434 $html .= "\n";
435
436 $is_assoc = SucomUtil::is_assoc( $data );
437
438 if ( $is_assoc ) {
439
440 ksort( $data );
441 }
442
443 foreach ( $data as $key => $val ) {
444
445 if ( is_string( $val ) && false !== strpos( $val, '<!--' ) ) { // Remove HTML comments.
446
447 $val = preg_replace( '/<!--.*-->/Ums', '', $val );
448
449 } elseif ( is_array( $val ) ) { // Just in case.
450
451 $val = print_r( $val, true );
452 }
453
454 /*
455 * Firefox does not allow double-dashes inside comment blocks.
456 */
457 $val = str_replace( array(
458 '--',
459 ), array(
460 '&hyphen;&hyphen;',
461 ), $val );
462
463 $html .= $is_assoc ? "\t$key = $val\n" : "\t$val\n";
464
465 unset( $data[ $key ] ); // Optimize memory usage.
466 }
467
468 } else $html .= $data;
469 }
470
471 $html .= ' -->' . "\n";
472
473 return $html;
474 }
475 }
476 }
477