PluginProbe
WP Coder – Insert & Manage Code Snippets / 4.5.2
WP Coder – Insert & Manage Code Snippets v4.5.2
4.5.2 4.5.1 1.1 2.3.1 2.3.2 2.4.1 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.1 3.1.1 3.2 3.2.1 3.3 3.4 3.5 All 40 releases
wp-coder / includes / snippets / class-tool-page-info.php

class-tool-page-info.php in WP Coder – Insert & Manage Code Snippets 4.5.2, at includes/snippets/class-tool-page-info.php

781 lines 23.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use WPCoder\WPCoder;
4
5 defined( 'ABSPATH' ) || exit;
6
7 class WPCoder_Page_Info {
8
9 public function __construct() {
10
11
12 add_action( 'template_redirect', static function () {
13 if ( is_user_logged_in() && WPCoder::user_can_manage() ) {
14 $GLOBALS['wpcoder_render_start'] = microtime( true );
15 }
16 } );
17 add_action( 'init', static function () {
18 if ( ! defined( 'SAVEQUERIES' ) ) {
19 if ( is_user_logged_in() && WPCoder::user_can_manage() ) {
20 define( 'SAVEQUERIES', true );
21 }
22 }
23 } );
24 add_action( 'admin_bar_menu', [ $this, 'add_admin_bar_template_info' ], 90 );
25 }
26
27 public function add_admin_bar_template_info( $wp_admin_bar ): void {
28 if ( ! is_user_logged_in() || ! WPCoder::user_can_manage() ) {
29 return;
30 }
31 if ( is_admin() ) {
32 return;
33 }
34
35 wp_enqueue_style( 'wpcoder-debug-bar', WPCoder::url() . 'assets/css/debug-bar.css', [], '1.0.0' );
36
37 global $template;
38 $theme = wp_get_theme();
39 // Collect core info
40 $tpl_path = is_string( $template ) ? wp_normalize_path( $template ) : '';
41 $tpl_file = $tpl_path ? basename( $tpl_path ) : '';
42 $body_cls = get_body_class();
43 $query_type = $this->query_flags();
44 $ctx = $this->current_object_info();
45 $render_ms = isset( $GLOBALS['wpcoder_render_start'] )
46 ? round( ( microtime( true ) - (float) $GLOBALS['wpcoder_render_start'] ) * 1000, 1 )
47 : null;
48 $stats = $this->db_stats();
49
50 // Root node
51 $wp_admin_bar->add_node( [
52 'id' => 'wpc_dev_info',
53 'title' => '<span class="ab-icon dashicons dashicons-hammer"></span><span class="ab-label">Dev Info</span>',
54 'meta' => [ 'class' => 'wpcoder-dev-info' ],
55 'href' => false
56 ] );
57
58
59 // Memory headline
60 $wp_admin_bar->add_node( [
61 'id' => 'wpc_dev_mem',
62 'parent' => 'wpc_dev_info',
63 'title' => 'Memory: ' . size_format( memory_get_peak_usage( true ) ),
64 'href' => false,
65 ] );
66
67 // Render headline
68 if ( $render_ms !== null ) {
69 $wp_admin_bar->add_node( [
70 'id' => 'wpc_dev_render',
71 'parent' => 'wpc_dev_info',
72 'title' => 'Render: ' . $render_ms . ' ms',
73 'href' => false,
74 ] );
75 }
76
77 $wp_admin_bar->add_node( [
78 'id' => 'wpc_dev_theme',
79 'parent' => 'wpc_dev_info',
80 'title' => 'Active Theme',
81 ] );
82
83 $wp_admin_bar->add_node( [
84 'id' => 'wpc_dev_theme_name',
85 'parent' => 'wpc_dev_theme',
86 'title' => 'Name: ' . esc_html( $theme->get( 'Name' ) ),
87 'href' => false
88 ] );
89
90 $wp_admin_bar->add_node( [
91 'id' => 'wpc_dev_theme_version',
92 'parent' => 'wpc_dev_theme',
93 'title' => 'Version: ' . esc_html( $theme->get( 'Version' ) ),
94 'href' => false
95 ] );
96
97 $wp_admin_bar->add_node( [
98 'id' => 'wpc_dev_theme_author',
99 'parent' => 'wpc_dev_theme',
100 'title' => 'Author: ' . esc_html( $theme->get( 'Author' ) ),
101 'href' => false
102 ] );
103
104
105 $wp_admin_bar->add_node( [
106 'id' => 'wpc_dev_tpl',
107 'parent' => 'wpc_dev_info',
108 'title' => 'Template Info',
109 'href' => false
110 ] );
111
112 if ( $tpl_file ) {
113 $wp_admin_bar->add_node( [
114 'id' => 'wpc_tpl_info',
115 'parent' => 'wpc_dev_tpl',
116 'title' => 'Template: ' . esc_html( $tpl_file ),
117 'href' => false
118 ] );
119
120 $wp_admin_bar->add_node( [
121 'id' => 'wpc_tpl_path',
122 'parent' => 'wpc_dev_tpl',
123 'title' => 'Path: ' . esc_html( $tpl_path ),
124 'href' => false
125 ] );
126 }
127
128 $structure = get_option( 'permalink_structure' ) ?: 'plain';
129 $wp_admin_bar->add_node( [
130 'id' => 'wpc_tpl_permalinks',
131 'parent' => 'wpc_dev_tpl',
132 'title' => 'Permalinks: ' . esc_html( $structure ),
133 'href' => false
134 ] );
135
136 $canonical = function_exists( 'wp_get_canonical_url' ) ? wp_get_canonical_url() : '';
137 $wp_admin_bar->add_node( [
138 'id' => 'wpc_tpl_urls',
139 'parent' => 'wpc_dev_tpl',
140 'title' => "canonical: " . esc_html( $canonical ),
141 'href' => false
142 ] );
143
144 $scheme = is_ssl() ? 'https://' : 'http://';
145 $host = $_SERVER['HTTP_HOST'] ?? '';
146 $req = $_SERVER['REQUEST_URI'] ?? '';
147 $full = esc_url_raw( $scheme . $host . $req );
148 $wp_admin_bar->add_node( [
149 'id' => 'wpc_dev_full_url',
150 'parent' => 'wpc_dev_tpl',
151 'title' => 'Current URL: ' . $full,
152 'href' => false
153 ] );
154
155 $wp_admin_bar->add_node( [
156 'id' => 'wpc_dev_query',
157 'parent' => 'wpc_dev_info',
158 'title' => 'Query Info',
159 ] );
160
161 foreach ( $ctx as $line_id => $line ) {
162 $wp_admin_bar->add_node( [
163 'id' => 'wpcoder_ctx_' . $line_id,
164 'parent' => 'wpc_dev_query',
165 'title' => esc_html( $line ),
166 ] );
167 }
168
169 if ( $query_type ) {
170 $wp_admin_bar->add_node( [
171 'id' => 'wpc_dev_query_type',
172 'parent' => 'wpc_dev_query',
173 'title' => 'Query: ' . esc_html( $query_type ),
174 ] );
175 }
176
177 if ( $stats['count'] !== null ) {
178 $wp_admin_bar->add_node( [
179 'id' => 'wpc_dev_query_db',
180 'parent' => 'wpc_dev_query',
181 'title' => 'Database Queries: ' . (int) $stats['count'],
182 ] );
183
184 $wp_admin_bar->add_node( [
185 'id' => 'wpc_dev_query_time',
186 'parent' => 'wpc_dev_query',
187 'title' => 'Query Time: ' . round( (float) $stats['time'] * 1000, 1 ) . ' ms',
188 ] );
189
190 $avg = $stats['time'] / max( 1, $stats['count'] );
191 $wp_admin_bar->add_node( [
192 'id' => 'wpc_dev_perf_db_avg',
193 'parent' => 'wpc_dev_query',
194 'title' => 'Avg Query: ' . number_format_i18n( $avg * 1000, 2 ) . ' ms',
195 'href' => false
196 ] );
197 }
198
199 if ( defined( 'SAVEQUERIES' ) && SAVEQUERIES && ! empty( $GLOBALS['wpdb']->queries ) ) {
200 $qs = $GLOBALS['wpdb']->queries;
201 usort( $qs, fn( $a, $b ) => ( $b[1] ?? 0 ) <=> ( $a[1] ?? 0 ) );
202 $top = array_slice( $qs, 0, 3 );
203 $tip = [];
204 foreach ( $top as $i => $q ) {
205 $tip[] = sprintf( "#%d (%.2f ms)\n%s", $i + 1, ( $q[1] ?? 0 ) * 1000, $q[0] ?? '' );
206 }
207 $wp_admin_bar->add_node([
208 'id' => 'wpc_dev_query_top',
209 'parent' => 'wpc_dev_query',
210 'title' => 'Top slow queries ?',
211 'meta' => [
212 'title' => implode("\n\n",$tip),
213 'class' => 'wpc-dev-has-tooltip'
214 ],
215 'href' => false,
216 ]);
217 }
218
219
220 if ( ! empty( $body_cls ) ) {
221 $wp_admin_bar->add_node( [
222 'id' => 'wpc_dev_body',
223 'parent' => 'wpc_dev_info',
224 'title' => 'Body Classes (' . count( $body_cls ) . ')',
225 'href' => false
226 ] );
227
228 $wp_admin_bar->add_node( [
229 'id' => 'wpc_dev_body_classes',
230 'parent' => 'wpc_dev_body',
231 'title' => implode( ' ', $body_cls ),
232 'href' => false
233 ] );
234 }
235
236 $scripts = wp_scripts();
237
238 $wp_admin_bar->add_node( [
239 'id' => 'wpc_dev_js',
240 'parent' => 'wpc_dev_info',
241 'title' => 'JS (' . count( $scripts->queue ) . ')',
242 'href' => false
243 ] );
244
245 $wp_admin_bar->add_node( [
246 'id' => 'wpc_dev_js_id',
247 'parent' => 'wpc_dev_js',
248 'title' => implode( ', ', (array) $scripts->queue ),
249 'href' => false
250 ] );
251
252
253 $styles = wp_styles();
254 $style_queue = array_diff( (array) $styles->queue, [ 'wpcoder-debug-bar' ] );
255
256 $wp_admin_bar->add_node( [
257 'id' => 'wpc_dev_css',
258 'parent' => 'wpc_dev_info',
259 'title' => 'CSS (' . count( $style_queue ) . ')',
260 'href' => false
261 ] );
262
263 $wp_admin_bar->add_node( [
264 'id' => 'wpc_dev_css_id',
265 'parent' => 'wpc_dev_css',
266 'title' => implode( ', ', (array) $style_queue ),
267 'href' => false
268 ] );
269
270 $wordpress_info = $this->get_wp_info();
271
272 $wp_admin_bar->add_menu( array(
273 'id' => 'wpc_dev_wordpress',
274 'parent' => 'wpc_dev_info',
275 'title' => __( 'WP Environment', 'wpcoderpro' ),
276 'href' => false
277 ) );
278
279 $wp_admin_bar->add_menu( array(
280 'id' => 'wpc_dev_wp_version',
281 'parent' => 'wpc_dev_wordpress',
282 'title' => sprintf( __( 'WP Version', 'wpcoderpro' ) . ': %s', $wordpress_info['wp_version'] ),
283 'href' => false
284 ) );
285
286 $wp_admin_bar->add_menu( array(
287 'id' => 'wpc_dev_wp_multisite',
288 'parent' => 'wpc_dev_wordpress',
289 'title' => sprintf( __( 'WP Multisite', 'wpcoderpro' ) . ': %s', ( $wordpress_info['wp_multisite'] ) ? __( 'enable', 'wpcoderpro' ) : __( 'disable', 'wpcoderpro' ) ),
290 'href' => false
291 ) );
292
293 $wp_admin_bar->add_menu( array(
294 'id' => 'wpc_dev_wp_memory_limit',
295 'parent' => 'wpc_dev_wordpress',
296 'title' => sprintf( __( 'WP Memory Limit', 'wpcoderpro' ) . ': %s', $wordpress_info['wp_memory_limit'] ),
297 'href' => false
298 ) );
299
300 $wp_admin_bar->add_menu( array(
301 'id' => 'wpc_dev_wp_debug_mode',
302 'parent' => 'wpc_dev_wordpress',
303 'title' => sprintf( __( 'WP Debug Mode', 'wpcoderpro' ) . ': %s', ( $wordpress_info['wp_debug_mode'] ) ? __( 'enable', 'wpcoderpro' ) : __( 'disable', 'wpcoderpro' ) ),
304 'href' => false
305 ) );
306
307 $wp_admin_bar->add_menu( array(
308 'id' => 'wpc_dev_wp_cron',
309 'parent' => 'wpc_dev_wordpress',
310 'title' => sprintf( __( 'WP Cron', 'wpcoderpro' ) . ': %s', ( $wordpress_info['wp_cron'] ) ? __( 'enable', 'wpcoderpro' ) : __( 'disable', 'wpcoderpro' ) ),
311 'href' => false
312 ) );
313
314 $wp_admin_bar->add_menu( array(
315 'id' => 'wpc_dev_language',
316 'parent' => 'wpc_dev_wordpress',
317 'title' => sprintf( __( 'WP language', 'wpcoderpro' ) . ': %s', $wordpress_info['language'] ),
318 'href' => false
319 ) );
320
321 $wp_admin_bar->add_menu( array(
322 'id' => 'wpc_dev_timezone',
323 'parent' => 'wpc_dev_wordpress',
324 'title' => sprintf( __( 'Timezone', 'wpcoderpro' ) . ': %s', $wordpress_info['timezone'] ),
325 'href' => false
326 ) );
327 $wp_admin_bar->add_node( [
328 'id' => 'wpc_dev_times',
329 'parent' => 'wpc_dev_wordpress',
330 'title' => 'Local: ' . wp_date( 'Y-m-d H:i:s' ) . ' · UTC: ' . gmdate( 'Y-m-d H:i:s' ),
331 'href' => false
332 ] );
333
334 $wp_admin_bar->add_node( [
335 'id' => 'wpc_dev_wordpress_cache',
336 'parent' => 'wpc_dev_wordpress',
337 'title' => 'Object Cache: ' . ( wp_using_ext_object_cache() ? 'ON (persistent)' : 'OFF' ),
338 ] );
339
340 $has_dropin = file_exists( WP_CONTENT_DIR . '/object-cache.php' );
341 $wp_admin_bar->add_node( [
342 'id' => 'wpc_dev_cache_dropin',
343 'parent' => 'wpc_dev_wordpress',
344 'title' => 'Cache drop-in: ' . ( $has_dropin ? 'present' : 'none' ),
345 'href' => false
346 ] );
347
348 $wp_admin_bar->add_menu( array(
349 'id' => 'wpc_dev_wordpress_environment',
350 'parent' => 'wpc_dev_wordpress',
351 'title' => sprintf( __( 'Env', 'wpcoderpro' ) . ': %s', $wordpress_info['environment'] ),
352 'href' => false
353 ) );
354
355
356 $get_environment_info = $this->get_environment_info();
357
358 $wp_admin_bar->add_menu( array(
359 'id' => 'wpc_dev_environment',
360 'parent' => 'wpc_dev_info',
361 'title' => __( 'Server Environment', 'wpcoderpro' ),
362 'href' => false
363 ) );
364
365 $wp_admin_bar->add_menu( array(
366 'id' => 'wpc_dev_environment_server_info',
367 'parent' => 'wpc_dev_environment',
368 'title' => sprintf( __( 'Server info', 'wpcoderpro' ) . ': %s', $get_environment_info['server_info'] ),
369 'href' => false
370 ) );
371
372 $wp_admin_bar->add_menu( array(
373 'id' => 'wpc_dev_environment_php_version',
374 'parent' => 'wpc_dev_environment',
375 'title' => sprintf( __( 'PHP version', 'wpcoderpro' ) . ': %s', $get_environment_info['php_version'] ),
376 'href' => false
377 ) );
378
379 $wp_admin_bar->add_menu( array(
380 'id' => 'wpc_dev_environment_mysql_version',
381 'parent' => 'wpc_dev_environment',
382 'title' => sprintf( __( 'MySQL version', 'wpcoderpro' ) . ': %s', $get_environment_info['mysql_version'] ),
383 'href' => false
384 ) );
385
386 $wp_admin_bar->add_menu( array(
387 'id' => 'wpc_dev_db_prefix',
388 'parent' => 'wpc_dev_environment',
389 'title' => sprintf( __( 'DB Prefix', 'wpcoderpro' ) . ': %s', $get_environment_info['db_prefix'] ),
390 'href' => false
391 ) );
392
393 $wp_admin_bar->add_menu( array(
394 'id' => 'wpc_dev_db_charset',
395 'parent' => 'wpc_dev_environment',
396 'title' => sprintf( __( 'DB Charset/Collate', 'wpcoderpro' ) . ': %s', $get_environment_info['db_charset'] ),
397 'href' => false
398 ) );
399
400 $wp_admin_bar->add_menu( array(
401 'id' => 'wpc_dev_environment_php_post_max_size',
402 'parent' => 'wpc_dev_environment',
403 'title' => sprintf( __( 'PHP Post Max Size', 'wpcoderpro' ) . ': %s', $get_environment_info['php_post_max_size'] ),
404 'href' => false
405 ) );
406
407 $wp_admin_bar->add_menu( array(
408 'id' => 'wpc_dev_environment_php_max_execution_time',
409 'parent' => 'wpc_dev_environment',
410 'title' => sprintf( __( 'PHP Time Limit', 'wpcoderpro' ) . ': %s' . __( 'sec', 'wpcoderpro' ), $get_environment_info['php_max_execution_time'] ),
411 'href' => false
412 ) );
413
414 $wp_admin_bar->add_menu( array(
415 'id' => 'wpc_dev_environment_php_max_input_vars',
416 'parent' => 'wpc_dev_environment',
417 'title' => sprintf( __( 'PHP Max Input Vars', 'wpcoderpro' ) . ': %s', $get_environment_info['php_max_input_vars'] ),
418 'href' => false
419 ) );
420
421 $wp_admin_bar->add_menu( array(
422 'id' => 'wpc_dev_environment_max_upload_size',
423 'parent' => 'wpc_dev_environment',
424 'title' => sprintf( __( 'Max Upload Size', 'wpcoderpro' ) . ': %s', $get_environment_info['max_upload_size'] ),
425 'href' => false
426 ) );
427
428 $wp_admin_bar->add_menu( array(
429 'id' => 'wpc_dev_environment_gzip_enabled',
430 'parent' => 'wpc_dev_environment',
431 'title' => sprintf( __( 'GZip', 'wpcoderpro' ) . ': %s', ( $get_environment_info['gzip_enabled'] == '1' ) ? __( 'enable', 'wpcoderpro' ) : __( 'disable', 'wpcoderpro' ) ),
432 'href' => false
433 ) );
434
435 $wp_admin_bar->add_menu( array(
436 'id' => 'wpc_dev_environment_mbstring_enabled',
437 'parent' => 'wpc_dev_environment',
438 'title' => sprintf( __( 'Multibyte String', 'wpcoderpro' ) . ': %s', ( $get_environment_info['mbstring_enabled'] == '1' ) ? __( 'enable', 'wpcoderpro' ) : __( 'disable', 'wpcoderpro' ) ),
439 'href' => false
440 ) );
441
442 $wp_admin_bar->add_menu( array(
443 'id' => 'wpc_dev_environment_ssl_enabled',
444 'parent' => 'wpc_dev_environment',
445 'title' => sprintf( __( 'SSL', 'wpcoderpro' ) . ': %s', ( $get_environment_info['ssl_enabled'] == '1' ) ? __( 'enable', 'wpcoderpro' ) : __( 'disable', 'wpcoderpro' ) ),
446 'href' => false
447 ) );
448
449 if(is_singular() || is_tax() || is_category() || is_tag() ) {
450
451 $shortcodes_content = $this->get_current_content_for_shortcode_scan();
452 $shortcodes_list = $this->collect_shortcodes_detailed( $shortcodes_content );
453
454 $wp_admin_bar->add_node( [
455 'id' => 'wpc_dev_shortcodes_full',
456 'parent' => 'wpc_dev_info',
457 'title' => 'Shortcodes (' . count( $shortcodes_list ) . ')',
458 'href' => false,
459 ] );
460
461 $wp_admin_bar->add_node( [
462 'id' => 'wpc_dev_shortcodes_list',
463 'parent' => 'wpc_dev_shortcodes_full',
464 'title' => $shortcodes_list ? implode( ", ", array_map( static function ( $it ) {
465 return esc_html( $it['full'] );
466 }, $shortcodes_list ) ) : __( 'None found', 'wpcoderpro' ),
467 'href' => false
468 ] );
469 }
470
471 }
472
473 private function db_stats(): array {
474 global $wpdb;
475 if ( ! defined( 'SAVEQUERIES' ) || ! SAVEQUERIES || empty( $wpdb->queries ) ) {
476 return [ 'count' => null, 'time' => null ];
477 }
478 // $wpdb->queries: [ [ sql, elapsed_time, callstack, start_time? ], ... ]
479 $count = count( $wpdb->queries );
480 $time = 0.0;
481 foreach ( $wpdb->queries as $q ) {
482 // $q[1] is seconds as float
483 $time += isset( $q[1] ) ? (float) $q[1] : 0.0;
484 }
485
486 return [ 'count' => $count, 'time' => $time ]; // time in seconds
487 }
488
489 private function query_flags(): string {
490 $flags = [];
491 // Order matters: more specific first
492 if ( is_front_page() ) {
493 $flags[] = 'front_page';
494 }
495 if ( is_home() ) {
496 $flags[] = 'home';
497 }
498 if ( is_singular() ) {
499 $flags[] = 'singular';
500 }
501 if ( is_page() ) {
502 $flags[] = 'page';
503 }
504 if ( is_single() ) {
505 $flags[] = 'single';
506 }
507 if ( is_attachment() ) {
508 $flags[] = 'attachment';
509 }
510 if ( is_archive() ) {
511 $flags[] = 'archive';
512 }
513 if ( is_category() ) {
514 $flags[] = 'category';
515 }
516 if ( is_tag() ) {
517 $flags[] = 'tag';
518 }
519 if ( is_tax() ) {
520 $flags[] = 'tax';
521 }
522 if ( is_author() ) {
523 $flags[] = 'author';
524 }
525 if ( is_date() ) {
526 $flags[] = 'date';
527 }
528 if ( is_search() ) {
529 $flags[] = 'search';
530 }
531 if ( is_404() ) {
532 $flags[] = '404';
533 }
534 if ( is_paged() ) {
535 $flags[] = 'paged';
536 }
537
538 return implode( ' · ', $flags );
539 }
540
541 private function current_object_info(): array {
542 $lines = [];
543
544 if ( is_singular() ) {
545 $post_id = get_the_ID();
546 $type = get_post_type( $post_id );
547 $slug = $post_id ? get_post_field( 'post_name', $post_id ) : '';
548 $lines[] = 'Post ID: ' . (int) $post_id;
549 $lines[] = 'Post Type: ' . (string) $type;
550 $lines[] = 'Slug: ' . (string) $slug;
551
552 return $lines;
553 }
554
555 if ( is_tax() || is_category() || is_tag() ) {
556 $term = get_queried_object();
557 if ( $term && ! is_wp_error( $term ) ) {
558 $lines[] = 'Taxonomy: ' . (string) $term->taxonomy;
559 $lines[] = 'Term ID: ' . (int) $term->term_id;
560 $lines[] = 'Term Slug: ' . (string) $term->slug;
561
562 return $lines;
563 }
564 }
565
566 if ( is_author() ) {
567 $user = get_queried_object();
568 if ( $user && ! is_wp_error( $user ) ) {
569 $lines[] = 'Author ID: ' . (int) $user->ID;
570 $lines[] = 'Login: ' . (string) $user->user_login;
571
572 return $lines;
573 }
574 }
575
576 if ( is_search() ) {
577 $lines[] = 'Search: ' . (string) get_search_query();
578
579 return $lines;
580 }
581
582 // Fallbacks
583 if ( is_front_page() ) {
584 $lines[] = 'Front Page';
585
586 return $lines;
587 }
588 if ( is_home() ) {
589 $lines[] = 'Blog Home';
590
591 return $lines;
592 }
593
594 // Generic queried object (archives without specific object)
595 $obj = get_queried_object();
596 if ( $obj && ! is_wp_error( $obj ) ) {
597 $lines[] = 'Object: ' . get_class( $obj );
598 }
599
600 return $lines ?: [ 'No specific object' ];
601 }
602
603 private function get_environment_info(): array {
604
605 global $wpdb;
606
607 return array(
608 'server_info' => $_SERVER['SERVER_SOFTWARE'],
609 'php_version' => phpversion(),
610 'php_post_max_size' => $this->convert( $this->let_to_num( ini_get( 'post_max_size' ) ) ),
611 'php_max_execution_time' => ini_get( 'max_execution_time' ),
612 'php_max_input_vars' => ini_get( 'max_input_vars' ),
613 'max_upload_size' => size_format( wp_max_upload_size() ),
614 'gzip_enabled' => is_callable( 'gzopen' ),
615 'mbstring_enabled' => extension_loaded( 'mbstring' ),
616 'ssl_enabled' => ( isset( $_SERVER['HTTPS'] ) && strtolower( $_SERVER['HTTPS'] ) === 'on' ) ? 1 : 0,
617 'mysql_version' => ( ! empty( $wpdb->is_mysql ) ? $wpdb->db_version() : '' ),
618 'db_prefix' => $wpdb->prefix,
619 'db_charset' => DB_CHARSET . ' / ' . ( DB_COLLATE ?: 'default' ),
620 );
621
622 }
623
624 // Returns structured WP info (human-readable + safe fallbacks)
625 private function get_wp_info(): array {
626 // Use core helpers instead of custom convert/let_to_num
627 $to_bytes = static function ( string $hr ) {
628 return function_exists( 'wp_convert_hr_to_bytes' ) ? wp_convert_hr_to_bytes( $hr ) : (int) $hr;
629 };
630
631 // Memory limits (constants may be undefined in edge envs)
632 $wp_mem_limit_str = defined( 'WP_MEMORY_LIMIT' ) ? WP_MEMORY_LIMIT : ini_get( 'memory_limit' );
633 $wp_mem_limit_b = $to_bytes( (string) $wp_mem_limit_str );
634
635 $wp_mem_max_str = defined( 'WP_MAX_MEMORY_LIMIT' ) ? WP_MAX_MEMORY_LIMIT : $wp_mem_limit_str;
636 $wp_mem_max_b = $to_bytes( (string) $wp_mem_max_str );
637
638 // Timezone name via WP API (handles timezone_string/gmt_offset)
639 $tz = function_exists( 'wp_timezone' ) ? wp_timezone()->getName() : ( get_option( 'timezone_string' ) ?: 'UTC' );
640
641 return [
642 // Core
643 'wp_version' => get_bloginfo( 'version' ),
644 'wp_multisite' => is_multisite(),
645
646 // Memory (both raw bytes and human readable)
647 'wp_memory_limit' => size_format( $wp_mem_limit_b ),
648 'wp_memory_limit_b' => $wp_mem_limit_b,
649 'wp_max_memory' => size_format( $wp_mem_max_b ),
650 'wp_max_memory_b' => $wp_mem_max_b,
651
652 // Flags
653 'wp_debug_mode' => (int) ( defined( 'WP_DEBUG' ) && WP_DEBUG ),
654 'wp_cron' => (int) ( ! defined( 'DISABLE_WP_CRON' ) || ! DISABLE_WP_CRON ),
655
656 // I18n / Time
657 'language' => get_locale(),
658 'timezone' => $tz,
659 'local_time' => function_exists( 'wp_date' ) ? wp_date( 'Y-m-d H:i:s' ) : date( 'Y-m-d H:i:s' ),
660 'utc_time' => gmdate( 'Y-m-d H:i:s' ),
661
662 // Env type (WP 5.5+)
663 'environment' => function_exists( 'wp_get_environment_type' ) ? wp_get_environment_type() : 'production',
664 ];
665 }
666
667 private function get_timezone(): string {
668 $tzstring = get_option( 'timezone_string' );
669
670 // Якщо в адмінці обрано місто → напр. Europe/Kiev
671 if ( ! empty( $tzstring ) ) {
672 return $tzstring;
673 }
674
675 // Якщо місто не задано → будуємо з gmt_offset
676 $offset = (float) get_option( 'gmt_offset' );
677 if ( 0 === $offset ) {
678 return 'UTC';
679 }
680
681 $hours = (int) $offset;
682 $minutes = abs( ( $offset - $hours ) * 60 );
683
684 return sprintf( 'UTC%+03d:%02d', $hours, $minutes );
685 }
686
687 private function convert( $size ): string {
688
689 $unit = array( 'B', 'KB', 'MB', 'GB', 'TB', 'PB' );
690
691 return @round( $size / pow( 1024, ( $i = floor( log( $size, 1024 ) ) ) ), 2 ) . ' ' . $unit[ $i ];
692
693 }
694
695 private function let_to_num( $size ) {
696
697 $l = substr( $size, - 1 );
698 $ret = substr( $size, 0, - 1 );
699
700 switch ( strtoupper( $l ) ) {
701 case 'P':
702 $ret *= 1024;
703 case 'T':
704 $ret *= 1024;
705 case 'G':
706 $ret *= 1024;
707 case 'M':
708 $ret *= 1024;
709 case 'K':
710 $ret *= 1024;
711 }
712
713 return $ret;
714
715 }
716
717 // Find shortcodes in a given string. Returns ['found'=>[tag=>count], 'unknown'=>[tag=>count]]
718 private function find_shortcodes_in_string(string $content): array {
719 global $wpc_shortcode_tags;
720 $result = ['found' => [], 'unknown' => []];
721 if ($content === '') return $result;
722
723 $pattern = get_shortcode_regex();
724 if ( preg_match_all( '/'.$pattern.'/s', $content, $matches, PREG_SET_ORDER ) ) {
725 foreach ( $matches as $m ) {
726 $tag = isset($m[2]) ? strtolower($m[2]) : '';
727 if ( $tag === '' ) continue;
728
729 // count found
730 $result['found'][$tag] = ($result['found'][$tag] ?? 0) + 1;
731
732 // mark unknown if not registered
733 if ( empty($wpc_shortcode_tags[$tag]) ) {
734 $result['unknown'][$tag] = ($result['unknown'][$tag] ?? 0) + 1;
735 }
736 }
737 }
738 // sort by count desc
739 arsort($result['found']);
740 arsort($result['unknown']);
741 return $result;
742 }
743
744 // Collect page content to scan for shortcodes
745 private function get_current_content_for_shortcode_scan(): string {
746 if ( is_singular() ) {
747 $pid = get_the_ID();
748 return $pid ? (string) get_post_field('post_content', $pid) : '';
749 }
750 if ( is_tax() || is_category() || is_tag() ) {
751 $term = get_queried_object();
752 return ($term && !is_wp_error($term) && !empty($term->description)) ? (string) $term->description : '';
753 }
754 return '';
755 }
756
757 // Scan content for shortcodes and return detailed list
758 private function collect_shortcodes_detailed(string $content): array {
759 $out = []; // each item: ['tag'=>string,'attrs'=>array,'full'=>string]
760 if ($content === '') return $out;
761
762 $regex = get_shortcode_regex();
763 if ( preg_match_all('/'.$regex.'/s', $content, $m, PREG_SET_ORDER) ) {
764 foreach ($m as $match) {
765 // $match[0] = full match, $match[2] = tag, $match[3] = attributes string, $match[5] = inner content (if any)
766 $tag = strtolower($match[2] ?? '');
767 $full = $match[0] ?? '';
768 $attrS = isset($match[3]) ? trim($match[3]) : '';
769 $attrs = shortcode_parse_atts($attrS) ?: [];
770
771 $out[] = [
772 'tag' => $tag,
773 'attrs' => $attrs,
774 'full' => $full, // original text as in content
775 ];
776 }
777 }
778 return $out;
779 }
780
781 }