WordPress.org

Make WordPress Core

Ticket #46707: 46707.diff

File 46707.diff, 19.6 KB (added by azaozz, 5 months ago)
  • src/js/_enqueues/admin/site-health.js

     
    99jQuery( document ).ready( function( $ ) {
    1010
    1111        var data;
    12 
    1312        var clipboard = new ClipboardJS( '.site-health-copy-buttons .copy-button' );
     13        var dirSizesNotice = $( '.health-check-dir-size-calc-notice' );
    1414
    1515        // Debug information copy section.
    1616        clipboard.on( 'success', function( e ) {
     
    209209                }
    210210        }
    211211
     212        function getDirectorySizes() {
     213                var data = {
     214                        action: 'health-check-get-sizes',
     215                        _wpnonce: SiteHealth.nonce.site_status_result,
     216                };
     217
     218                $.post( {
     219                        type: 'POST',
     220                        url: ajaxurl,
     221                        data: data,
     222                        dataType: 'json',
     223                } ).done( function( response ) {
     224                        updateDirSizes( response.data || {} );
     225
     226                        if ( response.success ) {
     227                                wp.a11y.speak( dirSizesNotice.find( '.health-check-dir-size-success' ).text() );
     228                        } else {
     229                                dirSizesNotice.addClass( 'has-errors' );
     230                                wp.a11y.speak( dirSizesNotice.find( '.health-check-dir-size-error' ).text() );
     231                        }
     232                } ).fail( function() {
     233                        dirSizesNotice.addClass( 'has-errors' );
     234                        wp.a11y.speak( dirSizesNotice.find( '.health-check-dir-size-error' ).text() );
     235                } ).always( function() {
     236                        dirSizesNotice.addClass( 'calculated' );
     237                } );
     238        }
     239
     240        function updateDirSizes( data ) {
     241                var copyButton = $( 'button.button.copy-button' );
     242                var clipdoardText = copyButton.attr( 'data-clipboard-text' );
     243
     244                $.each( data, function( name, value ) {
     245                        var text = value.debug || value.size;
     246
     247                        if ( typeof text !== 'undefined' ) {
     248                                clipdoardText = clipdoardText.replace( name + ': not calculated', name + ': ' + text );
     249                        }
     250                } );
     251
     252                copyButton.attr( 'data-clipboard-text', clipdoardText );
     253
     254                $( '#health-check-accordion-block-wp-paths-sizes' ).find( 'td[class]' ).each( function( i, element ) {
     255                        var td = $( element );
     256                        var name = td.attr( 'class' );
     257
     258                        if ( data.hasOwnProperty( name ) && data[ name ].size ) {
     259                                td.text( data[ name ].size );
     260                        }
     261                } );
     262        }
     263
     264        if ( dirSizesNotice.length ) {
     265                getDirectorySizes();
     266        }
    212267} );
  • src/wp-admin/admin-ajax.php

     
    136136        'health-check-is-in-debug-mode',
    137137        'health-check-background-updates',
    138138        'health-check-loopback-requests',
     139        'health-check-get-sizes',
    139140);
    140141
    141142// Deprecated
  • src/wp-admin/css/site-health.css

     
    391391        margin-left: 22px;
    392392}
    393393
     394.health-check-dir-size-calc-notice .spinner {
     395        visibility: visible;
     396        float: none;
     397        margin: -4px 2px 0;
     398}
     399
     400.health-check-dir-size-success,
     401.health-check-dir-size-error,
     402.health-check-dir-size-calc-notice.calculated .spinner,
     403.health-check-dir-size-calc-notice.calculated .health-check-dir-size-calculating,
     404.health-check-dir-size-calc-notice.calculated.has-errors .health-check-dir-size-success {
     405        display: none;
     406}
     407
     408.health-check-dir-size-calc-notice.calculated .health-check-dir-size-success,
     409.health-check-dir-size-calc-notice.calculated.has-errors .health-check-dir-size-error {
     410        display: inline;
     411}
     412
    394413@media screen and (max-width: 782px) {
    395414        .health-check-body {
    396415                margin: 0 12px;
  • src/wp-admin/includes/ajax-actions.php

     
    49584958
    49594959        wp_send_json_success();
    49604960}
     4961
     4962/**
     4963 * Ajax handler for site health check to get directories and database sizes.
     4964 *
     4965 * @since 5.2.0
     4966 */
     4967function wp_ajax_health_check_get_sizes() {
     4968        check_ajax_referer( 'health-check-site-status-result' );
     4969
     4970        if ( ! current_user_can( 'install_plugins' ) ) {
     4971                wp_send_json_error();
     4972        }
     4973
     4974        if ( ! class_exists( 'WP_Debug_Data' ) ) {
     4975                require_once( ABSPATH . 'wp-admin/includes/class-wp-debug-data.php' );
     4976        }
     4977
     4978        $sizes_data = WP_Debug_Data::get_sizes();
     4979        $all_sizes  = array();
     4980
     4981        foreach ( $sizes_data as $name => $value ) {
     4982                $name = sanitize_text_field( $name );
     4983                $data = array();
     4984
     4985                if ( isset( $value['size'] ) ) {
     4986                        if ( is_string( $value['size'] ) ) {
     4987                                $data['size'] = sanitize_text_field( $value['size'] );
     4988                        } else {
     4989                                $data['size'] = (int) $value['size'];
     4990                        }
     4991                }
     4992
     4993                if ( isset( $value['debug'] ) ) {
     4994                        if ( is_string( $value['debug'] ) ) {
     4995                                $data['debug'] = sanitize_text_field( $value['debug'] );
     4996                        } else {
     4997                                $data['debug'] = (int) $value['debug'];
     4998                        }
     4999                }
     5000
     5001                $all_sizes[ $name ] = $data;
     5002        }
     5003
     5004        if ( isset( $all_sizes['total_size']['debug'] ) && 'not available' === $all_sizes['total_size']['debug'] ) {
     5005                wp_send_json_error( $all_sizes );
     5006        }
     5007
     5008        wp_send_json_success( $all_sizes );
     5009}
  • src/wp-admin/includes/class-wp-debug-data.php

     
    385385                        );
    386386                }
    387387
    388                 $size_db = WP_Debug_Data::get_database_size();
     388                $not_calculated = __( 'Not calculated' );
    389389
    390                 /*
    391                  * We will be using the PHP max execution time to prevent the size calculations
    392                  * from causing a timeout. The default value is 30 seconds, and some
    393                  * hosts do not allow you to read configuration values.
    394                  */
    395                 if ( function_exists( 'ini_get' ) ) {
    396                         $max_execution_time = ini_get( 'max_execution_time' );
    397                 }
    398 
    399                 // The max_execution_time defaults to 0 when PHP runs from cli.
    400                 // We still want to limit it below.
    401                 if ( empty( $max_execution_time ) ) {
    402                         $max_execution_time = 30;
    403                 }
    404 
    405                 // Here 20 seconds is a "sensible default" for how long to make the user wait for the directory size calculation.
    406                 // When testing 20 seconds seem enough in nearly all cases. The remaining edge cases are likely testing or development sites
    407                 // that have very large number of files, for example `node_modules` in plugins or themes, etc.
    408                 if ( $max_execution_time > 20 ) {
    409                         $max_execution_time = 20;
    410                 } elseif ( $max_execution_time > 10 ) {
    411                         // If the max_execution_time is set to lower than 20 seconds, reduce it a bit to prevent
    412                         // edge-case timeouts that may happen after the size loop has finished running.
    413                         $max_execution_time -= 1;
    414                 }
    415 
    416                 // Go through the various installation directories and calculate their sizes.
    417                 $size_directories = array(
    418                         'wordpress' => array(
    419                                 'path' => ABSPATH,
    420                                 'size' => 0,
    421                         ),
    422                         'themes'    => array(
    423                                 'path' => trailingslashit( get_theme_root() ),
    424                                 'size' => 0,
    425                         ),
    426                         'plugins'   => array(
    427                                 'path' => trailingslashit( WP_PLUGIN_DIR ),
    428                                 'size' => 0,
    429                         ),
    430                         'uploads'   => array(
    431                                 'path' => $upload_dir['basedir'],
    432                                 'size' => 0,
    433                         ),
    434                 );
    435 
    436                 $size_total = 0;
    437 
    438                 // Loop over all the directories we want to gather the sizes for.
    439                 foreach ( $size_directories as $size => $attributes ) {
    440                         $dir_size = null; // Default to timeout.
    441 
    442                         if ( microtime( true ) - WP_START_TIMESTAMP < $max_execution_time ) {
    443                                 $dir_size = get_dirsize( $attributes['path'], $max_execution_time );
    444                         }
    445 
    446                         if ( false === $dir_size ) {
    447                                 // Error reading.
    448                                 $size_directories[ $size ]['size']  = __( 'The size cannot be calculated. The directory is not accessible. Usually caused by invalid permissions.' );
    449                                 $size_directories[ $size ]['debug'] = 'not accessible';
    450 
    451                                 // Stop total size calculation.
    452                                 $size_total = null;
    453                         } elseif ( null === $dir_size ) {
    454                                 // Timeout.
    455                                 $size_directories[ $size ]['size']  = __( 'The directory size calculation has timed out. Usually caused by a very large number of sub-directories and files.' );
    456                                 $size_directories[ $size ]['debug'] = 'timeout while calculating size';
    457 
    458                                 // Stop total size calculation.
    459                                 $size_total = null;
    460                         } else {
    461                                 $is_subdir = ( strpos( $size_directories[ $size ]['path'], ABSPATH ) === 0 );
    462 
    463                                 // phpcs:ignore WordPress.WP.CapitalPDangit.Misspelled
    464                                 if ( null !== $size_total && ( 'wordpress' === $size || ! $is_subdir ) ) {
    465                                         $size_total += $dir_size;
    466                                 }
    467 
    468                                 $size_directories[ $size ]['size']  = size_format( $dir_size, 2 );
    469                                 $size_directories[ $size ]['debug'] = $size_directories[ $size ]['size'];
    470                         }
    471                 }
    472 
    473                 if ( null !== $size_total && $size_db > 0 ) {
    474                         $size_total = size_format( $size_total + $size_db, 2 );
    475                 } else {
    476                         $size_total = 0;
    477                 }
    478 
    479390                $info['wp-paths-sizes']['fields'] = array(
    480391                        'uploads_path'       => array(
    481392                                'label' => __( 'Uploads Directory Location' ),
    482                                 'value' => $size_directories['uploads']['path'],
     393                                'value' => $upload_dir['basedir'],
    483394                        ),
    484395                        'uploads_size'       => array(
    485396                                'label' => __( 'Uploads Directory Size' ),
    486                                 'value' => $size_directories['uploads']['size'],
    487                                 'debug' => $size_directories['uploads']['debug'],
     397                                'value' => $not_calculated,
     398                                'debug' => 'not calculated',
    488399                        ),
    489400                        'themes_path'        => array(
    490401                                'label' => __( 'Themes Directory Location' ),
    491                                 'value' => $size_directories['themes']['path'],
     402                                'value' => trailingslashit( get_theme_root() ),
    492403                        ),
    493404                        'current_theme_path' => array(
    494405                                'label' => __( 'Current Theme Directory' ),
     
    496407                        ),
    497408                        'themes_size'        => array(
    498409                                'label' => __( 'Themes Directory Size' ),
    499                                 'value' => $size_directories['themes']['size'],
    500                                 'debug' => $size_directories['themes']['debug'],
     410                                'value' => $not_calculated,
     411                                'debug' => 'not calculated',
    501412                        ),
    502413                        'plugins_path'       => array(
    503414                                'label' => __( 'Plugins Directory Location' ),
    504                                 'value' => $size_directories['plugins']['path'],
     415                                'value' => trailingslashit( WP_PLUGIN_DIR ),
    505416                        ),
    506417                        'plugins_size'       => array(
    507418                                'label' => __( 'Plugins Directory Size' ),
    508                                 'value' => $size_directories['plugins']['size'],
    509                                 'debug' => $size_directories['plugins']['debug'],
     419                                'value' => $not_calculated,
     420                                'debug' => 'not calculated',
    510421                        ),
    511422                        'wordpress_path'     => array(
    512423                                'label' => __( 'WordPress Directory Location' ),
    513                                 'value' => $size_directories['wordpress']['path'],
     424                                'value' => ABSPATH,
    514425                        ),
    515426                        'wordpress_size'     => array(
    516427                                'label' => __( 'WordPress Directory Size' ),
    517                                 'value' => $size_directories['wordpress']['size'],
    518                                 'debug' => $size_directories['wordpress']['debug'],
     428                                'value' => $not_calculated,
     429                                'debug' => 'not calculated',
    519430                        ),
    520431                        'database_size'      => array(
    521432                                'label' => __( 'Database size' ),
    522                                 'value' => size_format( $size_db, 2 ),
     433                                'value' => $not_calculated,
     434                                'debug' => 'not calculated',
    523435                        ),
    524436                        'total_size'         => array(
    525437                                'label' => __( 'Total installation size' ),
    526                                 'value' => $size_total > 0 ? $size_total : __( 'Total size is not available. Some errors were encountered when determining the size of your installation.' ),
    527                                 'debug' => $size_total > 0 ? $size_total : 'not available',
     438                                'value' => $not_calculated,
     439                                'debug' => 'not calculated',
    528440                        ),
    529441                );
    530442
     
    11861098
    11871099                return (int) $size;
    11881100        }
     1101
     1102        /**
     1103         * Fetch the sizes of the WordPress directories: `wordpress` (ABSPATH), `plugins`, `themes`, and `uploads`.
     1104         * Intended to supplement the array returned by `WP_Debug_Data::debug_data()`.
     1105         *
     1106         * @since 5.2.0
     1107         *
     1108         * @return array The sizes of the directories, also the database size and total installation size.
     1109         */
     1110        public static function get_sizes() {
     1111                $size_db    = self::get_database_size();
     1112                $upload_dir = wp_get_upload_dir();
     1113
     1114                /*
     1115                 * We will be using the PHP max execution time to prevent the size calculations
     1116                 * from causing a timeout. The default value is 30 seconds, and some
     1117                 * hosts do not allow you to read configuration values.
     1118                 */
     1119                if ( function_exists( 'ini_get' ) ) {
     1120                        $max_execution_time = ini_get( 'max_execution_time' );
     1121                }
     1122
     1123                // The max_execution_time defaults to 0 when PHP runs from cli.
     1124                // We still want to limit it below.
     1125                if ( empty( $max_execution_time ) ) {
     1126                        $max_execution_time = 30;
     1127                }
     1128
     1129                // Here 20 seconds is a "sensible default" for how long to make the user wait for the directory size calculation.
     1130                // When testing 20 seconds seem enough in nearly all cases. The remaining edge cases are likely testing or development sites
     1131                // that have very large number of files, for example `node_modules` in plugins or themes, etc.
     1132                if ( $max_execution_time > 20 ) {
     1133                        $max_execution_time = 20;
     1134                } elseif ( $max_execution_time > 10 ) {
     1135                        // If the max_execution_time is set to lower than 20 seconds, reduce it a bit to prevent
     1136                        // edge-case timeouts that may happen after the size loop has finished running.
     1137                        $max_execution_time -= 1;
     1138                }
     1139
     1140                // Go through the various installation directories and calculate their sizes.
     1141                $all_sizes = array(
     1142                        'wordpress_size' => array(
     1143                                'path' => ABSPATH,
     1144                                'size' => 0,
     1145                        ),
     1146                        'themes_size'    => array(
     1147                                'path' => trailingslashit( get_theme_root() ),
     1148                                'size' => 0,
     1149                        ),
     1150                        'plugins_size'   => array(
     1151                                'path' => trailingslashit( WP_PLUGIN_DIR ),
     1152                                'size' => 0,
     1153                        ),
     1154                        'uploads_size'   => array(
     1155                                'path' => $upload_dir['basedir'],
     1156                                'size' => 0,
     1157                        ),
     1158                );
     1159
     1160                $size_total = 0;
     1161
     1162                // Loop over all the directories we want to gather the sizes for.
     1163                foreach ( $all_sizes as $name => $attributes ) {
     1164                        $dir_size = null; // Default to timeout.
     1165
     1166                        if ( microtime( true ) - WP_START_TIMESTAMP < $max_execution_time ) {
     1167                                $dir_size = get_dirsize( $attributes['path'], $max_execution_time );
     1168                        }
     1169
     1170                        unset( $all_sizes[ $name ]['path'] );
     1171
     1172                        if ( false === $dir_size ) {
     1173                                // Error reading.
     1174                                $all_sizes[ $name ]['size']  = __( 'The size cannot be calculated. The directory is not accessible. Usually caused by invalid permissions.' );
     1175                                $all_sizes[ $name ]['debug'] = 'not accessible';
     1176
     1177                                // Stop total size calculation.
     1178                                $size_total = null;
     1179                        } elseif ( null === $dir_size ) {
     1180                                // Timeout.
     1181                                $all_sizes[ $name ]['size']  = __( 'The directory size calculation has timed out. Usually caused by a very large number of sub-directories and files.' );
     1182                                $all_sizes[ $name ]['debug'] = 'timeout while calculating size';
     1183
     1184                                // Stop total size calculation.
     1185                                $size_total = null;
     1186                        } else {
     1187                                $is_subdir = ( strpos( $all_sizes[ $name ]['path'], ABSPATH ) === 0 );
     1188
     1189                                // phpcs:ignore WordPress.WP.CapitalPDangit.Misspelled
     1190                                if ( null !== $size_total && ( 'wordpress' === $name || ! $is_subdir ) ) {
     1191                                        $size_total += $dir_size;
     1192                                }
     1193
     1194                                $all_sizes[ $name ]['size']  = size_format( $dir_size, 2 );
     1195                                $all_sizes[ $name ]['debug'] = $all_sizes[ $name ]['size'];
     1196                        }
     1197                }
     1198
     1199                if ( $size_db > 0 ) {
     1200                        $database_size = size_format( $size_db, 2 );
     1201
     1202                        $all_sizes['database_size'] = array(
     1203                                'size'  => $database_size,
     1204                                'debug' => $database_size,
     1205                        );
     1206                } else {
     1207                        $all_sizes['database_size'] = array(
     1208                                'size'  => __( 'Not available' ),
     1209                                'debug' => 'not available',
     1210                        );
     1211                }
     1212
     1213                if ( null !== $size_total && $size_db > 0 ) {
     1214                        $total_size = size_format( $size_total + $size_db, 2 );
     1215
     1216                        $all_sizes['total_size'] = array(
     1217                                'size'  => $total_size,
     1218                                'debug' => $total_size,
     1219                        );
     1220                } else {
     1221                        $all_sizes['total_size'] = array(
     1222                                'size'  => __( 'Total size is not available. Some errors were encountered when determining the size of your installation.' ),
     1223                                'debug' => 'not available',
     1224                        );
     1225                }
     1226
     1227                return $all_sizes;
     1228        }
    11891229}
  • src/wp-admin/site-health-info.php

     
    6464
    6565<div class="health-check-body hide-if-no-js">
    6666        <?php
     67
    6768        WP_Debug_Data::check_for_updates();
    6869
    6970        $info = WP_Debug_Data::debug_data();
     
    8081        <p>
    8182                <?php _e( 'If you want to export a handy list of all the information on this page, you can use the button below to copy it to the clipboard. You can then paste it in a text file and save it to your harddrive, or paste it in an email exchange with a support engineer or theme/plugin developer for example.' ); ?>
    8283        </p>
     84        <p class="health-check-dir-size-calc-notice">
     85                <span class="spinner"></span>
     86                <span class="health-check-dir-size-calculating"><?php _e( 'Calculating directory sizes. This may take a while&hellip;' ); ?></span>
     87                <span class="health-check-dir-size-success"><?php _e( 'Successfully calculated directory sizes.' ); ?></span>
     88                <span class="health-check-dir-size-error"><?php _e( 'Some errors were encountered when determining the size of your installation.' ); ?></span>
     89        </p>
    8390
    8491        <div class="site-health-copy-buttons">
    8592                <div class="copy-button-wrapper">
     
    93100        <div id="health-check-debug" class="health-check-accordion">
    94101
    95102                <?php
     103
     104                $sizes_fields = array( 'uploads_size', 'themes_size', 'plugins_size', 'wordpress_size', 'database_size', 'total_size' );
     105
    96106                foreach ( $info as $section => $details ) {
    97107                        if ( ! isset( $details['fields'] ) || empty( $details['fields'] ) ) {
    98108                                continue;
    99109                        }
     110
    100111                        ?>
    101112                        <h3 class="health-check-accordion-heading">
    102113                                <button aria-expanded="false" class="health-check-accordion-trigger" aria-controls="health-check-accordion-block-<?php echo esc_attr( $section ); ?>" type="button">
    103114                                        <span class="title">
    104115                                                <?php echo esc_html( $details['label'] ); ?>
     116                                                <?php
    105117
    106                                                 <?php if ( isset( $details['show_count'] ) && $details['show_count'] ) : ?>
    107                                                         <?php printf( '(%d)', count( $details['fields'] ) ); ?>
    108                                                 <?php endif; ?>
     118                                                if ( isset( $details['show_count'] ) && $details['show_count'] ) {
     119                                                        printf( '(%d)', count( $details['fields'] ) );
     120                                                }
     121
     122                                                ?>
    109123                                        </span>
    110124                                        <span class="icon"></span>
    111125                                </button>
     
    113127
    114128                        <div id="health-check-accordion-block-<?php echo esc_attr( $section ); ?>" class="health-check-accordion-panel" hidden="hidden">
    115129                                <?php
     130
     131                                $kses_settings = array(
     132                                        'a'      => array(
     133                                                'href' => true,
     134                                        ),
     135                                        'strong' => true,
     136                                        'em'     => true,
     137                                );
     138
    116139                                if ( isset( $details['description'] ) && ! empty( $details['description'] ) ) {
    117                                         printf(
    118                                                 '<p>%s</p>',
    119                                                 wp_kses(
    120                                                         $details['description'],
    121                                                         array(
    122                                                                 'a'      => array(
    123                                                                         'href' => true,
    124                                                                 ),
    125                                                                 'strong' => true,
    126                                                                 'em'     => true,
    127                                                         )
    128                                                 )
    129                                         );
     140                                        printf( '<p>%s</p>', wp_kses( $details['description'], $kses_settings ) );
    130141                                }
     142
    131143                                ?>
    132144                                <table class="widefat striped health-check-table" role="presentation">
    133145                                        <tbody>
    134146                                        <?php
    135                                         foreach ( $details['fields'] as $field ) {
     147
     148                                        foreach ( $details['fields'] as $field_name => $field ) {
    136149                                                if ( is_array( $field['value'] ) ) {
    137150                                                        $values = '<ul>';
     151
    138152                                                        foreach ( $field['value'] as $name => $value ) {
    139                                                                 $values .= sprintf(
    140                                                                         '<li>%s: %s</li>',
    141                                                                         esc_html( $name ),
    142                                                                         esc_html( $value )
    143                                                                 );
     153                                                                $values .= sprintf( '<li>%s: %s</li>', esc_html( $name ), esc_html( $value ) );
    144154                                                        }
     155
    145156                                                        $values .= '</ul>';
    146157                                                } else {
    147158                                                        $values = esc_html( $field['value'] );
    148159                                                }
    149160
    150                                                 printf(
    151                                                         '<tr><td>%s</td><td>%s</td></tr>',
    152                                                         esc_html( $field['label'] ),
    153                                                         $values
    154                                                 );
     161                                                if ( in_array( $field_name, $sizes_fields, true ) ) {
     162                                                        printf( '<tr><td>%s</td><td class="%s">%s</td></tr>', esc_html( $field['label'] ), esc_attr( $field_name ), $values );
     163                                                } else {
     164                                                        printf( '<tr><td>%s</td><td>%s</td></tr>', esc_html( $field['label'] ), $values );
     165                                                }
    155166                                        }
     167
    156168                                        ?>
    157169                                        </tbody>
    158170                                </table>