PluginProbe
WPSSO Core – Complete Schema Markup and Meta Tags / 22.7.0
WPSSO Core – Complete Schema Markup and Meta Tags v22.7.0
22.7.0 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
← All changes | lib/com/debug.php +476 -0 22.2.122.7.0 View file →
@@ -1,0 +1,476 @@
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 +}