WordPress.org

Make WordPress Core


Ignore:
Timestamp:
01/12/2020 01:31:49 PM (3 months ago)
Author:
SergeyBiryukov
Message:

Site Health: Introduce Site Health Status dashboard widget.

The widget informs administrators of any potential issues that should be addressed to improve the performance or security of their website, and directs them to the Site Health screen for more details.

Props Clorith, hedgefield, guddu1315.
See #47606.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/class-wp-site-health.php

    r46797 r47063  
    99
    1010class WP_Site_Health {
     11    private static $instance = null;
     12
    1113    private $mysql_min_version_check;
    1214    private $mysql_rec_version_check;
     
    3032     */
    3133    public function __construct() {
     34        $this->maybe_create_scheduled_event();
     35
    3236        $this->prepare_sql_data();
    3337
     
    4347
    4448        add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
     49        add_action( 'wp_site_health_scheduled_check', array( $this, 'wp_cron_scheduled_check' ) );
     50    }
     51
     52    /**
     53     * Return an instance of the WP_Site_Health class, or create one if none exist yet.
     54     *
     55     * @since 5.4.0
     56     *
     57     * @return WP_Site_Health|null
     58     */
     59    public static function initialize() {
     60        if ( null === self::$instance ) {
     61            self::$instance = new WP_Site_Health();
     62        }
     63
     64        return self::$instance;
    4565    }
    4666
     
    5272    public function enqueue_scripts() {
    5373        $screen = get_current_screen();
    54         if ( 'site-health' !== $screen->id ) {
     74        if ( 'site-health' !== $screen->id && 'dashboard' !== $screen->id ) {
    5575            return;
    5676        }
     
    97117
    98118                    if ( method_exists( $this, $test_function ) && is_callable( array( $this, $test_function ) ) ) {
    99                         /**
    100                          * Filter the output of a finished Site Health test.
    101                          *
    102                          * @since 5.3.0
    103                          *
    104                          * @param array $test_result {
    105                          *     An associated array of test result data.
    106                          *
    107                          *     @param string $label  A label describing the test, and is used as a header in the output.
    108                          *     @param string $status The status of the test, which can be a value of `good`, `recommended` or `critical`.
    109                          *     @param array  $badge {
    110                          *         Tests are put into categories which have an associated badge shown, these can be modified and assigned here.
    111                          *
    112                          *         @param string $label The test label, for example `Performance`.
    113                          *         @param string $color Default `blue`. A string representing a color to use for the label.
    114                          *     }
    115                          *     @param string $description A more descriptive explanation of what the test looks for, and why it is important for the end user.
    116                          *     @param string $actions     An action to direct the user to where they can resolve the issue, if one exists.
    117                          *     @param string $test        The name of the test being ran, used as a reference point.
    118                          * }
    119                          */
    120                         $health_check_js_variables['site_status']['direct'][] = apply_filters( 'site_status_test_result', call_user_func( array( $this, $test_function ) ) );
     119                        $health_check_js_variables['site_status']['direct'][] = $this->perform_test( array( $this, $test_function ) );
    121120                        continue;
    122121                    }
     
    124123
    125124                if ( is_callable( $test['test'] ) ) {
    126                     /** This filter is documented in wp-admin/includes/class-wp-site-health.php */
    127                     $health_check_js_variables['site_status']['direct'][] = apply_filters( 'site_status_test_result', call_user_func( $test['test'] ) );
     125                    $health_check_js_variables['site_status']['direct'][] = $this->perform_test( $test['test'] );
    128126                }
    129127            }
     
    140138
    141139        wp_localize_script( 'site-health', 'SiteHealth', $health_check_js_variables );
     140    }
     141
     142    /**
     143     * Run a Site Health test directly.
     144     *
     145     * @since 5.4.0
     146     *
     147     * @param $callback
     148     *
     149     * @return mixed|void
     150     */
     151    private function perform_test( $callback ) {
     152        /**
     153         * Filter the output of a finished Site Health test.
     154         *
     155         * @since 5.3.0
     156         *
     157         * @param array $test_result {
     158         *     An associated array of test result data.
     159         *
     160         *     @param string $label  A label describing the test, and is used as a header in the output.
     161         *     @param string $status The status of the test, which can be a value of `good`, `recommended` or `critical`.
     162         *     @param array  $badge {
     163         *         Tests are put into categories which have an associated badge shown, these can be modified and assigned here.
     164         *
     165         *         @param string $label The test label, for example `Performance`.
     166         *         @param string $color Default `blue`. A string representing a color to use for the label.
     167         *     }
     168         *     @param string $description A more descriptive explanation of what the test looks for, and why it is important for the end user.
     169         *     @param string $actions     An action to direct the user to where they can resolve the issue, if one exists.
     170         *     @param string $test        The name of the test being ran, used as a reference point.
     171         * }
     172         */
     173        return apply_filters( 'site_status_test_result', call_user_func( $callback ) );
    142174    }
    143175
     
    20062038     */
    20072039    public function admin_body_class( $body_class ) {
     2040        $screen = get_current_screen();
     2041        if ( 'site-health' !== $screen->id ) {
     2042            return $body_class;
     2043        }
     2044
    20082045        $body_class .= ' site-health';
    20092046
     
    21682205        );
    21692206    }
     2207
     2208    /**
     2209     * Create a weekly cron event, if one does not already exist.
     2210     *
     2211     * @since 5.4.0
     2212     */
     2213    public function maybe_create_scheduled_event() {
     2214        if ( ! wp_next_scheduled( 'wp_site_health_scheduled_check' ) && ! wp_installing() ) {
     2215            wp_schedule_event( time(), 'weekly', 'wp_site_health_scheduled_check' );
     2216        }
     2217    }
     2218
     2219    /**
     2220     * Run our scheduled event to check and update the latest site health status for the website.
     2221     *
     2222     * @since 5.4.0
     2223     */
     2224    public function wp_cron_scheduled_check() {
     2225        // Bootstrap wp-admin, as WP_Cron doesn't do this for us.
     2226        require_once( trailingslashit( ABSPATH ) . 'wp-admin/includes/admin.php' );
     2227
     2228        $tests = WP_Site_Health::get_tests();
     2229
     2230        $results = array();
     2231
     2232        $site_status = array(
     2233            'good'        => 0,
     2234            'recommended' => 0,
     2235            'critical'    => 0,
     2236        );
     2237
     2238        // Don't run https test on localhost
     2239        if ( 'localhost' === preg_replace( '|https?://|', '', get_site_url() ) ) {
     2240            unset( $tests['direct']['https_status'] );
     2241        }
     2242
     2243        foreach ( $tests['direct'] as $test ) {
     2244
     2245            if ( is_string( $test['test'] ) ) {
     2246                $test_function = sprintf(
     2247                    'get_test_%s',
     2248                    $test['test']
     2249                );
     2250
     2251                if ( method_exists( $this, $test_function ) && is_callable( array( $this, $test_function ) ) ) {
     2252                    $results[] = $this->perform_test( array( $this, $test_function ) );
     2253                    continue;
     2254                }
     2255            }
     2256
     2257            if ( is_callable( $test['test'] ) ) {
     2258                $results[] = $this->perform_test( $test['test'] );
     2259            }
     2260        }
     2261
     2262        foreach ( $tests['async'] as $test ) {
     2263            if ( is_string( $test['test'] ) ) {
     2264                if ( isset( $test['has_rest'] ) && $test['has_rest'] ) {
     2265                    $result_fetch = wp_remote_post(
     2266                        rest_url( $test['test'] ),
     2267                        array(
     2268                            'body' => array(
     2269                                '_wpnonce' => wp_create_nonce( 'wp_rest' ),
     2270                            ),
     2271                        )
     2272                    );
     2273                } else {
     2274                    $result_fetch = wp_remote_post(
     2275                        admin_url( 'admin-ajax.php' ),
     2276                        array(
     2277                            'body' => array(
     2278                                'action'   => $test['test'],
     2279                                '_wpnonce' => wp_create_nonce( 'health-check-site-status' ),
     2280                            ),
     2281                        )
     2282                    );
     2283                }
     2284
     2285                if ( ! is_wp_error( $result_fetch ) ) {
     2286                    $results[] = json_decode( wp_remote_retrieve_body( $result_fetch ) );
     2287                } else {
     2288                    $results[] = array(
     2289                        'status' => 'recommended',
     2290                        'label'  => __( 'A test is unavailable' ),
     2291                    );
     2292                }
     2293            }
     2294        }
     2295
     2296        foreach ( $results as $result ) {
     2297            if ( 'critical' === $result['status'] ) {
     2298                $site_status['critical']++;
     2299            } elseif ( 'recommended' === $result['status'] ) {
     2300                $site_status['recommended']++;
     2301            } else {
     2302                $site_status['good']++;
     2303            }
     2304        }
     2305
     2306        set_transient( 'health-check-site-status-result', wp_json_encode( $site_status ) );
     2307    }
    21702308}
Note: See TracChangeset for help on using the changeset viewer.