WordPress.org

Make WordPress Core

Ticket #47606: 47606.patch

File 47606.patch, 13.6 KB (added by Clorith, 11 months ago)
  • src/wp-settings.php

     
    354354        wp_recovery_mode()->initialize();
    355355}
    356356
     357// Create an instance of WP_Site_Health so that Cron events may fire.
     358if ( ! class_exists( 'WP_Site_Health' ) ) {
     359        require_once( ABSPATH . 'wp-admin/includes/class-wp-site-health.php' );
     360}
     361WP_Site_Health::initialize();
     362
    357363// Load active plugins.
    358364foreach ( wp_get_active_and_valid_plugins() as $plugin ) {
    359365        wp_register_plugin_realpath( $plugin );
  • src/wp-admin/includes/dashboard.php

     
    4242                wp_add_dashboard_widget( 'dashboard_php_nag', __( 'PHP Update Required' ), 'wp_dashboard_php_nag' );
    4343        }
    4444
     45        // Site Health
     46        if ( current_user_can( 'view_site_health_checks' ) ) {
     47                if ( ! class_exists( 'WP_Site_Health' ) ) {
     48                        require_once( ABSPATH . 'wp-admin/includes/class-wp-site-health.php' );
     49                }
     50
     51                WP_Site_Health::initialize();
     52
     53                wp_enqueue_style( 'site-health' );
     54                wp_enqueue_script( 'site-health' );
     55
     56                wp_add_dashboard_widget( 'dashboard_site_health', __( 'Site Health Status' ), 'wp_dashboard_site_health' );
     57        }
     58
    4559        // Right Now
    4660        if ( is_blog_admin() && current_user_can( 'edit_posts' ) ) {
    4761                wp_add_dashboard_widget( 'dashboard_right_now', __( 'At a Glance' ), 'wp_dashboard_right_now' );
     
    17501764        return $classes;
    17511765}
    17521766
     1767/**
     1768 * Display the Site Status widget.
     1769 *
     1770 * @since 5.4.0
     1771 */
     1772function wp_dashboard_site_health() {
     1773        $get_issues = get_transient( 'health-check-site-status-result' );
     1774
     1775        $issue_counts = new \stdClass();
     1776
     1777        if ( false !== $get_issues ) {
     1778                $issue_counts = json_decode( $get_issues );
     1779        }
     1780
     1781        if ( ! is_object( $issue_counts ) || empty( $issue_counts ) ) {
     1782                $issue_counts = (object) array(
     1783                        'good'        => 0,
     1784                        'recommended' => 0,
     1785                        'critical'    => 0,
     1786                );
     1787        }
     1788
     1789        $issues_total = $issue_counts->recommended + $issue_counts->critical;
     1790        ?>
     1791        <div class="health-check-title-section site-health-progress-wrapper loading hide-if-no-js">
     1792                <div class="site-health-progress">
     1793                        <svg role="img" aria-hidden="true" focusable="false" width="100%" height="100%" viewBox="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg">
     1794                                <circle r="90" cx="100" cy="100" fill="transparent" stroke-dasharray="565.48" stroke-dashoffset="0"></circle>
     1795                                <circle id="bar" r="90" cx="100" cy="100" fill="transparent" stroke-dasharray="565.48" stroke-dashoffset="0"></circle>
     1796                        </svg>
     1797                </div>
     1798                <div class="site-health-progress-label">
     1799                        <?php if ( false === $get_issues ) : ?>
     1800                                <?php _e( 'No information yet&hellip;', 'health-check' ); ?>
     1801                        <?php else : ?>
     1802                                <?php _e( 'Results are still loading&hellip;', 'health-check' ); ?>
     1803                        <?php endif; ?>
     1804                </div>
     1805        </div>
     1806
     1807        <?php if ( false === $get_issues ) : ?>
     1808                <p>
     1809                        <?php _e( 'No Site Health information has been gathered yet, you can do so by visiting the Site Health page, alternatively the checks will run periodically.' ); ?>
     1810                </p>
     1811
     1812                <p>
     1813                        <?php
     1814                        printf(
     1815                        // translators: %s: URL for the Site Health page.
     1816                                __( '<a href="%s">Visit the Site Health page</a> to gather information on about your site.' ),
     1817                                esc_url( admin_url( 'site-health.php' ) )
     1818                        );
     1819                        ?>
     1820                </p>
     1821
     1822        <?php else : ?>
     1823                <p>
     1824                        <?php if ( $issue_counts->critical > 0 ) : ?>
     1825                                <?php _e( 'Your site has critical issues that should be addressed as soon as possible to improve the performance or security of your website.' ); ?>
     1826                        <?php elseif ( $issues_total <= 0 ) : ?>
     1827                                <?php _e( 'Great job! Your site currently passes all site health checks.' ); ?>
     1828                        <?php else : ?>
     1829                                <?php _e( 'Your site health is looking quite good, but there are still some things you can do to improve the performance and security of your website.' ); ?>
     1830                        <?php endif; ?>
     1831                </p>
     1832        <?php endif; ?>
     1833
     1834        <?php if ( $issues_total > 0 && false !== $get_issues ) : ?>
     1835                <p>
     1836                        <?php
     1837                        printf(
     1838                        // translators: 1: Count of issues. 2: URL for the Site Health page.
     1839                                __( 'Take a look at the <strong>%1$d items</strong> on the <a href="%2$s">Site Health Check status page</a>.' ),
     1840                                $issues_total,
     1841                                esc_url( admin_url( 'site-health.php' ) )
     1842                        );
     1843                        ?>
     1844                </p>
     1845        <?php endif; ?>
     1846
     1847        <?php
     1848}
     1849
    17531850/**
    17541851 * Empty function usable by plugins to output empty dashboard widget (to be populated later by JS).
    17551852 *
  • src/wp-admin/includes/class-wp-site-health.php

     
    88 */
    99
    1010class WP_Site_Health {
     11        private static $instance = null;
     12
    1113        private $mysql_min_version_check;
    1214        private $mysql_rec_version_check;
    1315
     
    2931         * @since 5.2.0
    3032         */
    3133        public function __construct() {
     34                $this->maybe_create_scheduled_event();
     35
    3236                $this->prepare_sql_data();
    3337
    3438                $this->timeout_late_cron   = 0;
     
    4246                add_filter( 'admin_body_class', array( $this, 'admin_body_class' ) );
    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
    4767        /**
     
    5171         */
    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                }
    5777
     
    96116                                        );
    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 ) ) );
    121                                                 continue;
    122                                         }
    123                                 }
    124 
    125                                 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'] ) );
    128                                 }
    129                         }
    130 
    131                         foreach ( $tests['async'] as $test ) {
    132                                 if ( is_string( $test['test'] ) ) {
    133                                         $health_check_js_variables['site_status']['async'][] = array(
    134                                                 'test'      => $test['test'],
    135                                                 'completed' => false,
    136                                         );
    137                                 }
    138                         }
    139                 }
    140 
    141                 wp_localize_script( 'site-health', 'SiteHealth', $health_check_js_variables );
     119                                                $health_check_js_variables['site_status']['direct'][] = $this->perform_test( array( $this, $test_function ) );
     120                                                continue;
     121                                        }
     122                                }
     123
     124                                if ( is_callable( $test['test'] ) ) {
     125                                        $health_check_js_variables['site_status']['direct'][] = $this->perform_test( $test['test'] );
     126                                }
     127                        }
     128
     129                        foreach ( $tests['async'] as $test ) {
     130                                if ( is_string( $test['test'] ) ) {
     131                                        $health_check_js_variables['site_status']['async'][] = array(
     132                                                'test'      => $test['test'],
     133                                                'completed' => false,
     134                                        );
     135                                }
     136                        }
     137                }
     138
     139                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
    144176        /**
     
    20052037         * @return string The modified body class string.
    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
    20102047                return $body_class;
     
    21672204                        'message' => __( 'The loopback request to your site completed successfully.' ),
    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}
  • src/wp-includes/cron.php

     
    823823                        'interval' => DAY_IN_SECONDS,
    824824                        'display'  => __( 'Once Daily' ),
    825825                ),
     826                'weekly'     => array(
     827                        'interval' => 7 * DAY_IN_SECONDS,
     828                        'display'  => __( 'Once weekly' ),
     829                ),
    826830        );
    827831        /**
    828832         * Filters the non-default cron schedules.