Make WordPress Core

Ticket #23133: cron.php.diff

File cron.php.diff, 4.6 KB (added by loushou, 10 years ago)

possible patch for check and message

  • src/wp-includes/cron.php

     
    244244        $keys = array_keys( $crons );
    245245        if ( isset($keys[0]) && $keys[0] > $gmt_time )
    246246                return;
     247       
     248        // maybe force alternate cron if server setup is unusual
     249        $force_alternate_wp_cron = _maybe_force_alternate_wp_cron();
    247250
    248         if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
     251        if ( $force_alternate_wp_cron || ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) ) {
    249252                if ( ! empty( $_POST ) || defined( 'DOING_AJAX' ) ||  defined( 'XMLRPC_REQUEST' ) ) {
    250253                        return;
    251254                }
     
    302305}
    303306
    304307/**
     308 * Test the server setup to see if we need to fallback to the 'alternate cron' method.
     309 * Some server setups, for some reason do not allow loopback http requests. This
     310 * function specifically tests whether that functionality is available, and cachees
     311 * the result for 12 hours.
     312 *
     313 * @since 4.0.1
     314 *
     315 * @return bool True, if we need to force alternate cron because of server setup, False otherwise
     316 */
     317function _maybe_force_alternate_wp_cron() {
     318
     319        // if a response has been cached from earlier, then just reuse it
     320        $cached_response = get_transient( 'loopback_response' );
     321
     322        // if no cache exists, and we are not already forcing alternate cron using another method
     323        if ( ! $cached_response && defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
     324                // cache buster
     325                $rnd = substr( md5( time() . NONCE_SALT ), 10, 10 );
     326
     327                // create an unfiltered request to test our loopback connection with
     328                $loopback_request = array(
     329                        'url'  => add_query_arg( 'wp_loopback_test', $loopback_request, site_url( 'wp-cron.php' ) ),
     330                        'args' => array(
     331                                /* short timeout for the request */
     332                                'timeout'   => 0.01,
     333                                /* make this request blocking so that we get a response code */
     334                                'blocking'  => true,
     335                                /* force the wp-cron.php script to die early by sending post data */
     336                                'body'      => array( 'wp_loopback_test_chk' => sha1( $loopback_request ) ),
     337                                /** This filter is documented in wp-includes/class-http.php */
     338                                'sslverify' => apply_filters( 'https_local_ssl_verify', false )
     339                        )
     340                );
     341
     342                // fetch the response from the server
     343                $response = wp_remote_post( $loopback_request['url'], $loopback_request['args'] );
     344
     345                // default the response to an unknown error, because wp_remote_post could return a WP_Error.
     346                // if the WP_Error is returned, the failure is the same as a non-200 response
     347                $cached_response = 'ERROR';
     348
     349                // parse the response into just a response code, if it is present
     350                if ( is_array($response) && isset( $response['response'], $response['response']['code'] ) ) {
     351                        $cached_response = $response['response']['code'];
     352                }
     353
     354                // cache the response
     355                set_transient( 'loopback_response', $cached_response, DAY_IN_SECONDS / 2 );
     356        }
     357
     358        // if our response is 200, then we are good. otherwise we need to force alternate cron
     359        return $cached_response != 200;
     360}
     361
     362/**
     363 * Performs a check when the admin loads, to see if the server is setup so that WP Cron can
     364 * function normally. Upon failure, it spawns an admin notice.
     365 *
     366 * @since 4.0.1
     367 *
     368 * @return null Simply checks and spawns a notice if needed
     369 */
     370function wp_cron_admin_check() {
     371
     372        // check if the cron is currently being forced to use the 'alternate cron' method
     373        // only perform this check if the current user needs to know about it
     374        // Issue: https://core.trac.wordpress.org/ticket/23133
     375        // ticket was created in regards to failed future posts, which is handled by cron,
     376        // thus the edit_posts permission sounds most logical
     377        if ( current_user_can( 'edit_posts' ) &&  _maybe_force_alternate_wp_cron() ) {
     378                // if we are currently forcing it, then add a notice about it in the admin
     379                add_action( 'admin_notices', 'wp_cron_admin_check_failed_message' );
     380        }
     381}
     382add_action( 'admin_init', 'wp_cron_admin_check' );
     383
     384/**
     385 * Displays an admin notice, informing the admin user they have been switched to the
     386 * Alternative Cron method. Definitely needs some verbiage work, and probably a translation.
     387 *
     388 * @since 4.0.1
     389 *
     390 * @return null Simply displays a message
     391 */
     392function wp_cron_admin_check_failed_message() {
     393        echo '<div id="alternate-cron-force" class="error"><p>';
     394        echo __( 'Your server is preventing WP Cron from functioning properly. ' );
     395        echo __( 'As a fallback, you have been switched to using <a href="http://codex.wordpress.org/Editing_wp-config.php#Alternative_Cron">Alternative Cron</a> for now. ' );
     396        echo '</p></div>';
     397}
     398
     399/**
    305400 * Run scheduled callbacks or spawn cron for all scheduled events.
    306401 *
    307402 * @since 2.1.0