| @@ -1,6 +1,6 @@ | ||
| 1 | 1 | <?php |
| 2 | -/* | |
| 2 | +/** | |
| 3 | 3 | +=====================================================================+ |
| 4 | 4 | | ____ _ ____ __ _ _ | |
| 5 | 5 | | / ___|___ __| | ___ | _ \ _ __ ___ / _(_) | ___ _ __ | |
| 6 | 6 | | | | / _ \ / _` |/ _ \ | |_) | '__/ _ \| |_| | |/ _ \ '__| | |
| @@ -6,33 +6,38 @@ | ||
| 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 { |
| 19 | 21 | |
| 20 | - /******************************************************************** | |
| 22 | + /** | |
| 21 | 23 | * Array to handle all results |
| 22 | 24 | */ |
| 23 | 25 | private $buffer = []; |
| 24 | 26 | |
| 25 | - /******************************************************************** | |
| 27 | + /** | |
| 26 | 28 | * Initialize. |
| 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 | 35 | $this->function_exists('code-profiler'); |
| 33 | 36 | $this->check_wpdb('wpdb'); |
| 37 | + $this->check_cache('cache'); | |
| 34 | 38 | $this->check_proxy('proxy'); |
| 39 | + $this->is_multisite('multisite'); | |
| 35 | 40 | $this->get_all_plugins('plugins'); |
| 36 | 41 | $this->get_theme('themes'); |
| 37 | 42 | $this->get_cp_config(); |
| 38 | 43 | |
| @@ -38,9 +43,9 @@ | ||
| 38 | 43 | |
| 39 | 44 | echo esc_textarea( print_r( $this->buffer, true ) ); |
| 40 | 45 | } |
| 41 | 46 | |
| 42 | - /******************************************************************** | |
| 47 | + /** | |
| 43 | 48 | * Retrieve system info: |
| 44 | 49 | * * PHP version |
| 45 | 50 | * * PHP SAPI |
| 46 | 51 | * * HTTP server |
| @@ -52,8 +57,14 @@ | ||
| 52 | 57 | private function get_system_info( $key ) { |
| 53 | 58 | |
| 54 | 59 | $this->buffer[ $key ]['OS'] = php_uname(); |
| 55 | 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 | + | |
| 56 | 67 | if (! empty( $_SERVER['SERVER_SOFTWARE'] ) ) { |
| 57 | 68 | $this->buffer[ $key ]['HTTP server'] = $_SERVER['SERVER_SOFTWARE']; |
| 58 | 69 | } else { |
| 59 | 70 | $this->buffer[ $key ]['HTTP server'] = 'N/A'; |
| @@ -81,9 +92,9 @@ | ||
| 81 | 92 | if (! empty( $tmp ) ) { |
| 82 | 93 | if ( is_writable( $tmp ) ) { |
| 83 | 94 | $tmp .= ' (writable)'; |
| 84 | 95 | } else { |
| 85 | - $tmp .= ' (not writable!)'; | |
| 96 | + $tmp .= ' (not writable!)' .' ⚠️'; | |
| 86 | 97 | } |
| 87 | 98 | } |
| 88 | 99 | $tmp = $this->shorten_path( $tmp ); |
| 89 | 100 | $this->buffer[ $key ]['Temp directory'] = $tmp; |
| @@ -101,8 +112,18 @@ | ||
| 101 | 112 | $this->buffer[ $key ]['Last error']['file'] = $this->shorten_path( $this->buffer[ $key ]['Last error']['file'] ); |
| 102 | 113 | } |
| 103 | 114 | |
| 104 | 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 | + } | |
| 105 | 126 | global $wp_version; |
| 106 | 127 | $this->buffer[ $key ]['WordPress']['version'] = $wp_version; |
| 107 | 128 | $wp_debug = ''; |
| 108 | 129 | if ( defined('WP_DEBUG') ) { |
| @@ -119,11 +140,41 @@ | ||
| 119 | 140 | $wp_debug = $this->shorten_path( $wp_debug ) ." (". number_format( $filesize ) ." bytes)"; |
| 120 | 141 | } |
| 121 | 142 | $this->buffer[ $key ]['WordPress']['WP_DEBUG_LOG'] = $wp_debug; |
| 122 | 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 | + } | |
| 123 | 173 | } |
| 124 | 174 | |
| 125 | - /******************************************************************** | |
| 175 | + | |
| 176 | + /** | |
| 126 | 177 | * Verify if some important PHP functions are available. |
| 127 | 178 | */ |
| 128 | 179 | private function function_exists( $key ) { |
| 129 | 180 | |
| @@ -131,18 +182,26 @@ | ||
| 131 | 182 | 'register_shutdown_function' => 'shutdown', |
| 132 | 183 | 'register_tick_function' => 'tick', |
| 133 | 184 | 'stream_wrapper_unregister' => 'unregister', |
| 134 | 185 | 'stream_wrapper_register' => 'register', |
| 135 | - 'stream_wrapper_restore' => 'restore' | |
| 186 | + 'stream_wrapper_restore' => 'restore', | |
| 187 | + 'hrtime' => 'hrtime' | |
| 136 | 188 | ]; |
| 137 | 189 | |
| 138 | 190 | foreach ( $required_functions as $function => $value ) { |
| 139 | - $this->buffer[ $key ][ $value ] = function_exists( $function ); | |
| 191 | + $this->buffer[ $key ]['function'][ $value ] = function_exists( $function ); | |
| 140 | 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 | + } | |
| 141 | 200 | } |
| 142 | 201 | |
| 143 | 202 | |
| 144 | - /******************************************************************** | |
| 203 | + /** | |
| 145 | 204 | * Return the version and type (free/pro) of Code Profiler. |
| 146 | 205 | */ |
| 147 | 206 | private function cp_info( $key ) { |
| 148 | 207 | |
| @@ -168,9 +227,9 @@ | ||
| 168 | 227 | $this->buffer[ $key ]['data_dir']['writable'] = is_writable( $dir ); |
| 169 | 228 | } |
| 170 | 229 | |
| 171 | 230 | |
| 172 | - /******************************************************************** | |
| 231 | + /** | |
| 173 | 232 | * Check if there are subclasses of the wpdb class and |
| 174 | 233 | * look for wp-content/db.php |
| 175 | 234 | */ |
| 176 | 235 | function check_wpdb( $key ) { |
| @@ -186,18 +245,21 @@ | ||
| 186 | 245 | $this->buffer[ $key ][ $db_php ] = file_exists( WP_CONTENT_DIR .'/db.php'); |
| 187 | 246 | } |
| 188 | 247 | |
| 189 | 248 | |
| 190 | - /******************************************************************** | |
| 249 | + /** | |
| 191 | 250 | * Check for advanced cache |
| 192 | 251 | */ |
| 193 | 252 | private function check_cache( $key ) { |
| 194 | 253 | |
| 195 | - $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 | + } | |
| 196 | 258 | } |
| 197 | 259 | |
| 198 | 260 | |
| 199 | - /******************************************************************** | |
| 261 | + /** | |
| 200 | 262 | * Check for reverse proxy or CDN |
| 201 | 263 | */ |
| 202 | 264 | private function check_proxy( $key ) { |
| 203 | 265 | |
| @@ -216,9 +278,24 @@ | ||
| 216 | 278 | |
| 217 | 279 | } |
| 218 | 280 | |
| 219 | 281 | |
| 220 | - /******************************************************************** | |
| 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 | + /** | |
| 221 | 298 | * Retrieve the list of all plugins and sort them |
| 222 | 299 | * (active or disabled). |
| 223 | 300 | */ |
| 224 | 301 | private function get_all_plugins( $key ) { |
| @@ -265,9 +342,9 @@ | ||
| 265 | 342 | |
| 266 | 343 | } |
| 267 | 344 | |
| 268 | 345 | |
| 269 | - /******************************************************************** | |
| 346 | + /** | |
| 270 | 347 | * Retrieve the active theme. |
| 271 | 348 | */ |
| 272 | 349 | private function get_theme( $key ) { |
| 273 | 350 | |
| @@ -289,9 +366,9 @@ | ||
| 289 | 366 | } |
| 290 | 367 | } |
| 291 | 368 | |
| 292 | 369 | |
| 293 | - /******************************************************************** | |
| 370 | + /** | |
| 294 | 371 | * Retrieve Code Profiler's configuration |
| 295 | 372 | */ |
| 296 | 373 | private function get_cp_config() { |
| 297 | 374 | |
| @@ -298,15 +375,16 @@ | ||
| 298 | 375 | $cp_options = get_option('code-profiler'); |
| 299 | 376 | |
| 300 | 377 | $list = [ |
| 301 | 378 | 'hide_empty_value', |
| 302 | - 'warn_composer', | |
| 303 | 379 | 'enable_wpcli', |
| 304 | 380 | 'disable_wpcron', |
| 305 | 381 | // 'disable_db-php', |
| 306 | 382 | 'http_response', |
| 307 | 383 | // 'backtrace_limit', |
| 308 | - 'accuracy' | |
| 384 | + 'accuracy', | |
| 385 | + 'buffer', | |
| 386 | + 'exclusions' | |
| 309 | 387 | ]; |
| 310 | 388 | foreach( $list as $element ) { |
| 311 | 389 | $this->buffer['options'][ $element ] = isset( $cp_options[ $element ] )? $cp_options[ $element ]:0; |
| 312 | 390 | } |
| @@ -311,14 +389,42 @@ | ||
| 311 | 389 | $this->buffer['options'][ $element ] = isset( $cp_options[ $element ] )? $cp_options[ $element ]:0; |
| 312 | 390 | } |
| 313 | 391 | } |
| 314 | 392 | |
| 315 | - /******************************************************************** | |
| 393 | + /** | |
| 316 | 394 | * Remove the ABSPATH from a path |
| 317 | 395 | */ |
| 318 | 396 | private function shorten_path( $path ) { |
| 319 | 397 | |
| 320 | 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; | |
| 321 | 427 | } |
| 322 | 428 | |
| 323 | 429 | } |
| 324 | 430 | |