Make WordPress Core

Ticket #39165: 39165.14.diff

File 39165.14.diff, 34.8 KB (added by xkon, 7 years ago)

checks for theme / plugin updates

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