Make WordPress Core


Ignore:
Timestamp:
01/12/2020 01:31:49 PM (7 years 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.