wp/wp-admin/includes/class-wp-debug-data.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
    21 
    21 
    22 	/**
    22 	/**
    23 	 * Static function for generating site debug data when required.
    23 	 * Static function for generating site debug data when required.
    24 	 *
    24 	 *
    25 	 * @since 5.2.0
    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.
    26 	 *
    29 	 *
    27 	 * @throws ImagickException
    30 	 * @throws ImagickException
    28 	 * @global wpdb $wpdb WordPress database abstraction object.
    31 	 * @global wpdb $wpdb WordPress database abstraction object.
    29 	 *
    32 	 *
    30 	 * @return array The debug data for the site.
    33 	 * @return array The debug data for the site.
    31 	 */
    34 	 */
    32 	static function debug_data() {
    35 	static function debug_data() {
    33 		global $wpdb;
    36 		global $wpdb;
    34 
    37 
    35 		// Save few function calls.
    38 		// Save few function calls.
    36 		$upload_dir             = wp_get_upload_dir();
    39 		$upload_dir             = wp_upload_dir();
    37 		$permalink_structure    = get_option( 'permalink_structure' );
    40 		$permalink_structure    = get_option( 'permalink_structure' );
    38 		$is_ssl                 = is_ssl();
    41 		$is_ssl                 = is_ssl();
       
    42 		$is_multisite           = is_multisite();
    39 		$users_can_register     = get_option( 'users_can_register' );
    43 		$users_can_register     = get_option( 'users_can_register' );
       
    44 		$blog_public            = get_option( 'blog_public' );
    40 		$default_comment_status = get_option( 'default_comment_status' );
    45 		$default_comment_status = get_option( 'default_comment_status' );
    41 		$is_multisite           = is_multisite();
    46 		$environment_type       = wp_get_environment_type();
    42 		$core_version           = get_bloginfo( 'version' );
    47 		$core_version           = get_bloginfo( 'version' );
    43 		$core_updates           = get_core_updates();
    48 		$core_updates           = get_core_updates();
    44 		$core_update_needed     = '';
    49 		$core_update_needed     = '';
    45 
    50 
    46 		foreach ( $core_updates as $core => $update ) {
    51 		foreach ( $core_updates as $core => $update ) {
    47 			if ( 'upgrade' === $update->response ) {
    52 			if ( 'upgrade' === $update->response ) {
    48 				// translators: %s: Latest WordPress version number.
    53 				/* translators: %s: Latest WordPress version number. */
    49 				$core_update_needed = ' ' . sprintf( __( '(Latest version: %s)' ), $update->version );
    54 				$core_update_needed = ' ' . sprintf( __( '(Latest version: %s)' ), $update->version );
    50 			} else {
    55 			} else {
    51 				$core_update_needed = '';
    56 				$core_update_needed = '';
    52 			}
    57 			}
    53 		}
    58 		}
    69 				),
    74 				),
    70 				'user_language'          => array(
    75 				'user_language'          => array(
    71 					'label' => __( 'User Language' ),
    76 					'label' => __( 'User Language' ),
    72 					'value' => get_user_locale(),
    77 					'value' => get_user_locale(),
    73 				),
    78 				),
       
    79 				'timezone'               => array(
       
    80 					'label' => __( 'Timezone' ),
       
    81 					'value' => wp_timezone_string(),
       
    82 				),
    74 				'home_url'               => array(
    83 				'home_url'               => array(
    75 					'label'   => __( 'Home URL' ),
    84 					'label'   => __( 'Home URL' ),
    76 					'value'   => get_bloginfo( 'url' ),
    85 					'value'   => get_bloginfo( 'url' ),
    77 					'private' => true,
    86 					'private' => true,
    78 				),
    87 				),
    81 					'value'   => get_bloginfo( 'wpurl' ),
    90 					'value'   => get_bloginfo( 'wpurl' ),
    82 					'private' => true,
    91 					'private' => true,
    83 				),
    92 				),
    84 				'permalink'              => array(
    93 				'permalink'              => array(
    85 					'label' => __( 'Permalink structure' ),
    94 					'label' => __( 'Permalink structure' ),
    86 					'value' => $permalink_structure ?: __( 'No permalink structure set' ),
    95 					'value' => $permalink_structure ? $permalink_structure : __( 'No permalink structure set' ),
    87 					'debug' => $permalink_structure,
    96 					'debug' => $permalink_structure,
    88 				),
    97 				),
    89 				'https_status'           => array(
    98 				'https_status'           => array(
    90 					'label' => __( 'Is this site using HTTPS?' ),
    99 					'label' => __( 'Is this site using HTTPS?' ),
    91 					'value' => $is_ssl ? __( 'Yes' ) : __( 'No' ),
   100 					'value' => $is_ssl ? __( 'Yes' ) : __( 'No' ),
    92 					'debug' => $is_ssl,
   101 					'debug' => $is_ssl,
    93 				),
   102 				),
       
   103 				'multisite'              => array(
       
   104 					'label' => __( 'Is this a multisite?' ),
       
   105 					'value' => $is_multisite ? __( 'Yes' ) : __( 'No' ),
       
   106 					'debug' => $is_multisite,
       
   107 				),
    94 				'user_registration'      => array(
   108 				'user_registration'      => array(
    95 					'label' => __( 'Can anyone register on this site?' ),
   109 					'label' => __( 'Can anyone register on this site?' ),
    96 					'value' => $users_can_register ? __( 'Yes' ) : __( 'No' ),
   110 					'value' => $users_can_register ? __( 'Yes' ) : __( 'No' ),
    97 					'debug' => $users_can_register,
   111 					'debug' => $users_can_register,
    98 				),
   112 				),
       
   113 				'blog_public'            => array(
       
   114 					'label' => __( 'Is this site discouraging search engines?' ),
       
   115 					'value' => $blog_public ? __( 'No' ) : __( 'Yes' ),
       
   116 					'debug' => $blog_public,
       
   117 				),
    99 				'default_comment_status' => array(
   118 				'default_comment_status' => array(
   100 					'label' => __( 'Default comment status' ),
   119 					'label' => __( 'Default comment status' ),
   101 					'value' => 'open' === $default_comment_status ? _x( 'Open', 'comment status' ) : _x( 'Closed', 'comment status' ),
   120 					'value' => 'open' === $default_comment_status ? _x( 'Open', 'comment status' ) : _x( 'Closed', 'comment status' ),
   102 					'debug' => $default_comment_status,
   121 					'debug' => $default_comment_status,
   103 				),
   122 				),
   104 				'multisite'              => array(
   123 				'environment_type'       => array(
   105 					'label' => __( 'Is this a multisite?' ),
   124 					'label' => __( 'Environment type' ),
   106 					'value' => $is_multisite ? __( 'Yes' ) : __( 'No' ),
   125 					'value' => $environment_type,
   107 					'debug' => $is_multisite,
   126 					'debug' => $environment_type,
   108 				),
   127 				),
   109 			),
   128 			),
   110 		);
   129 		);
   111 
   130 
   112 		if ( ! $is_multisite ) {
   131 		if ( ! $is_multisite ) {
   117 		}
   136 		}
   118 
   137 
   119 		$info['wp-dropins'] = array(
   138 		$info['wp-dropins'] = array(
   120 			'label'       => __( 'Drop-ins' ),
   139 			'label'       => __( 'Drop-ins' ),
   121 			'show_count'  => true,
   140 			'show_count'  => true,
   122 			'description' => __( 'Drop-ins are single files that replace or enhance WordPress features in ways that are not possible for traditional plugins.' ),
   141 			'description' => sprintf(
       
   142 				/* translators: %s: wp-content directory name. */
       
   143 				__( '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.' ),
       
   144 				'<code>' . str_replace( ABSPATH, '', WP_CONTENT_DIR ) . '</code>'
       
   145 			),
   123 			'fields'      => array(),
   146 			'fields'      => array(),
   124 		);
   147 		);
   125 
   148 
   126 		$info['wp-active-theme'] = array(
   149 		$info['wp-active-theme'] = array(
   127 			'label'  => __( 'Active Theme' ),
   150 			'label'  => __( 'Active Theme' ),
   128 			'fields' => array(),
   151 			'fields' => array(),
   129 		);
   152 		);
   130 
   153 
   131 		$info['wp-themes'] = array(
   154 		$info['wp-parent-theme'] = array(
   132 			'label'      => __( 'Other Themes' ),
   155 			'label'  => __( 'Parent Theme' ),
       
   156 			'fields' => array(),
       
   157 		);
       
   158 
       
   159 		$info['wp-themes-inactive'] = array(
       
   160 			'label'      => __( 'Inactive Themes' ),
   133 			'show_count' => true,
   161 			'show_count' => true,
   134 			'fields'     => array(),
   162 			'fields'     => array(),
   135 		);
   163 		);
   136 
   164 
   137 		$info['wp-mu-plugins'] = array(
   165 		$info['wp-mu-plugins'] = array(
   287 				'WP_LOCAL_DEV'        => array(
   315 				'WP_LOCAL_DEV'        => array(
   288 					'label' => 'WP_LOCAL_DEV',
   316 					'label' => 'WP_LOCAL_DEV',
   289 					'value' => $wp_local_dev,
   317 					'value' => $wp_local_dev,
   290 					'debug' => $wp_local_dev_debug,
   318 					'debug' => $wp_local_dev_debug,
   291 				),
   319 				),
       
   320 				'DB_CHARSET'          => array(
       
   321 					'label' => 'DB_CHARSET',
       
   322 					'value' => ( defined( 'DB_CHARSET' ) ? DB_CHARSET : __( 'Undefined' ) ),
       
   323 					'debug' => ( defined( 'DB_CHARSET' ) ? DB_CHARSET : 'undefined' ),
       
   324 				),
       
   325 				'DB_COLLATE'          => array(
       
   326 					'label' => 'DB_COLLATE',
       
   327 					'value' => ( defined( 'DB_COLLATE' ) ? DB_COLLATE : __( 'Undefined' ) ),
       
   328 					'debug' => ( defined( 'DB_COLLATE' ) ? DB_COLLATE : 'undefined' ),
       
   329 				),
   292 			),
   330 			),
   293 		);
   331 		);
   294 
   332 
   295 		$is_writable_abspath            = wp_is_writable( ABSPATH );
   333 		$is_writable_abspath            = wp_is_writable( ABSPATH );
   296 		$is_writable_wp_content_dir     = wp_is_writable( WP_CONTENT_DIR );
   334 		$is_writable_wp_content_dir     = wp_is_writable( WP_CONTENT_DIR );
   297 		$is_writable_upload_dir         = wp_is_writable( $upload_dir['basedir'] );
   335 		$is_writable_upload_dir         = wp_is_writable( $upload_dir['basedir'] );
   298 		$is_writable_wp_plugin_dir      = wp_is_writable( WP_PLUGIN_DIR );
   336 		$is_writable_wp_plugin_dir      = wp_is_writable( WP_PLUGIN_DIR );
   299 		$is_writable_template_directory = wp_is_writable( get_template_directory() . '/..' );
   337 		$is_writable_template_directory = wp_is_writable( get_theme_root( get_template() ) );
   300 
   338 
   301 		$info['wp-filesystem'] = array(
   339 		$info['wp-filesystem'] = array(
   302 			'label'       => __( 'Filesystem Permissions' ),
   340 			'label'       => __( 'Filesystem Permissions' ),
   303 			'description' => __( 'Shows whether WordPress is able to write to the directories it needs access to.' ),
   341 			'description' => __( 'Shows whether WordPress is able to write to the directories it needs access to.' ),
   304 			'fields'      => array(
   342 			'fields'      => array(
   380 			);
   418 			);
   381 		} else {
   419 		} else {
   382 			$info['wp-core']['fields']['dotorg_communication'] = array(
   420 			$info['wp-core']['fields']['dotorg_communication'] = array(
   383 				'label' => __( 'Communication with WordPress.org' ),
   421 				'label' => __( 'Communication with WordPress.org' ),
   384 				'value' => sprintf(
   422 				'value' => sprintf(
   385 					// translators: 1: The IP address WordPress.org resolves to. 2: The error returned by the lookup.
   423 					/* translators: 1: The IP address WordPress.org resolves to. 2: The error returned by the lookup. */
   386 					__( 'Unable to reach WordPress.org at %1$s: %2$s' ),
   424 					__( 'Unable to reach WordPress.org at %1$s: %2$s' ),
   387 					gethostbyname( 'wordpress.org' ),
   425 					gethostbyname( 'wordpress.org' ),
   388 					$wp_dotorg->get_error_message()
   426 					$wp_dotorg->get_error_message()
   389 				),
   427 				),
   390 				'debug' => $wp_dotorg->get_error_message(),
   428 				'debug' => $wp_dotorg->get_error_message(),
   484 
   522 
   485 		$info['wp-media']['fields']['imagemagick_version'] = array(
   523 		$info['wp-media']['fields']['imagemagick_version'] = array(
   486 			'label' => __( 'ImageMagick version string' ),
   524 			'label' => __( 'ImageMagick version string' ),
   487 			'value' => ( is_array( $imagick_version ) ? $imagick_version['versionString'] : $imagick_version ),
   525 			'value' => ( is_array( $imagick_version ) ? $imagick_version['versionString'] : $imagick_version ),
   488 		);
   526 		);
       
   527 
       
   528 		if ( ! function_exists( 'ini_get' ) ) {
       
   529 			$info['wp-media']['fields']['ini_get'] = array(
       
   530 				'label' => __( 'File upload settings' ),
       
   531 				'value' => sprintf(
       
   532 					/* translators: %s: ini_get() */
       
   533 					__( 'Unable to determine some settings, as the %s function has been disabled.' ),
       
   534 					'ini_get()'
       
   535 				),
       
   536 				'debug' => 'ini_get() is disabled',
       
   537 			);
       
   538 		} else {
       
   539 			// Get the PHP ini directive values.
       
   540 			$post_max_size       = ini_get( 'post_max_size' );
       
   541 			$upload_max_filesize = ini_get( 'upload_max_filesize' );
       
   542 			$max_file_uploads    = ini_get( 'max_file_uploads' );
       
   543 			$effective           = min( wp_convert_hr_to_bytes( $post_max_size ), wp_convert_hr_to_bytes( $upload_max_filesize ) );
       
   544 
       
   545 			// Add info in Media section.
       
   546 			$info['wp-media']['fields']['file_uploads']        = array(
       
   547 				'label' => __( 'File uploads' ),
       
   548 				'value' => empty( ini_get( 'file_uploads' ) ) ? __( 'Disabled' ) : __( 'Enabled' ),
       
   549 				'debug' => 'File uploads is turned off',
       
   550 			);
       
   551 			$info['wp-media']['fields']['post_max_size']       = array(
       
   552 				'label' => __( 'Max size of post data allowed' ),
       
   553 				'value' => $post_max_size,
       
   554 			);
       
   555 			$info['wp-media']['fields']['upload_max_filesize'] = array(
       
   556 				'label' => __( 'Max size of an uploaded file' ),
       
   557 				'value' => $upload_max_filesize,
       
   558 			);
       
   559 			$info['wp-media']['fields']['max_effective_size']  = array(
       
   560 				'label' => __( 'Max effective file size' ),
       
   561 				'value' => size_format( $effective ),
       
   562 			);
       
   563 			$info['wp-media']['fields']['max_file_uploads']    = array(
       
   564 				'label' => __( 'Max number of files allowed' ),
       
   565 				'value' => number_format( $max_file_uploads ),
       
   566 			);
       
   567 		}
   489 
   568 
   490 		// If Imagick is used as our editor, provide some more information about its limitations.
   569 		// If Imagick is used as our editor, provide some more information about its limitations.
   491 		if ( 'WP_Image_Editor_Imagick' === _wp_image_editor_choose() && isset( $imagick ) && $imagick instanceof Imagick ) {
   570 		if ( 'WP_Image_Editor_Imagick' === _wp_image_editor_choose() && isset( $imagick ) && $imagick instanceof Imagick ) {
   492 			$limits = array(
   571 			$limits = array(
   493 				'area'   => ( defined( 'imagick::RESOURCETYPE_AREA' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_AREA ) ) : $not_available ),
   572 				'area'   => ( defined( 'imagick::RESOURCETYPE_AREA' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_AREA ) ) : $not_available ),
   555 			$server_architecture = 'unknown';
   634 			$server_architecture = 'unknown';
   556 		}
   635 		}
   557 
   636 
   558 		if ( function_exists( 'phpversion' ) ) {
   637 		if ( function_exists( 'phpversion' ) ) {
   559 			$php_version_debug = phpversion();
   638 			$php_version_debug = phpversion();
   560 			// Whether PHP supports 64bit
   639 			// Whether PHP supports 64-bit.
   561 			$php64bit = ( PHP_INT_SIZE * 8 === 64 );
   640 			$php64bit = ( PHP_INT_SIZE * 8 === 64 );
   562 
   641 
   563 			$php_version = sprintf(
   642 			$php_version = sprintf(
   564 				'%s %s',
   643 				'%s %s',
   565 				$php_version_debug,
   644 				$php_version_debug,
   603 
   682 
   604 		// Some servers disable `ini_set()` and `ini_get()`, we check this before trying to get configuration values.
   683 		// Some servers disable `ini_set()` and `ini_get()`, we check this before trying to get configuration values.
   605 		if ( ! function_exists( 'ini_get' ) ) {
   684 		if ( ! function_exists( 'ini_get' ) ) {
   606 			$info['wp-server']['fields']['ini_get'] = array(
   685 			$info['wp-server']['fields']['ini_get'] = array(
   607 				'label' => __( 'Server settings' ),
   686 				'label' => __( 'Server settings' ),
   608 				'value' => __( 'Unable to determine some settings, as the ini_get() function has been disabled.' ),
   687 				'value' => sprintf(
       
   688 					/* translators: %s: ini_get() */
       
   689 					__( 'Unable to determine some settings, as the %s function has been disabled.' ),
       
   690 					'ini_get()'
       
   691 				),
   609 				'debug' => 'ini_get() is disabled',
   692 				'debug' => 'ini_get() is disabled',
   610 			);
   693 			);
   611 		} else {
   694 		} else {
   612 			$info['wp-server']['fields']['max_input_variables'] = array(
   695 			$info['wp-server']['fields']['max_input_variables'] = array(
   613 				'label' => __( 'PHP max input variables' ),
   696 				'label' => __( 'PHP max input variables' ),
   615 			);
   698 			);
   616 			$info['wp-server']['fields']['time_limit']          = array(
   699 			$info['wp-server']['fields']['time_limit']          = array(
   617 				'label' => __( 'PHP time limit' ),
   700 				'label' => __( 'PHP time limit' ),
   618 				'value' => ini_get( 'max_execution_time' ),
   701 				'value' => ini_get( 'max_execution_time' ),
   619 			);
   702 			);
   620 			$info['wp-server']['fields']['memory_limit']        = array(
   703 
   621 				'label' => __( 'PHP memory limit' ),
   704 			if ( WP_Site_Health::get_instance()->php_memory_limit !== ini_get( 'memory_limit' ) ) {
   622 				'value' => ini_get( 'memory_limit' ),
   705 				$info['wp-server']['fields']['memory_limit']       = array(
   623 			);
   706 					'label' => __( 'PHP memory limit' ),
       
   707 					'value' => WP_Site_Health::get_instance()->php_memory_limit,
       
   708 				);
       
   709 				$info['wp-server']['fields']['admin_memory_limit'] = array(
       
   710 					'label' => __( 'PHP memory limit (only for admin screens)' ),
       
   711 					'value' => ini_get( 'memory_limit' ),
       
   712 				);
       
   713 			} else {
       
   714 				$info['wp-server']['fields']['memory_limit'] = array(
       
   715 					'label' => __( 'PHP memory limit' ),
       
   716 					'value' => ini_get( 'memory_limit' ),
       
   717 				);
       
   718 			}
       
   719 
   624 			$info['wp-server']['fields']['max_input_time']      = array(
   720 			$info['wp-server']['fields']['max_input_time']      = array(
   625 				'label' => __( 'Max input time' ),
   721 				'label' => __( 'Max input time' ),
   626 				'value' => ini_get( 'max_input_time' ),
   722 				'value' => ini_get( 'max_input_time' ),
   627 			);
   723 			);
   628 			$info['wp-server']['fields']['upload_max_size']     = array(
   724 			$info['wp-server']['fields']['upload_max_filesize'] = array(
   629 				'label' => __( 'Upload max filesize' ),
   725 				'label' => __( 'Upload max filesize' ),
   630 				'value' => ini_get( 'upload_max_filesize' ),
   726 				'value' => ini_get( 'upload_max_filesize' ),
   631 			);
   727 			);
   632 			$info['wp-server']['fields']['php_post_max_size']   = array(
   728 			$info['wp-server']['fields']['php_post_max_size']   = array(
   633 				'label' => __( 'PHP post max size' ),
   729 				'label' => __( 'PHP post max size' ),
   648 				'value' => $not_available,
   744 				'value' => $not_available,
   649 				'debug' => 'not available',
   745 				'debug' => 'not available',
   650 			);
   746 			);
   651 		}
   747 		}
   652 
   748 
   653 		// SUHOSIN
   749 		// SUHOSIN.
   654 		$suhosin_loaded = ( extension_loaded( 'suhosin' ) || ( defined( 'SUHOSIN_PATCH' ) && constant( 'SUHOSIN_PATCH' ) ) );
   750 		$suhosin_loaded = ( extension_loaded( 'suhosin' ) || ( defined( 'SUHOSIN_PATCH' ) && constant( 'SUHOSIN_PATCH' ) ) );
   655 
   751 
   656 		$info['wp-server']['fields']['suhosin'] = array(
   752 		$info['wp-server']['fields']['suhosin'] = array(
   657 			'label' => __( 'Is SUHOSIN installed?' ),
   753 			'label' => __( 'Is SUHOSIN installed?' ),
   658 			'value' => ( $suhosin_loaded ? __( 'Yes' ) : __( 'No' ) ),
   754 			'value' => ( $suhosin_loaded ? __( 'Yes' ) : __( 'No' ) ),
   659 			'debug' => $suhosin_loaded,
   755 			'debug' => $suhosin_loaded,
   660 		);
   756 		);
   661 
   757 
   662 		// Imagick
   758 		// Imagick.
   663 		$imagick_loaded = extension_loaded( 'imagick' );
   759 		$imagick_loaded = extension_loaded( 'imagick' );
   664 
   760 
   665 		$info['wp-server']['fields']['imagick_availability'] = array(
   761 		$info['wp-server']['fields']['imagick_availability'] = array(
   666 			'label' => __( 'Is the Imagick library available?' ),
   762 			'label' => __( 'Is the Imagick library available?' ),
   667 			'value' => ( $imagick_loaded ? __( 'Yes' ) : __( 'No' ) ),
   763 			'value' => ( $imagick_loaded ? __( 'Yes' ) : __( 'No' ) ),
   668 			'debug' => $imagick_loaded,
   764 			'debug' => $imagick_loaded,
   669 		);
   765 		);
   670 
   766 
       
   767 		// Pretty permalinks.
       
   768 		$pretty_permalinks_supported = got_url_rewrite();
       
   769 
       
   770 		$info['wp-server']['fields']['pretty_permalinks'] = array(
       
   771 			'label' => __( 'Are pretty permalinks supported?' ),
       
   772 			'value' => ( $pretty_permalinks_supported ? __( 'Yes' ) : __( 'No' ) ),
       
   773 			'debug' => $pretty_permalinks_supported,
       
   774 		);
       
   775 
   671 		// Check if a .htaccess file exists.
   776 		// Check if a .htaccess file exists.
   672 		if ( is_file( ABSPATH . '.htaccess' ) ) {
   777 		if ( is_file( ABSPATH . '.htaccess' ) ) {
   673 			// If the file exists, grab the content of it.
   778 			// If the file exists, grab the content of it.
   674 			$htaccess_content = file_get_contents( ABSPATH . '.htaccess' );
   779 			$htaccess_content = file_get_contents( ABSPATH . '.htaccess' );
   675 
   780 
   676 			// Filter away the core WordPress rules.
   781 			// Filter away the core WordPress rules.
   677 			$filtered_htaccess_content = trim( preg_replace( '/\# BEGIN WordPress[\s\S]+?# END WordPress/si', '', $htaccess_content ) );
   782 			$filtered_htaccess_content = trim( preg_replace( '/\# BEGIN WordPress[\s\S]+?# END WordPress/si', '', $htaccess_content ) );
   678 			$filtered_htaccess_content = ! empty( $filtered_htaccess_content );
   783 			$filtered_htaccess_content = ! empty( $filtered_htaccess_content );
   679 
   784 
       
   785 			if ( $filtered_htaccess_content ) {
       
   786 				/* translators: %s: .htaccess */
       
   787 				$htaccess_rules_string = sprintf( __( 'Custom rules have been added to your %s file.' ), '.htaccess' );
       
   788 			} else {
       
   789 				/* translators: %s: .htaccess */
       
   790 				$htaccess_rules_string = sprintf( __( 'Your %s file contains only core WordPress features.' ), '.htaccess' );
       
   791 			}
       
   792 
   680 			$info['wp-server']['fields']['htaccess_extra_rules'] = array(
   793 			$info['wp-server']['fields']['htaccess_extra_rules'] = array(
   681 				'label' => __( '.htaccess rules' ),
   794 				'label' => __( '.htaccess rules' ),
   682 				'value' => ( $filtered_htaccess_content ? __( 'Custom rules have been added to your .htaccess file.' ) : __( 'Your .htaccess file contains only core WordPress features.' ) ),
   795 				'value' => $htaccess_rules_string,
   683 				'debug' => $filtered_htaccess_content,
   796 				'debug' => $filtered_htaccess_content,
   684 			);
   797 			);
   685 		}
   798 		}
   686 
   799 
   687 		// Populate the database debug fields.
   800 		// Populate the database debug fields.
   694 		} else {
   807 		} else {
   695 			// Unknown sql extension.
   808 			// Unknown sql extension.
   696 			$extension = null;
   809 			$extension = null;
   697 		}
   810 		}
   698 
   811 
   699 		/*
   812 		$server = $wpdb->get_var( 'SELECT VERSION()' );
   700 		 * Check what database engine is used, this will throw compatibility
       
   701 		 * warnings from PHP compatibility testers, but `mysql_*` is
       
   702 		 * still valid in PHP 5.6, so we need to account for that.
       
   703 		 */
       
   704 		if ( method_exists( $wpdb, 'db_version' ) ) {
       
   705 			if ( $wpdb->use_mysqli ) {
       
   706 				// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysqli_get_server_info
       
   707 				$server = mysqli_get_server_info( $wpdb->dbh );
       
   708 			} else {
       
   709 				// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_server_info
       
   710 				$server = mysql_get_server_info( $wpdb->dbh );
       
   711 			}
       
   712 		} else {
       
   713 			$server = null;
       
   714 		}
       
   715 
   813 
   716 		if ( isset( $wpdb->use_mysqli ) && $wpdb->use_mysqli ) {
   814 		if ( isset( $wpdb->use_mysqli ) && $wpdb->use_mysqli ) {
   717 			$client_version = $wpdb->dbh->client_info;
   815 			$client_version = $wpdb->dbh->client_info;
   718 		} else {
   816 		} else {
   719 			// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_client_info
   817 			// phpcs:ignore WordPress.DB.RestrictedFunctions.mysql_mysql_get_client_info,PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
   720 			if ( preg_match( '|[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}|', mysql_get_client_info(), $matches ) ) {
   818 			if ( preg_match( '|[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}|', mysql_get_client_info(), $matches ) ) {
   721 				$client_version = $matches[0];
   819 				$client_version = $matches[0];
   722 			} else {
   820 			} else {
   723 				$client_version = null;
   821 				$client_version = null;
   724 			}
   822 			}
   738 			'label' => __( 'Client version' ),
   836 			'label' => __( 'Client version' ),
   739 			'value' => $client_version,
   837 			'value' => $client_version,
   740 		);
   838 		);
   741 
   839 
   742 		$info['wp-database']['fields']['database_user'] = array(
   840 		$info['wp-database']['fields']['database_user'] = array(
   743 			'label'   => __( 'Database user' ),
   841 			'label'   => __( 'Database username' ),
   744 			'value'   => $wpdb->dbuser,
   842 			'value'   => $wpdb->dbuser,
   745 			'private' => true,
   843 			'private' => true,
   746 		);
   844 		);
   747 
   845 
   748 		$info['wp-database']['fields']['database_host'] = array(
   846 		$info['wp-database']['fields']['database_host'] = array(
   756 			'value'   => $wpdb->dbname,
   854 			'value'   => $wpdb->dbname,
   757 			'private' => true,
   855 			'private' => true,
   758 		);
   856 		);
   759 
   857 
   760 		$info['wp-database']['fields']['database_prefix'] = array(
   858 		$info['wp-database']['fields']['database_prefix'] = array(
   761 			'label'   => __( 'Database prefix' ),
   859 			'label'   => __( 'Table prefix' ),
   762 			'value'   => $wpdb->prefix,
   860 			'value'   => $wpdb->prefix,
       
   861 			'private' => true,
       
   862 		);
       
   863 
       
   864 		$info['wp-database']['fields']['database_charset'] = array(
       
   865 			'label'   => __( 'Database charset' ),
       
   866 			'value'   => $wpdb->charset,
       
   867 			'private' => true,
       
   868 		);
       
   869 
       
   870 		$info['wp-database']['fields']['database_collate'] = array(
       
   871 			'label'   => __( 'Database collation' ),
       
   872 			'value'   => $wpdb->collate,
   763 			'private' => true,
   873 			'private' => true,
   764 		);
   874 		);
   765 
   875 
   766 		// List must use plugins if there are any.
   876 		// List must use plugins if there are any.
   767 		$mu_plugins = get_mu_plugins();
   877 		$mu_plugins = get_mu_plugins();
   772 
   882 
   773 			$plugin_version_string       = __( 'No version or author information is available.' );
   883 			$plugin_version_string       = __( 'No version or author information is available.' );
   774 			$plugin_version_string_debug = 'author: (undefined), version: (undefined)';
   884 			$plugin_version_string_debug = 'author: (undefined), version: (undefined)';
   775 
   885 
   776 			if ( ! empty( $plugin_version ) && ! empty( $plugin_author ) ) {
   886 			if ( ! empty( $plugin_version ) && ! empty( $plugin_author ) ) {
   777 				// translators: 1: Plugin version number. 2: Plugin author name.
   887 				/* translators: 1: Plugin version number. 2: Plugin author name. */
   778 				$plugin_version_string       = sprintf( __( 'Version %1$s by %2$s' ), $plugin_version, $plugin_author );
   888 				$plugin_version_string       = sprintf( __( 'Version %1$s by %2$s' ), $plugin_version, $plugin_author );
   779 				$plugin_version_string_debug = sprintf( 'version: %s, author: %s', $plugin_version, $plugin_author );
   889 				$plugin_version_string_debug = sprintf( 'version: %s, author: %s', $plugin_version, $plugin_author );
   780 			} else {
   890 			} else {
   781 				if ( ! empty( $plugin_author ) ) {
   891 				if ( ! empty( $plugin_author ) ) {
   782 					// translators: %s: Plugin author name.
   892 					/* translators: %s: Plugin author name. */
   783 					$plugin_version_string       = sprintf( __( 'By %s' ), $plugin_author );
   893 					$plugin_version_string       = sprintf( __( 'By %s' ), $plugin_author );
   784 					$plugin_version_string_debug = sprintf( 'author: %s, version: (undefined)', $plugin_author );
   894 					$plugin_version_string_debug = sprintf( 'author: %s, version: (undefined)', $plugin_author );
   785 				}
   895 				}
   786 
   896 
   787 				if ( ! empty( $plugin_version ) ) {
   897 				if ( ! empty( $plugin_version ) ) {
   788 					// translators: %s: Plugin version number.
   898 					/* translators: %s: Plugin version number. */
   789 					$plugin_version_string       = sprintf( __( 'Version %s' ), $plugin_version );
   899 					$plugin_version_string       = sprintf( __( 'Version %s' ), $plugin_version );
   790 					$plugin_version_string_debug = sprintf( 'author: (undefined), version: %s', $plugin_version );
   900 					$plugin_version_string_debug = sprintf( 'author: (undefined), version: %s', $plugin_version );
   791 				}
   901 				}
   792 			}
   902 			}
   793 
   903 
   799 		}
   909 		}
   800 
   910 
   801 		// List all available plugins.
   911 		// List all available plugins.
   802 		$plugins        = get_plugins();
   912 		$plugins        = get_plugins();
   803 		$plugin_updates = get_plugin_updates();
   913 		$plugin_updates = get_plugin_updates();
       
   914 		$transient      = get_site_transient( 'update_plugins' );
       
   915 
       
   916 		$auto_updates = array();
       
   917 
       
   918 		$auto_updates_enabled = wp_is_auto_update_enabled_for_type( 'plugin' );
       
   919 
       
   920 		if ( $auto_updates_enabled ) {
       
   921 			$auto_updates = (array) get_site_option( 'auto_update_plugins', array() );
       
   922 		}
   804 
   923 
   805 		foreach ( $plugins as $plugin_path => $plugin ) {
   924 		foreach ( $plugins as $plugin_path => $plugin ) {
   806 			$plugin_part = ( is_plugin_active( $plugin_path ) ) ? 'wp-plugins-active' : 'wp-plugins-inactive';
   925 			$plugin_part = ( is_plugin_active( $plugin_path ) ) ? 'wp-plugins-active' : 'wp-plugins-inactive';
   807 
   926 
   808 			$plugin_version = $plugin['Version'];
   927 			$plugin_version = $plugin['Version'];
   810 
   929 
   811 			$plugin_version_string       = __( 'No version or author information is available.' );
   930 			$plugin_version_string       = __( 'No version or author information is available.' );
   812 			$plugin_version_string_debug = 'author: (undefined), version: (undefined)';
   931 			$plugin_version_string_debug = 'author: (undefined), version: (undefined)';
   813 
   932 
   814 			if ( ! empty( $plugin_version ) && ! empty( $plugin_author ) ) {
   933 			if ( ! empty( $plugin_version ) && ! empty( $plugin_author ) ) {
   815 				// translators: 1: Plugin version number. 2: Plugin author name.
   934 				/* translators: 1: Plugin version number. 2: Plugin author name. */
   816 				$plugin_version_string       = sprintf( __( 'Version %1$s by %2$s' ), $plugin_version, $plugin_author );
   935 				$plugin_version_string       = sprintf( __( 'Version %1$s by %2$s' ), $plugin_version, $plugin_author );
   817 				$plugin_version_string_debug = sprintf( 'version: %s, author: %s', $plugin_version, $plugin_author );
   936 				$plugin_version_string_debug = sprintf( 'version: %s, author: %s', $plugin_version, $plugin_author );
   818 			} else {
   937 			} else {
   819 				if ( ! empty( $plugin_author ) ) {
   938 				if ( ! empty( $plugin_author ) ) {
   820 					// translators: %s: Plugin author name.
   939 					/* translators: %s: Plugin author name. */
   821 					$plugin_version_string       = sprintf( __( 'By %s' ), $plugin_author );
   940 					$plugin_version_string       = sprintf( __( 'By %s' ), $plugin_author );
   822 					$plugin_version_string_debug = sprintf( 'author: %s, version: (undefined)', $plugin_author );
   941 					$plugin_version_string_debug = sprintf( 'author: %s, version: (undefined)', $plugin_author );
   823 				}
   942 				}
   824 
   943 
   825 				if ( ! empty( $plugin_version ) ) {
   944 				if ( ! empty( $plugin_version ) ) {
   826 					// translators: %s: Plugin version number.
   945 					/* translators: %s: Plugin version number. */
   827 					$plugin_version_string       = sprintf( __( 'Version %s' ), $plugin_version );
   946 					$plugin_version_string       = sprintf( __( 'Version %s' ), $plugin_version );
   828 					$plugin_version_string_debug = sprintf( 'author: (undefined), version: %s', $plugin_version );
   947 					$plugin_version_string_debug = sprintf( 'author: (undefined), version: %s', $plugin_version );
   829 				}
   948 				}
   830 			}
   949 			}
   831 
   950 
   832 			if ( array_key_exists( $plugin_path, $plugin_updates ) ) {
   951 			if ( array_key_exists( $plugin_path, $plugin_updates ) ) {
   833 				// translators: %s: Latest plugin version number.
   952 				/* translators: %s: Latest plugin version number. */
   834 				$plugin_version_string       .= ' ' . sprintf( __( '(Latest version: %s)' ), $plugin_updates[ $plugin_path ]->update->new_version );
   953 				$plugin_version_string       .= ' ' . sprintf( __( '(Latest version: %s)' ), $plugin_updates[ $plugin_path ]->update->new_version );
   835 				$plugin_version_string_debug .= sprintf( ' (latest version: %s)', $plugin_updates[ $plugin_path ]->update->new_version );
   954 				$plugin_version_string_debug .= sprintf( ' (latest version: %s)', $plugin_updates[ $plugin_path ]->update->new_version );
       
   955 			}
       
   956 
       
   957 			if ( $auto_updates_enabled ) {
       
   958 				if ( isset( $transient->response[ $plugin_path ] ) ) {
       
   959 					$item = $transient->response[ $plugin_path ];
       
   960 				} elseif ( isset( $transient->no_update[ $plugin_path ] ) ) {
       
   961 					$item = $transient->no_update[ $plugin_path ];
       
   962 				} else {
       
   963 					$item = array(
       
   964 						'id'            => $plugin_path,
       
   965 						'slug'          => '',
       
   966 						'plugin'        => $plugin_path,
       
   967 						'new_version'   => '',
       
   968 						'url'           => '',
       
   969 						'package'       => '',
       
   970 						'icons'         => array(),
       
   971 						'banners'       => array(),
       
   972 						'banners_rtl'   => array(),
       
   973 						'tested'        => '',
       
   974 						'requires_php'  => '',
       
   975 						'compatibility' => new stdClass(),
       
   976 					);
       
   977 					$item = array_merge( $item, array_intersect_key( $plugin, $item ) );
       
   978 				}
       
   979 
       
   980 				$type = 'plugin';
       
   981 				/** This filter is documented in wp-admin/includes/class-wp-automatic-updater.php */
       
   982 				$auto_update_forced = apply_filters( "auto_update_{$type}", null, (object) $item );
       
   983 
       
   984 				if ( ! is_null( $auto_update_forced ) ) {
       
   985 					$enabled = $auto_update_forced;
       
   986 				} else {
       
   987 					$enabled = in_array( $plugin_path, $auto_updates, true );
       
   988 				}
       
   989 
       
   990 				if ( $enabled ) {
       
   991 					$auto_updates_string = __( 'Auto-updates enabled' );
       
   992 				} else {
       
   993 					$auto_updates_string = __( 'Auto-updates disabled' );
       
   994 				}
       
   995 
       
   996 				/**
       
   997 				 * Filters the text string of the auto-updates setting for each plugin in the Site Health debug data.
       
   998 				 *
       
   999 				 * @since 5.5.0
       
  1000 				 *
       
  1001 				 * @param string $auto_updates_string The string output for the auto-updates column.
       
  1002 				 * @param string $plugin_path         The path to the plugin file.
       
  1003 				 * @param array  $plugin              An array of plugin data.
       
  1004 				 * @param bool   $enabled             Whether auto-updates are enabled for this item.
       
  1005 				 */
       
  1006 				$auto_updates_string = apply_filters( 'plugin_auto_update_debug_string', $auto_updates_string, $plugin_path, $plugin, $enabled );
       
  1007 
       
  1008 				$plugin_version_string       .= ' | ' . $auto_updates_string;
       
  1009 				$plugin_version_string_debug .= ', ' . $auto_updates_string;
   836 			}
  1010 			}
   837 
  1011 
   838 			$info[ $plugin_part ]['fields'][ sanitize_text_field( $plugin['Name'] ) ] = array(
  1012 			$info[ $plugin_part ]['fields'][ sanitize_text_field( $plugin['Name'] ) ] = array(
   839 				'label' => $plugin['Name'],
  1013 				'label' => $plugin['Name'],
   840 				'value' => $plugin_version_string,
  1014 				'value' => $plugin_version_string,
   852 			}
  1026 			}
   853 		}
  1027 		}
   854 
  1028 
   855 		$active_theme  = wp_get_theme();
  1029 		$active_theme  = wp_get_theme();
   856 		$theme_updates = get_theme_updates();
  1030 		$theme_updates = get_theme_updates();
   857 
  1031 		$transient     = get_site_transient( 'update_themes' );
   858 		// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
  1032 
   859 		$active_theme_version       = $active_theme->Version;
  1033 		$active_theme_version       = $active_theme->version;
   860 		$active_theme_version_debug = $active_theme_version;
  1034 		$active_theme_version_debug = $active_theme_version;
       
  1035 
       
  1036 		$auto_updates         = array();
       
  1037 		$auto_updates_enabled = wp_is_auto_update_enabled_for_type( 'theme' );
       
  1038 		if ( $auto_updates_enabled ) {
       
  1039 			$auto_updates = (array) get_site_option( 'auto_update_themes', array() );
       
  1040 		}
   861 
  1041 
   862 		if ( array_key_exists( $active_theme->stylesheet, $theme_updates ) ) {
  1042 		if ( array_key_exists( $active_theme->stylesheet, $theme_updates ) ) {
   863 			$theme_update_new_version = $theme_updates[ $active_theme->stylesheet ]->update['new_version'];
  1043 			$theme_update_new_version = $theme_updates[ $active_theme->stylesheet ]->update['new_version'];
   864 
  1044 
   865 			// translators: %s: Latest theme version number.
  1045 			/* translators: %s: Latest theme version number. */
   866 			$active_theme_version       .= ' ' . sprintf( __( '(Latest version: %s)' ), $theme_update_new_version );
  1046 			$active_theme_version       .= ' ' . sprintf( __( '(Latest version: %s)' ), $theme_update_new_version );
   867 			$active_theme_version_debug .= sprintf( ' (latest version: %s)', $theme_update_new_version );
  1047 			$active_theme_version_debug .= sprintf( ' (latest version: %s)', $theme_update_new_version );
   868 		}
  1048 		}
   869 
  1049 
   870 		$active_theme_author_uri = $active_theme->offsetGet( 'Author URI' );
  1050 		$active_theme_author_uri = $active_theme->display( 'AuthorURI' );
       
  1051 
       
  1052 		if ( $active_theme->parent_theme ) {
       
  1053 			$active_theme_parent_theme = sprintf(
       
  1054 				/* translators: 1: Theme name. 2: Theme slug. */
       
  1055 				__( '%1$s (%2$s)' ),
       
  1056 				$active_theme->parent_theme,
       
  1057 				$active_theme->template
       
  1058 			);
       
  1059 			$active_theme_parent_theme_debug = sprintf(
       
  1060 				'%s (%s)',
       
  1061 				$active_theme->parent_theme,
       
  1062 				$active_theme->template
       
  1063 			);
       
  1064 		} else {
       
  1065 			$active_theme_parent_theme       = __( 'None' );
       
  1066 			$active_theme_parent_theme_debug = 'none';
       
  1067 		}
   871 
  1068 
   872 		$info['wp-active-theme']['fields'] = array(
  1069 		$info['wp-active-theme']['fields'] = array(
   873 			'name'           => array(
  1070 			'name'           => array(
   874 				'label' => __( 'Name' ),
  1071 				'label' => __( 'Name' ),
   875 				// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
  1072 				'value' => sprintf(
   876 				'value' => $active_theme->Name,
  1073 					/* translators: 1: Theme name. 2: Theme slug. */
       
  1074 					__( '%1$s (%2$s)' ),
       
  1075 					$active_theme->name,
       
  1076 					$active_theme->stylesheet
       
  1077 				),
   877 			),
  1078 			),
   878 			'version'        => array(
  1079 			'version'        => array(
   879 				'label' => __( 'Version' ),
  1080 				'label' => __( 'Version' ),
   880 				'value' => $active_theme_version,
  1081 				'value' => $active_theme_version,
   881 				'debug' => $active_theme_version_debug,
  1082 				'debug' => $active_theme_version_debug,
   882 			),
  1083 			),
   883 			'author'         => array(
  1084 			'author'         => array(
   884 				'label' => __( 'Author' ),
  1085 				'label' => __( 'Author' ),
   885 				// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
  1086 				'value' => wp_kses( $active_theme->author, array() ),
   886 				'value' => wp_kses( $active_theme->Author, array() ),
       
   887 			),
  1087 			),
   888 			'author_website' => array(
  1088 			'author_website' => array(
   889 				'label' => __( 'Author website' ),
  1089 				'label' => __( 'Author website' ),
   890 				'value' => ( $active_theme_author_uri ? $active_theme_author_uri : __( 'Undefined' ) ),
  1090 				'value' => ( $active_theme_author_uri ? $active_theme_author_uri : __( 'Undefined' ) ),
   891 				'debug' => ( $active_theme_author_uri ? $active_theme_author_uri : '(undefined)' ),
  1091 				'debug' => ( $active_theme_author_uri ? $active_theme_author_uri : '(undefined)' ),
   892 			),
  1092 			),
   893 			'parent_theme'   => array(
  1093 			'parent_theme'   => array(
   894 				'label' => __( 'Parent theme' ),
  1094 				'label' => __( 'Parent theme' ),
   895 				'value' => ( $active_theme->parent_theme ? $active_theme->parent_theme : __( 'None' ) ),
  1095 				'value' => $active_theme_parent_theme,
   896 				'debug' => ( $active_theme->parent_theme ? $active_theme->parent_theme : 'none' ),
  1096 				'debug' => $active_theme_parent_theme_debug,
   897 			),
  1097 			),
   898 			'theme_features' => array(
  1098 			'theme_features' => array(
   899 				'label' => __( 'Theme features' ),
  1099 				'label' => __( 'Theme features' ),
   900 				'value' => implode( ', ', $theme_features ),
  1100 				'value' => implode( ', ', $theme_features ),
   901 			),
  1101 			),
   902 			'theme_path'     => array(
  1102 			'theme_path'     => array(
   903 				'label' => __( 'Theme directory location' ),
  1103 				'label' => __( 'Theme directory location' ),
   904 				'value' => get_template_directory(),
  1104 				'value' => get_stylesheet_directory(),
   905 			),
  1105 			),
   906 		);
  1106 		);
       
  1107 
       
  1108 		if ( $auto_updates_enabled ) {
       
  1109 			if ( isset( $transient->response[ $active_theme->stylesheet ] ) ) {
       
  1110 				$item = $transient->response[ $active_theme->stylesheet ];
       
  1111 			} elseif ( isset( $transient->no_update[ $active_theme->stylesheet ] ) ) {
       
  1112 				$item = $transient->no_update[ $active_theme->stylesheet ];
       
  1113 			} else {
       
  1114 				$item = array(
       
  1115 					'theme'        => $active_theme->stylesheet,
       
  1116 					'new_version'  => $active_theme->version,
       
  1117 					'url'          => '',
       
  1118 					'package'      => '',
       
  1119 					'requires'     => '',
       
  1120 					'requires_php' => '',
       
  1121 				);
       
  1122 			}
       
  1123 
       
  1124 			$type = 'theme';
       
  1125 			/** This filter is documented in wp-admin/includes/class-wp-automatic-updater.php */
       
  1126 			$auto_update_forced = apply_filters( "auto_update_{$type}", null, (object) $item );
       
  1127 
       
  1128 			if ( ! is_null( $auto_update_forced ) ) {
       
  1129 				$enabled = $auto_update_forced;
       
  1130 			} else {
       
  1131 				$enabled = in_array( $active_theme->stylesheet, $auto_updates, true );
       
  1132 			}
       
  1133 
       
  1134 			if ( $enabled ) {
       
  1135 				$auto_updates_string = __( 'Enabled' );
       
  1136 			} else {
       
  1137 				$auto_updates_string = __( 'Disabled' );
       
  1138 			}
       
  1139 
       
  1140 			/** This filter is documented in wp-admin/includes/class-wp-debug-data.php */
       
  1141 			$auto_updates_string = apply_filters( 'theme_auto_update_debug_string', $auto_updates_string, $active_theme, $enabled );
       
  1142 
       
  1143 			$info['wp-active-theme']['fields']['auto_update'] = array(
       
  1144 				'label' => __( 'Auto-updates' ),
       
  1145 				'value' => $auto_updates_string,
       
  1146 				'debug' => $auto_updates_string,
       
  1147 			);
       
  1148 		}
       
  1149 
       
  1150 		$parent_theme = $active_theme->parent();
       
  1151 
       
  1152 		if ( $parent_theme ) {
       
  1153 			$parent_theme_version       = $parent_theme->version;
       
  1154 			$parent_theme_version_debug = $parent_theme_version;
       
  1155 
       
  1156 			if ( array_key_exists( $parent_theme->stylesheet, $theme_updates ) ) {
       
  1157 				$parent_theme_update_new_version = $theme_updates[ $parent_theme->stylesheet ]->update['new_version'];
       
  1158 
       
  1159 				/* translators: %s: Latest theme version number. */
       
  1160 				$parent_theme_version       .= ' ' . sprintf( __( '(Latest version: %s)' ), $parent_theme_update_new_version );
       
  1161 				$parent_theme_version_debug .= sprintf( ' (latest version: %s)', $parent_theme_update_new_version );
       
  1162 			}
       
  1163 
       
  1164 			$parent_theme_author_uri = $parent_theme->display( 'AuthorURI' );
       
  1165 
       
  1166 			$info['wp-parent-theme']['fields'] = array(
       
  1167 				'name'           => array(
       
  1168 					'label' => __( 'Name' ),
       
  1169 					'value' => sprintf(
       
  1170 						/* translators: 1: Theme name. 2: Theme slug. */
       
  1171 						__( '%1$s (%2$s)' ),
       
  1172 						$parent_theme->name,
       
  1173 						$parent_theme->stylesheet
       
  1174 					),
       
  1175 				),
       
  1176 				'version'        => array(
       
  1177 					'label' => __( 'Version' ),
       
  1178 					'value' => $parent_theme_version,
       
  1179 					'debug' => $parent_theme_version_debug,
       
  1180 				),
       
  1181 				'author'         => array(
       
  1182 					'label' => __( 'Author' ),
       
  1183 					'value' => wp_kses( $parent_theme->author, array() ),
       
  1184 				),
       
  1185 				'author_website' => array(
       
  1186 					'label' => __( 'Author website' ),
       
  1187 					'value' => ( $parent_theme_author_uri ? $parent_theme_author_uri : __( 'Undefined' ) ),
       
  1188 					'debug' => ( $parent_theme_author_uri ? $parent_theme_author_uri : '(undefined)' ),
       
  1189 				),
       
  1190 				'theme_path'     => array(
       
  1191 					'label' => __( 'Theme directory location' ),
       
  1192 					'value' => get_template_directory(),
       
  1193 				),
       
  1194 			);
       
  1195 
       
  1196 			if ( $auto_updates_enabled ) {
       
  1197 				if ( isset( $transient->response[ $parent_theme->stylesheet ] ) ) {
       
  1198 					$item = $transient->response[ $parent_theme->stylesheet ];
       
  1199 				} elseif ( isset( $transient->no_update[ $parent_theme->stylesheet ] ) ) {
       
  1200 					$item = $transient->no_update[ $parent_theme->stylesheet ];
       
  1201 				} else {
       
  1202 					$item = array(
       
  1203 						'theme'        => $parent_theme->stylesheet,
       
  1204 						'new_version'  => $parent_theme->version,
       
  1205 						'url'          => '',
       
  1206 						'package'      => '',
       
  1207 						'requires'     => '',
       
  1208 						'requires_php' => '',
       
  1209 					);
       
  1210 				}
       
  1211 
       
  1212 				$type = 'theme';
       
  1213 				/** This filter is documented in wp-admin/includes/class-wp-automatic-updater.php */
       
  1214 				$auto_update_forced = apply_filters( "auto_update_{$type}", 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 		}
   907 
  1238 
   908 		// Populate a list of all themes available in the install.
  1239 		// Populate a list of all themes available in the install.
   909 		$all_themes = wp_get_themes();
  1240 		$all_themes = wp_get_themes();
   910 
  1241 
   911 		foreach ( $all_themes as $theme_slug => $theme ) {
  1242 		foreach ( $all_themes as $theme_slug => $theme ) {
   912 			// Ignore the currently active theme from the list of all themes.
  1243 			// Exclude the currently active theme from the list of all themes.
   913 			if ( $active_theme->stylesheet === $theme_slug ) {
  1244 			if ( $active_theme->stylesheet === $theme_slug ) {
   914 				continue;
  1245 				continue;
   915 			}
  1246 			}
   916 			// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
  1247 
   917 			$theme_version = $theme->Version;
  1248 			// Exclude the currently active parent theme from the list of all themes.
   918 			// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
  1249 			if ( ! empty( $parent_theme ) && $parent_theme->stylesheet === $theme_slug ) {
   919 			$theme_author = $theme->Author;
  1250 				continue;
   920 
  1251 			}
   921 			// Sanitize
  1252 
       
  1253 			$theme_version = $theme->version;
       
  1254 			$theme_author  = $theme->author;
       
  1255 
       
  1256 			// Sanitize.
   922 			$theme_author = wp_kses( $theme_author, array() );
  1257 			$theme_author = wp_kses( $theme_author, array() );
   923 
  1258 
   924 			$theme_version_string       = __( 'No version or author information is available.' );
  1259 			$theme_version_string       = __( 'No version or author information is available.' );
   925 			$theme_version_string_debug = 'undefined';
  1260 			$theme_version_string_debug = 'undefined';
   926 
  1261 
   927 			if ( ! empty( $theme_version ) && ! empty( $theme_author ) ) {
  1262 			if ( ! empty( $theme_version ) && ! empty( $theme_author ) ) {
   928 				// translators: 1: Theme version number. 2: Theme author name.
  1263 				/* translators: 1: Theme version number. 2: Theme author name. */
   929 				$theme_version_string       = sprintf( __( 'Version %1$s by %2$s' ), $theme_version, $theme_author );
  1264 				$theme_version_string       = sprintf( __( 'Version %1$s by %2$s' ), $theme_version, $theme_author );
   930 				$theme_version_string_debug = sprintf( 'version: %s, author: %s', $theme_version, $theme_author );
  1265 				$theme_version_string_debug = sprintf( 'version: %s, author: %s', $theme_version, $theme_author );
   931 			} else {
  1266 			} else {
   932 				if ( ! empty( $theme_author ) ) {
  1267 				if ( ! empty( $theme_author ) ) {
   933 					// translators: %s: Theme author name.
  1268 					/* translators: %s: Theme author name. */
   934 					$theme_version_string       = sprintf( __( 'By %s' ), $theme_author );
  1269 					$theme_version_string       = sprintf( __( 'By %s' ), $theme_author );
   935 					$theme_version_string_debug = sprintf( 'author: %s, version: (undefined)', $theme_author );
  1270 					$theme_version_string_debug = sprintf( 'author: %s, version: (undefined)', $theme_author );
   936 				}
  1271 				}
   937 
  1272 
   938 				if ( ! empty( $theme_version ) ) {
  1273 				if ( ! empty( $theme_version ) ) {
   939 					// translators: %s: Theme version number.
  1274 					/* translators: %s: Theme version number. */
   940 					$theme_version_string       = sprintf( __( 'Version %s' ), $theme_version );
  1275 					$theme_version_string       = sprintf( __( 'Version %s' ), $theme_version );
   941 					$theme_version_string_debug = sprintf( 'author: (undefined), version: %s', $theme_version );
  1276 					$theme_version_string_debug = sprintf( 'author: (undefined), version: %s', $theme_version );
   942 				}
  1277 				}
   943 			}
  1278 			}
   944 
  1279 
   945 			if ( array_key_exists( $theme_slug, $theme_updates ) ) {
  1280 			if ( array_key_exists( $theme_slug, $theme_updates ) ) {
   946 				// translators: %s: Latest theme version number.
  1281 				/* translators: %s: Latest theme version number. */
   947 				$theme_version_string       .= ' ' . sprintf( __( '(Latest version: %s)' ), $theme_updates[ $theme_slug ]->update['new_version'] );
  1282 				$theme_version_string       .= ' ' . sprintf( __( '(Latest version: %s)' ), $theme_updates[ $theme_slug ]->update['new_version'] );
   948 				$theme_version_string_debug .= 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'] );
   949 			}
  1284 			}
   950 
  1285 
   951 			// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
  1286 			if ( $auto_updates_enabled ) {
   952 			$info['wp-themes']['fields'][ sanitize_text_field( $theme->Name ) ] = array(
  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 				$type = 'theme';
       
  1303 				/** This filter is documented in wp-admin/includes/class-wp-automatic-updater.php */
       
  1304 				$auto_update_forced = apply_filters( "auto_update_{$type}", null, (object) $item );
       
  1305 
       
  1306 				if ( ! is_null( $auto_update_forced ) ) {
       
  1307 					$enabled = $auto_update_forced;
       
  1308 				} else {
       
  1309 					$enabled = in_array( $theme_slug, $auto_updates, true );
       
  1310 				}
       
  1311 
       
  1312 				if ( $enabled ) {
       
  1313 					$auto_updates_string = __( 'Auto-updates enabled' );
       
  1314 				} else {
       
  1315 					$auto_updates_string = __( 'Auto-updates disabled' );
       
  1316 				}
       
  1317 
       
  1318 				/**
       
  1319 				 * Filters the text string of the auto-updates setting for each theme in the Site Health debug data.
       
  1320 				 *
       
  1321 				 * @since 5.5.0
       
  1322 				 *
       
  1323 				 * @param string   $auto_updates_string The string output for the auto-updates column.
       
  1324 				 * @param WP_Theme $theme               An object of theme data.
       
  1325 				 * @param bool     $enabled             Whether auto-updates are enabled for this item.
       
  1326 				 */
       
  1327 				$auto_updates_string = apply_filters( 'theme_auto_update_debug_string', $auto_updates_string, $theme, $enabled );
       
  1328 
       
  1329 				$theme_version_string       .= ' | ' . $auto_updates_string;
       
  1330 				$theme_version_string_debug .= ',' . $auto_updates_string;
       
  1331 			}
       
  1332 
       
  1333 			$info['wp-themes-inactive']['fields'][ sanitize_text_field( $theme->name ) ] = array(
   953 				'label' => sprintf(
  1334 				'label' => sprintf(
   954 					// translators: 1: Theme name. 2: Theme slug.
  1335 					/* translators: 1: Theme name. 2: Theme slug. */
   955 					__( '%1$s (%2$s)' ),
  1336 					__( '%1$s (%2$s)' ),
   956 					// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
  1337 					$theme->name,
   957 					$theme->Name,
       
   958 					$theme_slug
  1338 					$theme_slug
   959 				),
  1339 				),
   960 				'value' => $theme_version_string,
  1340 				'value' => $theme_version_string,
   961 				'debug' => $theme_version_string_debug,
  1341 				'debug' => $theme_version_string_debug,
   962 			);
  1342 			);
   963 		}
  1343 		}
   964 
  1344 
   965 		// Add more filesystem checks
  1345 		// Add more filesystem checks.
   966 		if ( defined( 'WPMU_PLUGIN_DIR' ) && is_dir( WPMU_PLUGIN_DIR ) ) {
  1346 		if ( defined( 'WPMU_PLUGIN_DIR' ) && is_dir( WPMU_PLUGIN_DIR ) ) {
   967 			$is_writable_wpmu_plugin_dir = wp_is_writable( WPMU_PLUGIN_DIR );
  1347 			$is_writable_wpmu_plugin_dir = wp_is_writable( WPMU_PLUGIN_DIR );
   968 
  1348 
   969 			$info['wp-filesystem']['fields']['mu-plugins'] = array(
  1349 			$info['wp-filesystem']['fields']['mu-plugins'] = array(
   970 				'label' => __( 'The must use plugins directory' ),
  1350 				'label' => __( 'The must use plugins directory' ),
  1023 	/**
  1403 	/**
  1024 	 * Format the information gathered for debugging, in a manner suitable for copying to a forum or support ticket.
  1404 	 * Format the information gathered for debugging, in a manner suitable for copying to a forum or support ticket.
  1025 	 *
  1405 	 *
  1026 	 * @since 5.2.0
  1406 	 * @since 5.2.0
  1027 	 *
  1407 	 *
  1028 	 * @param array $info_array Information gathered from the `WP_Debug_Data::debug_data` function.
  1408 	 * @param array  $info_array Information gathered from the `WP_Debug_Data::debug_data` function.
  1029 	 * @param string $type      The data type to return, either 'info' or 'debug'.
  1409 	 * @param string $type       The data type to return, either 'info' or 'debug'.
  1030 	 * @return string The formatted data.
  1410 	 * @return string The formatted data.
  1031 	 */
  1411 	 */
  1032 	public static function format( $info_array, $type ) {
  1412 	public static function format( $info_array, $type ) {
  1033 		$return = "`\n";
  1413 		$return = "`\n";
  1034 
  1414