Make WordPress Core

Ticket #39165: 39165.7.patch

File 39165.7.patch, 24.0 KB (added by michalzuber, 7 years ago)

Add Filesystem permissions section and additional WP constants ABSPATH, WP_HOME and WP_SITEURL

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