ru-se.com

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

wp-cron.php (3939B)


      1 <?php
      2 /**
      3  * A pseudo-cron daemon for scheduling WordPress tasks.
      4  *
      5  * WP-Cron is triggered when the site receives a visit. In the scenario
      6  * where a site may not receive enough visits to execute scheduled tasks
      7  * in a timely manner, this file can be called directly or via a server
      8  * cron daemon for X number of times.
      9  *
     10  * Defining DISABLE_WP_CRON as true and calling this file directly are
     11  * mutually exclusive and the latter does not rely on the former to work.
     12  *
     13  * The HTTP request to this file will not slow down the visitor who happens to
     14  * visit when a scheduled cron event runs.
     15  *
     16  * @package WordPress
     17  */
     18 
     19 ignore_user_abort( true );
     20 
     21 /* Don't make the request block till we finish, if possible. */
     22 if ( function_exists( 'fastcgi_finish_request' ) && version_compare( phpversion(), '7.0.16', '>=' ) ) {
     23 	if ( ! headers_sent() ) {
     24 		header( 'Expires: Wed, 11 Jan 1984 05:00:00 GMT' );
     25 		header( 'Cache-Control: no-cache, must-revalidate, max-age=0' );
     26 	}
     27 
     28 	fastcgi_finish_request();
     29 }
     30 
     31 if ( ! empty( $_POST ) || defined( 'DOING_AJAX' ) || defined( 'DOING_CRON' ) ) {
     32 	die();
     33 }
     34 
     35 /**
     36  * Tell WordPress we are doing the cron task.
     37  *
     38  * @var bool
     39  */
     40 define( 'DOING_CRON', true );
     41 
     42 if ( ! defined( 'ABSPATH' ) ) {
     43 	/** Set up WordPress environment */
     44 	require_once __DIR__ . '/wp-load.php';
     45 }
     46 
     47 /**
     48  * Retrieves the cron lock.
     49  *
     50  * Returns the uncached `doing_cron` transient.
     51  *
     52  * @ignore
     53  * @since 3.3.0
     54  *
     55  * @global wpdb $wpdb WordPress database abstraction object.
     56  *
     57  * @return string|false Value of the `doing_cron` transient, 0|false otherwise.
     58  */
     59 function _get_cron_lock() {
     60 	global $wpdb;
     61 
     62 	$value = 0;
     63 	if ( wp_using_ext_object_cache() ) {
     64 		/*
     65 		 * Skip local cache and force re-fetch of doing_cron transient
     66 		 * in case another process updated the cache.
     67 		 */
     68 		$value = wp_cache_get( 'doing_cron', 'transient', true );
     69 	} else {
     70 		$row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", '_transient_doing_cron' ) );
     71 		if ( is_object( $row ) ) {
     72 			$value = $row->option_value;
     73 		}
     74 	}
     75 
     76 	return $value;
     77 }
     78 
     79 $crons = wp_get_ready_cron_jobs();
     80 if ( empty( $crons ) ) {
     81 	die();
     82 }
     83 
     84 $gmt_time = microtime( true );
     85 
     86 // The cron lock: a unix timestamp from when the cron was spawned.
     87 $doing_cron_transient = get_transient( 'doing_cron' );
     88 
     89 // Use global $doing_wp_cron lock, otherwise use the GET lock. If no lock, try to grab a new lock.
     90 if ( empty( $doing_wp_cron ) ) {
     91 	if ( empty( $_GET['doing_wp_cron'] ) ) {
     92 		// Called from external script/job. Try setting a lock.
     93 		if ( $doing_cron_transient && ( $doing_cron_transient + WP_CRON_LOCK_TIMEOUT > $gmt_time ) ) {
     94 			return;
     95 		}
     96 		$doing_wp_cron        = sprintf( '%.22F', microtime( true ) );
     97 		$doing_cron_transient = $doing_wp_cron;
     98 		set_transient( 'doing_cron', $doing_wp_cron );
     99 	} else {
    100 		$doing_wp_cron = $_GET['doing_wp_cron'];
    101 	}
    102 }
    103 
    104 /*
    105  * The cron lock (a unix timestamp set when the cron was spawned),
    106  * must match $doing_wp_cron (the "key").
    107  */
    108 if ( $doing_cron_transient !== $doing_wp_cron ) {
    109 	return;
    110 }
    111 
    112 foreach ( $crons as $timestamp => $cronhooks ) {
    113 	if ( $timestamp > $gmt_time ) {
    114 		break;
    115 	}
    116 
    117 	foreach ( $cronhooks as $hook => $keys ) {
    118 
    119 		foreach ( $keys as $k => $v ) {
    120 
    121 			$schedule = $v['schedule'];
    122 
    123 			if ( $schedule ) {
    124 				wp_reschedule_event( $timestamp, $schedule, $hook, $v['args'] );
    125 			}
    126 
    127 			wp_unschedule_event( $timestamp, $hook, $v['args'] );
    128 
    129 			/**
    130 			 * Fires scheduled events.
    131 			 *
    132 			 * @ignore
    133 			 * @since 2.1.0
    134 			 *
    135 			 * @param string $hook Name of the hook that was scheduled to be fired.
    136 			 * @param array  $args The arguments to be passed to the hook.
    137 			 */
    138 			do_action_ref_array( $hook, $v['args'] );
    139 
    140 			// If the hook ran too long and another cron process stole the lock, quit.
    141 			if ( _get_cron_lock() !== $doing_wp_cron ) {
    142 				return;
    143 			}
    144 		}
    145 	}
    146 }
    147 
    148 if ( _get_cron_lock() === $doing_wp_cron ) {
    149 	delete_transient( 'doing_cron' );
    150 }
    151 
    152 die();