| | 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 | */ |
| | 317 | function _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 | */ |
| | 370 | function 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 | } |
| | 382 | add_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 | */ |
| | 392 | function 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 | /** |