Make WordPress Core

Ticket #39165: 39165.8.patch

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