wp/wp-includes/cron.php
changeset 5 5e2f62d02dcd
parent 0 d970ebf37754
child 7 cf61fcea0001
equal deleted inserted replaced
4:346c88efed21 5:5e2f62d02dcd
    11  * Schedules a hook which will be executed once by the WordPress actions core at
    11  * Schedules a hook which will be executed once by the WordPress actions core at
    12  * a time which you specify. The action will fire off when someone visits your
    12  * a time which you specify. The action will fire off when someone visits your
    13  * WordPress site, if the schedule time has passed.
    13  * WordPress site, if the schedule time has passed.
    14  *
    14  *
    15  * @since 2.1.0
    15  * @since 2.1.0
    16  * @link http://codex.wordpress.org/Function_Reference/wp_schedule_single_event
    16  * @link https://codex.wordpress.org/Function_Reference/wp_schedule_single_event
    17  *
    17  *
    18  * @param int $timestamp Timestamp for when to run the event.
    18  * @param int $timestamp Timestamp for when to run the event.
    19  * @param string $hook Action hook to execute when cron is run.
    19  * @param string $hook Action hook to execute when cron is run.
    20  * @param array $args Optional. Arguments to pass to the hook's callback function.
    20  * @param array $args Optional. Arguments to pass to the hook's callback function.
    21  */
    21  */
    22 function wp_schedule_single_event( $timestamp, $hook, $args = array()) {
    22 function wp_schedule_single_event( $timestamp, $hook, $args = array()) {
    23 	// don't schedule a duplicate if there's already an identical event due in the next 10 minutes
    23 	// don't schedule a duplicate if there's already an identical event due within 10 minutes of it
    24 	$next = wp_next_scheduled($hook, $args);
    24 	$next = wp_next_scheduled($hook, $args);
    25 	if ( $next && $next <= $timestamp + 10 * MINUTE_IN_SECONDS )
    25 	if ( $next && abs( $next - $timestamp ) <= 10 * MINUTE_IN_SECONDS ) {
    26 		return;
    26 		return;
       
    27 	}
    27 
    28 
    28 	$crons = _get_cron_array();
    29 	$crons = _get_cron_array();
    29 	$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => false, 'args' => $args );
    30 	$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => false, 'args' => $args );
    30 	$event = apply_filters('schedule_event', $event);
    31 	/**
       
    32 	 * Filter a single event before it is scheduled.
       
    33 	 *
       
    34 	 * @since 3.1.0
       
    35 	 *
       
    36 	 * @param object $event An object containing an event's data.
       
    37 	 */
       
    38 	$event = apply_filters( 'schedule_event', $event );
    31 
    39 
    32 	// A plugin disallowed this event
    40 	// A plugin disallowed this event
    33 	if ( ! $event )
    41 	if ( ! $event )
    34 		return false;
    42 		return false;
    35 
    43 
    56  *
    64  *
    57  * @param int $timestamp Timestamp for when to run the event.
    65  * @param int $timestamp Timestamp for when to run the event.
    58  * @param string $recurrence How often the event should recur.
    66  * @param string $recurrence How often the event should recur.
    59  * @param string $hook Action hook to execute when cron is run.
    67  * @param string $hook Action hook to execute when cron is run.
    60  * @param array $args Optional. Arguments to pass to the hook's callback function.
    68  * @param array $args Optional. Arguments to pass to the hook's callback function.
    61  * @return bool|null False on failure, null when complete with scheduling event.
    69  * @return false|null False on failure, null when complete with scheduling event.
    62  */
    70  */
    63 function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) {
    71 function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) {
    64 	$crons = _get_cron_array();
    72 	$crons = _get_cron_array();
    65 	$schedules = wp_get_schedules();
    73 	$schedules = wp_get_schedules();
    66 
    74 
    67 	if ( !isset( $schedules[$recurrence] ) )
    75 	if ( !isset( $schedules[$recurrence] ) )
    68 		return false;
    76 		return false;
    69 
    77 
    70 	$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => $recurrence, 'args' => $args, 'interval' => $schedules[$recurrence]['interval'] );
    78 	$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => $recurrence, 'args' => $args, 'interval' => $schedules[$recurrence]['interval'] );
    71 	$event = apply_filters('schedule_event', $event);
    79 	/** This filter is documented in wp-includes/cron.php */
       
    80 	$event = apply_filters( 'schedule_event', $event );
    72 
    81 
    73 	// A plugin disallowed this event
    82 	// A plugin disallowed this event
    74 	if ( ! $event )
    83 	if ( ! $event )
    75 		return false;
    84 		return false;
    76 
    85 
    88  *
    97  *
    89  * @param int $timestamp Timestamp for when to run the event.
    98  * @param int $timestamp Timestamp for when to run the event.
    90  * @param string $recurrence How often the event should recur.
    99  * @param string $recurrence How often the event should recur.
    91  * @param string $hook Action hook to execute when cron is run.
   100  * @param string $hook Action hook to execute when cron is run.
    92  * @param array $args Optional. Arguments to pass to the hook's callback function.
   101  * @param array $args Optional. Arguments to pass to the hook's callback function.
    93  * @return bool|null False on failure. Null when event is rescheduled.
   102  * @return false|null False on failure. Null when event is rescheduled.
    94  */
   103  */
    95 function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array()) {
   104 function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array() ) {
    96 	$crons = _get_cron_array();
   105 	$crons = _get_cron_array();
    97 	$schedules = wp_get_schedules();
   106 	$schedules = wp_get_schedules();
    98 	$key = md5(serialize($args));
   107 	$key = md5( serialize( $args ) );
    99 	$interval = 0;
   108 	$interval = 0;
   100 
   109 
   101 	// First we try to get it from the schedule
   110 	// First we try to get it from the schedule
   102 	if ( 0 == $interval )
   111 	if ( isset( $schedules[ $recurrence ] ) ) {
   103 		$interval = $schedules[$recurrence]['interval'];
   112 		$interval = $schedules[ $recurrence ]['interval'];
       
   113 	}
   104 	// Now we try to get it from the saved interval in case the schedule disappears
   114 	// Now we try to get it from the saved interval in case the schedule disappears
   105 	if ( 0 == $interval )
   115 	if ( 0 == $interval ) {
   106 		$interval = $crons[$timestamp][$hook][$key]['interval'];
   116 		$interval = $crons[ $timestamp ][ $hook ][ $key ]['interval'];
       
   117 	}
   107 	// Now we assume something is wrong and fail to schedule
   118 	// Now we assume something is wrong and fail to schedule
   108 	if ( 0 == $interval )
   119 	if ( 0 == $interval ) {
   109 		return false;
   120 		return false;
       
   121 	}
   110 
   122 
   111 	$now = time();
   123 	$now = time();
   112 
   124 
   113 	if ( $timestamp >= $now )
   125 	if ( $timestamp >= $now ) {
   114 		$timestamp = $now + $interval;
   126 		$timestamp = $now + $interval;
   115 	else
   127 	} else {
   116 		$timestamp = $now + ($interval - (($now - $timestamp) % $interval));
   128 		$timestamp = $now + ( $interval - ( ( $now - $timestamp ) % $interval ) );
       
   129 	}
   117 
   130 
   118 	wp_schedule_event( $timestamp, $recurrence, $hook, $args );
   131 	wp_schedule_event( $timestamp, $recurrence, $hook, $args );
   119 }
   132 }
   120 
   133 
   121 /**
   134 /**
   158 	if ( !is_array($args) ) {
   171 	if ( !is_array($args) ) {
   159 		_deprecated_argument( __FUNCTION__, '3.0', __('This argument has changed to an array to match the behavior of the other cron functions.') );
   172 		_deprecated_argument( __FUNCTION__, '3.0', __('This argument has changed to an array to match the behavior of the other cron functions.') );
   160 		$args = array_slice( func_get_args(), 1 );
   173 		$args = array_slice( func_get_args(), 1 );
   161 	}
   174 	}
   162 
   175 
   163 	while ( $timestamp = wp_next_scheduled( $hook, $args ) )
   176 	// This logic duplicates wp_next_scheduled()
   164 		wp_unschedule_event( $timestamp, $hook, $args );
   177 	// It's required due to a scenario where wp_unschedule_event() fails due to update_option() failing,
       
   178 	// and, wp_next_scheduled() returns the same schedule in an infinite loop.
       
   179 	$crons = _get_cron_array();
       
   180 	if ( empty( $crons ) )
       
   181 		return;
       
   182 
       
   183 	$key = md5( serialize( $args ) );
       
   184 	foreach ( $crons as $timestamp => $cron ) {
       
   185 		if ( isset( $cron[ $hook ][ $key ] ) ) {
       
   186 			wp_unschedule_event( $timestamp, $hook, $args );
       
   187 		}
       
   188 	}
   165 }
   189 }
   166 
   190 
   167 /**
   191 /**
   168  * Retrieve the next timestamp for a cron event.
   192  * Retrieve the next timestamp for a cron event.
   169  *
   193  *
   220 
   244 
   221 	$keys = array_keys( $crons );
   245 	$keys = array_keys( $crons );
   222 	if ( isset($keys[0]) && $keys[0] > $gmt_time )
   246 	if ( isset($keys[0]) && $keys[0] > $gmt_time )
   223 		return;
   247 		return;
   224 
   248 
   225 	if ( defined('ALTERNATE_WP_CRON') && ALTERNATE_WP_CRON ) {
   249 	if ( defined( 'ALTERNATE_WP_CRON' ) && ALTERNATE_WP_CRON ) {
   226 		if ( !empty($_POST) || defined('DOING_AJAX') )
   250 		if ( ! empty( $_POST ) || defined( 'DOING_AJAX' ) ||  defined( 'XMLRPC_REQUEST' ) ) {
   227 			return;
   251 			return;
       
   252 		}
   228 
   253 
   229 		$doing_wp_cron = sprintf( '%.22F', $gmt_time );
   254 		$doing_wp_cron = sprintf( '%.22F', $gmt_time );
   230 		set_transient( 'doing_cron', $doing_wp_cron );
   255 		set_transient( 'doing_cron', $doing_wp_cron );
   231 
   256 
   232 		ob_start();
   257 		ob_start();
   242 	}
   267 	}
   243 
   268 
   244 	$doing_wp_cron = sprintf( '%.22F', $gmt_time );
   269 	$doing_wp_cron = sprintf( '%.22F', $gmt_time );
   245 	set_transient( 'doing_cron', $doing_wp_cron );
   270 	set_transient( 'doing_cron', $doing_wp_cron );
   246 
   271 
       
   272 	/**
       
   273 	 * Filter the cron request arguments.
       
   274 	 *
       
   275 	 * @since 3.5.0
       
   276 	 *
       
   277 	 * @param array $cron_request_array {
       
   278 	 *     An array of cron request URL arguments.
       
   279 	 *
       
   280 	 *     @type string $url  The cron request URL.
       
   281 	 *     @type int    $key  The 22 digit GMT microtime.
       
   282 	 *     @type array  $args {
       
   283 	 *         An array of cron request arguments.
       
   284 	 *
       
   285 	 *         @type int  $timeout   The request timeout in seconds. Default .01 seconds.
       
   286 	 *         @type bool $blocking  Whether to set blocking for the request. Default false.
       
   287 	 *         @type bool $sslverify Whether SSL should be verified for the request. Default false.
       
   288 	 *     }
       
   289 	 * }
       
   290 	 */
   247 	$cron_request = apply_filters( 'cron_request', array(
   291 	$cron_request = apply_filters( 'cron_request', array(
   248 		'url' => site_url( 'wp-cron.php?doing_wp_cron=' . $doing_wp_cron ),
   292 		'url'  => add_query_arg( 'doing_wp_cron', $doing_wp_cron, site_url( 'wp-cron.php' ) ),
   249 		'key' => $doing_wp_cron,
   293 		'key'  => $doing_wp_cron,
   250 		'args' => array( 'timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters( 'https_local_ssl_verify', true ) )
   294 		'args' => array(
       
   295 			'timeout'   => 0.01,
       
   296 			'blocking'  => false,
       
   297 			/** This filter is documented in wp-includes/class-http.php */
       
   298 			'sslverify' => apply_filters( 'https_local_ssl_verify', false )
       
   299 		)
   251 	) );
   300 	) );
   252 
   301 
   253 	wp_remote_post( $cron_request['url'], $cron_request['args'] );
   302 	wp_remote_post( $cron_request['url'], $cron_request['args'] );
   254 }
   303 }
   255 
   304 
   298  * The 'interval' is a number in seconds of when the cron job should run. So for
   347  * The 'interval' is a number in seconds of when the cron job should run. So for
   299  * 'hourly', the time is 3600 or 60*60. For weekly, the value would be
   348  * 'hourly', the time is 3600 or 60*60. For weekly, the value would be
   300  * 60*60*24*7 or 604800. The value of 'interval' would then be 604800.
   349  * 60*60*24*7 or 604800. The value of 'interval' would then be 604800.
   301  *
   350  *
   302  * The 'display' is the description. For the 'weekly' key, the 'display' would
   351  * The 'display' is the description. For the 'weekly' key, the 'display' would
   303  * be <code>__('Once Weekly')</code>.
   352  * be `__( 'Once Weekly' )`.
   304  *
   353  *
   305  * For your plugin, you will be passed an array. you can easily add your
   354  * For your plugin, you will be passed an array. you can easily add your
   306  * schedule by doing the following.
   355  * schedule by doing the following.
   307  * <code>
   356  *
   308  * // filter parameter variable name is 'array'
   357  *     // Filter parameter variable name is 'array'.
   309  *	$array['weekly'] = array(
   358  *     $array['weekly'] = array(
   310  *		'interval' => 604800,
   359  *         'interval' => 604800,
   311  *		'display' => __('Once Weekly')
   360  *     	   'display'  => __( 'Once Weekly' )
   312  *	);
   361  *     );
   313  * </code>
   362  *
   314  *
   363  *
   315  * @since 2.1.0
   364  * @since 2.1.0
   316  *
   365  *
   317  * @return array
   366  * @return array
   318  */
   367  */
   320 	$schedules = array(
   369 	$schedules = array(
   321 		'hourly'     => array( 'interval' => HOUR_IN_SECONDS,      'display' => __( 'Once Hourly' ) ),
   370 		'hourly'     => array( 'interval' => HOUR_IN_SECONDS,      'display' => __( 'Once Hourly' ) ),
   322 		'twicedaily' => array( 'interval' => 12 * HOUR_IN_SECONDS, 'display' => __( 'Twice Daily' ) ),
   371 		'twicedaily' => array( 'interval' => 12 * HOUR_IN_SECONDS, 'display' => __( 'Twice Daily' ) ),
   323 		'daily'      => array( 'interval' => DAY_IN_SECONDS,       'display' => __( 'Once Daily' ) ),
   372 		'daily'      => array( 'interval' => DAY_IN_SECONDS,       'display' => __( 'Once Daily' ) ),
   324 	);
   373 	);
       
   374 	/**
       
   375 	 * Filter the non-default cron schedules.
       
   376 	 *
       
   377 	 * @since 2.1.0
       
   378 	 *
       
   379 	 * @param array $new_schedules An array of non-default cron schedules. Default empty.
       
   380 	 */
   325 	return array_merge( apply_filters( 'cron_schedules', array() ), $schedules );
   381 	return array_merge( apply_filters( 'cron_schedules', array() ), $schedules );
   326 }
   382 }
   327 
   383 
   328 /**
   384 /**
   329  * Retrieve Cron schedule for hook with arguments.
   385  * Retrieve Cron schedule for hook with arguments.