Make WordPress Core

Ticket #39165: 39165.6.patch

File 39165.6.patch, 22.4 KB (added by Clorith, 7 years ago)
  • src/wp-admin/info.php

     
     1<?php
     2/**
     3 * Get system status for debugging and support.
     4 *
     5 * @package WordPress
     6 * @subpackage Administration
     7 */
     8
     9/** WordPress Administration Bootstrap */
     10require_once( dirname( __FILE__ ) . '/admin.php' );
     11
     12if ( ! current_user_can( 'update_core' ) ) {
     13        wp_die( __( 'Sorry, you do not have permission to access this page.' ) );
     14}
     15
     16global $wpdb;
     17
     18$title = __( 'System information' );
     19
     20require_once( ABSPATH . 'wp-admin/admin-header.php' );
     21?>
     22
     23        <div class="wrap">
     24                <h1 class="wp-heading-inline">
     25                        <?php echo esc_html( $title ); ?>
     26
     27                        <?php if ( ! isset( $_GET['phpinfo'] ) ) { ?>
     28                                <a href="<?php echo esc_url( admin_url( 'info.php?phpinfo' ) ); ?>" class="page-title-action"><?php esc_html_e( 'PHP Information' ); ?></a>
     29                        <?php } else { ?>
     30                                <a href="<?php echo esc_url( admin_url( 'info.php' ) ); ?>" class="page-title-action"><?php esc_html_e( 'Debug Information' ); ?></a>
     31                        <?php } ?>
     32                </h1>
     33
     34                <hr class="wp-header-end">
     35
     36                <?php
     37                if ( ! isset( $_GET['phpinfo'] ) ) {
     38
     39                        $info = array(
     40                                'wp-core'             => array(
     41                                        'label'  => __( 'WordPress' ),
     42                                        'fields' => array(
     43                                                array(
     44                                                        'label' => __( 'Version' ),
     45                                                        'value' => get_bloginfo( 'version' )
     46                                                ),
     47                                                array(
     48                                                        'label' => __( 'Language' ),
     49                                                        'value' => get_locale()
     50                                                ),
     51                                                array(
     52                                                        'label'   => __( 'Home URL' ),
     53                                                        'value'   => get_bloginfo( 'url' ),
     54                                                        'private' => true
     55                                                ),
     56                                                array(
     57                                                        'label'   => __( 'Site URL' ),
     58                                                        'value'   => get_bloginfo( 'wpurl' ),
     59                                                        'private' => true
     60                                                ),
     61                                                array(
     62                                                        'label' => __( 'Permalink structure' ),
     63                                                        'value' => get_option( 'permalink_structure' )
     64                                                ),
     65                                                array(
     66                                                        'label' => __( 'Is this site using HTTPS' ),
     67                                                        'value' => ( is_ssl() ? __( 'Yes' ) : __( 'No' ) )
     68                                                ),
     69                                                array(
     70                                                        'label' => __( 'Is the main WordPress directory writable' ),
     71                                                        'value' => ( wp_is_writable( ABSPATH ) ? __( 'Yes' ) : __( 'No' ) )
     72                                                ),
     73                                                array(
     74                                                        'label' => __( 'Is the theme directory writable' ),
     75                                                        'value' => ( wp_is_writable( get_template_directory() . '/..' ) ? __( 'Yes' ) : __( 'No' ) )
     76                                                ),
     77                                                array(
     78                                                        'label' => __( 'Is the plugin directory writable' ),
     79                                                        'value' => ( wp_is_writable( WP_PLUGIN_DIR ) ? __( 'Yes' ) : __( 'No' ) )
     80                                                ),
     81                                                array(
     82                                                        'label' => __( 'Can anyone register on this site' ),
     83                                                        'value' => ( get_option( 'users_can_register' ) ? __( 'Yes' ) : __( 'No' ) )
     84                                                ),
     85                                                array(
     86                                                        'label' => __( 'Default comment status' ),
     87                                                        'value' => get_option( 'default_comment_status' )
     88                                                ),
     89                                                array(
     90                                                        'label' => __( 'Is this a multisite' ),
     91                                                        'value' => ( is_multisite() ? __( 'Yes' ) : __( 'No' ) )
     92                                                )
     93                                        ),
     94                                ),
     95                                'wp-dropins'          => array(
     96                                        'label'       => __( 'Drop-ins' ),
     97                                        'description' => __( 'Drop-ins are single files that replace or enhance WordPress features in ways that are not possible for traditional plugins' ),
     98                                        'fields'      => array()
     99                                ),
     100                                'wp-active-theme'     => array(
     101                                        'label'  => __( 'Active theme' ),
     102                                        'fields' => array()
     103                                ),
     104                                'wp-themes'           => array(
     105                                        'label'      => __( 'Other themes' ),
     106                                        'show_count' => true,
     107                                        'fields'     => array()
     108                                ),
     109                                'wp-mu-plugins'       => array(
     110                                        'label'      => __( 'Must User Plugins' ),
     111                                        'show_count' => true,
     112                                        'fields'     => array()
     113                                ),
     114                                'wp-plugins-active'   => array(
     115                                        'label'      => __( 'Active Plugins' ),
     116                                        'show_count' => true,
     117                                        'fields'     => array()
     118                                ),
     119                                'wp-plugins-inactive' => array(
     120                                        'label'      => __( 'Inactive Plugins' ),
     121                                        'show_count' => true,
     122                                        'fields'     => array()
     123                                ),
     124                                'wp-server'           => array(
     125                                        'label'       => 'Server',
     126                                        'description' => __( 'The options shown below relate to your server setup. If changes are required, you may need your web host\'s assistance.' ),
     127                                        'fields'      => array()
     128                                ),
     129                                'wp-database'         => array(
     130                                        'label'  => __( 'Database' ),
     131                                        'fields' => array()
     132                                ),
     133                                'wp-constants'        => array(
     134                                        'label'       => __( 'WordPress constants' ),
     135                                        'description' => __( 'These values represent values set in your websites code which affect WordPress in various ways that may be of importance when seeking help with your site.' ),
     136                                        'fields'      => array(
     137                                                array(
     138                                                        'label' => 'WP_DEBUG',
     139                                                        'value' => ( ! defined( 'WP_DEBUG' ) ? __( 'Undefined' ) : ( WP_DEBUG ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     140                                                ),
     141                                                array(
     142                                                        'label' => 'WP_MAX_MEMORY_LIMIT',
     143                                                        'value' => ( ! defined( 'WP_MAX_MEMORY_LIMIT' ) ? __( 'Undefined' ) : WP_MAX_MEMORY_LIMIT )
     144                                                ),
     145                                                array(
     146                                                        'label' => 'WP_DEBUG_DISPLAY',
     147                                                        'value' => ( ! defined( 'WP_DEBUG_DISPLAY' ) ? __( 'Undefined' ) : ( WP_DEBUG_DISPLAY ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     148                                                ),
     149                                                array(
     150                                                        'label' => 'WP_DEBUG_LOG',
     151                                                        'value' => ( ! defined( 'WP_DEBUG_LOG' ) ? __( 'Undefined' ) : ( WP_DEBUG_LOG ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     152                                                ),
     153                                                array(
     154                                                        'label' => 'SCRIPT_DEBUG',
     155                                                        'value' => ( ! defined( 'SCRIPT_DEBUG' ) ? __( 'Undefined' ) : ( SCRIPT_DEBUG ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     156                                                ),
     157                                                array(
     158                                                        'label' => 'WP_CACHE',
     159                                                        'value' => ( ! defined( 'WP_CACHE' ) ? __( 'Undefined' ) : ( WP_CACHE ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     160                                                ),
     161                                                array(
     162                                                        'label' => 'CONCATENATE_SCRIPTS',
     163                                                        'value' => ( ! defined( 'CONCATENATE_SCRIPTS' ) ? __( 'Undefined' ) : ( CONCATENATE_SCRIPTS ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     164                                                ),
     165                                                array(
     166                                                        'label' => 'COMPRESS_SCRIPTS',
     167                                                        'value' => ( ! defined( 'COMPRESS_SCRIPTS' ) ? __( 'Undefined' ) : ( COMPRESS_SCRIPTS ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     168                                                ),
     169                                                array(
     170                                                        'label' => 'COMPRESS_CSS',
     171                                                        'value' => ( ! defined( 'COMPRESS_CSS' ) ? __( 'Undefined' ) : ( COMPRESS_CSS ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     172                                                ),
     173                                                array(
     174                                                        'label' => 'WP_LOCAL_DEV',
     175                                                        'value' => ( ! defined( 'WP_LOCAL_DEV' ) ? __( 'Undefined' ) : ( WP_LOCAL_DEV ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     176                                                )
     177                                        )
     178                                )
     179                        );
     180
     181                        if ( is_multisite() ) {
     182                                $network_query = new WP_Network_Query();
     183                                $network_ids   = $network_query->query( array(
     184                                        'fields'        => 'ids',
     185                                        'number'        => 100,
     186                                        'no_found_rows' => false,
     187                                ) );
     188
     189                                $site_count = 0;
     190                                foreach ( $network_ids AS $network_id ) {
     191                                        $site_count += get_blog_count( $network_id );
     192                                }
     193
     194                                $info['wp-core']['fields'][] = array(
     195                                        'label' => __( 'User Count' ),
     196                                        'value' => get_user_count()
     197                                );
     198                                $info['wp-core']['fields'][] = array(
     199                                        'label' => __( 'Site Count' ),
     200                                        'value' => $site_count
     201                                );
     202                                $info['wp-core']['fields'][] = array(
     203                                        'label' => __( 'Network Count' ),
     204                                        'value' => $network_query->found_networks
     205                                );
     206                        } else {
     207                                $user_count = count_users();
     208
     209                                $info['wp-core']['fields'][] = array(
     210                                        'label' => __( 'User Count' ),
     211                                        'value' => $user_count['total_users']
     212                                );
     213                        }
     214
     215                        // WordPress features requiring processing.
     216                        $wp_dotorg = wp_remote_get( 'https://wordpress.org', array( 'timeout' => 10 ) );
     217                        if ( ! is_wp_error( $wp_dotorg ) ) {
     218                                $info['wp-core']['fields'][] = array(
     219                                        'label' => __( 'Communication with WordPress.org' ),
     220                                        'value' => sprintf(
     221                                                __( 'WordPress.org is reachable' )
     222                                        )
     223                                );
     224                        } else {
     225                                $info['wp-core']['fields'][] = array(
     226                                        'label' => __( 'Communication with WordPress.org' ),
     227                                        'value' => sprintf(
     228                                        // translators: %1$s: The IP address WordPress.org resolves to. %2$s: The error returned by the lookup.
     229                                                __( 'Unable to reach WordPress.org at %1$s: %2$s' ),
     230                                                gethostbyname( 'wordpress.org' ),
     231                                                $wp_dotorg->get_error_message()
     232                                        )
     233                                );
     234                        }
     235
     236                        // Get drop-ins.
     237                        $dropins            = get_dropins();
     238                        $dropin_description = _get_dropins();
     239                        foreach ( $dropins AS $dropin_key => $dropin ) {
     240                                $info['wp-dropins']['fields'][] = array(
     241                                        'label' => $dropin_key,
     242                                        'value' => $dropin_description[ $dropin_key ][0]
     243                                );
     244                        }
     245
     246                        // Populate the server debug fields.
     247                        $info['wp-server']['fields'][] = array(
     248                                'label' => _( 'Server architecture' ),
     249                                'value' => ( ! function_exists( 'php_uname' ) ? __( 'Unable to determine server architecture' ) : sprintf( '%s %s %s', php_uname( 's' ), php_uname( 'r' ), php_uname( 'm' ) ) )
     250                        );
     251                        $info['wp-server']['fields'][] = array(
     252                                'label' => __( 'PHP Version' ),
     253                                'value' => ( ! function_exists( 'phpversion' ) ? __( 'Unable to determine PHP version' ) : phpversion() )
     254                        );
     255                        $info['wp-server']['fields'][] = array(
     256                                'label' => __( 'PHP SAPI' ),
     257                                'value' => ( ! function_exists( 'php_sapi_name' ) ? __( 'Unable to determine PHP SAPI' ) : php_sapi_name() )
     258                        );
     259
     260                        if ( ! function_exists( 'ini_get' ) ) {
     261                                $info['wp-server']['fields'][] = array(
     262                                        'label' => __( 'Server settings' ),
     263                                        'value' => __( 'Unable to determine some settings as the ini_get() function has been disabled' )
     264                                );
     265                        } else {
     266                                $info['wp-server']['fields'][] = array(
     267                                        'label' => __( 'PHP max input variables' ),
     268                                        'value' => ini_get( 'max_input_vars' )
     269                                );
     270                                $info['wp-server']['fields'][] = array(
     271                                        'label' => __( 'PHP time limit' ),
     272                                        'value' => ini_get( 'max_execution_time' )
     273                                );
     274                                $info['wp-server']['fields'][] = array(
     275                                        'label' => __( 'PHP memory limit' ),
     276                                        'value' => ini_get( 'memory_limit' )
     277                                );
     278                                $info['wp-server']['fields'][] = array(
     279                                        'label' => __( 'Upload max filesize' ),
     280                                        'value' => ini_get( 'upload_max_filesize' )
     281                                );
     282                                $info['wp-server']['fields'][] = array(
     283                                        'label' => __( 'PHP post max size' ),
     284                                        'value' => ini_get( 'post_max_size' )
     285                                );
     286                        }
     287
     288                        if ( function_exists( 'curl_version' ) ) {
     289                                $cURL                          = curl_version();
     290                                $info['wp-server']['fields'][] = array(
     291                                        'label' => __( 'cURL Version' ),
     292                                        'value' => sprintf( '%s %s', $cURL['version'], $cURL['ssl_version'] )
     293                                );
     294                        } else {
     295                                $info['wp-server']['fields'][] = array(
     296                                        'label' => __( 'cURL Version' ),
     297                                        'value' => __( 'Your server does not support cURL' )
     298                                );
     299                        }
     300
     301                        $info['wp-server']['fields'][] = array(
     302                                'label' => __( 'SUHOSIN installed' ),
     303                                'value' => ( ( extension_loaded( 'suhosin' ) || ( defined( 'SUHOSIN_PATCH' ) && constant( 'SUHOSIN_PATCH' ) ) ) ? __( 'Yes' ) : __( 'No' ) )
     304                        );
     305
     306                        $info['wp-server']['fields'][] = array(
     307                                'label' => __( 'Is the Imagick library available' ),
     308                                'value' => ( extension_loaded( 'imagick' ) ? __( 'Yes' ) : __( 'No' ) )
     309                        );
     310
     311
     312                        // Populate the database debug fields.
     313                        if ( is_resource( $wpdb->dbh ) ) {
     314                                // Old mysql extension.
     315                                $extension = 'mysql';
     316                        } else if ( is_object( $wpdb->dbh ) ) {
     317                                // mysqli or PDO.
     318                                $extension = get_class( $wpdb->dbh );
     319                        } else {
     320                                // Unknown sql extension.
     321                                $extension = null;
     322                        }
     323
     324                        if ( method_exists( $wpdb, 'db_version' ) ) {
     325                                if ( $wpdb->use_mysqli ) {
     326                                        $server = mysqli_get_server_info( $wpdb->dbh );
     327                                } else {
     328                                        $server = mysql_get_server_info( $wpdb->dbh );
     329                                }
     330                        } else {
     331                                $server = null;
     332                        }
     333
     334                        if ( isset( $wpdb->use_mysqli ) && $wpdb->use_mysqli ) {
     335                                $client_version = $wpdb->dbh->client_info;
     336                        } else {
     337                                if ( preg_match( '|[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}|', mysql_get_client_info(), $matches ) ) {
     338                                        $client_version = $matches[0];
     339                                } else {
     340                                        $client_version = null;
     341                                }
     342                        }
     343
     344                        $info['wp-database']['fields'][] = array(
     345                                'label' => __( 'Extension' ),
     346                                'value' => $extension
     347                        );
     348                        $info['wp-database']['fields'][] = array(
     349                                'label' => __( 'Server version' ),
     350                                'value' => $server
     351                        );
     352                        $info['wp-database']['fields'][] = array(
     353                                'label' => __( 'Client version' ),
     354                                'value' => $client_version
     355                        );
     356                        $info['wp-database']['fields'][] = array(
     357                                'label'   => __( 'Database user' ),
     358                                'value'   => $wpdb->dbuser,
     359                                'private' => true
     360                        );
     361                        $info['wp-database']['fields'][] = array(
     362                                'label'   => __( 'Database host' ),
     363                                'value'   => $wpdb->dbhost,
     364                                'private' => true
     365                        );
     366                        $info['wp-database']['fields'][] = array(
     367                                'label'   => __( 'Database table' ),
     368                                'value'   => $wpdb->dbname,
     369                                'private' => true
     370                        );
     371                        $info['wp-database']['fields'][] = array(
     372                                'label' => __( 'Database prefix' ),
     373                                'value' => $wpdb->prefix
     374                        );
     375
     376
     377                        // List must use plugins if there are any.
     378                        $mu_plugins = get_mu_plugins();
     379
     380                        foreach ( $mu_plugins AS $plugin_path => $plugin ) {
     381                                $info['wp-mu-plugins']['fields'][] = array(
     382                                        'label' => $plugin['Name'],
     383                                        // translators: %1$s: Plugin version number. %2$s: Plugin author name.
     384                                        'value' => sprintf( __( 'version %1$s by %2$s' ), $plugin['Version'], $plugin['Author'] )
     385                                );
     386                        }
     387
     388
     389                        // List all available plugins.
     390                        $plugins = get_plugins();
     391
     392                        foreach ( $plugins AS $plugin_path => $plugin ) {
     393                                $plugin_part = ( is_plugin_active( $plugin_path ) ) ? 'wp-plugins-active' : 'wp-plugins-inactive';
     394
     395                                $info[ $plugin_part ]['fields'][] = array(
     396                                        'label' => $plugin['Name'],
     397                                        // translators: %1$s: Plugin version number. %2$s: Plugin author name.
     398                                        'value' => sprintf( __( 'version %1$s by %2$s' ), $plugin['Version'], $plugin['Author'] )
     399                                );
     400                        }
     401
     402
     403                        // Populate the section for the currently active theme.
     404                        global $_wp_theme_features;
     405                        $theme_features = array();
     406                        foreach ( $_wp_theme_features AS $feature => $options ) {
     407                                $theme_features[] = $feature;
     408                        }
     409
     410                        $active_theme                      = wp_get_theme();
     411                        $info['wp-active-theme']['fields'] = array(
     412                                array(
     413                                        'label' => __( 'Name' ),
     414                                        'value' => $active_theme->Name
     415                                ),
     416                                array(
     417                                        'label' => __( 'Version' ),
     418                                        'value' => $active_theme->Version
     419                                ),
     420                                array(
     421                                        'label' => __( 'Author' ),
     422                                        'value' => wp_kses( $active_theme->Author, array() )
     423                                ),
     424                                array(
     425                                        'label' => __( 'Author website' ),
     426                                        'value' => ( $active_theme->offsetGet( 'Author URI' ) ?: __( 'Undefined' ) )
     427                                ),
     428                                array(
     429                                        'label' => __( 'Parent theme' ),
     430                                        'value' => ( $active_theme->parent_theme ?: __( 'Not a child theme' ) )
     431                                ),
     432                                array(
     433                                        'label' => __( 'Supported theme features' ),
     434                                        'value' => implode( ', ', $theme_features )
     435                                )
     436                        );
     437
     438                        // Populate a list of all themes available in the install.
     439                        $all_themes = wp_get_themes();
     440
     441                        foreach ( $all_themes AS $theme_slug => $theme ) {
     442                                // Ignore the currently active theme from the list of all themes.
     443                                if ( $active_theme->stylesheet == $theme_slug ) {
     444                                        continue;
     445                                }
     446
     447                                $info['wp-themes']['fields'][] = array(
     448                                        // translators: %1$s: Theme name. %2$s: Theme slug.
     449                                        'label' => sprintf( __( '%1$s (%2$s)' ), $theme->Name, $theme_slug ),
     450                                        // translators: %1$s Theme version number. %2$s: Theme author name.
     451                                        'value' => sprintf( __( 'version %1$s by %2$s ' ), $theme->Version, wp_kses( $theme->Author, array() ) )
     452                                );
     453                        }
     454
     455
     456                        /**
     457                         * Add or modify new debug sections.
     458                         *
     459                         * Plugin or themes may wish to introduce their own debug information without creating additional admin pages for this
     460                         * kind of information as it is rarely needed, they can then utilize this filter to introduce their own sections.
     461                         *
     462                         * This filter intentionally does not include the fields introduced by core as those should always be un-modified
     463                         * and reliable for support related scenarios, take note that the core fields will take priority if a filtered value
     464                         * is trying to use the same array keys.
     465                         *
     466                         * Array keys added by core are all prefixed with `wp-`, plugins and themes are encouraged to use their own slug as
     467                         * a prefix, both for consistency as well as avoiding key collisions.
     468                         *
     469                         * @since 4.9.0
     470                         *
     471                         * @param array $args {
     472                         *     The debug information to be added to the core information page.
     473                         *
     474                         *     @type string  $label        The title for this section of the debug output.
     475                         *     @type string  $description  Optional. A description for your information section which may contain basic HTML
     476                         *                                 markup: `em`, `strong` and `a` for linking to documentation or putting emphasis.
     477                         *     @type boolean $show_count   Optional. If set to `true` the amount of fields will be included in the title for
     478                         *                                 this section.
     479                         *     @type boolean $private      Optional. If set to `true` the section and all associated fields will be excluded
     480                         *                                 from the copy-paste text area.
     481                         *     @type array   $fields {
     482                         *         An associative array containing the data to be displayed.
     483                         *
     484                         *         @type string  $label    The label for this piece of information.
     485                         *         @type string  $value    The output that is of interest for this field.
     486                         *         @type boolean $private  Optional. If set to `true` the field will not be included in the copy-paste text area
     487                         *                                 on top of the page, allowing you to show, for example, API keys here.
     488                         *     }
     489                         * }
     490                         */
     491                        $external_info = apply_filters( 'debug_information', array() );
     492
     493                        // Merge the core and external debug fields.
     494                        $info = array_replace_recursive( $info, array_replace_recursive( $external_info, $info ) );
     495                        ?>
     496
     497
     498                        <div class="notice notice-info">
     499                                <p>
     500                                        <?php esc_html_e( 'The system information shown below can also be copied and pasted into support requests such as on the WordPress.org forums, or to your theme and plugin developers.' ); ?>
     501                                </p>
     502                                <p>
     503                                        <button type="button" class="button button-primary" onclick="document.getElementById('system-information-copy-wrapper').style.display = 'block'; this.style.display = 'none';"><?php esc_html_e( 'Show copy and paste field' ); ?></button>
     504                                </p>
     505
     506                                <div id="system-information-copy-wrapper" style="display: none;">
     507                                <textarea id="system-information-copy-field" class="widefat" rows="10">`
     508<?php
     509                                        foreach ( $info AS $section => $details ) {
     510                                                // Skip this section if there are no fields, or the section has been declared as private.
     511                                                if ( empty( $details['fields'] ) || ( isset( $details['private'] ) && $details['private'] ) ) {
     512                                                        continue;
     513                                                }
     514
     515                                                printf(
     516                                                        "### %s%s ###\n\n",
     517                                                        $details['label'],
     518                                                        ( isset( $details['show_count'] ) && $details['show_count'] ? sprintf( ' (%d)', count( $details['fields'] ) ) : '' )
     519                                                );
     520
     521                                                foreach ( $details['fields'] AS $field ) {
     522                                                        if ( isset( $field['private'] ) && true === $field['private'] ) {
     523                                                                continue;
     524                                                        }
     525
     526                                                        printf(
     527                                                                "%s: %s\n",
     528                                                                $field['label'],
     529                                                                $field['value']
     530                                                        );
     531                                                }
     532                                                echo "\n";
     533                                        }
     534?>
     535`</textarea>
     536                                        <p>
     537                                                <?php esc_html_e( 'Some information may be filtered out from the list you are about to copy, this is information that may be considers private, and is not meant to be shared in a public forum.' ); ?>
     538                                                <br>
     539                                                <button type="button" class="button button-primary" onclick="document.getElementById('system-information-copy-field').select();"><?php esc_html_e( 'Mark field for copying' ); ?></button>
     540                                        </p>
     541                                </div>
     542                        </div>
     543
     544                        <div id="system-information-table-of-contents">
     545                                <?php
     546                                $toc = array();
     547
     548                                foreach ( $info AS $section => $details ) {
     549                                        if ( empty( $details['fields'] ) ) {
     550                                                continue;
     551                                        }
     552
     553                                        $toc[] = sprintf(
     554                                                '<a href="#%s">%s</a>',
     555                                                esc_attr( $section ),
     556                                                esc_html( $details['label'] )
     557                                        );
     558                                }
     559
     560                                echo implode( ' | ', $toc );
     561                                ?>
     562                        </div>
     563
     564                        <?php
     565                        foreach ( $info AS $section => $details ) {
     566                                if ( ! isset( $details['fields'] ) || empty( $details['fields'] ) ) {
     567                                        continue;
     568                                }
     569
     570                                printf(
     571                                        '<h2 id="%s">%s%s</h2>',
     572                                        esc_attr( $section ),
     573                                        esc_html( $details['label'] ),
     574                                        ( isset( $details['show_count'] ) && $details['show_count'] ? sprintf( ' (%d)', count( $details['fields'] ) ) : '' )
     575                                );
     576
     577                                if ( isset( $details['description'] ) && ! empty( $details['description'] ) ) {
     578                                        printf(
     579                                                '<p>%s</p>',
     580                                                wp_kses( $details['description'], array(
     581                                                        'a'      => array(
     582                                                                'href' => true
     583                                                        ),
     584                                                        'strong' => true,
     585                                                        'em'     => true,
     586                                                ) )
     587                                        );
     588                                }
     589                                ?>
     590                                <table class="widefat striped">
     591                                        <tbody>
     592                                        <?php
     593                                        foreach ( $details['fields'] AS $field ) {
     594                                                printf(
     595                                                        '<tr><td>%s</td><td>%s</td></tr>',
     596                                                        esc_html( $field['label'] ),
     597                                                        esc_html( $field['value'] )
     598                                                );
     599                                        }
     600                                        ?>
     601                                        </tbody>
     602                                </table>
     603                                <span style="display: block; width: 100%; text-align: <?php echo ( is_rtl() ? 'left' : 'right' ); ?>">
     604                                        <a href="#system-information-table-of-contents"><?php esc_html_e( 'Return to table of contents' ); ?></a>
     605                                </span>
     606                                <?php
     607                        }
     608                } else {
     609                        ?>
     610
     611                        <div class="notice notice-warning">
     612                                <p>
     613                                        <?php esc_html_e( 'Some scenarios require you to look up more detailed server configurations than what is normally required. This page allows you to view all available configuration options for your PHP setup. Please be advised that WordPress does not guarantee that any information shown on this page may not be considered private.' ); ?>
     614                                </p>
     615                        </div>
     616
     617                        <?php
     618                        ob_start();
     619                        phpinfo();
     620                        $phpinfo_raw = ob_get_clean();
     621
     622                        // Extract the body of the `phpinfo()` call, to avoid all the styles they introduce.
     623                        preg_match_all("/<body[^>]*>(.*)<\/body>/siU", $phpinfo_raw, $phpinfo );
     624
     625                        // Extract the styles `phpinfo()` creates for this page.
     626                        preg_match_all( "/<style[^>]*>(.*)<\/style>/siU", $phpinfo_raw, $styles );
     627
     628                        // We remove various styles that break the visual flow of wp-admin.
     629                        $remove_patterns = array(
     630                                "/a:.+?\n/si",
     631                                "/body.+?\n/si"
     632                        );
     633                        $styles = preg_replace( $remove_patterns, "", $styles[1][0] );
     634
     635                        // Output the styles as an inline style block.
     636                        echo '<style type="text/css">' . $styles . '</style>';
     637
     638                        // Output the actual phpinfo data.
     639                        echo $phpinfo[1][0];
     640                        ?>
     641
     642                <?php } ?>
     643        </div>
     644
     645<?php
     646include( ABSPATH . 'wp-admin/admin-footer.php' );