Make WordPress Core

Ticket #39165: 39165.13.diff

File 39165.13.diff, 33.5 KB (added by birgire, 7 years ago)
  • src/wp-admin/admin-footer.php

    diff --git src/wp-admin/admin-footer.php src/wp-admin/admin-footer.php
    index 6014d17..bc42ba1 100644
    global $hook_suffix; 
    4343                echo apply_filters( 'admin_footer_text', '<span id="footer-thankyou">' . $text . '</span>' );
    4444                ?>
    4545        </p>
     46    <p id="footer-debug" class="alignright">
     47                <?php
     48                printf(
     49                        '<a href="%s">%s</a>',
     50                        esc_url( admin_url( 'info.php' ) ),
     51                        __( 'Show debug info' )
     52                )
     53                ?>
     54    </p>
    4655        <p id="footer-upgrade" class="alignright">
    4756                <?php
    4857                /**
  • new file src/wp-admin/css/debug.css

    diff --git src/wp-admin/css/debug.css src/wp-admin/css/debug.css
    new file mode 100644
    index 0000000..4832316
    - +  
     1body.info-php tbody td {
     2    width: 80%;
     3}
     4
     5body.info-php tbody td ul,
     6body.info-php tbody td ol {
     7    margin: 0;
     8}
     9
     10body.info-php thead th:first-child,
     11body.info-php tbody td:first-child {
     12    width: 20%;
     13}
     14
     15#wpfooter #footer-debug {
     16    margin-left: 10px;
     17}
  • new file src/wp-admin/info.php

    diff --git src/wp-admin/info.php src/wp-admin/info.php
    new file mode 100644
    index 0000000..6d70a4b
    - +  
     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                        global $wpdb;
     42
     43                        $upload_dir = wp_upload_dir();
     44                        if ( file_exists( ABSPATH . 'wp-config.php' ) ) {
     45                                $wp_config_path = ABSPATH . 'wp-config.php';
     46                        } elseif ( file_exists( dirname( ABSPATH ) . '/wp-config.php' ) && ! file_exists( dirname( ABSPATH ) . '/wp-settings.php' ) ) {
     47                                $wp_config_path = dirname( ABSPATH ) . '/wp-config.php';
     48                        }
     49
     50                        $info = array(
     51                                'wp-core'             => array(
     52                                        'label'  => __( 'WordPress' ),
     53                                        'fields' => array(
     54                                                array(
     55                                                        'label' => __( 'Version' ),
     56                                                        'value' => get_bloginfo( 'version' ),
     57                                                ),
     58                                                array(
     59                                                        'label' => __( 'Site Language' ),
     60                                                        'value' => get_locale(),
     61                                                ),
     62                                                array(
     63                                                        'label'   => __( 'Home URL' ),
     64                                                        'value'   => get_bloginfo( 'url' ),
     65                                                        'private' => true,
     66                                                ),
     67                                                array(
     68                                                        'label'   => __( 'Site URL' ),
     69                                                        'value'   => get_bloginfo( 'wpurl' ),
     70                                                        'private' => true,
     71                                                ),
     72                                                array(
     73                                                        'label' => __( 'Permalink structure' ),
     74                                                        'value' => get_option( 'permalink_structure' ),
     75                                                ),
     76                                                array(
     77                                                        'label' => __( 'Is this site using HTTPS?' ),
     78                                                        'value' => ( is_ssl() ? __( 'Yes' ) : __( 'No' ) ),
     79                                                ),
     80                                                array(
     81                                                        'label' => __( 'Can anyone register on this site?' ),
     82                                                        'value' => ( get_option( 'users_can_register' ) ? __( 'Yes' ) : __( 'No' ) ),
     83                                                ),
     84                                                array(
     85                                                        'label' => __( 'Default comment status' ),
     86                                                        'value' => get_option( 'default_comment_status' ),
     87                                                ),
     88                                                array(
     89                                                        'label' => __( 'Is this a multisite?' ),
     90                                                        'value' => ( is_multisite() ? __( 'Yes' ) : __( 'No' ) ),
     91                                                ),
     92                                        ),
     93                                ),
     94                                'wp-dropins'          => array(
     95                                        'label'       => __( 'Drop-ins' ),
     96                                        'description' => __( 'Drop-ins are single files that replace or enhance WordPress features in ways that are not possible for traditional plugins' ),
     97                                        'fields'      => array(),
     98                                ),
     99                                'wp-active-theme'     => array(
     100                                        'label'  => __( 'Active Theme' ),
     101                                        'fields' => array(),
     102                                ),
     103                                'wp-themes'           => array(
     104                                        'label'      => __( 'Other themes' ),
     105                                        'show_count' => true,
     106                                        'fields'     => array(),
     107                                ),
     108                                'wp-mu-plugins'       => array(
     109                                        'label'      => __( 'Must Use Plugins' ),
     110                                        'show_count' => true,
     111                                        'fields'     => array(),
     112                                ),
     113                                'wp-plugins-active'   => array(
     114                                        'label'      => __( 'Active Plugins' ),
     115                                        'show_count' => true,
     116                                        'fields'     => array(),
     117                                ),
     118                                'wp-plugins-inactive' => array(
     119                                        'label'      => __( 'Inactive Plugins' ),
     120                                        'show_count' => true,
     121                                        'fields'     => array(),
     122                                ),
     123                                'wp-media'            => array(
     124                                        'label'  => __( 'Media handling' ),
     125                                        'fields' => array(),
     126                                ),
     127                                'wp-server'           => array(
     128                                        'label'       => __( 'Server' ),
     129                                        'description' => __( 'The options shown below relate to your server setup. If changes are required, you may need your web host\'s assistance.' ),
     130                                        'fields'      => array(),
     131                                ),
     132                                'wp-database'         => array(
     133                                        'label'  => __( 'Database' ),
     134                                        'fields' => array(),
     135                                ),
     136                                'wp-constants'        => array(
     137                                        'label'       => __( 'WordPress constants' ),
     138                                        '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.' ),
     139                                        'fields'      => array(
     140                                                array(
     141                                                        'label' => 'ABSPATH',
     142                                                        'value' => ( ! defined( 'ABSPATH' ) ? __( 'Undefined' ) : ABSPATH ),
     143                                                ),
     144                                                array(
     145                                                        'label' => 'WP_HOME',
     146                                                        'value' => ( ! defined( 'WP_HOME' ) ? __( 'Undefined' ) : WP_HOME ),
     147                                                ),
     148                                                array(
     149                                                        'label' => 'WP_SITEURL',
     150                                                        'value' => ( ! defined( 'WP_SITEURL' ) ? __( 'Undefined' ) : WP_SITEURL ),
     151                                                ),
     152                                                array(
     153                                                        'label' => 'WP_DEBUG',
     154                                                        'value' => ( ! defined( 'WP_DEBUG' ) ? __( 'Undefined' ) : ( WP_DEBUG ? __( 'Enabled' ) : __( 'Disabled' ) ) ),
     155                                                ),
     156                                                array(
     157                                                        'label' => 'WP_MAX_MEMORY_LIMIT',
     158                                                        'value' => ( ! defined( 'WP_MAX_MEMORY_LIMIT' ) ? __( 'Undefined' ) : WP_MAX_MEMORY_LIMIT ),
     159                                                ),
     160                                                array(
     161                                                        'label' => 'WP_DEBUG_DISPLAY',
     162                                                        'value' => ( ! defined( 'WP_DEBUG_DISPLAY' ) ? __( 'Undefined' ) : ( WP_DEBUG_DISPLAY ? __( 'Enabled' ) : __( 'Disabled' ) ) ),
     163                                                ),
     164                                                array(
     165                                                        'label' => 'WP_DEBUG_LOG',
     166                                                        'value' => ( ! defined( 'WP_DEBUG_LOG' ) ? __( 'Undefined' ) : ( WP_DEBUG_LOG ? __( 'Enabled' ) : __( 'Disabled' ) ) ),
     167                                                ),
     168                                                array(
     169                                                        'label' => 'SCRIPT_DEBUG',
     170                                                        'value' => ( ! defined( 'SCRIPT_DEBUG' ) ? __( 'Undefined' ) : ( SCRIPT_DEBUG ? __( 'Enabled' ) : __( 'Disabled' ) ) ),
     171                                                ),
     172                                                array(
     173                                                        'label' => 'WP_CACHE',
     174                                                        'value' => ( ! defined( 'WP_CACHE' ) ? __( 'Undefined' ) : ( WP_CACHE ? __( 'Enabled' ) : __( 'Disabled' ) ) ),
     175                                                ),
     176                                                array(
     177                                                        'label' => 'CONCATENATE_SCRIPTS',
     178                                                        'value' => ( ! defined( 'CONCATENATE_SCRIPTS' ) ? __( 'Undefined' ) : ( CONCATENATE_SCRIPTS ? __( 'Enabled' ) : __( 'Disabled' ) ) ),
     179                                                ),
     180                                                array(
     181                                                        'label' => 'COMPRESS_SCRIPTS',
     182                                                        'value' => ( ! defined( 'COMPRESS_SCRIPTS' ) ? __( 'Undefined' ) : ( COMPRESS_SCRIPTS ? __( 'Enabled' ) : __( 'Disabled' ) ) ),
     183                                                ),
     184                                                array(
     185                                                        'label' => 'COMPRESS_CSS',
     186                                                        'value' => ( ! defined( 'COMPRESS_CSS' ) ? __( 'Undefined' ) : ( COMPRESS_CSS ? __( 'Enabled' ) : __( 'Disabled' ) ) ),
     187                                                ),
     188                                                array(
     189                                                        'label' => 'WP_LOCAL_DEV',
     190                                                        'value' => ( ! defined( 'WP_LOCAL_DEV' ) ? __( 'Undefined' ) : ( WP_LOCAL_DEV ? __( 'Enabled' ) : __( 'Disabled' ) ) ),
     191                                                ),
     192                                        ),
     193                                ),
     194                                'wp-filesystem'       => array(
     195                                        'label'       => __( 'Filesystem permissions' ),
     196                                        'description' => __( 'The status of various locations WordPress needs to write files in various scenarios.' ),
     197                                        'fields'      => array(
     198                                                array(
     199                                                        'label' => __( 'The main WordPress directory' ),
     200                                                        'value' => ( wp_is_writable( ABSPATH ) ? __( 'Writable' ) : __( 'Not writable' ) ),
     201                                                ),
     202                                                array(
     203                                                        'label' => __( 'The wp-content directory' ),
     204                                                        'value' => ( wp_is_writable( WP_CONTENT_DIR ) ? __( 'Writable' ) : __( 'Not writable' ) ),
     205                                                ),
     206                                                array(
     207                                                        'label' => __( 'The uploads directory' ),
     208                                                        'value' => ( wp_is_writable( $upload_dir['basedir'] ) ? __( 'Writable' ) : __( 'Not writable' ) ),
     209                                                ),
     210                                                array(
     211                                                        'label' => __( 'The plugins directory' ),
     212                                                        'value' => ( wp_is_writable( WP_PLUGIN_DIR ) ? __( 'Writable' ) : __( 'Not writable' ) ),
     213                                                ),
     214                                                array(
     215                                                        'label' => __( 'The themes directory' ),
     216                                                        'value' => ( wp_is_writable( get_template_directory() . '/..' ) ? __( 'Writable' ) : __( 'Not writable' ) ),
     217                                                ),
     218                                        ),
     219                                ),
     220                        );
     221
     222                        if ( is_multisite() ) {
     223                                $network_query = new WP_Network_Query();
     224                                $network_ids   = $network_query->query( array(
     225                                        'fields'        => 'ids',
     226                                        'number'        => 100,
     227                                        'no_found_rows' => false,
     228                                ) );
     229
     230                                $site_count = 0;
     231                                foreach ( $network_ids as $network_id ) {
     232                                        $site_count += get_blog_count( $network_id );
     233                                }
     234
     235                                $info['wp-core']['fields'][] = array(
     236                                        'label' => __( 'User Count' ),
     237                                        'value' => get_user_count(),
     238                                );
     239                                $info['wp-core']['fields'][] = array(
     240                                        'label' => __( 'Site Count' ),
     241                                        'value' => $site_count,
     242                                );
     243                                $info['wp-core']['fields'][] = array(
     244                                        'label' => __( 'Network Count' ),
     245                                        'value' => $network_query->found_networks,
     246                                );
     247                        } else {
     248                                $user_count = count_users();
     249
     250                                $info['wp-core']['fields'][] = array(
     251                                        'label' => __( 'User Count' ),
     252                                        'value' => $user_count['total_users'],
     253                                );
     254                        }
     255
     256                        // WordPress features requiring processing.
     257                        $wp_dotorg = wp_remote_get( 'https://wordpress.org', array( 'timeout' => 10 ) );
     258                        if ( ! is_wp_error( $wp_dotorg ) ) {
     259                                $info['wp-core']['fields'][] = array(
     260                                        'label' => __( 'Communication with WordPress.org' ),
     261                                        'value' => sprintf(
     262                                                __( 'WordPress.org is reachable' )
     263                                        ),
     264                                );
     265                        } else {
     266                                $info['wp-core']['fields'][] = array(
     267                                        'label' => __( 'Communication with WordPress.org' ),
     268                                        'value' => sprintf(
     269                                                // translators: %1$s: The IP address WordPress.org resolves to. %2$s: The error returned by the lookup.
     270                                                __( 'Unable to reach WordPress.org at %1$s: %2$s' ),
     271                                                gethostbyname( 'wordpress.org' ),
     272                                                $wp_dotorg->get_error_message()
     273                                        ),
     274                                );
     275                        }
     276
     277                        // Get drop-ins.
     278                        $dropins            = get_dropins();
     279                        $dropin_description = _get_dropins();
     280                        foreach ( $dropins as $dropin_key => $dropin ) {
     281                                $info['wp-dropins']['fields'][] = array(
     282                                        'label' => $dropin_key,
     283                                        'value' => $dropin_description[ $dropin_key ][0],
     284                                );
     285                        }
     286
     287                        // Populate the media fields.
     288                        $info['wp-media']['fields'][] = array(
     289                                'label' => __( 'Active editor' ),
     290                                'value' => _wp_image_editor_choose(),
     291                        );
     292
     293                        // Get ImageMagic information, if available.
     294                        if ( class_exists( 'Imagick' ) ) {
     295                                // Save the Imagick instance for later use.
     296                                $imagick         = new Imagick();
     297                                $imagick_version = $imagick->getVersion();
     298                        } else {
     299                                $imagick_version = 'Imagick not available';
     300                        }
     301                        $info['wp-media']['fields'][] = array(
     302                                'label' => __( 'Imagick Module Version' ),
     303                                'value' => ( is_array( $imagick_version ) ? $imagick_version['versionNumber'] : $imagick_version ),
     304                        );
     305                        $info['wp-media']['fields'][] = array(
     306                                'label' => __( 'ImageMagick Version' ),
     307                                'value' => ( is_array( $imagick_version ) ? $imagick_version['versionString'] : $imagick_version ),
     308                        );
     309
     310                        // If Imagick is used as our editor, provide some more information about its limitations.
     311                        if ( 'WP_Image_Editor_Imagick' === _wp_image_editor_choose() && isset( $imagick ) && $imagick instanceof Imagick ) {
     312                                $limits = array(
     313                                        array(
     314                                                'label' => __( 'Area' ),
     315                                                'value' => defined( 'imagick::RESOURCETYPE_AREA' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_AREA ) ) : __( 'Not Available' ),
     316                                        ),
     317                                        array(
     318                                                'label' => __( 'Disk' ),
     319                                                'value' => defined( 'imagick::RESOURCETYPE_DISK' ) ? $imagick->getResourceLimit( imagick::RESOURCETYPE_DISK ) : __( 'Not Available' ),
     320                                        ),
     321                                        array(
     322                                                'label' => __( 'File' ),
     323                                                'value' => defined( 'imagick::RESOURCETYPE_FILE' ) ? $imagick->getResourceLimit( imagick::RESOURCETYPE_FILE ) : __( 'Not Available' ),
     324                                        ),
     325                                        array(
     326                                                'label' => __( 'Map' ),
     327                                                'value' => defined( 'imagick::RESOURCETYPE_MAP' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_MAP ) ) : __( 'Not Available' ),
     328                                        ),
     329                                        array(
     330                                                'label' => __( 'Memory' ),
     331                                                'value' => defined( 'imagick::RESOURCETYPE_MEMORY' ) ? size_format( $imagick->getResourceLimit( imagick::RESOURCETYPE_MEMORY ) ) : __( 'Not Available' ),
     332                                        ),
     333                                        array(
     334                                                'label' => __( 'Thread' ),
     335                                                'value' => defined( 'imagick::RESOURCETYPE_THREAD' ) ? $imagick->getResourceLimit( imagick::RESOURCETYPE_THREAD ) : __( 'Not Available' ),
     336                                        ),
     337                                );
     338
     339                                $info['wp-media']['fields'][] = array(
     340                                        'label' => __( 'Imagick Resource Limits' ),
     341                                        'value' => $limits,
     342                                );
     343                        }
     344
     345                        // Get GD information, if available.
     346                        if ( function_exists( 'gd_info' ) ) {
     347                                $gd = gd_info();
     348                        } else {
     349                                $gd = false;
     350                        }
     351                        $info['wp-media']['fields'][] = array(
     352                                'label' => __( 'GD Version' ),
     353                                'value' => ( is_array( $gd ) ? $gd['GD Version'] : 'GD not available' ),
     354                        );
     355
     356                        // Get Ghostscript information, if available.
     357                        if ( function_exists( 'exec' ) ) {
     358                                $gs = exec( 'gs --version' );
     359                                $gs = ( ! empty( $gs ) ? $gs : 'Not available' );
     360                        } else {
     361                                $gs = __( 'Unable to determine if Ghostscript is installed' );
     362                        }
     363                        $info['wp-media']['fields'][] = array(
     364                                'label' => __( 'Ghostscript Version' ),
     365                                'value' => $gs,
     366                        );
     367
     368                        // Populate the server debug fields.
     369                        $info['wp-server']['fields'][] = array(
     370                                'label' => __( 'Server architecture' ),
     371                                'value' => ( ! function_exists( 'php_uname' ) ? __( 'Unable to determine server architecture' ) : sprintf( '%s %s %s', php_uname( 's' ), php_uname( 'r' ), php_uname( 'm' ) ) ),
     372                        );
     373                        $info['wp-server']['fields'][] = array(
     374                                'label' => __( 'PHP Version' ),
     375                                'value' => ( ! function_exists( 'phpversion' ) ? __( 'Unable to determine PHP version' ) : sprintf(
     376                                        '%s %s',
     377                                        phpversion(),
     378                                        ( 64 === PHP_INT_SIZE * 8 ? __( '(Supports 64bit values)' ) : '' )
     379                                )
     380                                ),
     381                        );
     382                        $info['wp-server']['fields'][] = array(
     383                                'label' => __( 'PHP SAPI' ),
     384                                'value' => ( ! function_exists( 'php_sapi_name' ) ? __( 'Unable to determine PHP SAPI' ) : php_sapi_name() ),
     385                        );
     386
     387                        if ( ! function_exists( 'ini_get' ) ) {
     388                                $info['wp-server']['fields'][] = array(
     389                                        'label' => __( 'Server settings' ),
     390                                        'value' => __( 'Unable to determine some settings as the ini_get() function has been disabled' ),
     391                                );
     392                        } else {
     393                                $info['wp-server']['fields'][] = array(
     394                                        'label' => __( 'PHP max input variables' ),
     395                                        'value' => ini_get( 'max_input_vars' ),
     396                                );
     397                                $info['wp-server']['fields'][] = array(
     398                                        'label' => __( 'PHP time limit' ),
     399                                        'value' => ini_get( 'max_execution_time' ),
     400                                );
     401                                $info['wp-server']['fields'][] = array(
     402                                        'label' => __( 'PHP memory limit' ),
     403                                        'value' => ini_get( 'memory_limit' ),
     404                                );
     405                                $info['wp-server']['fields'][] = array(
     406                                        'label' => __( 'Max input time' ),
     407                                        'value' => ini_get( 'max_input_time' ),
     408                                );
     409                                $info['wp-server']['fields'][] = array(
     410                                        'label' => __( 'Upload max filesize' ),
     411                                        'value' => ini_get( 'upload_max_filesize' ),
     412                                );
     413                                $info['wp-server']['fields'][] = array(
     414                                        'label' => __( 'PHP post max size' ),
     415                                        'value' => ini_get( 'post_max_size' ),
     416                                );
     417                        }
     418
     419                        if ( function_exists( 'curl_version' ) ) {
     420                                $curl                          = curl_version();
     421                                $info['wp-server']['fields'][] = array(
     422                                        'label' => __( 'cURL Version' ),
     423                                        'value' => sprintf( '%s %s', $curl['version'], $curl['ssl_version'] ),
     424                                );
     425                        } else {
     426                                $info['wp-server']['fields'][] = array(
     427                                        'label' => __( 'cURL Version' ),
     428                                        'value' => __( 'Your server does not support cURL' ),
     429                                );
     430                        }
     431
     432                        $info['wp-server']['fields'][] = array(
     433                                'label' => __( 'SUHOSIN installed' ),
     434                                'value' => ( ( extension_loaded( 'suhosin' ) || ( defined( 'SUHOSIN_PATCH' ) && constant( 'SUHOSIN_PATCH' ) ) ) ? __( 'Yes' ) : __( 'No' ) ),
     435                        );
     436
     437                        $info['wp-server']['fields'][] = array(
     438                                'label' => __( 'Is the Imagick library available' ),
     439                                'value' => ( extension_loaded( 'imagick' ) ? __( 'Yes' ) : __( 'No' ) ),
     440                        );
     441
     442                        // Populate the database debug fields.
     443                        if ( is_resource( $wpdb->dbh ) ) {
     444                                // Old mysql extension.
     445                                $extension = 'mysql';
     446                        } elseif ( is_object( $wpdb->dbh ) ) {
     447                                // mysqli or PDO.
     448                                $extension = get_class( $wpdb->dbh );
     449                        } else {
     450                                // Unknown sql extension.
     451                                $extension = null;
     452                        }
     453
     454                        if ( method_exists( $wpdb, 'db_version' ) ) {
     455                                if ( $wpdb->use_mysqli ) {
     456                                        $server = mysqli_get_server_info( $wpdb->dbh );
     457                                } else {
     458                                        $server = mysql_get_server_info( $wpdb->dbh );
     459                                }
     460                        } else {
     461                                $server = null;
     462                        }
     463
     464                        if ( isset( $wpdb->use_mysqli ) && $wpdb->use_mysqli ) {
     465                                $client_version = $wpdb->dbh->client_info;
     466                        } else {
     467                                if ( preg_match( '|[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}|', mysql_get_client_info(), $matches ) ) {
     468                                        $client_version = $matches[0];
     469                                } else {
     470                                        $client_version = null;
     471                                }
     472                        }
     473
     474                        $info['wp-database']['fields'][] = array(
     475                                'label' => __( 'Extension' ),
     476                                'value' => $extension,
     477                        );
     478                        $info['wp-database']['fields'][] = array(
     479                                'label' => __( 'Server version' ),
     480                                'value' => $server,
     481                        );
     482                        $info['wp-database']['fields'][] = array(
     483                                'label' => __( 'Client version' ),
     484                                'value' => $client_version,
     485                        );
     486                        $info['wp-database']['fields'][] = array(
     487                                'label'   => __( 'Database user' ),
     488                                'value'   => $wpdb->dbuser,
     489                                'private' => true,
     490                        );
     491                        $info['wp-database']['fields'][] = array(
     492                                'label'   => __( 'Database host' ),
     493                                'value'   => $wpdb->dbhost,
     494                                'private' => true,
     495                        );
     496                        $info['wp-database']['fields'][] = array(
     497                                'label'   => __( 'Database name' ),
     498                                'value'   => $wpdb->dbname,
     499                                'private' => true,
     500                        );
     501                        $info['wp-database']['fields'][] = array(
     502                                'label' => __( 'Database prefix' ),
     503                                'value' => $wpdb->prefix,
     504                        );
     505
     506
     507                        // List must use plugins if there are any.
     508                        $mu_plugins = get_mu_plugins();
     509
     510                        foreach ( $mu_plugins as $plugin_path => $plugin ) {
     511                                $plugin_version = $plugin['Version'];
     512                                $plugin_author  = $plugin['Author'];
     513
     514                                $plugin_version_string = __( 'No version or author information available' );
     515
     516                                if ( ! empty( $plugin_version ) && ! empty( $plugin_author ) ) {
     517                                        // translators: %1$s: Plugin version number. %2$s: Plugin author name.
     518                                        $plugin_version_string = sprintf( __( 'Version %1$s by %2$s' ), $plugin_version, $plugin_author );
     519                                }
     520                                if ( empty( $plugin_version ) && ! empty( $plugin_author ) ) {
     521                                        // translators: %s: Plugin author name.
     522                                        $plugin_version_string = sprintf( __( 'By %s' ), $plugin_author );
     523                                }
     524                                if ( ! empty( $plugin_version ) && empty( $plugin_author ) ) {
     525                                        // translators: %s: Plugin version number.
     526                                        $plugin_version_string = sprintf( __( 'Version %s' ), $plugin_version );
     527                                }
     528
     529                                $info['wp-mu-plugins']['fields'][] = array(
     530                                        'label' => $plugin['Name'],
     531                                        'value' => $plugin_version_string,
     532                                );
     533                        }
     534
     535                        // List all available plugins.
     536                        $plugins = get_plugins();
     537
     538                        foreach ( $plugins as $plugin_path => $plugin ) {
     539                                $plugin_part = ( is_plugin_active( $plugin_path ) ) ? 'wp-plugins-active' : 'wp-plugins-inactive';
     540
     541                                $plugin_version = $plugin['Version'];
     542                                $plugin_author  = $plugin['Author'];
     543
     544                                $plugin_version_string = __( 'No version or author information available' );
     545
     546                                if ( ! empty( $plugin_version ) && ! empty( $plugin_author ) ) {
     547                                        // translators: %1$s: Plugin version number. %2$s: Plugin author name.
     548                                        $plugin_version_string = sprintf( __( 'Version %1$s by %2$s' ), $plugin_version, $plugin_author );
     549                                }
     550                                if ( empty( $plugin_version ) && ! empty( $plugin_author ) ) {
     551                                        // translators: %s: Plugin author name.
     552                                        $plugin_version_string = sprintf( __( 'By %s' ), $plugin_author );
     553                                }
     554                                if ( ! empty( $plugin_version ) && empty( $plugin_author ) ) {
     555                                        // translators: %s: Plugin version number.
     556                                        $plugin_version_string = sprintf( __( 'Version %s' ), $plugin_version );
     557                                }
     558
     559                                $info[ $plugin_part ]['fields'][] = array(
     560                                        'label' => $plugin['Name'],
     561                                        'value' => $plugin_version_string,
     562                                );
     563                        }
     564
     565                        // Populate the section for the currently active theme.
     566                        global $_wp_theme_features;
     567                        $theme_features = array();
     568                        if ( ! empty( $_wp_theme_features ) ) {
     569                                foreach ( $_wp_theme_features as $feature => $options ) {
     570                                        $theme_features[] = $feature;
     571                                }
     572                        }
     573
     574                        $active_theme                      = wp_get_theme();
     575                        $info['wp-active-theme']['fields'] = array(
     576                                array(
     577                                        'label' => __( 'Name' ),
     578                                        'value' => $active_theme->Name,
     579                                ),
     580                                array(
     581                                        'label' => __( 'Version' ),
     582                                        'value' => $active_theme->Version,
     583                                ),
     584                                array(
     585                                        'label' => __( 'Author' ),
     586                                        'value' => wp_kses( $active_theme->Author, array() ),
     587                                ),
     588                                array(
     589                                        'label' => __( 'Author website' ),
     590                                        'value' => ( $active_theme->offsetGet( 'Author URI' ) ? $active_theme->offsetGet( 'Author URI' ) : __( 'Undefined' ) ),
     591                                ),
     592                                array(
     593                                        'label' => __( 'Parent theme' ),
     594                                        'value' => ( $active_theme->parent_theme ? $active_theme->parent_theme : __( 'Not a child theme' ) ),
     595                                ),
     596                                array(
     597                                        'label' => __( 'Supported theme features' ),
     598                                        'value' => implode( ', ', $theme_features ),
     599                                ),
     600                        );
     601
     602                        // Populate a list of all themes available in the install.
     603                        $all_themes = wp_get_themes();
     604
     605                        foreach ( $all_themes as $theme_slug => $theme ) {
     606                                // Ignore the currently active theme from the list of all themes.
     607                                if ( $active_theme->stylesheet === $theme_slug ) {
     608                                        continue;
     609                                }
     610
     611                                $theme_version = $theme->Version;
     612                                $theme_author  = $theme->Author;
     613
     614                                $theme_version_string = __( 'No version or author information available' );
     615
     616                                if ( ! empty( $theme_version ) && ! empty( $theme_author ) ) {
     617                                        // translators: %1$s: Theme version number. %2$s: Theme author name.
     618                                        $theme_version_string = sprintf( __( 'Version %1$s by %2$s' ), $theme_version, wp_kses( $theme_author, array() ) );
     619                                }
     620                                if ( empty( $theme_version ) && ! empty( $theme_author ) ) {
     621                                        // translators: %s: Theme author name.
     622                                        $theme_version_string = sprintf( __( 'By %s' ), wp_kses( $theme_author, array() ) );
     623                                }
     624                                if ( ! empty( $theme_version ) && empty( $theme_author ) ) {
     625                                        // translators: %s: Theme version number.
     626                                        $theme_version_string = sprintf( __( 'Version %s' ), $theme_version );
     627                                }
     628
     629
     630                                $info['wp-themes']['fields'][] = array(
     631                                        // translators: %1$s: Theme name. %2$s: Theme slug.
     632                                        'label' => sprintf( __( '%1$s (%2$s)' ), $theme->Name, $theme_slug ),
     633                                        'value' => $theme_version_string,
     634                                );
     635                        }
     636
     637                        // Add more filesystem checks.
     638                        if ( defined( 'WPMU_PLUGIN_DIR' ) && is_dir( WPMU_PLUGIN_DIR ) ) {
     639                                $info['wp-filesystem']['fields'][] = array(
     640                                        'label' => __( 'The Must Use Plugins directory' ),
     641                                        'value' => ( wp_is_writable( WPMU_PLUGIN_DIR ) ? __( 'Writable' ) : __( 'Not writable' ) ),
     642                                );
     643                        }
     644
     645                        /**
     646                         * Add or modify new debug sections.
     647                         *
     648                         * Plugin or themes may wish to introduce their own debug information without creating additional admin pages for this
     649                         * kind of information as it is rarely needed, they can then utilize this filter to introduce their own sections.
     650                         *
     651                         * This filter intentionally does not include the fields introduced by core as those should always be un-modified
     652                         * and reliable for support related scenarios, take note that the core fields will take priority if a filtered value
     653                         * is trying to use the same array keys.
     654                         *
     655                         * Array keys added by core are all prefixed with `wp-`, plugins and themes are encouraged to use their own slug as
     656                         * a prefix, both for consistency as well as avoiding key collisions.
     657                         *
     658                         * @since 5.0.0
     659                         *
     660                         * @param array $args {
     661                         *     The debug information to be added to the core information page.
     662                         *
     663                         *     @type string  $label        The title for this section of the debug output.
     664                         *     @type string  $description  Optional. A description for your information section which may contain basic HTML
     665                         *                                 markup: `em`, `strong` and `a` for linking to documentation or putting emphasis.
     666                         *     @type boolean $show_count   Optional. If set to `true` the amount of fields will be included in the title for
     667                         *                                 this section.
     668                         *     @type boolean $private      Optional. If set to `true` the section and all associated fields will be excluded
     669                         *                                 from the copy-paste text area.
     670                         *     @type array   $fields {
     671                         *         An associative array containing the data to be displayed.
     672                         *
     673                         *         @type string  $label    The label for this piece of information.
     674                         *         @type string  $value    The output that is of interest for this field.
     675                         *         @type boolean $private  Optional. If set to `true` the field will not be included in the copy-paste text area
     676                         *                                 on top of the page, allowing you to show, for example, API keys here.
     677                         *     }
     678                         * }
     679                         */
     680                        $external_info = apply_filters( 'debug_information', array() );
     681
     682                        // Merge the core and external debug fields.
     683                        $info = array_replace_recursive( $info, array_replace_recursive( $external_info, $info ) );
     684                        ?>
     685
     686                        <div class="notice notice-info">
     687                                <p>
     688                                        <?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.' ); ?>
     689                                </p>
     690                                <p>
     691                                        <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>
     692                                </p>
     693
     694                                <div id="system-information-copy-wrapper" style="display: none;">
     695                                        <textarea id="system-information-copy-field" class="widefat" rows="10">`
     696                                        <?php
     697                                        foreach ( $info as $section => $details ) {
     698                                                // Skip this section if there are no fields, or the section has been declared as private.
     699                                                if ( empty( $details['fields'] ) || ( isset( $details['private'] ) && $details['private'] ) ) {
     700                                                        continue;
     701                                                }
     702
     703                                                printf(
     704                                                        "### %s%s ###\n\n",
     705                                                        esc_html( $details['label'] ),
     706                                                        ( isset( $details['show_count'] ) && $details['show_count'] ? sprintf( ' (%d)', count( $details['fields'] ) ) : '' )
     707                                                );
     708
     709                                                foreach ( $details['fields'] as $field ) {
     710                                                        if ( isset( $field['private'] ) && true === $field['private'] ) {
     711                                                                continue;
     712                                                        }
     713
     714                                                        if ( is_array( $field['value'] ) ) {
     715                                                                $values = '';
     716                                                                foreach ( $field['value'] as $subfield ) {
     717                                                                        $values .= sprintf(
     718                                                                                "\n\t %s: %s",
     719                                                                                esc_html( $subfield['label'] ),
     720                                                                                esc_html( $subfield['value'] )
     721                                                                        );
     722                                                                }
     723                                                        } else {
     724                                                                $values = esc_html( $field['value'] );
     725                                                        }
     726
     727                                                        printf(
     728                                                                "%s: %s\n",
     729                                                                esc_html( $field['label'] ),
     730                                                                $values
     731                                                        );
     732                                                }
     733                                                echo "\n";
     734                                        }
     735                                        ?>
     736                                        </textarea>
     737                                        <p>
     738                                                <?php esc_html_e( 'Some information may be filtered out from the list you are about to copy, this is information that may be considered private, and is not meant to be shared in a public forum.' ); ?>
     739                                                <br>
     740                                                <button type="button" class="button button-primary" onclick="document.getElementById('system-information-copy-field').select(); document.execCommand( 'copy' );"><?php esc_html_e( 'Copy' ); ?></button>
     741                                        </p>
     742                                </div>
     743                        </div>
     744
     745                        <div id="system-information-table-of-contents">
     746                                <?php
     747                                $toc = array();
     748
     749                                foreach ( $info as $section => $details ) {
     750                                        if ( empty( $details['fields'] ) ) {
     751                                                continue;
     752                                        }
     753
     754                                        $toc[] = sprintf(
     755                                                '<a href="#%s" class="debug-toc">%s</a>',
     756                                                esc_attr( $section ),
     757                                                esc_html( $details['label'] )
     758                                        );
     759                                }
     760
     761                                echo implode( ' | ', $toc );
     762                                ?>
     763                        </div>
     764
     765                        <?php
     766                        foreach ( $info as $section => $details ) {
     767                                if ( ! isset( $details['fields'] ) || empty( $details['fields'] ) ) {
     768                                        continue;
     769                                }
     770
     771                                printf(
     772                                        '<h2 id="%s">%s%s</h2>',
     773                                        esc_attr( $section ),
     774                                        esc_html( $details['label'] ),
     775                                        ( isset( $details['show_count'] ) && $details['show_count'] ? sprintf( ' (%d)', count( $details['fields'] ) ) : '' )
     776                                );
     777
     778                                if ( isset( $details['description'] ) && ! empty( $details['description'] ) ) {
     779                                        printf(
     780                                                '<p>%s</p>',
     781                                                wp_kses( $details['description'], array(
     782                                                        'a'      => array(
     783                                                                'href' => true,
     784                                                        ),
     785                                                        'strong' => true,
     786                                                        'em'     => true,
     787                                                ) )
     788                                        );
     789                                }
     790                                ?>
     791                                <table class="widefat striped">
     792                                        <tbody>
     793                                        <?php
     794                                        foreach ( $details['fields'] as $field ) {
     795                                                if ( is_array( $field['value'] ) ) {
     796                                                        $values = '';
     797                                                        foreach ( $field['value'] as $item ) {
     798                                                                $values .= sprintf(
     799                                                                        '<li>%s: %s</li>',
     800                                                                        esc_html( $item['label'] ),
     801                                                                        esc_html( $item['value'] )
     802                                                                );
     803                                                        }
     804                                                } else {
     805                                                        $values = esc_html( $field['value'] );
     806                                                }
     807
     808                                                printf(
     809                                                        '<tr><td>%s</td><td>%s</td></tr>',
     810                                                        esc_html( $field['label'] ),
     811                                                        $values
     812                                                );
     813                                        }
     814                                        ?>
     815                                        </tbody>
     816                                </table>
     817                                <span style="display: block; width: 100%; text-align: <?php echo ( is_rtl() ? 'left' : 'right' ); ?>">
     818                                        <a href="#system-information-table-of-contents" class="debug-toc"><?php esc_html_e( 'Return to table of contents' ); ?></a>
     819                                </span>
     820                                <?php
     821                        }
     822                } else {
     823                        if ( ! function_exists( 'phpinfo' ) ) {
     824                        ?>
     825
     826                                <div class="notice notice-error">
     827                                        <p>
     828                                                <?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.' ); ?>
     829                                        </p>
     830                                </div>
     831
     832                        <?php } else { ?>
     833
     834                                <div class="notice notice-warning">
     835                                        <p>
     836                                                <?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.' ); ?>
     837                                        </p>
     838                                </div>
     839
     840                                <?php
     841                                ob_start();
     842                                phpinfo();
     843                                $phpinfo_raw = ob_get_clean();
     844
     845                                // Extract the body of the `phpinfo()` call, to avoid all the styles they introduce.
     846                                preg_match_all( '/<body[^>]*>(.*)<\/body>/siU', $phpinfo_raw, $phpinfo );
     847
     848                                // Extract the styles `phpinfo()` creates for this page.
     849                                preg_match_all( '/<style[^>]*>(.*)<\/style>/siU', $phpinfo_raw, $styles );
     850
     851                                // We remove various styles that break the visual flow of wp-admin.
     852                                $remove_patterns = array(
     853                                        "/a:.+?\n/si",
     854                                        "/body.+?\n/si",
     855                                );
     856
     857                                // Output the styles as an inline style block.
     858                                if ( isset( $styles[1][0] ) ) {
     859                                        $styles = preg_replace( $remove_patterns, '', $styles[1][0] );
     860                                        echo '<style type="text/css">' . $styles . '</style>';
     861                                }
     862
     863                                // Output the actual phpinfo data.
     864                                if ( isset( $phpinfo[1][0] ) ) {
     865                                        echo $phpinfo[1][0];
     866                                }
     867                                ?>
     868
     869                        <?php } ?>
     870
     871                <?php } ?>
     872        </div>
     873
     874<script type="text/javascript">
     875        jQuery(document).ready( function( $ ) {
     876                $(".debug-toc").click( function( e ) {
     877                        e.preventDefault();
     878                        // Remove the height of the admin bar, and an extra 10px for better positioning.           
     879                        var offset = $( $(this).attr('href') ).offset().top - $("#wpadminbar").height() - 10;
     880                        $('html, body').animate({
     881                                scrollTop: offset           
     882                        }, 1200);
     883                });
     884        });
     885</script>
     886
     887<?php
     888require ABSPATH . 'wp-admin/admin-footer.php';
  • src/wp-includes/script-loader.php

    diff --git src/wp-includes/script-loader.php src/wp-includes/script-loader.php
    index 6a1a7f2..a074b92 100644
    function wp_default_styles( &$styles ) { 
    10691069        $styles->add( 'site-icon', "/wp-admin/css/site-icon$suffix.css" );
    10701070        $styles->add( 'l10n', "/wp-admin/css/l10n$suffix.css" );
    10711071        $styles->add( 'code-editor', "/wp-admin/css/code-editor$suffix.css", array( 'wp-codemirror' ) );
     1072        $styles->add( 'debug', "/wp-admin/css/debug$suffix.css" );
    10721073
    1073         $styles->add( 'wp-admin', false, array( 'dashicons', 'common', 'forms', 'admin-menu', 'dashboard', 'list-tables', 'edit', 'revisions', 'media', 'themes', 'about', 'nav-menus', 'widgets', 'site-icon', 'l10n' ) );
     1074        $styles->add( 'wp-admin', false, array( 'dashicons', 'common', 'forms', 'admin-menu', 'dashboard', 'list-tables', 'edit', 'revisions', 'media', 'themes', 'about', 'nav-menus', 'widgets', 'site-icon', 'l10n', 'debug' ) );
    10741075
    10751076        $styles->add( 'login', "/wp-admin/css/login$suffix.css", array( 'dashicons', 'buttons', 'forms', 'l10n' ) );
    10761077        $styles->add( 'install', "/wp-admin/css/install$suffix.css", array( 'buttons' ) );