PluginProbe
Code Profiler – WordPress Performance Profiling and Debugging Made Easy / 1.9.6
Code Profiler – WordPress Performance Profiling and Debugging Made Easy v1.9.6
1.9.6 1.9.5 1.9.4 1.9.3 trunk 1.4 1.4.1 1.4.2 1.4.3 1.4.4 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.6 1.6.1 1.6.10 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 All 41 releases
← All changes | lib/class-troubleshooter.php +213 -24 1.4.41.9.6 View file →
@@ -1,6 +1,6 @@
1 1 <?php
2 -/*
2 +/**
3 3 +=====================================================================+
4 4 | ____ _ ____ __ _ _ |
5 5 | / ___|___ __| | ___ | _ \ _ __ ___ / _(_) | ___ _ __ |
6 6 | | | / _ \ / _` |/ _ \ | |_) | '__/ _ \| |_| | |/ _ \ '__| |
@@ -6,13 +6,15 @@
6 6 | | | / _ \ / _` |/ _ \ | |_) | '__/ _ \| |_| | |/ _ \ '__| |
7 7 | | |__| (_) | (_| | __/ | __/| | | (_) | _| | | __/ | |
8 8 | \____\___/ \__,_|\___| |_| |_| \___/|_| |_|_|\___|_| |
9 9 | |
10 - | (c) Jerome Bruandet ~ https://code-profiler.com/ |
11 - +=====================================================================+
10 + | (c) Jerome Bruandet ~ https://nintechnet.com/codeprofiler/ |
11 + +=====================================================================+ 2024-08-14
12 12 */
13 13
14 -if (! defined( 'ABSPATH' ) ) { die( 'Forbidden' ); }
14 +if (! defined('ABSPATH') ) {
15 + die('Forbidden');
16 +}
15 17
16 18 // =====================================================================
17 19
18 20 class CP_Troubleshooter {
@@ -27,11 +29,15 @@
27 29 */
28 30 public function __construct() {
29 31
30 32 $this->get_system_info('sysinfo');
33 + $this->test_admin_ajax('admin-ajax');
31 34 $this->cp_info('code-profiler');
32 - $this->function_exists('functions');
35 + $this->function_exists('code-profiler');
33 36 $this->check_wpdb('wpdb');
37 + $this->check_cache('cache');
38 + $this->check_proxy('proxy');
39 + $this->is_multisite('multisite');
34 40 $this->get_all_plugins('plugins');
35 41 $this->get_theme('themes');
36 42 $this->get_cp_config();
37 43
@@ -45,13 +51,20 @@
45 51 * * HTTP server
46 52 * * Opcode cache
47 53 * * PHP directives (time limit, memory available, temp dir etc)
48 54 * * PHP last error
55 + * * WordPress
49 56 */
50 57 private function get_system_info( $key ) {
51 58
52 59 $this->buffer[ $key ]['OS'] = php_uname();
53 60
61 + if (! empty( $_SERVER['SERVER_NAME'] ) ) {
62 + $this->buffer[ $key ]['SERVER_NAME'] = $_SERVER['SERVER_NAME'];
63 + } else {
64 + $this->buffer[ $key ]['SERVER_NAME'] = 'N/A';
65 + }
66 +
54 67 if (! empty( $_SERVER['SERVER_SOFTWARE'] ) ) {
55 68 $this->buffer[ $key ]['HTTP server'] = $_SERVER['SERVER_SOFTWARE'];
56 69 } else {
57 70 $this->buffer[ $key ]['HTTP server'] = 'N/A';
@@ -79,19 +92,85 @@
79 92 if (! empty( $tmp ) ) {
80 93 if ( is_writable( $tmp ) ) {
81 94 $tmp .= ' (writable)';
82 95 } else {
83 - $tmp .= ' (not writable!)';
96 + $tmp .= ' (not writable!)' .' ⚠️';
84 97 }
85 98 }
86 99 $tmp = $this->shorten_path( $tmp );
87 100 $this->buffer[ $key ]['Temp directory'] = $tmp;
88 101 $this->buffer[ $key ]['Log errors'] = ini_get('log_errors');
89 - $this->buffer[ $key ]['Error log'] = ini_get('error_log');
90 - $this->buffer[ $key ]['Last error'] = error_get_last();
102 +
103 + $error_log = ini_get('error_log');
104 + $filesize = 0;
105 + if ( is_file( $error_log ) ) {
106 + $filesize = filesize( $error_log );
107 + }
108 + $this->buffer[ $key ]['Error log'] = "$error_log (". number_format( $filesize ) ." bytes)";
109 +
110 + $this->buffer[ $key ]['Last error'] = error_get_last();
91 111 if ( isset( $this->buffer[ $key ]['Last error']['file'] ) ) {
92 112 $this->buffer[ $key ]['Last error']['file'] = $this->shorten_path( $this->buffer[ $key ]['Last error']['file'] );
93 113 }
114 +
115 + // WordPress
116 + if ( defined('WP_MEMORY_LIMIT') ) {
117 + $this->buffer[ $key ]['WordPress']['WP_MEMORY_LIMIT'] = WP_MEMORY_LIMIT;
118 + } else {
119 + $this->buffer[ $key ]['WordPress']['WP_MEMORY_LIMIT'] = 'N/A';
120 + }
121 + if ( defined('WP_MAX_MEMORY_LIMIT') ) {
122 + $this->buffer[ $key ]['WordPress']['WP_MAX_MEMORY_LIMIT'] = WP_MAX_MEMORY_LIMIT;
123 + } else {
124 + $this->buffer[ $key ]['WordPress']['WP_MAX_MEMORY_LIMIT'] = 'N/A';
125 + }
126 + global $wp_version;
127 + $this->buffer[ $key ]['WordPress']['version'] = $wp_version;
128 + $wp_debug = '';
129 + if ( defined('WP_DEBUG') ) {
130 + $wp_debug = WP_DEBUG;
131 + }
132 + $this->buffer[ $key ]['WordPress']['WP_DEBUG'] = $wp_debug;
133 + $wp_debug = '';
134 + $filesize = 0;
135 + if ( defined('WP_DEBUG_LOG') ) {
136 + $wp_debug = WP_DEBUG_LOG;
137 + }
138 + if ( is_file( $wp_debug ) ) {
139 + $filesize = filesize( $error_log );
140 + $wp_debug = $this->shorten_path( $wp_debug ) ." (". number_format( $filesize ) ." bytes)";
141 + }
142 + $this->buffer[ $key ]['WordPress']['WP_DEBUG_LOG'] = $wp_debug;
143 +
144 + /**
145 + * WPMU plugins directory.
146 + */
147 + $this->buffer[ $key ]['WordPress']['WPMU_PLUGIN_DIR']['DIR'] =
148 + $this->shorten_path( WPMU_PLUGIN_DIR );
149 + $this->buffer[ $key ]['WordPress']['WPMU_PLUGIN_DIR']['writable'] =
150 + is_writable( WPMU_PLUGIN_DIR );
151 +
152 + /**
153 + * SAVEQUERIES: make sure it is not set to false.
154 + */
155 + if ( defined('SAVEQUERIES') ) {
156 + if ( SAVEQUERIES === false ) {
157 + $this->buffer[ $key ]['WordPress']['SAVEQUERIES'] = 'FALSE' .' ⚠️';
158 + } else {
159 + $this->buffer[ $key ]['WordPress']['SAVEQUERIES'] = SAVEQUERIES;
160 + }
161 + } else {
162 + $this->buffer[ $key ]['WordPress']['SAVEQUERIES'] = 'N/A';
163 + }
164 +
165 + /**
166 + * xdebug.
167 + */
168 + if ( extension_loaded('xdebug') ) {
169 + $this->buffer[ $key ]['Xdebug'] = esc_html__('Extension is loaded', 'code-profiler') .' ⚠️';
170 + } else {
171 + $this->buffer[ $key ]['Xdebug'] = '0';
172 + }
94 173 }
95 174
96 175
97 176 /**
@@ -99,18 +178,26 @@
99 178 */
100 179 private function function_exists( $key ) {
101 180
102 181 $required_functions = [
103 - 'register_shutdown_function',
104 - 'register_tick_function',
105 - 'stream_wrapper_unregister',
106 - 'stream_wrapper_register',
107 - 'stream_wrapper_restore'
182 + 'register_shutdown_function' => 'shutdown',
183 + 'register_tick_function' => 'tick',
184 + 'stream_wrapper_unregister' => 'unregister',
185 + 'stream_wrapper_register' => 'register',
186 + 'stream_wrapper_restore' => 'restore',
187 + 'hrtime' => 'hrtime'
108 188 ];
109 189
110 - foreach ( $required_functions as $function ) {
111 - $this->buffer[ $key ][ $function ] = function_exists( $function );
190 + foreach ( $required_functions as $function => $value ) {
191 + $this->buffer[ $key ]['function'][ $value ] = function_exists( $function );
112 192 }
193 +
194 + $required_methods = [
195 + 'PhpToken' => 'tokenize'
196 + ];
197 + foreach ( $required_methods as $class => $value ) {
198 + $this->buffer[ $key ]['method'][ $value ] = method_exists( $class, $value );
199 + }
113 200 }
114 201
115 202
116 203 /**
@@ -163,13 +250,52 @@
163 250 * Check for advanced cache
164 251 */
165 252 private function check_cache( $key ) {
166 253
167 - $this->buffer[ $key ]['cache'] = defined('WP_CACHE') && file_exists(WP_CONTENT_DIR . '/advanced-cache.php');
254 + $this->buffer[ $key ] = [];
255 + if ( defined('WP_CACHE') && file_exists( WP_CONTENT_DIR . '/advanced-cache.php') ) {
256 + $this->buffer[ $key ][ $this->shorten_path( WP_CONTENT_DIR . '/advanced-cache.php') ] = 1;
257 + }
168 258 }
169 259
170 260
171 261 /**
262 + * Check for reverse proxy or CDN
263 + */
264 + private function check_proxy( $key ) {
265 +
266 + $this->buffer[ $key ] = [];
267 + $proxies = [
268 + 'HTTP_X_FORWARDED_FOR',
269 + 'HTTP_CF_CONNECTING_IP',
270 + 'HTTP_INCAP_CLIENT_IP'
271 + ];
272 +
273 + foreach( $proxies as $proxy ) {
274 + if (! empty( $_SERVER[ $proxy ] ) ) {
275 + $this->buffer[ $key ][ $proxy ] = 1;
276 + }
277 + }
278 +
279 + }
280 +
281 +
282 + /**
283 + * Check if that is a multisite installation.
284 + */
285 + private function is_multisite( $key ) {
286 +
287 + if ( is_multisite() ) {
288 + global $current_blog;
289 + $this->buffer[ $key ] = "site: {$current_blog->site_id}, blog: {$current_blog->blog_id}";
290 + return;
291 + }
292 +
293 + $this->buffer[ $key ] = 0;
294 + }
295 +
296 +
297 + /**
172 298 * Retrieve the list of all plugins and sort them
173 299 * (active or disabled).
174 300 */
175 301 private function get_all_plugins( $key ) {
@@ -179,15 +305,40 @@
179 305 }
180 306 $plugins = get_plugins();
181 307 foreach( $plugins as $k => $v ) {
182 308 if ( $slug = substr( $k, 0, strpos( $k, '/') ) ) {
183 - $this->buffer[ $key ][ $slug ] = "{$v['Name']} - {$v['Version']}";
309 + $name = 'N/A'; $version = 'N/A'; $uri = 'N/A';
310 + if (! empty( $v['Name'] ) ) {
311 + $name = $v['Name'];
312 + }
313 + if (! empty( $v['Version'] ) ) {
314 + $version = $v['Version'];
315 + }
316 + if (! empty( $v['PluginURI'] ) ) {
317 + $uri = $v['PluginURI'];
318 + }
319 + if ( is_plugin_active( $k ) ) {
320 + $this->buffer[ $key ]['active'][ $slug ] = "$name - $version - $uri";
321 +
322 + } else {
323 + $this->buffer[ $key ]['inactive'][ $slug ] = "$name - $version - $uri";
324 + }
184 325 }
185 326 }
186 327
187 328 $mu_plugins = get_mu_plugins();
188 329 foreach( $mu_plugins as $k => $v ) {
189 - $this->buffer[ $key ]['mu-plugins'][ $k ] = "{$v['Name']} - {$v['Version']}";
330 + $name = 'N/A'; $version = 'N/A'; $uri = 'N/A';
331 + if (! empty( $v['Name'] ) ) {
332 + $name = $v['Name'];
333 + }
334 + if (! empty( $v['Version'] ) ) {
335 + $version = $v['Version'];
336 + }
337 + if (! empty( $v['PluginURI'] ) ) {
338 + $uri = $v['PluginURI'];
339 + }
340 + $this->buffer[ $key ]['mu-plugins'][ $k ] = "$name - $version - $uri";
190 341 }
191 342
192 343 }
193 344
@@ -199,13 +350,20 @@
199 350
200 351 $themes = wp_get_themes();
201 352 $active = get_option('template');
202 353 foreach( $themes as $k => $v ) {
203 - $version = $v->Version;
354 + $name = 'N/A'; $version = 'N/A';
355 + if ( $v->Name ) {
356 + $name = $v->Name;
357 + }
358 + if ( $v->Version ) {
359 + $version = $v->Version;
360 + }
204 361 if ( $k == $active ) {
205 - $version .= ' (active)';
362 + $this->buffer[ $key ]['active'][ $k ] = "$name - $version";
363 + } else {
364 + $this->buffer[ $key ]['inactive'][ $k ] = "$name - $version";
206 365 }
207 - $this->buffer[ $key ][ $k ] = "{$v->Name} - $version";
208 366 }
209 367 }
210 368
211 369
@@ -217,13 +375,16 @@
217 375 $cp_options = get_option('code-profiler');
218 376
219 377 $list = [
220 378 'hide_empty_value',
221 - // 'warn_composer',
222 379 'enable_wpcli',
223 380 'disable_wpcron',
224 - // 'disable_db-php',
225 - 'http_response'
381 + // 'disable_db-php',
382 + 'http_response',
383 + // 'backtrace_limit',
384 + 'accuracy',
385 + 'buffer',
386 + 'exclusions'
226 387 ];
227 388 foreach( $list as $element ) {
228 389 $this->buffer['options'][ $element ] = isset( $cp_options[ $element ] )? $cp_options[ $element ]:0;
229 390 }
@@ -234,8 +395,36 @@
234 395 */
235 396 private function shorten_path( $path ) {
236 397
237 398 return str_replace( ABSPATH, '', $path );
399 + }
400 +
401 +
402 + /**
403 + * Test if admin-ajax is accessible.
404 + */
405 + private function test_admin_ajax( $key ) {
406 +
407 + $headers = [
408 + // Devs must be allowed to use it on localhost over TLS too
409 + 'sslverify' => apply_filters('https_local_ssl_verify', false )
410 + ];
411 + $res = wp_safe_remote_get( admin_url('admin-ajax.php?action=generate-password'), $headers );
412 +
413 + /* Translators: Error message */
414 + $error = __('Error: %s', 'code-profiler');
415 +
416 + // Connection error
417 + if ( is_wp_error( $res ) ) {
418 + $msg = sprintf( $error, $res->get_error_message() );
419 +
420 + } elseif ( $res['response']['code'] != 200 ) {
421 + $msg = sprintf( $error, $res['response']['code'] ." ". $res['response']['message'] );
422 +
423 + } else {
424 + $msg = "OK";
425 + }
426 + $this->buffer[ $key ]['access'] = $msg;
238 427 }
239 428
240 429 }
241 430