[ Index ] |
PHP Cross Reference of WordPress |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Class for providing debug data based on a users WordPress environment. 4 * 5 * @package WordPress 6 * @subpackage Site_Health 7 * @since 5.2.0 8 */ 9 10 class WP_Debug_Data { 11 /** 12 * Calls all core functions to check for updates. 13 * 14 * @since 5.2.0 15 */ 16 static function check_for_updates() { 17 wp_version_check(); 18 wp_update_plugins(); 19 wp_update_themes(); 20 } 21 22 /** 23 * Static function for generating site debug data when required. 24 * 25 * @since 5.2.0 26 * @since 5.3.0 Added database charset, database collation, 27 * and timezone information. 28 * @since 5.5.0 Added pretty permalinks support information. 29 * 30 * @throws ImagickException 31 * @global wpdb $wpdb WordPress database abstraction object. 32 * 33 * @return array The debug data for the site. 34 */ 35 static function debug_data() { 36 global $wpdb; 37 38 // Save few function calls. 39 $upload_dir = wp_upload_dir(); 40 $permalink_structure = get_option( 'permalink_structure' ); 41 $is_ssl = is_ssl(); 42 $is_multisite = is_multisite(); 43 $users_can_register = get_option( 'users_can_register' ); 44 $blog_public = get_option( 'blog_public' ); 45 $default_comment_status = get_option( 'default_comment_status' ); 46 $environment_type = wp_get_environment_type(); 47 $core_version = get_bloginfo( 'version' ); 48 $core_updates = get_core_updates(); 49 $core_update_needed = ''; 50 51 if ( is_array( $core_updates ) ) { 52 foreach ( $core_updates as $core => $update ) { 53 if ( 'upgrade' === $update->response ) { 54 /* translators: %s: Latest WordPress version number. */ 55 $core_update_needed = ' ' . sprintf( __( '(Latest version: %s)' ), $update->version ); 56 } else { 57 $core_update_needed = ''; 58 } 59 } 60 } 61 62 // Set up the array that holds all debug information. 63 $info = array(); 64 65 $info['wp-core'] = array( 66 'label' => __( 'WordPress' ), 67 'fields' => array( 68 'version' => array( 69 'label' => __( 'Version' ), 70 'value' => $core_version . $core_update_needed, 71 'debug' => $core_version, 72 ), 73 'site_language' => array( 74 'label' => __( 'Site Language' ), 75 'value' => get_locale(), 76 ), 77 'user_language' => array( 78 'label' => __( 'User Language' ), 79 'value' => get_user_locale(), 80 ), 81 'timezone' => array( 82 'label' => __( 'Timezone' ), 83 'value' => wp_timezone_string(), 84 ), 85 'home_url' => array( 86 'label' => __( 'Home URL' ), 87 'value' => get_bloginfo( 'url' ), 88 'private' => true, 89 ), 90 'site_url' => array( 91 'label' => __( 'Site URL' ), 92 'value' => get_bloginfo( 'wpurl' ), 93 'private' => true, 94 ), 95 'permalink' => array( 96 'label' => __( 'Permalink structure' ), 97 'value' => $permalink_structure ? $permalink_structure : __( 'No permalink structure set' ), 98 'debug' => $permalink_structure, 99 ), 100 'https_status' => array( 101 'label' => __( 'Is this site using HTTPS?' ), 102 'value' => $is_ssl ? __( 'Yes' ) : __( 'No' ), 103 'debug' => $is_ssl, 104 ), 105 'multisite' => array( 106 'label' => __( 'Is this a multisite?' ), 107 'value' => $is_multisite ? __( 'Yes' ) : __( 'No' ), 108 'debug' => $is_multisite, 109 ), 110 'user_registration' => array( 111 'label' => __( 'Can anyone register on this site?' ), 112 'value' => $users_can_register ? __( 'Yes' ) : __( 'No' ), 113 'debug' => $users_can_register, 114 ), 115 'blog_public' => array( 116 'label' => __( 'Is this site discouraging search engines?' ), 117 'value' => $blog_public ? __( 'No' ) : __( 'Yes' ), 118 'debug' => $blog_public, 119 ), 120 'default_comment_status' => array( 121 'label' => __( 'Default comment status' ), 122 'value' => 'open' === $default_comment_status ? _x( 'Open', 'comment status' ) : _x( 'Closed', 'comment status' ), 123 'debug' => $default_comment_status, 124 ), 125 'environment_type' => array( 126 'label' => __( 'Environment type' ), 127 'value' => $environment_type, 128 'debug' => $environment_type, 129 ), 130 ), 131 ); 132 133 if ( ! $is_multisite ) { 134 $info['wp-paths-sizes'] = array( 135 'label' => __( 'Directories and Sizes' ), 136 'fields' => array(), 137 ); 138 } 139 140 $info['wp-dropins'] = array( 141 'label' => __( 'Drop-ins' ), 142 'show_count' => true, 143 'description' => sprintf( 144 /* translators: %s: wp-content directory name. */ 145 __( 'Drop-ins are single files, found in the %s directory, that replace or enhance WordPress features in ways that are not possible for traditional plugins.' ), 146 '<code>' . str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '</code>' 147 ), 148 'fields' => array(), 149 ); 150 151 $info['wp-active-theme'] = array( 152 'label' => __( 'Active Theme' ), 153 'fields' => array(), 154 ); 155 156 $info['wp-parent-theme'] = array( 157 'label' => __( 'Parent Theme' ), 158 'fields' => array(), 159 ); 160 161 $info['wp-themes-inactive'] = array( 162 'label' => __( 'Inactive Themes' ), 163 'show_count' => true, 164 'fields' => array(), 165 ); 166 167 $info['wp-mu-plugins'] = array( 168 'label' => __( 'Must Use Plugins' ), 169 'show_count' => true, 170 'fields' => array(), 171 ); 172 173 $info['wp-plugins-active'] = array( 174 'label' => __( 'Active Plugins' ), 175 'show_count' => true, 176 'fields' => array(), 177 ); 178 179 $info['wp-plugins-inactive'] = array( 180 'label' => __( 'Inactive Plugins' ), 181 'show_count' => true, 182 'fields' => array(), 183 ); 184 185 $info['wp-media'] = array( 186 'label' => __( 'Media Handling' ), 187 'fields' => array(), 188 ); 189 190 $info['wp-server'] = array( 191 'label' => __( 'Server' ), 192 'description' => __( 'The options shown below relate to your server setup. If changes are required, you may need your web host’s assistance.' ), 193 'fields' => array(), 194 ); 195 196 $info['wp-database'] = array( 197 'label' => __( 'Database' ), 198 'fields' => array(), 199 ); 200 201 // Check if WP_DEBUG_LOG is set. 202 $wp_debug_log_value = __( 'Disabled' ); 203 204 if ( is_string( WP_DEBUG_LOG ) ) { 205 $wp_debug_log_value = WP_DEBUG_LOG; 206 } elseif ( WP_DEBUG_LOG ) { 207 $wp_debug_log_value = __( 'Enabled' ); 208 } 209 210 // Check CONCATENATE_SCRIPTS. 211 if ( defined( 'CONCATENATE_SCRIPTS' ) ) { 212 $concatenate_scripts = CONCATENATE_SCRIPTS ? __( 'Enabled' ) : __( 'Disabled' ); 213 $concatenate_scripts_debug = CONCATENATE_SCRIPTS ? 'true' : 'false'; 214 } else { 215 $concatenate_scripts = __( 'Undefined' ); 216 $concatenate_scripts_debug = 'undefined'; 217 } 218 219 // Check COMPRESS_SCRIPTS. 220 if ( defined( 'COMPRESS_SCRIPTS' ) ) { 221 $compress_scripts = COMPRESS_SCRIPTS ? __( 'Enabled' ) : __( 'Disabled' ); 222 $compress_scripts_debug = COMPRESS_SCRIPTS ? 'true' : 'false'; 223 } else { 224 $compress_scripts = __( 'Undefined' ); 225 $compress_scripts_debug = 'undefined'; 226 } 227 228 // Check COMPRESS_CSS. 229 if ( defined( 'COMPRESS_CSS' ) ) { 230 $compress_css = COMPRESS_CSS ? __( 'Enabled' ) : __( 'Disabled' ); 231 $compress_css_debug = COMPRESS_CSS ? 'true' : 'false'; 232 } else { 233 $compress_css = __( 'Undefined' ); 234 $compress_css_debug = 'undefined'; 235 } 236 237 // Check WP_LOCAL_DEV. 238 if ( defined( 'WP_LOCAL_DEV' ) ) { 239 $wp_local_dev = WP_LOCAL_DEV ? __( 'Enabled' ) : __( 'Disabled' ); 240 $wp_local_dev_debug = WP_LOCAL_DEV ? 'true' : 'false'; 241 } else { 242 $wp_local_dev = __( 'Undefined' ); 243 $wp_local_dev_debug = 'undefined'; 244 } 245 246 $info['wp-constants'] = array( 247 'label' => __( 'WordPress Constants' ), 248 'description' => __( 'These settings alter where and how parts of WordPress are loaded.' ), 249 'fields' => array( 250 'ABSPATH' => array( 251 'label' => 'ABSPATH', 252 'value' => ABSPATH, 253 'private' => true, 254 ), 255 'WP_HOME' => array( 256 'label' => 'WP_HOME', 257 'value' => ( defined( 'WP_HOME' ) ? WP_HOME : __( 'Undefined' ) ), 258 'debug' => ( defined( 'WP_HOME' ) ? WP_HOME : 'undefined' ), 259 ), 260 'WP_SITEURL' => array( 261 'label' => 'WP_SITEURL', 262 'value' => ( defined( 'WP_SITEURL' ) ? WP_SITEURL : __( 'Undefined' ) ), 263 'debug' => ( defined( 'WP_SITEURL' ) ? WP_SITEURL : 'undefined' ), 264 ), 265 'WP_CONTENT_DIR' => array( 266 'label' => 'WP_CONTENT_DIR', 267 'value' => WP_CONTENT_DIR, 268 ), 269 'WP_PLUGIN_DIR' => array( 270 'label' => 'WP_PLUGIN_DIR', 271 'value' => WP_PLUGIN_DIR, 272 ), 273 'WP_MEMORY_LIMIT' => array( 274 'label' => 'WP_MEMORY_LIMIT', 275 'value' => WP_MEMORY_LIMIT, 276 ), 277 'WP_MAX_MEMORY_LIMIT' => array( 278 'label' => 'WP_MAX_MEMORY_LIMIT', 279 'value' => WP_MAX_MEMORY_LIMIT, 280 ), 281 'WP_DEBUG' => array( 282 'label' => 'WP_DEBUG', 283 'value' => WP_DEBUG ? __( 'Enabled' ) : __( 'Disabled' ), 284 'debug' => WP_DEBUG, 285 ), 286 'WP_DEBUG_DISPLAY' => array( 287 'label' => 'WP_DEBUG_DISPLAY', 288 'value' => WP_DEBUG_DISPLAY ? __( 'Enabled' ) : __( 'Disabled' ), 289 'debug' => WP_DEBUG_DISPLAY, 290 ), 291 'WP_DEBUG_LOG' => array( 292 'label' => 'WP_DEBUG_LOG', 293 'value' => $wp_debug_log_value, 294 'debug' => WP_DEBUG_LOG, 295 ), 296 'SCRIPT_DEBUG' => array( 297 'label' => 'SCRIPT_DEBUG', 298 'value' => SCRIPT_DEBUG ? __( 'Enabled' ) : __( 'Disabled' ), 299 'debug' => SCRIPT_DEBUG, 300 ), 301 'WP_CACHE' => array( 302 'label' => 'WP_CACHE', 303 'value' => WP_CACHE ? __( 'Enabled' ) : __( 'Disabled' ), 304 'debug' => WP_CACHE, 305 ), 306 'CONCATENATE_SCRIPTS' => array( 307 'label' => 'CONCATENATE_SCRIPTS', 308 'value' => $concatenate_scripts, 309 'debug' => $concatenate_scripts_debug, 310 ), 311 'COMPRESS_SCRIPTS' => array( 312 'label' => 'COMPRESS_SCRIPTS', 313 'value' => $compress_scripts, 314 'debug' => $compress_scripts_debug, 315 ), 316 'COMPRESS_CSS' => array( 317 'label' => 'COMPRESS_CSS', 318 'value' => $compress_css, 319 'debug' => $compress_css_debug, 320 ), 321 'WP_LOCAL_DEV' => array( 322 'label' => 'WP_LOCAL_DEV', 323 'value' => $wp_local_dev, 324 'debug' => $wp_local_dev_debug, 325 ), 326 'DB_CHARSET' => array( 327 'label' => 'DB_CHARSET', 328 'value' => ( defined( 'DB_CHARSET' ) ? DB_CHARSET : __( 'Undefined' ) ), 329 'debug' => ( defined( 'DB_CHARSET' ) ? DB_CHARSET : 'undefined' ), 330 ), 331 'DB_COLLATE' => array( 332 'label' => 'DB_COLLATE', 333 'value' => ( defined( 'DB_COLLATE' ) ? DB_COLLATE : __( 'Undefined' ) ), 334 'debug' => ( defined( 'DB_COLLATE' ) ? DB_COLLATE : 'undefined' ), 335 ), 336 ), 337 ); 338 339 $is_writable_abspath = wp_is_writable( ABSPATH ); 340 $is_writable_wp_content_dir = wp_is_writable( WP_CONTENT_DIR ); 341 $is_writable_upload_dir = wp_is_writable( $upload_dir['basedir'] ); 342 $is_writable_wp_plugin_dir = wp_is_writable( WP_PLUGIN_DIR ); 343 $is_writable_template_directory = wp_is_writable( get_theme_root( get_template() ) ); 344 345 $info['wp-filesystem'] = array( 346 'label' => __( 'Filesystem Permissions' ), 347 'description' => __( 'Shows whether WordPress is able to write to the directories it needs access to.' ), 348 'fields' => array( 349 'wordpress' => array( 350 'label' => __( 'The main WordPress directory' ), 351 'value' => ( $is_writable_abspath ? __( 'Writable' ) : __( 'Not writable' ) ), 352 'debug' => ( $is_writable_abspath ? 'writable' : 'not writable' ), 353 ), 354 'wp-content' => array( 355 'label' => __( 'The wp-content directory' ), 356 'value' => ( $is_writable_wp_content_dir ? __( 'Writable' ) : __( 'Not writable' ) ), 357 'debug' => ( $is_writable_wp_content_dir ? 'writable' : 'not writable' ), 358 ), 359 'uploads' => array( 360 'label' => __( 'The uploads directory' ), 361 'value' => ( $is_writable_upload_dir ? __( 'Writable' ) : __( 'Not writable' ) ), 362 'debug' => ( $is_writable_upload_dir ? 'writable' : 'not writable' ), 363 ), 364 'plugins' => array( 365 'label' => __( 'The plugins directory' ), 366 'value' => ( $is_writable_wp_plugin_dir ? __( 'Writable' ) : __( 'Not writable' ) ), 367 'debug' => ( $is_writable_wp_plugin_dir ? 'writable' : 'not writable' ), 368 ), 369 'themes' => array( 370 'label' => __( 'The themes directory' ), 371 'value' => ( $is_writable_template_directory ? __( 'Writable' ) : __( 'Not writable' ) ), 372 'debug' => ( $is_writable_template_directory ? 'writable' : 'not writable' ), 373 ), 374 ), 375 ); 376 377 // Conditionally add debug information for multisite setups. 378 if ( is_multisite() ) { 379 $network_query = new WP_Network_Query(); 380 $network_ids = $network_query->query( 381 array( 382 'fields' => 'ids', 383 'number' => 100, 384 'no_found_rows' => false, 385 ) 386 ); 387 388 $site_count = 0; 389 foreach ( $network_ids as $network_id ) { 390 $site_count += get_blog_count( $network_id ); 391 } 392 393 $info['wp-core']['fields']['user_count'] = array( 394 'label' => __( 'User count' ), 395 'value' => get_user_count(), 396 ); 397 398 $info['wp-core']['fields']['site_count'] = array( 399 'label' => __( 'Site count' ), 400 'value' => $site_count, 401 ); 402 403 $info['wp-core']['fields']['network_count'] = array( 404 'label' => __( 'Network count' ), 405 'value' => $network_query->found_networks, 406 ); 407 } else { 408 $user_count = count_users(); 409 410 $info['wp-core']['fields']['user_count'] = array( 411 'label' => __( 'User count' ), 412 'value' => $user_count['total_users'], 413 ); 414 } 415 416 // WordPress features requiring processing. 417 $wp_dotorg = wp_remote_get( 'https://wordpress.org', array( 'timeout' => 10 ) ); 418 419 if ( ! is_wp_error( $wp_dotorg ) ) { 420 $info['wp-core']['fields']['dotorg_communication'] = array( 421 'label' => __( 'Communication with WordPress.org' ), 422 'value' => __( 'WordPress.org is reachable' ), 423 'debug' => 'true', 424 ); 425 } else { 426 $info['wp-core']['fields']['dotorg_communication'] = array( 427 'label' => __( 'Communication with WordPress.org' ), 428 'value' => sprintf( 429 /* translators: 1: The IP address WordPress.org resolves to. 2: The error returned by the lookup. */ 430 __( 'Unable to reach WordPress.org at %1$s: %2$s' ), 431 gethostbyname( 'wordpress.org' ), 432 $wp_dotorg->get_error_message() 433 ), 434 'debug' => $wp_dotorg->get_error_message(), 435 ); 436 } 437 438 // Remove accordion for Directories and Sizes if in Multisite. 439 if ( ! $is_multisite ) { 440 $loading = __( 'Loading…' ); 441 442 $info['wp-paths-sizes']['fields'] = array( 443 'wordpress_path' => array( 444 'label' => __( 'WordPress directory location' ), 445 'value' => untrailingslashit( ABSPATH ), 446 ), 447 'wordpress_size' => array( 448 'label' => __( 'WordPress directory size' ), 449 'value' => $loading, 450 'debug' => 'loading...', 451 ), 452 'uploads_path' => array( 453 'label' => __( 'Uploads directory location' ), 454 'value' => $upload_dir['basedir'], 455 ), 456 'uploads_size' => array( 457 'label' => __( 'Uploads directory size' ), 458 'value' => $loading, 459 'debug' => 'loading...', 460 ), 461 'themes_path' => array( 462 'label' => __( 'Themes directory location' ), 463 'value' => get_theme_root(), 464 ), 465 'themes_size' => array( 466 'label' => __( 'Themes directory size' ), 467 'value' => $loading, 468 'debug' => 'loading...', 469 ), 470 'plugins_path' => array( 471 'label' => __( 'Plugins directory location' ), 472 'value' => WP_PLUGIN_DIR, 473 ), 474 'plugins_size' => array( 475 'label' => __( 'Plugins directory size' ), 476 'value' => $loading, 477 'debug' => 'loading...', 478 ), 479 'database_size' => array( 480 'label' => __( 'Database size' ), 481 'value' => $loading, 482 'debug' => 'loading...', 483 ), 484 'total_size' => array( 485 'label' => __( 'Total installation size' ), 486 'value' => $loading, 487 'debug' => 'loading...', 488 ), 489 ); 490 } 491 492 // Get a list of all drop-in replacements. 493 $dropins = get_dropins(); 494 495 // Get dropins descriptions. 496 $dropin_descriptions = _get_dropins(); 497 498 // Spare few function calls. 499 $not_available = __( 'Not available' ); 500 501 foreach ( $dropins as $dropin_key => $dropin ) { 502 $info['wp-dropins']['fields'][ sanitize_text_field( $dropin_key ) ] = array( 503 'label' => $dropin_key, 504 'value' => $dropin_descriptions[ $dropin_key ][0], 505 'debug' => 'true', 506 ); 507 } 508 509 // Populate the media fields. 510 $info['wp-media']['fields']['image_editor'] = array( 511 'label' => __( 'Active editor' ), 512 'value' => _wp_image_editor_choose(), 513 ); 514 515 // Get ImageMagic information, if available. 516 if ( class_exists( 'Imagick' ) ) { 517 // Save the Imagick instance for later use. 518 $imagick = new Imagick(); 519 $imagick_version = $imagick->getVersion(); 520 } else { 521 $imagick_version = __( 'Not available' ); 522 } 523 524 $info['wp-media']['fields']['imagick_module_version'] = array( 525 'label' => __( 'ImageMagick version number' ), 526 'value' => ( is_array( $imagick_version ) ? $imagick_version['versionNumber'] : $imagick_version ), 527 ); 528 529 $info['wp-media']['fields']['imagemagick_version'] = array( 530 'label' => __( 'ImageMagick version string' ), 531 'value' => ( is_array( $imagick_version ) ? $imagick_version['versionString'] : $imagick_version ), 532 ); 533 534 if ( ! function_exists( 'ini_get' ) ) { 535 $info['wp-media']['fields']['ini_get'] = array( 536 'label' => __( 'File upload settings' ), 537 'value' => sprintf( 538 /* translators: %s: ini_get() */ 539 __( 'Unable to determine some settings, as the %s function has been disabled.' ), 540 'ini_get()' 541 ), 542 'debug' => 'ini_get() is disabled', 543 ); 544 } else { 545 // Get the PHP ini directive values. 546 $post_max_size = ini_get( 'post_max_size' ); 547 $upload_max_filesize = ini_get( 'upload_max_filesize' ); 548 $max_file_uploads = ini_get( 'max_file_uploads' ); 549 $effective = min( wp_convert_hr_to_bytes( $post_max_size ), wp_convert_hr_to_bytes( $upload_max_filesize ) ); 550 551 // Add info in Media section. 552 $info['wp-media']['fields']['file_uploads'] = array( 553 'label' => __( 'File uploads' ), 554 'value' => empty( ini_get( 'file_uploads' ) ) ? __( 'Disabled' ) : __( 'Enabled' ), 555 'debug' => 'File uploads is turned off', 556 ); 557 $info['wp-media']['fields']['post_max_size'] = array( 558 'label' => __( 'Max size of post data allowed' ), 559 'value' => $post_max_size, 560 ); 561 $info['wp-media']['fields']['upload_max_filesize'] = array( 562 'label' => __( 'Max size of an uploaded file' ), 563 'value' => $upload_max_filesize, 564 ); 565 $info['wp-media']['fields']['max_effective_size'] = array( 566 'label' => __( 'Max effective file size' ), 567 'value' => size_format( $effective ), 568 ); 569 $info['wp-media']['fields']['max_file_uploads'] = array( 570 'label' => __( 'Max number of files allowed' ), 571 'value' => number_format( $max_file_uploads ), 572 ); 573 } 574 575 // If Imagick is used as our editor, provide some more information about its limitations. 576 if ( 'WP_Image_Editor_Imagick' === _wp_image_editor_choose() && isset( $imagick ) && $imagick instanceof Imagick ) { 577 $limits = array( 578 'area' => ( defined( 'imagick::RESOURCETYPE_AREA' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_AREA ) ) : $not_available ), 579 'disk' => ( defined( 'imagick::RESOURCETYPE_DISK' ) ? $imagick->getResourceLimit( imagick::RESOURCETYPE_DISK ) : $not_available ), 580 'file' => ( defined( 'imagick::RESOURCETYPE_FILE' ) ? $imagick->getResourceLimit( imagick::RESOURCETYPE_FILE ) : $not_available ), 581 'map' => ( defined( 'imagick::RESOURCETYPE_MAP' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_MAP ) ) : $not_available ), 582 'memory' => ( defined( 'imagick::RESOURCETYPE_MEMORY' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_MEMORY ) ) : $not_available ), 583 'thread' => ( defined( 'imagick::RESOURCETYPE_THREAD' ) ? $imagick->getResourceLimit( imagick::RESOURCETYPE_THREAD ) : $not_available ), 584 ); 585 586 $limits_debug = array( 587 'imagick::RESOURCETYPE_AREA' => ( defined( 'imagick::RESOURCETYPE_AREA' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_AREA ) ) : 'not available' ), 588 'imagick::RESOURCETYPE_DISK' => ( defined( 'imagick::RESOURCETYPE_DISK' ) ? $imagick->getResourceLimit( imagick::RESOURCETYPE_DISK ) : 'not available' ), 589 'imagick::RESOURCETYPE_FILE' => ( defined( 'imagick::RESOURCETYPE_FILE' ) ? $imagick->getResourceLimit( imagick::RESOURCETYPE_FILE ) : 'not available' ), 590 'imagick::RESOURCETYPE_MAP' => ( defined( 'imagick::RESOURCETYPE_MAP' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_MAP ) ) : 'not available' ), 591 'imagick::RESOURCETYPE_MEMORY' => ( defined( 'imagick::RESOURCETYPE_MEMORY' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_MEMORY ) ) : 'not available' ), 592 'imagick::RESOURCETYPE_THREAD' => ( defined( 'imagick::RESOURCETYPE_THREAD' ) ? $imagick->getResourceLimit( imagick::RESOURCETYPE_THREAD ) : 'not available' ), 593 ); 594 595 $info['wp-media']['fields']['imagick_limits'] = array( 596 'label' => __( 'Imagick Resource Limits' ), 597 'value' => $limits, 598 'debug' => $limits_debug, 599 ); 600 } 601 602 // Get GD information, if available. 603 if ( function_exists( 'gd_info' ) ) { 604 $gd = gd_info(); 605 } else { 606 $gd = false; 607 } 608 609 $info['wp-media']['fields']['gd_version'] = array( 610 'label' => __( 'GD version' ), 611 'value' => ( is_array( $gd ) ? $gd['GD Version'] : $not_available ), 612 'debug' => ( is_array( $gd ) ? $gd['GD Version'] : 'not available' ), 613 ); 614 615 // Get Ghostscript information, if available. 616 if ( function_exists( 'exec' ) ) { 617 $gs = exec( 'gs --version' ); 618 619 if ( empty( $gs ) ) { 620 $gs = $not_available; 621 $gs_debug = 'not available'; 622 } else { 623 $gs_debug = $gs; 624 } 625 } else { 626 $gs = __( 'Unable to determine if Ghostscript is installed' ); 627 $gs_debug = 'unknown'; 628 } 629 630 $info['wp-media']['fields']['ghostscript_version'] = array( 631 'label' => __( 'Ghostscript version' ), 632 'value' => $gs, 633 'debug' => $gs_debug, 634 ); 635 636 // Populate the server debug fields. 637 if ( function_exists( 'php_uname' ) ) { 638 $server_architecture = sprintf( '%s %s %s', php_uname( 's' ), php_uname( 'r' ), php_uname( 'm' ) ); 639 } else { 640 $server_architecture = 'unknown'; 641 } 642 643 if ( function_exists( 'phpversion' ) ) { 644 $php_version_debug = phpversion(); 645 // Whether PHP supports 64-bit. 646 $php64bit = ( PHP_INT_SIZE * 8 === 64 ); 647 648 $php_version = sprintf( 649 '%s %s', 650 $php_version_debug, 651 ( $php64bit ? __( '(Supports 64bit values)' ) : __( '(Does not support 64bit values)' ) ) 652 ); 653 654 if ( $php64bit ) { 655 $php_version_debug .= ' 64bit'; 656 } 657 } else { 658 $php_version = __( 'Unable to determine PHP version' ); 659 $php_version_debug = 'unknown'; 660 } 661 662 if ( function_exists( 'php_sapi_name' ) ) { 663 $php_sapi = php_sapi_name(); 664 } else { 665 $php_sapi = 'unknown'; 666 } 667 668 $info['wp-server']['fields']['server_architecture'] = array( 669 'label' => __( 'Server architecture' ), 670 'value' => ( 'unknown' !== $server_architecture ? $server_architecture : __( 'Unable to determine server architecture' ) ), 671 'debug' => $server_architecture, 672 ); 673 $info['wp-server']['fields']['httpd_software'] = array( 674 'label' => __( 'Web server' ), 675 'value' => ( isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : __( 'Unable to determine what web server software is used' ) ), 676 'debug' => ( isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : 'unknown' ), 677 ); 678 $info['wp-server']['fields']['php_version'] = array( 679 'label' => __( 'PHP version' ), 680 'value' => $php_version, 681 'debug' => $php_version_debug, 682 ); 683 $info['wp-server']['fields']['php_sapi'] = array( 684 'label' => __( 'PHP SAPI' ), 685 'value' => ( 'unknown' !== $php_sapi ? $php_sapi : __( 'Unable to determine PHP SAPI' ) ), 686 'debug' => $php_sapi, 687 ); 688 689 // Some servers disable `ini_set()` and `ini_get()`, we check this before trying to get configuration values. 690 if ( ! function_exists( 'ini_get' ) ) { 691 $info['wp-server']['fields']['ini_get'] = array( 692 'label' => __( 'Server settings' ), 693 'value' => sprintf( 694 /* translators: %s: ini_get() */ 695 __( 'Unable to determine some settings, as the %s function has been disabled.' ), 696 'ini_get()' 697 ), 698 'debug' => 'ini_get() is disabled', 699 ); 700 } else { 701 $info['wp-server']['fields']['max_input_variables'] = array( 702 'label' => __( 'PHP max input variables' ), 703 'value' => ini_get( 'max_input_vars' ), 704 ); 705 $info['wp-server']['fields']['time_limit'] = array( 706 'label' => __( 'PHP time limit' ), 707 'value' => ini_get( 'max_execution_time' ), 708 ); 709 710 if ( WP_Site_Health::get_instance()->php_memory_limit !== ini_get( 'memory_limit' ) ) { 711 $info['wp-server']['fields']['memory_limit'] = array( 712 'label' => __( 'PHP memory limit' ), 713 'value' => WP_Site_Health::get_instance()->php_memory_limit, 714 ); 715 $info['wp-server']['fields']['admin_memory_limit'] = array( 716 'label' => __( 'PHP memory limit (only for admin screens)' ), 717 'value' => ini_get( 'memory_limit' ), 718 ); 719 } else { 720 $info['wp-server']['fields']['memory_limit'] = array( 721 'label' => __( 'PHP memory limit' ), 722 'value' => ini_get( 'memory_limit' ), 723 ); 724 } 725 726 $info['wp-server']['fields']['max_input_time'] = array( 727 'label' => __( 'Max input time' ), 728 'value' => ini_get( 'max_input_time' ), 729 ); 730 $info['wp-server']['fields']['upload_max_filesize'] = array( 731 'label' => __( 'Upload max filesize' ), 732 'value' => ini_get( 'upload_max_filesize' ), 733 ); 734 $info['wp-server']['fields']['php_post_max_size'] = array( 735 'label' => __( 'PHP post max size' ), 736 'value' => ini_get( 'post_max_size' ), 737 ); 738 } 739 740 if ( function_exists( 'curl_version' ) ) { 741 $curl = curl_version(); 742 743 $info['wp-server']['fields']['curl_version'] = array( 744 'label' => __( 'cURL version' ), 745 'value' => sprintf( '%s %s', $curl['version'], $curl['ssl_version'] ), 746 ); 747 } else { 748 $info['wp-server']['fields']['curl_version'] = array( 749 'label' => __( 'cURL version' ), 750 'value' => $not_available, 751 'debug' => 'not available', 752 ); 753 } 754 755 // SUHOSIN. 756 $suhosin_loaded = ( extension_loaded( 'suhosin' ) || ( defined( 'SUHOSIN_PATCH' ) && constant( 'SUHOSIN_PATCH' ) ) ); 757 758 $info['wp-server']['fields']['suhosin'] = array( 759 'label' => __( 'Is SUHOSIN installed?' ), 760 'value' => ( $suhosin_loaded ? __( 'Yes' ) : __( 'No' ) ), 761 'debug' => $suhosin_loaded, 762 ); 763 764 // Imagick. 765 $imagick_loaded = extension_loaded( 'imagick' ); 766 767 $info['wp-server']['fields']['imagick_availability'] = array( 768 'label' => __( 'Is the Imagick library available?' ), 769 'value' => ( $imagick_loaded ? __( 'Yes' ) : __( 'No' ) ), 770 'debug' => $imagick_loaded, 771 ); 772 773 // Pretty permalinks. 774 $pretty_permalinks_supported = got_url_rewrite(); 775 776 $info['wp-server']['fields']['pretty_permalinks'] = array( 777 'label' => __( 'Are pretty permalinks supported?' ), 778 'value' => ( $pretty_permalinks_supported ? __( 'Yes' ) : __( 'No' ) ), 779 'debug' => $pretty_permalinks_supported, 780 ); 781 782 // Check if a .htaccess file exists. 783 if ( is_file( ABSPATH . '.htaccess' ) ) { 784 // If the file exists, grab the content of it. 785 $htaccess_content = file_get_contents( ABSPATH . '.htaccess' ); 786 787 // Filter away the core WordPress rules. 788 $filtered_htaccess_content = trim( preg_replace( '/\# BEGIN WordPress[\s\S]+?# END WordPress/si', '', $htaccess_content ) ); 789 $filtered_htaccess_content = ! empty( $filtered_htaccess_content ); 790 791 if ( $filtered_htaccess_content ) { 792 /* translators: %s: .htaccess */ 793 $htaccess_rules_string = sprintf( __( 'Custom rules have been added to your %s file.' ), '.htaccess' ); 794 } else { 795 /* translators: %s: .htaccess */ 796 $htaccess_rules_string = sprintf( __( 'Your %s file contains only core WordPress features.' ), '.htaccess' ); 797 } 798 799 $info['wp-server']['fields']['htaccess_extra_rules'] = array( 800 'label' => __( '.htaccess rules' ), 801 'value' => $htaccess_rules_string, 802 'debug' => $filtered_htaccess_content, 803 ); 804 } 805 806 // Populate the database debug fields. 807 if ( is_resource( $wpdb->dbh ) ) { 808 // Old mysql extension. 809 $extension = 'mysql'; 810 } elseif ( is_object( $wpdb->dbh ) ) { 811 // mysqli or PDO. 812 $extension = get_class( $wpdb->dbh ); 813 } else { 814 // Unknown sql extension. 815 $extension = null; 816 } 817 818 $server = $wpdb->get_var( 'SELECT VERSION()' ); 819 820 if ( isset( $wpdb->use_mysqli ) && $wpdb->use_mysqli ) { 821 $client_version = $wpdb->dbh->client_info; 822 } else { 823 // phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_client_info,PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved 824 if ( preg_match( '|[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}|', mysql_get_client_info(), $matches ) ) { 825 $client_version = $matches[0]; 826 } else { 827 $client_version = null; 828 } 829 } 830 831 $info['wp-database']['fields']['extension'] = array( 832 'label' => __( 'Extension' ), 833 'value' => $extension, 834 ); 835 836 $info['wp-database']['fields']['server_version'] = array( 837 'label' => __( 'Server version' ), 838 'value' => $server, 839 ); 840 841 $info['wp-database']['fields']['client_version'] = array( 842 'label' => __( 'Client version' ), 843 'value' => $client_version, 844 ); 845 846 $info['wp-database']['fields']['database_user'] = array( 847 'label' => __( 'Database username' ), 848 'value' => $wpdb->dbuser, 849 'private' => true, 850 ); 851 852 $info['wp-database']['fields']['database_host'] = array( 853 'label' => __( 'Database host' ), 854 'value' => $wpdb->dbhost, 855 'private' => true, 856 ); 857 858 $info['wp-database']['fields']['database_name'] = array( 859 'label' => __( 'Database name' ), 860 'value' => $wpdb->dbname, 861 'private' => true, 862 ); 863 864 $info['wp-database']['fields']['database_prefix'] = array( 865 'label' => __( 'Table prefix' ), 866 'value' => $wpdb->prefix, 867 'private' => true, 868 ); 869 870 $info['wp-database']['fields']['database_charset'] = array( 871 'label' => __( 'Database charset' ), 872 'value' => $wpdb->charset, 873 'private' => true, 874 ); 875 876 $info['wp-database']['fields']['database_collate'] = array( 877 'label' => __( 'Database collation' ), 878 'value' => $wpdb->collate, 879 'private' => true, 880 ); 881 882 // List must use plugins if there are any. 883 $mu_plugins = get_mu_plugins(); 884 885 foreach ( $mu_plugins as $plugin_path => $plugin ) { 886 $plugin_version = $plugin['Version']; 887 $plugin_author = $plugin['Author']; 888 889 $plugin_version_string = __( 'No version or author information is available.' ); 890 $plugin_version_string_debug = 'author: (undefined), version: (undefined)'; 891 892 if ( ! empty( $plugin_version ) && ! empty( $plugin_author ) ) { 893 /* translators: 1: Plugin version number. 2: Plugin author name. */ 894 $plugin_version_string = sprintf( __( 'Version %1$s by %2$s' ), $plugin_version, $plugin_author ); 895 $plugin_version_string_debug = sprintf( 'version: %s, author: %s', $plugin_version, $plugin_author ); 896 } else { 897 if ( ! empty( $plugin_author ) ) { 898 /* translators: %s: Plugin author name. */ 899 $plugin_version_string = sprintf( __( 'By %s' ), $plugin_author ); 900 $plugin_version_string_debug = sprintf( 'author: %s, version: (undefined)', $plugin_author ); 901 } 902 903 if ( ! empty( $plugin_version ) ) { 904 /* translators: %s: Plugin version number. */ 905 $plugin_version_string = sprintf( __( 'Version %s' ), $plugin_version ); 906 $plugin_version_string_debug = sprintf( 'author: (undefined), version: %s', $plugin_version ); 907 } 908 } 909 910 $info['wp-mu-plugins']['fields'][ sanitize_text_field( $plugin['Name'] ) ] = array( 911 'label' => $plugin['Name'], 912 'value' => $plugin_version_string, 913 'debug' => $plugin_version_string_debug, 914 ); 915 } 916 917 // List all available plugins. 918 $plugins = get_plugins(); 919 $plugin_updates = get_plugin_updates(); 920 $transient = get_site_transient( 'update_plugins' ); 921 922 $auto_updates = array(); 923 924 $auto_updates_enabled = wp_is_auto_update_enabled_for_type( 'plugin' ); 925 926 if ( $auto_updates_enabled ) { 927 $auto_updates = (array) get_site_option( 'auto_update_plugins', array() ); 928 } 929 930 foreach ( $plugins as $plugin_path => $plugin ) { 931 $plugin_part = ( is_plugin_active( $plugin_path ) ) ? 'wp-plugins-active' : 'wp-plugins-inactive'; 932 933 $plugin_version = $plugin['Version']; 934 $plugin_author = $plugin['Author']; 935 936 $plugin_version_string = __( 'No version or author information is available.' ); 937 $plugin_version_string_debug = 'author: (undefined), version: (undefined)'; 938 939 if ( ! empty( $plugin_version ) && ! empty( $plugin_author ) ) { 940 /* translators: 1: Plugin version number. 2: Plugin author name. */ 941 $plugin_version_string = sprintf( __( 'Version %1$s by %2$s' ), $plugin_version, $plugin_author ); 942 $plugin_version_string_debug = sprintf( 'version: %s, author: %s', $plugin_version, $plugin_author ); 943 } else { 944 if ( ! empty( $plugin_author ) ) { 945 /* translators: %s: Plugin author name. */ 946 $plugin_version_string = sprintf( __( 'By %s' ), $plugin_author ); 947 $plugin_version_string_debug = sprintf( 'author: %s, version: (undefined)', $plugin_author ); 948 } 949 950 if ( ! empty( $plugin_version ) ) { 951 /* translators: %s: Plugin version number. */ 952 $plugin_version_string = sprintf( __( 'Version %s' ), $plugin_version ); 953 $plugin_version_string_debug = sprintf( 'author: (undefined), version: %s', $plugin_version ); 954 } 955 } 956 957 if ( array_key_exists( $plugin_path, $plugin_updates ) ) { 958 /* translators: %s: Latest plugin version number. */ 959 $plugin_version_string .= ' ' . sprintf( __( '(Latest version: %s)' ), $plugin_updates[ $plugin_path ]->update->new_version ); 960 $plugin_version_string_debug .= sprintf( ' (latest version: %s)', $plugin_updates[ $plugin_path ]->update->new_version ); 961 } 962 963 if ( $auto_updates_enabled ) { 964 if ( isset( $transient->response[ $plugin_path ] ) ) { 965 $item = $transient->response[ $plugin_path ]; 966 } elseif ( isset( $transient->no_update[ $plugin_path ] ) ) { 967 $item = $transient->no_update[ $plugin_path ]; 968 } else { 969 $item = array( 970 'id' => $plugin_path, 971 'slug' => '', 972 'plugin' => $plugin_path, 973 'new_version' => '', 974 'url' => '', 975 'package' => '', 976 'icons' => array(), 977 'banners' => array(), 978 'banners_rtl' => array(), 979 'tested' => '', 980 'requires_php' => '', 981 'compatibility' => new stdClass(), 982 ); 983 $item = wp_parse_args( $plugin, $item ); 984 } 985 986 $auto_update_forced = wp_is_auto_update_forced_for_item( 'plugin', null, (object) $item ); 987 988 if ( ! is_null( $auto_update_forced ) ) { 989 $enabled = $auto_update_forced; 990 } else { 991 $enabled = in_array( $plugin_path, $auto_updates, true ); 992 } 993 994 if ( $enabled ) { 995 $auto_updates_string = __( 'Auto-updates enabled' ); 996 } else { 997 $auto_updates_string = __( 'Auto-updates disabled' ); 998 } 999 1000 /** 1001 * Filters the text string of the auto-updates setting for each plugin in the Site Health debug data. 1002 * 1003 * @since 5.5.0 1004 * 1005 * @param string $auto_updates_string The string output for the auto-updates column. 1006 * @param string $plugin_path The path to the plugin file. 1007 * @param array $plugin An array of plugin data. 1008 * @param bool $enabled Whether auto-updates are enabled for this item. 1009 */ 1010 $auto_updates_string = apply_filters( 'plugin_auto_update_debug_string', $auto_updates_string, $plugin_path, $plugin, $enabled ); 1011 1012 $plugin_version_string .= ' | ' . $auto_updates_string; 1013 $plugin_version_string_debug .= ', ' . $auto_updates_string; 1014 } 1015 1016 $info[ $plugin_part ]['fields'][ sanitize_text_field( $plugin['Name'] ) ] = array( 1017 'label' => $plugin['Name'], 1018 'value' => $plugin_version_string, 1019 'debug' => $plugin_version_string_debug, 1020 ); 1021 } 1022 1023 // Populate the section for the currently active theme. 1024 global $_wp_theme_features; 1025 $theme_features = array(); 1026 1027 if ( ! empty( $_wp_theme_features ) ) { 1028 foreach ( $_wp_theme_features as $feature => $options ) { 1029 $theme_features[] = $feature; 1030 } 1031 } 1032 1033 $active_theme = wp_get_theme(); 1034 $theme_updates = get_theme_updates(); 1035 $transient = get_site_transient( 'update_themes' ); 1036 1037 $active_theme_version = $active_theme->version; 1038 $active_theme_version_debug = $active_theme_version; 1039 1040 $auto_updates = array(); 1041 $auto_updates_enabled = wp_is_auto_update_enabled_for_type( 'theme' ); 1042 if ( $auto_updates_enabled ) { 1043 $auto_updates = (array) get_site_option( 'auto_update_themes', array() ); 1044 } 1045 1046 if ( array_key_exists( $active_theme->stylesheet, $theme_updates ) ) { 1047 $theme_update_new_version = $theme_updates[ $active_theme->stylesheet ]->update['new_version']; 1048 1049 /* translators: %s: Latest theme version number. */ 1050 $active_theme_version .= ' ' . sprintf( __( '(Latest version: %s)' ), $theme_update_new_version ); 1051 $active_theme_version_debug .= sprintf( ' (latest version: %s)', $theme_update_new_version ); 1052 } 1053 1054 $active_theme_author_uri = $active_theme->display( 'AuthorURI' ); 1055 1056 if ( $active_theme->parent_theme ) { 1057 $active_theme_parent_theme = sprintf( 1058 /* translators: 1: Theme name. 2: Theme slug. */ 1059 __( '%1$s (%2$s)' ), 1060 $active_theme->parent_theme, 1061 $active_theme->template 1062 ); 1063 $active_theme_parent_theme_debug = sprintf( 1064 '%s (%s)', 1065 $active_theme->parent_theme, 1066 $active_theme->template 1067 ); 1068 } else { 1069 $active_theme_parent_theme = __( 'None' ); 1070 $active_theme_parent_theme_debug = 'none'; 1071 } 1072 1073 $info['wp-active-theme']['fields'] = array( 1074 'name' => array( 1075 'label' => __( 'Name' ), 1076 'value' => sprintf( 1077 /* translators: 1: Theme name. 2: Theme slug. */ 1078 __( '%1$s (%2$s)' ), 1079 $active_theme->name, 1080 $active_theme->stylesheet 1081 ), 1082 ), 1083 'version' => array( 1084 'label' => __( 'Version' ), 1085 'value' => $active_theme_version, 1086 'debug' => $active_theme_version_debug, 1087 ), 1088 'author' => array( 1089 'label' => __( 'Author' ), 1090 'value' => wp_kses( $active_theme->author, array() ), 1091 ), 1092 'author_website' => array( 1093 'label' => __( 'Author website' ), 1094 'value' => ( $active_theme_author_uri ? $active_theme_author_uri : __( 'Undefined' ) ), 1095 'debug' => ( $active_theme_author_uri ? $active_theme_author_uri : '(undefined)' ), 1096 ), 1097 'parent_theme' => array( 1098 'label' => __( 'Parent theme' ), 1099 'value' => $active_theme_parent_theme, 1100 'debug' => $active_theme_parent_theme_debug, 1101 ), 1102 'theme_features' => array( 1103 'label' => __( 'Theme features' ), 1104 'value' => implode( ', ', $theme_features ), 1105 ), 1106 'theme_path' => array( 1107 'label' => __( 'Theme directory location' ), 1108 'value' => get_stylesheet_directory(), 1109 ), 1110 ); 1111 1112 if ( $auto_updates_enabled ) { 1113 if ( isset( $transient->response[ $active_theme->stylesheet ] ) ) { 1114 $item = $transient->response[ $active_theme->stylesheet ]; 1115 } elseif ( isset( $transient->no_update[ $active_theme->stylesheet ] ) ) { 1116 $item = $transient->no_update[ $active_theme->stylesheet ]; 1117 } else { 1118 $item = array( 1119 'theme' => $active_theme->stylesheet, 1120 'new_version' => $active_theme->version, 1121 'url' => '', 1122 'package' => '', 1123 'requires' => '', 1124 'requires_php' => '', 1125 ); 1126 } 1127 1128 $auto_update_forced = wp_is_auto_update_forced_for_item( 'theme', null, (object) $item ); 1129 1130 if ( ! is_null( $auto_update_forced ) ) { 1131 $enabled = $auto_update_forced; 1132 } else { 1133 $enabled = in_array( $active_theme->stylesheet, $auto_updates, true ); 1134 } 1135 1136 if ( $enabled ) { 1137 $auto_updates_string = __( 'Enabled' ); 1138 } else { 1139 $auto_updates_string = __( 'Disabled' ); 1140 } 1141 1142 /** This filter is documented in wp-admin/includes/class-wp-debug-data.php */ 1143 $auto_updates_string = apply_filters( 'theme_auto_update_debug_string', $auto_updates_string, $active_theme, $enabled ); 1144 1145 $info['wp-active-theme']['fields']['auto_update'] = array( 1146 'label' => __( 'Auto-updates' ), 1147 'value' => $auto_updates_string, 1148 'debug' => $auto_updates_string, 1149 ); 1150 } 1151 1152 $parent_theme = $active_theme->parent(); 1153 1154 if ( $parent_theme ) { 1155 $parent_theme_version = $parent_theme->version; 1156 $parent_theme_version_debug = $parent_theme_version; 1157 1158 if ( array_key_exists( $parent_theme->stylesheet, $theme_updates ) ) { 1159 $parent_theme_update_new_version = $theme_updates[ $parent_theme->stylesheet ]->update['new_version']; 1160 1161 /* translators: %s: Latest theme version number. */ 1162 $parent_theme_version .= ' ' . sprintf( __( '(Latest version: %s)' ), $parent_theme_update_new_version ); 1163 $parent_theme_version_debug .= sprintf( ' (latest version: %s)', $parent_theme_update_new_version ); 1164 } 1165 1166 $parent_theme_author_uri = $parent_theme->display( 'AuthorURI' ); 1167 1168 $info['wp-parent-theme']['fields'] = array( 1169 'name' => array( 1170 'label' => __( 'Name' ), 1171 'value' => sprintf( 1172 /* translators: 1: Theme name. 2: Theme slug. */ 1173 __( '%1$s (%2$s)' ), 1174 $parent_theme->name, 1175 $parent_theme->stylesheet 1176 ), 1177 ), 1178 'version' => array( 1179 'label' => __( 'Version' ), 1180 'value' => $parent_theme_version, 1181 'debug' => $parent_theme_version_debug, 1182 ), 1183 'author' => array( 1184 'label' => __( 'Author' ), 1185 'value' => wp_kses( $parent_theme->author, array() ), 1186 ), 1187 'author_website' => array( 1188 'label' => __( 'Author website' ), 1189 'value' => ( $parent_theme_author_uri ? $parent_theme_author_uri : __( 'Undefined' ) ), 1190 'debug' => ( $parent_theme_author_uri ? $parent_theme_author_uri : '(undefined)' ), 1191 ), 1192 'theme_path' => array( 1193 'label' => __( 'Theme directory location' ), 1194 'value' => get_template_directory(), 1195 ), 1196 ); 1197 1198 if ( $auto_updates_enabled ) { 1199 if ( isset( $transient->response[ $parent_theme->stylesheet ] ) ) { 1200 $item = $transient->response[ $parent_theme->stylesheet ]; 1201 } elseif ( isset( $transient->no_update[ $parent_theme->stylesheet ] ) ) { 1202 $item = $transient->no_update[ $parent_theme->stylesheet ]; 1203 } else { 1204 $item = array( 1205 'theme' => $parent_theme->stylesheet, 1206 'new_version' => $parent_theme->version, 1207 'url' => '', 1208 'package' => '', 1209 'requires' => '', 1210 'requires_php' => '', 1211 ); 1212 } 1213 1214 $auto_update_forced = wp_is_auto_update_forced_for_item( 'theme', null, (object) $item ); 1215 1216 if ( ! is_null( $auto_update_forced ) ) { 1217 $enabled = $auto_update_forced; 1218 } else { 1219 $enabled = in_array( $parent_theme->stylesheet, $auto_updates, true ); 1220 } 1221 1222 if ( $enabled ) { 1223 $parent_theme_auto_update_string = __( 'Enabled' ); 1224 } else { 1225 $parent_theme_auto_update_string = __( 'Disabled' ); 1226 } 1227 1228 /** This filter is documented in wp-admin/includes/class-wp-debug-data.php */ 1229 $parent_theme_auto_update_string = apply_filters( 'theme_auto_update_debug_string', $auto_updates_string, $parent_theme, $enabled ); 1230 1231 $info['wp-parent-theme']['fields']['auto_update'] = array( 1232 'label' => __( 'Auto-update' ), 1233 'value' => $parent_theme_auto_update_string, 1234 'debug' => $parent_theme_auto_update_string, 1235 ); 1236 } 1237 } 1238 1239 // Populate a list of all themes available in the install. 1240 $all_themes = wp_get_themes(); 1241 1242 foreach ( $all_themes as $theme_slug => $theme ) { 1243 // Exclude the currently active theme from the list of all themes. 1244 if ( $active_theme->stylesheet === $theme_slug ) { 1245 continue; 1246 } 1247 1248 // Exclude the currently active parent theme from the list of all themes. 1249 if ( ! empty( $parent_theme ) && $parent_theme->stylesheet === $theme_slug ) { 1250 continue; 1251 } 1252 1253 $theme_version = $theme->version; 1254 $theme_author = $theme->author; 1255 1256 // Sanitize. 1257 $theme_author = wp_kses( $theme_author, array() ); 1258 1259 $theme_version_string = __( 'No version or author information is available.' ); 1260 $theme_version_string_debug = 'undefined'; 1261 1262 if ( ! empty( $theme_version ) && ! empty( $theme_author ) ) { 1263 /* translators: 1: Theme version number. 2: Theme author name. */ 1264 $theme_version_string = sprintf( __( 'Version %1$s by %2$s' ), $theme_version, $theme_author ); 1265 $theme_version_string_debug = sprintf( 'version: %s, author: %s', $theme_version, $theme_author ); 1266 } else { 1267 if ( ! empty( $theme_author ) ) { 1268 /* translators: %s: Theme author name. */ 1269 $theme_version_string = sprintf( __( 'By %s' ), $theme_author ); 1270 $theme_version_string_debug = sprintf( 'author: %s, version: (undefined)', $theme_author ); 1271 } 1272 1273 if ( ! empty( $theme_version ) ) { 1274 /* translators: %s: Theme version number. */ 1275 $theme_version_string = sprintf( __( 'Version %s' ), $theme_version ); 1276 $theme_version_string_debug = sprintf( 'author: (undefined), version: %s', $theme_version ); 1277 } 1278 } 1279 1280 if ( array_key_exists( $theme_slug, $theme_updates ) ) { 1281 /* translators: %s: Latest theme version number. */ 1282 $theme_version_string .= ' ' . sprintf( __( '(Latest version: %s)' ), $theme_updates[ $theme_slug ]->update['new_version'] ); 1283 $theme_version_string_debug .= sprintf( ' (latest version: %s)', $theme_updates[ $theme_slug ]->update['new_version'] ); 1284 } 1285 1286 if ( $auto_updates_enabled ) { 1287 if ( isset( $transient->response[ $theme_slug ] ) ) { 1288 $item = $transient->response[ $theme_slug ]; 1289 } elseif ( isset( $transient->no_update[ $theme_slug ] ) ) { 1290 $item = $transient->no_update[ $theme_slug ]; 1291 } else { 1292 $item = array( 1293 'theme' => $theme_slug, 1294 'new_version' => $theme->version, 1295 'url' => '', 1296 'package' => '', 1297 'requires' => '', 1298 'requires_php' => '', 1299 ); 1300 } 1301 1302 $auto_update_forced = wp_is_auto_update_forced_for_item( 'theme', null, (object) $item ); 1303 1304 if ( ! is_null( $auto_update_forced ) ) { 1305 $enabled = $auto_update_forced; 1306 } else { 1307 $enabled = in_array( $theme_slug, $auto_updates, true ); 1308 } 1309 1310 if ( $enabled ) { 1311 $auto_updates_string = __( 'Auto-updates enabled' ); 1312 } else { 1313 $auto_updates_string = __( 'Auto-updates disabled' ); 1314 } 1315 1316 /** 1317 * Filters the text string of the auto-updates setting for each theme in the Site Health debug data. 1318 * 1319 * @since 5.5.0 1320 * 1321 * @param string $auto_updates_string The string output for the auto-updates column. 1322 * @param WP_Theme $theme An object of theme data. 1323 * @param bool $enabled Whether auto-updates are enabled for this item. 1324 */ 1325 $auto_updates_string = apply_filters( 'theme_auto_update_debug_string', $auto_updates_string, $theme, $enabled ); 1326 1327 $theme_version_string .= ' | ' . $auto_updates_string; 1328 $theme_version_string_debug .= ', ' . $auto_updates_string; 1329 } 1330 1331 $info['wp-themes-inactive']['fields'][ sanitize_text_field( $theme->name ) ] = array( 1332 'label' => sprintf( 1333 /* translators: 1: Theme name. 2: Theme slug. */ 1334 __( '%1$s (%2$s)' ), 1335 $theme->name, 1336 $theme_slug 1337 ), 1338 'value' => $theme_version_string, 1339 'debug' => $theme_version_string_debug, 1340 ); 1341 } 1342 1343 // Add more filesystem checks. 1344 if ( defined( 'WPMU_PLUGIN_DIR' ) && is_dir( WPMU_PLUGIN_DIR ) ) { 1345 $is_writable_wpmu_plugin_dir = wp_is_writable( WPMU_PLUGIN_DIR ); 1346 1347 $info['wp-filesystem']['fields']['mu-plugins'] = array( 1348 'label' => __( 'The must use plugins directory' ), 1349 'value' => ( $is_writable_wpmu_plugin_dir ? __( 'Writable' ) : __( 'Not writable' ) ), 1350 'debug' => ( $is_writable_wpmu_plugin_dir ? 'writable' : 'not writable' ), 1351 ); 1352 } 1353 1354 /** 1355 * Add or modify the debug information. 1356 * 1357 * Plugin or themes may wish to introduce their own debug information without creating additional admin pages 1358 * they can utilize this filter to introduce their own sections or add more data to existing sections. 1359 * 1360 * Array keys for sections added by core are all prefixed with `wp-`, plugins and themes should use their own slug as 1361 * a prefix, both for consistency as well as avoiding key collisions. Note that the array keys are used as labels 1362 * for the copied data. 1363 * 1364 * All strings are expected to be plain text except $description that can contain inline HTML tags (see below). 1365 * 1366 * @since 5.2.0 1367 * 1368 * @param array $args { 1369 * The debug information to be added to the core information page. 1370 * 1371 * This is an associative multi-dimensional array, up to three levels deep. The topmost array holds the sections. 1372 * Each section has a `$fields` associative array (see below), and each `$value` in `$fields` can be 1373 * another associative array of name/value pairs when there is more structured data to display. 1374 * 1375 * @type string $label The title for this section of the debug output. 1376 * @type string $description Optional. A description for your information section which may contain basic HTML 1377 * markup, inline tags only as it is outputted in a paragraph. 1378 * @type boolean $show_count Optional. If set to `true` the amount of fields will be included in the title for 1379 * this section. 1380 * @type boolean $private Optional. If set to `true` the section and all associated fields will be excluded 1381 * from the copied data. 1382 * @type array $fields { 1383 * An associative array containing the data to be displayed. 1384 * 1385 * @type string $label The label for this piece of information. 1386 * @type string $value The output that is displayed for this field. Text should be translated. Can be 1387 * an associative array that is displayed as name/value pairs. 1388 * @type string $debug Optional. The output that is used for this field when the user copies the data. 1389 * It should be more concise and not translated. If not set, the content of `$value` is used. 1390 * Note that the array keys are used as labels for the copied data. 1391 * @type boolean $private Optional. If set to `true` the field will not be included in the copied data 1392 * allowing you to show, for example, API keys here. 1393 * } 1394 * } 1395 */ 1396 $info = apply_filters( 'debug_information', $info ); 1397 1398 return $info; 1399 } 1400 1401 /** 1402 * Format the information gathered for debugging, in a manner suitable for copying to a forum or support ticket. 1403 * 1404 * @since 5.2.0 1405 * 1406 * @param array $info_array Information gathered from the `WP_Debug_Data::debug_data` function. 1407 * @param string $type The data type to return, either 'info' or 'debug'. 1408 * @return string The formatted data. 1409 */ 1410 public static function format( $info_array, $type ) { 1411 $return = "`\n"; 1412 1413 foreach ( $info_array as $section => $details ) { 1414 // Skip this section if there are no fields, or the section has been declared as private. 1415 if ( empty( $details['fields'] ) || ( isset( $details['private'] ) && $details['private'] ) ) { 1416 continue; 1417 } 1418 1419 $section_label = 'debug' === $type ? $section : $details['label']; 1420 1421 $return .= sprintf( 1422 "### %s%s ###\n\n", 1423 $section_label, 1424 ( isset( $details['show_count'] ) && $details['show_count'] ? sprintf( ' (%d)', count( $details['fields'] ) ) : '' ) 1425 ); 1426 1427 foreach ( $details['fields'] as $field_name => $field ) { 1428 if ( isset( $field['private'] ) && true === $field['private'] ) { 1429 continue; 1430 } 1431 1432 if ( 'debug' === $type && isset( $field['debug'] ) ) { 1433 $debug_data = $field['debug']; 1434 } else { 1435 $debug_data = $field['value']; 1436 } 1437 1438 // Can be array, one level deep only. 1439 if ( is_array( $debug_data ) ) { 1440 $value = ''; 1441 1442 foreach ( $debug_data as $sub_field_name => $sub_field_value ) { 1443 $value .= sprintf( "\n\t%s: %s", $sub_field_name, $sub_field_value ); 1444 } 1445 } elseif ( is_bool( $debug_data ) ) { 1446 $value = $debug_data ? 'true' : 'false'; 1447 } elseif ( empty( $debug_data ) && '0' !== $debug_data ) { 1448 $value = 'undefined'; 1449 } else { 1450 $value = $debug_data; 1451 } 1452 1453 if ( 'debug' === $type ) { 1454 $label = $field_name; 1455 } else { 1456 $label = $field['label']; 1457 } 1458 1459 $return .= sprintf( "%s: %s\n", $label, $value ); 1460 } 1461 1462 $return .= "\n"; 1463 } 1464 1465 $return .= '`'; 1466 1467 return $return; 1468 } 1469 1470 /** 1471 * Fetch the total size of all the database tables for the active database user. 1472 * 1473 * @since 5.2.0 1474 * 1475 * @return int The size of the database, in bytes. 1476 */ 1477 public static function get_database_size() { 1478 global $wpdb; 1479 $size = 0; 1480 $rows = $wpdb->get_results( 'SHOW TABLE STATUS', ARRAY_A ); 1481 1482 if ( $wpdb->num_rows > 0 ) { 1483 foreach ( $rows as $row ) { 1484 $size += $row['Data_length'] + $row['Index_length']; 1485 } 1486 } 1487 1488 return (int) $size; 1489 } 1490 1491 /** 1492 * Fetch the sizes of the WordPress directories: `wordpress` (ABSPATH), `plugins`, `themes`, and `uploads`. 1493 * Intended to supplement the array returned by `WP_Debug_Data::debug_data()`. 1494 * 1495 * @since 5.2.0 1496 * 1497 * @return array The sizes of the directories, also the database size and total installation size. 1498 */ 1499 public static function get_sizes() { 1500 $size_db = self::get_database_size(); 1501 $upload_dir = wp_get_upload_dir(); 1502 1503 /* 1504 * We will be using the PHP max execution time to prevent the size calculations 1505 * from causing a timeout. The default value is 30 seconds, and some 1506 * hosts do not allow you to read configuration values. 1507 */ 1508 if ( function_exists( 'ini_get' ) ) { 1509 $max_execution_time = ini_get( 'max_execution_time' ); 1510 } 1511 1512 // The max_execution_time defaults to 0 when PHP runs from cli. 1513 // We still want to limit it below. 1514 if ( empty( $max_execution_time ) ) { 1515 $max_execution_time = 30; 1516 } 1517 1518 if ( $max_execution_time > 20 ) { 1519 // If the max_execution_time is set to lower than 20 seconds, reduce it a bit to prevent 1520 // edge-case timeouts that may happen after the size loop has finished running. 1521 $max_execution_time -= 2; 1522 } 1523 1524 // Go through the various installation directories and calculate their sizes. 1525 // No trailing slashes. 1526 $paths = array( 1527 'wordpress_size' => untrailingslashit( ABSPATH ), 1528 'themes_size' => get_theme_root(), 1529 'plugins_size' => WP_PLUGIN_DIR, 1530 'uploads_size' => $upload_dir['basedir'], 1531 ); 1532 1533 $exclude = $paths; 1534 unset( $exclude['wordpress_size'] ); 1535 $exclude = array_values( $exclude ); 1536 1537 $size_total = 0; 1538 $all_sizes = array(); 1539 1540 // Loop over all the directories we want to gather the sizes for. 1541 foreach ( $paths as $name => $path ) { 1542 $dir_size = null; // Default to timeout. 1543 $results = array( 1544 'path' => $path, 1545 'raw' => 0, 1546 ); 1547 1548 if ( microtime( true ) - WP_START_TIMESTAMP < $max_execution_time ) { 1549 if ( 'wordpress_size' === $name ) { 1550 $dir_size = recurse_dirsize( $path, $exclude, $max_execution_time ); 1551 } else { 1552 $dir_size = recurse_dirsize( $path, null, $max_execution_time ); 1553 } 1554 } 1555 1556 if ( false === $dir_size ) { 1557 // Error reading. 1558 $results['size'] = __( 'The size cannot be calculated. The directory is not accessible. Usually caused by invalid permissions.' ); 1559 $results['debug'] = 'not accessible'; 1560 1561 // Stop total size calculation. 1562 $size_total = null; 1563 } elseif ( null === $dir_size ) { 1564 // Timeout. 1565 $results['size'] = __( 'The directory size calculation has timed out. Usually caused by a very large number of sub-directories and files.' ); 1566 $results['debug'] = 'timeout while calculating size'; 1567 1568 // Stop total size calculation. 1569 $size_total = null; 1570 } else { 1571 if ( null !== $size_total ) { 1572 $size_total += $dir_size; 1573 } 1574 1575 $results['raw'] = $dir_size; 1576 $results['size'] = size_format( $dir_size, 2 ); 1577 $results['debug'] = $results['size'] . " ({$dir_size} bytes)"; 1578 } 1579 1580 $all_sizes[ $name ] = $results; 1581 } 1582 1583 if ( $size_db > 0 ) { 1584 $database_size = size_format( $size_db, 2 ); 1585 1586 $all_sizes['database_size'] = array( 1587 'raw' => $size_db, 1588 'size' => $database_size, 1589 'debug' => $database_size . " ({$size_db} bytes)", 1590 ); 1591 } else { 1592 $all_sizes['database_size'] = array( 1593 'size' => __( 'Not available' ), 1594 'debug' => 'not available', 1595 ); 1596 } 1597 1598 if ( null !== $size_total && $size_db > 0 ) { 1599 $total_size = $size_total + $size_db; 1600 $total_size_mb = size_format( $total_size, 2 ); 1601 1602 $all_sizes['total_size'] = array( 1603 'raw' => $total_size, 1604 'size' => $total_size_mb, 1605 'debug' => $total_size_mb . " ({$total_size} bytes)", 1606 ); 1607 } else { 1608 $all_sizes['total_size'] = array( 1609 'size' => __( 'Total size is not available. Some errors were encountered when determining the size of your installation.' ), 1610 'debug' => 'not available', 1611 ); 1612 } 1613 1614 return $all_sizes; 1615 } 1616 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Feb 26 01:00:04 2021 | Cross-referenced by PHPXref 0.7.1 |