Make WordPress Core

Ticket #39165: 39165.15.diff

File 39165.15.diff, 35.2 KB (added by xkon, 7 years ago)

notice on core update also

  • src/wp-admin/admin-footer.php

     
    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                /**
  • src/wp-admin/css/debug.css

     
     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}
  • src/wp-admin/info.php

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

     
    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' ) );