Make WordPress Core

Ticket #39165: 39165.4.patch

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

     
     1<?php
     2/**
     3 * Get system status for debugging and support.
     4 *
     5 * @package WordPress
     6 * @subpackage Administration
     7 */
     8
     9/** WordPress Administration Bootstrap */
     10require_once( dirname( __FILE__ ) . '/admin.php' );
     11
     12if ( ! current_user_can( 'update_core' ) ) {
     13        wp_die( __( 'Sorry, you do not have permission to access this page.' ) );
     14}
     15
     16global $wpdb;
     17
     18$title = __( 'System information' );
     19
     20require_once( ABSPATH . 'wp-admin/admin-header.php' );
     21
     22$info = array(
     23        'wp-core'             => array(
     24                'label'  => __( 'WordPress' ),
     25                'fields' => array(
     26                        array(
     27                                'label' => __( 'Version' ),
     28                                'value' => get_bloginfo( 'version' )
     29                        ),
     30                        array(
     31                                'label' => __( 'Language' ),
     32                                'value' => get_locale()
     33                        ),
     34                        array(
     35                                'label'   => __( 'Home URL' ),
     36                                'value'   => get_bloginfo( 'url' ),
     37                                'private' => true
     38                        ),
     39                        array(
     40                                'label'   => __( 'Site URL' ),
     41                                'value'   => get_bloginfo( 'wpurl' ),
     42                                'private' => true
     43                        ),
     44                        array(
     45                                'label' => __( 'Is this site using HTTPS' ),
     46                                'value' => ( is_ssl() ? __( 'Enabled' ) : __( 'Disabled' ) )
     47                        ),
     48                        array(
     49                                'label' => __( 'Is the theme directory writable' ),
     50                                'value' => ( wp_is_writable( TEMPLATEPATH . '/..' ) ? __( 'Yes' ) : __( 'No' ) )
     51                        ),
     52                        array(
     53                                'label' => __( 'Is the plugin directory writable' ),
     54                                'value' => ( wp_is_writable( WP_PLUGIN_DIR ) ? __( 'Yes' ) : __( 'No' ) )
     55                        ),
     56                        array(
     57                                'label' => __( 'WordPress memory limit' ),
     58                                'value' => WP_MAX_MEMORY_LIMIT
     59                        ),
     60                        array(
     61                                'label' => __( 'Is this a multisite' ),
     62                                'value' => ( is_multisite() ? __( 'Yes' ) : __( 'No' ) )
     63                        )
     64                ),
     65        ),
     66        'wp-active-theme'     => array(
     67                'label'  => __( 'Active theme' ),
     68                'fields' => array()
     69        ),
     70        'wp-themes'           => array(
     71                'label'      => __( 'Other themes' ),
     72                'show_count' => true,
     73                'fields'     => array()
     74        ),
     75        'wp-mu-plugins'       => array(
     76                'label'      => __( 'Must User Plugins' ),
     77                'show_count' => true,
     78                'fields'     => array()
     79        ),
     80        'wp-plugins-active'   => array(
     81                'label'      => __( 'Active Plugins' ),
     82                'show_count' => true,
     83                'fields'     => array()
     84        ),
     85        'wp-plugins-inactive' => array(
     86                'label'      => __( 'Inactive Plugins' ),
     87                'show_count' => true,
     88                'fields'     => array()
     89        ),
     90        'wp-server'           => array(
     91                'label'       => 'Server',
     92                'description' => __( 'The options shown below relate to your server setup. If changes are required, you may need your web host\'s assistance.' ),
     93                'fields'      => array()
     94        ),
     95        'wp-database'         => array(
     96                'label'  => __( 'Database' ),
     97                'fields' => array()
     98        ),
     99        'wp-constants'        => array(
     100                'label'       => __( 'WordPress constants' ),
     101                '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.' ),
     102                'fields'      => array(
     103                        array(
     104                                'label' => 'WP_DEBUG',
     105                                'value' => ( ! defined( 'WP_DEBUG' ) ? __( 'Not defined' ) : ( WP_DEBUG ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     106                        ),
     107                        array(
     108                                'label' => 'WP_DEBUG_DISPLAY',
     109                                'value' => ( ! defined( 'WP_DEBUG_DISPLAY' ) ? __( 'Not defined' ) : ( WP_DEBUG_DISPLAY ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     110                        ),
     111                        array(
     112                                'label' => 'WP_DEBUG_LOG',
     113                                'value' => ( ! defined( 'WP_DEBUG_LOG' ) ? __( 'Not defined' ) : ( WP_DEBUG_LOG ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     114                        ),
     115                        array(
     116                                'label' => 'SCRIPT_DEBUG',
     117                                'value' => ( ! defined( 'SCRIPT_DEBUG' ) ? __( 'Not defined' ) : ( SCRIPT_DEBUG ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     118                        ),
     119                        array(
     120                                'label' => 'WP_CACHE',
     121                                'value' => ( ! defined( 'WP_CACHE' ) ? __( 'Not defined' ) : ( WP_CACHE ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     122                        ),
     123                        array(
     124                                'label' => 'CONCATENATE_SCRIPTS',
     125                                'value' => ( ! defined( 'CONCATENATE_SCRIPTS' ) ? __( 'Not defined' ) : ( CONCATENATE_SCRIPTS ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     126                        ),
     127                        array(
     128                                'label' => 'COMPRESS_SCRIPTS',
     129                                'value' => ( ! defined( 'COMPRESS_SCRIPTS' ) ? __( 'Not defined' ) : ( COMPRESS_SCRIPTS ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     130                        ),
     131                        array(
     132                                'label' => 'COMPRESS_CSS',
     133                                'value' => ( ! defined( 'COMPRESS_CSS' ) ? __( 'Not defined' ) : ( COMPRESS_CSS ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     134                        ),
     135                        array(
     136                                'label' => 'WP_LOCAL_DEV',
     137                                'value' => ( ! defined( 'WP_LOCAL_DEV' ) ? __( 'Not defined' ) : ( WP_LOCAL_DEV ? __( 'Enabled' ) : __( 'Disabled' ) ) )
     138                        )
     139                )
     140        )
     141);
     142
     143if ( is_multisite() ) {
     144        $network_query = new WP_Network_Query();
     145        $network_ids   = $network_query->query( array(
     146                'fields'        => 'ids',
     147                'number'        => 100,
     148                'no_found_rows' => false,
     149        ) );
     150
     151        $site_count = 0;
     152        foreach ( $network_ids as $network_id ) {
     153                $site_count += get_blog_count( $network_id );
     154        }
     155
     156        $info['wp-core']['fields'][] = array(
     157                'label' => __( 'User Count' ),
     158                'value' => get_user_count()
     159        );
     160        $info['wp-core']['fields'][] = array(
     161                'label' => __( 'Site Count' ),
     162                'value' => $site_count
     163        );
     164        $info['wp-core']['fields'][] = array(
     165                'label' => __( 'Network Count' ),
     166                'value' => $network_query->found_networks
     167        );
     168} else {
     169        $user_count = count_users();
     170
     171        $info['wp-core']['fields'][] = array(
     172                'label' => __( 'User Count' ),
     173                'value' => $user_count['total_users']
     174        );
     175}
     176
     177// Populate the server debug fields
     178$info['wp-server']['fields'][] = array(
     179        'label' => _( 'Server architecture' ),
     180        'value' => ( ! function_exists( 'php_uname' ) ? __( 'Unable to determine architecture' ) : php_uname( 'm' ) )
     181);
     182$info['wp-server']['fields'][] = array(
     183        'label' => __( 'PHP Version' ),
     184        'value' => phpversion()
     185);
     186$info['wp-server']['fields'][] = array(
     187        'label' => __( 'PHP SAPI' ),
     188        'value' => php_sapi_name()
     189);
     190$info['wp-server']['fields'][] = array(
     191        'label' => __( 'PHP max input variables' ),
     192        'value' => ini_get( 'max_input_vars' )
     193);
     194$info['wp-server']['fields'][] = array(
     195        'label' => __( 'PHP time limit' ),
     196        'value' => ini_get( 'max_execution_time' )
     197);
     198$info['wp-server']['fields'][] = array(
     199        'label' => __( 'PHP memory limit' ),
     200        'value' => ini_get( 'memory_limit' )
     201);
     202$info['wp-server']['fields'][] = array(
     203        'label' => __( 'Upload max filesize' ),
     204        'value' => ini_get( 'upload_max_filesize' )
     205);
     206$info['wp-server']['fields'][] = array(
     207        'label' => __( 'PHP post max size' ),
     208        'value' => ini_get( 'post_max_size' )
     209);
     210
     211$cURL                          = curl_version();
     212$info['wp-server']['fields'][] = array(
     213        'label' => __( 'cURL Version' ),
     214        'value' => sprintf( '%s %s', $cURL['version'], $cURL['ssl_version'] )
     215);
     216
     217$info['wp-server']['fields'][] = array(
     218        'label' => __( 'SUHOSIN installed' ),
     219        'value' => ( ( extension_loaded( 'suhosin' ) || ( defined( 'SUHOSIN_PATCH' ) && constant( 'SUHOSIN_PATCH' ) ) ) ? __( 'Yes' ) : __( 'No' ) )
     220);
     221
     222$info['wp-server']['fields'][] = array(
     223        'label' => __( 'Is the Imagick library available' ),
     224        'value' => ( extension_loaded( 'imagick' ) ? __( 'Yes' ) : __( 'No' ) )
     225);
     226
     227
     228// Populate the database debug fields.
     229if ( is_resource( $wpdb->dbh ) ) {
     230        # Old mysql extension
     231        $extension = 'mysql';
     232} else if ( is_object( $wpdb->dbh ) ) {
     233        # mysqli or PDO
     234        $extension = get_class( $wpdb->dbh );
     235} else {
     236        # Who knows?
     237        $extension = null;
     238}
     239
     240if ( method_exists( $wpdb, 'db_version' ) ) {
     241        $server = $wpdb->db_version();
     242} else {
     243        $server = null;
     244}
     245
     246if ( isset( $wpdb->use_mysqli ) && $wpdb->use_mysqli ) {
     247        $client_version = mysqli_get_client_version();
     248} else {
     249        if ( preg_match( '|[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}|', mysql_get_client_info(), $matches ) ) {
     250                $client_version = $matches[0];
     251        } else {
     252                $client_version = null;
     253        }
     254}
     255
     256$info['wp-database']['fields'][] = array(
     257        'label' => __( 'Extension' ),
     258        'value' => $extension
     259);
     260$info['wp-database']['fields'][] = array(
     261        'label' => __( 'Server version' ),
     262        'value' => $server
     263);
     264$info['wp-database']['fields'][] = array(
     265        'label' => __( 'Client version' ),
     266        'value' => $client_version
     267);
     268$info['wp-database']['fields'][] = array(
     269        'label'   => __( 'Database user' ),
     270        'value'   => $wpdb->dbuser,
     271        'private' => true
     272);
     273$info['wp-database']['fields'][] = array(
     274        'label'   => __( 'Database host' ),
     275        'value'   => $wpdb->dbhost,
     276        'private' => true
     277);
     278$info['wp-database']['fields'][] = array(
     279        'label'   => __( 'Database table' ),
     280        'value'   => $wpdb->dbname,
     281        'private' => true
     282);
     283$info['wp-database']['fields'][] = array(
     284        'label' => __( 'Database prefix' ),
     285        'value' => $wpdb->prefix
     286);
     287
     288
     289// List must use plugins if there are any
     290$mu_plugins = get_mu_plugins();
     291
     292foreach ( $mu_plugins AS $plugin_path => $plugin ) {
     293        $info['wp-mu-plugins']['fields'][] = array(
     294                'label' => $plugin['Name'],
     295                // translators: %1$s: Plugin version number. %2$s: Plugin author name.
     296                'value' => sprintf( __( 'version %1$s by %2$s' ), $plugin['Version'], $plugin['Author'] )
     297        );
     298}
     299
     300
     301// List all available plugins
     302$plugins = get_plugins();
     303
     304foreach ( $plugins AS $plugin_path => $plugin ) {
     305        $plugin_part = ( is_plugin_active( $plugin_path ) ) ? 'wp-plugins-active' : 'wp-plugins-inactive';
     306
     307        $info[ $plugin_part ]['fields'][] = array(
     308                'label' => $plugin['Name'],
     309                // translators: %1$s: Plugin version number. %2$s: Plugin author name.
     310                'value' => sprintf( __( 'version %1$s by %2$s' ), $plugin['Version'], $plugin['Author'] )
     311        );
     312}
     313
     314
     315// Populate the section for the currently active theme
     316$theme                             = wp_get_theme();
     317$info['wp-active-theme']['fields'] = array(
     318        array(
     319                'label' => __( 'Name' ),
     320                'value' => $theme->Name
     321        ),
     322        array(
     323                'label' => __( 'Version' ),
     324                'value' => $theme->Version
     325        ),
     326        array(
     327                'label' => __( 'Author' ),
     328                'value' => wp_kses( $theme->Author, array() )
     329        ),
     330        array(
     331                'label' => __( 'Author website' ),
     332                'value' => $theme->offsetGet( 'Author URI' )
     333        ),
     334        array(
     335                'label' => __( 'Parent theme' ),
     336                'value' => ( $theme->parent_Theme ?: __( 'Not a child theme' ) )
     337        )
     338);
     339
     340
     341// Populate a list of all themes available in the install
     342$all_themes = wp_get_themes();
     343
     344foreach ( $all_themes AS $theme_slug => $theme ) {
     345        $info['wp-themes']['fields'][] = array(
     346                // translators: %1$s: Theme name. %2$s: Theme slug.
     347                'label' => sprintf( '%1$s (%2$s)', $theme->Name, $theme_slug ),
     348                // translators: %1$s Theme version number. %2$s: Theme author name.
     349                'value' => sprintf( 'version %1$s by %2$s', $theme->Version, wp_kses( $theme->Author, array() ) )
     350        );
     351}
     352
     353
     354/**
     355 * Add or modify new debug sections.
     356 *
     357 * Plugin or themes may wish to introduce their own debug information without creating additional admin pages for this
     358 * kind of information as it is rarely needed, they can then utilize this filter to introduce their own sections.
     359 *
     360 * This filter intentionally does not include the fields introduced by core as those should always be un-modified
     361 * and reliable for support related scenarios, take note that the core fields will take priority if a filtered value
     362 * is trying to use the same array keys.
     363 *
     364 * Array keys added by core are all prefixed with `wp-`, plugins and themes are encouraged to use their own slug as
     365 * a prefix, both for consistency as well as avoiding key collisions.
     366 *
     367 * @since 4.9.0
     368 *
     369 * @param array $args {
     370 *     The debug information to be added to the core information page.
     371 *
     372 *     @type string $label        The title for this section of the debug output.
     373 *     @type string $description  Optional. A description for your information section which may contain basic HTML
     374 *                                markup: `em`, `strong` and `a` for linking to documentation or putting emphasis.
     375 *     @type boolean $show_count  Options. If set to `true` the amount of fields will be included in the title for
     376 *                                this section.
     377 *     @type array $fields {
     378 *         An associative array containing the data to be displayed.
     379 *
     380 *         @type string $label     The label for this piece of information.
     381 *         @type string $value     The output that is of interest for this field.
     382 *         @type boolean $private  Optional. If set to `true` the field will not be included in the copy-paste text area
     383 *                                 on top of the page, allowing you to show, for example, API keys here.
     384 *     }
     385 * }
     386 */
     387$external_info = apply_filters( 'debug_information', array() );
     388
     389// Merge the core and external debug fields
     390$info = array_merge( $external_info, $info );
     391?>
     392
     393        <div class="wrap">
     394                <h1 class="wp-heading-inline">
     395                        <?php echo esc_html( $title ); ?>
     396                </h1>
     397
     398                <div class="notice notice-info">
     399                        <p>
     400                                <?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.' ); ?>
     401                        </p>
     402                        <p>
     403                                <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>
     404
     405                        <div id="system-information-copy-wrapper" style="display: none;">
     406                                <textarea id="system-information-copy-field" class="widefat" rows="10">`
     407                                        <?php
     408                                        foreach ( $info as $section => $details ) {
     409                                                if ( empty( $details['fields'] ) ) {
     410                                                        continue;
     411                                                }
     412
     413                                                printf(
     414                                                        "### %s%S ###\n\n",
     415                                                        $details['label'],
     416                                                        ( isset( $details['show_count'] ) && $details['show_count'] ? sprintf( ' (%d)', count( $details['fields'] ) ) : '' )
     417                                                );
     418
     419                                                foreach ( $details['fields'] as $field ) {
     420                                                        if ( isset( $field['private'] ) && true === $field['private'] ) {
     421                                                                continue;
     422                                                        }
     423
     424                                                        printf(
     425                                                                "%s: %s\n",
     426                                                                $field['label'],
     427                                                                $field['value']
     428                                                        );
     429                                                }
     430                                                echo "\n";
     431                                        }
     432                                        ?>
     433                                        `</textarea>
     434
     435                                <button type="button" class="button button-primary" onclick="document.getElementById('system-information-copy-field').select();"><?php esc_html_e( 'Mark field for copying' ); ?></button>
     436                        </div>
     437                        </p>
     438                </div>
     439
     440                <?php
     441                foreach ( $info AS $section => $details ) {
     442                        if ( ! isset( $details['fields'] ) || empty( $details['fields'] ) ) {
     443                                continue;
     444                        }
     445
     446                        printf(
     447                                '<h2>%s%s</h2>',
     448                                esc_html( $details['label'] ),
     449                                ( isset( $details['show_count'] ) && $details['show_count'] ? sprintf( ' (%d)', count( $details['fields'] ) ) : '' )
     450                        );
     451
     452                        if ( isset( $details['description'] ) && ! empty( $details['description'] ) ) {
     453                                printf(
     454                                        '<p>%s</p>',
     455                                        wp_kses( $details['description'], array(
     456                                                'a'      => array(
     457                                                        'href' => true
     458                                                ),
     459                                                'strong' => true,
     460                                                'em'     => true,
     461                                        ) )
     462                                );
     463                        }
     464                        ?>
     465                        <table class="widefat">
     466                                <tbody>
     467                                <?php
     468                                foreach ( $details['fields'] as $field ) {
     469                                        printf(
     470                                                '<tr><td>%s</td><td>%s</td></tr>',
     471                                                esc_html( $field['label'] ),
     472                                                esc_html( $field['value'] )
     473                                        );
     474                                }
     475                                ?>
     476                                </tbody>
     477                        </table>
     478                        <?php
     479                }
     480                ?>
     481
     482        </div>
     483
     484<?php
     485include( ABSPATH . 'wp-admin/admin-footer.php' );