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