web/wp-includes/cron.php
changeset 194 32102edaa81b
parent 136 bde1974c263b
child 204 09a1c134465b
equal deleted inserted replaced
193:2f6f6f7551ca 194:32102edaa81b
    24 	$next = wp_next_scheduled($hook, $args);
    24 	$next = wp_next_scheduled($hook, $args);
    25 	if ( $next && $next <= $timestamp + 600 )
    25 	if ( $next && $next <= $timestamp + 600 )
    26 		return;
    26 		return;
    27 
    27 
    28 	$crons = _get_cron_array();
    28 	$crons = _get_cron_array();
    29 	$key = md5(serialize($args));
    29 	$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => false, 'args' => $args );
    30 	$crons[$timestamp][$hook][$key] = array( 'schedule' => false, 'args' => $args );
    30 	$event = apply_filters('schedule_event', $event);
       
    31 
       
    32 	// A plugin disallowed this event
       
    33 	if ( ! $event )
       
    34 		return false;
       
    35 
       
    36 	$key = md5(serialize($event->args));
       
    37 
       
    38 	$crons[$event->timestamp][$event->hook][$key] = array( 'schedule' => $event->schedule, 'args' => $event->args );
    31 	uksort( $crons, "strnatcasecmp" );
    39 	uksort( $crons, "strnatcasecmp" );
    32 	_set_cron_array( $crons );
    40 	_set_cron_array( $crons );
    33 }
    41 }
    34 
    42 
    35 /**
    43 /**
    37  *
    45  *
    38  * Schedules a hook which will be executed by the WordPress actions core on a
    46  * Schedules a hook which will be executed by the WordPress actions core on a
    39  * specific interval, specified by you. The action will trigger when someone
    47  * specific interval, specified by you. The action will trigger when someone
    40  * visits your WordPress site, if the scheduled time has passed.
    48  * visits your WordPress site, if the scheduled time has passed.
    41  *
    49  *
    42  * Valid values for the recurrence are hourly, daily and twicedaily.  These can
    50  * Valid values for the recurrence are hourly, daily and twicedaily. These can
    43  * be extended using the cron_schedules filter in wp_get_schedules().
    51  * be extended using the cron_schedules filter in wp_get_schedules().
       
    52  *
       
    53  * Use wp_next_scheduled() to prevent duplicates
    44  *
    54  *
    45  * @since 2.1.0
    55  * @since 2.1.0
    46  *
    56  *
    47  * @param int $timestamp Timestamp for when to run the event.
    57  * @param int $timestamp Timestamp for when to run the event.
    48  * @param string $recurrence How often the event should recur.
    58  * @param string $recurrence How often the event should recur.
    51  * @return bool|null False on failure, null when complete with scheduling event.
    61  * @return bool|null False on failure, null when complete with scheduling event.
    52  */
    62  */
    53 function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) {
    63 function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) {
    54 	$crons = _get_cron_array();
    64 	$crons = _get_cron_array();
    55 	$schedules = wp_get_schedules();
    65 	$schedules = wp_get_schedules();
    56 	$key = md5(serialize($args));
    66 
    57 	if ( !isset( $schedules[$recurrence] ) )
    67 	if ( !isset( $schedules[$recurrence] ) )
    58 		return false;
    68 		return false;
    59 	$crons[$timestamp][$hook][$key] = array( 'schedule' => $recurrence, 'args' => $args, 'interval' => $schedules[$recurrence]['interval'] );
    69 
       
    70 	$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => $recurrence, 'args' => $args, 'interval' => $schedules[$recurrence]['interval'] );
       
    71 	$event = apply_filters('schedule_event', $event);
       
    72 
       
    73 	// A plugin disallowed this event
       
    74 	if ( ! $event )
       
    75 		return false;
       
    76 
       
    77 	$key = md5(serialize($event->args));
       
    78 
       
    79 	$crons[$event->timestamp][$event->hook][$key] = array( 'schedule' => $event->schedule, 'args' => $event->args, 'interval' => $event->interval );
    60 	uksort( $crons, "strnatcasecmp" );
    80 	uksort( $crons, "strnatcasecmp" );
    61 	_set_cron_array( $crons );
    81 	_set_cron_array( $crons );
    62 }
    82 }
    63 
    83 
    64 /**
    84 /**
    88 	if ( 0 == $interval )
   108 	if ( 0 == $interval )
    89 		return false;
   109 		return false;
    90 
   110 
    91 	$now = time();
   111 	$now = time();
    92 
   112 
    93     if ( $timestamp >= $now )
   113 	if ( $timestamp >= $now )
    94         $timestamp = $now + $interval;
   114 		$timestamp = $now + $interval;
    95     else
   115 	else
    96         $timestamp = $now + ($interval - (($now - $timestamp) % $interval));
   116 		$timestamp = $now + ($interval - (($now - $timestamp) % $interval));
    97 
   117 
    98 	wp_schedule_event( $timestamp, $recurrence, $hook, $args );
   118 	wp_schedule_event( $timestamp, $recurrence, $hook, $args );
    99 }
   119 }
   100 
   120 
   101 /**
   121 /**
   128  * Unschedule all cron jobs attached to a specific hook.
   148  * Unschedule all cron jobs attached to a specific hook.
   129  *
   149  *
   130  * @since 2.1.0
   150  * @since 2.1.0
   131  *
   151  *
   132  * @param string $hook Action hook, the execution of which will be unscheduled.
   152  * @param string $hook Action hook, the execution of which will be unscheduled.
   133  * @param mixed $args,... Optional. Event arguments.
   153  * @param array $args Optional. Arguments that were to be pass to the hook's callback function.
   134  */
   154  */
   135 function wp_clear_scheduled_hook( $hook ) {
   155 function wp_clear_scheduled_hook( $hook, $args = array() ) {
   136 	$args = array_slice( func_get_args(), 1 );
   156 	// Backward compatibility
       
   157 	// Previously this function took the arguments as discrete vars rather than an array like the rest of the API
       
   158 	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.') );
       
   160 		$args = array_slice( func_get_args(), 1 );
       
   161 	}
   137 
   162 
   138 	while ( $timestamp = wp_next_scheduled( $hook, $args ) )
   163 	while ( $timestamp = wp_next_scheduled( $hook, $args ) )
   139 		wp_unschedule_event( $timestamp, $hook, $args );
   164 		wp_unschedule_event( $timestamp, $hook, $args );
   140 }
   165 }
   141 
   166 
   167  *
   192  *
   168  * @return null Cron could not be spawned, because it is not needed to run.
   193  * @return null Cron could not be spawned, because it is not needed to run.
   169  */
   194  */
   170 function spawn_cron( $local_time = 0 ) {
   195 function spawn_cron( $local_time = 0 ) {
   171 
   196 
   172 	if ( !$local_time )
   197 	if ( ! $local_time )
   173 		$local_time = time();
   198 		$local_time = microtime( true );
   174 
   199 
   175 	if ( defined('DOING_CRON') || isset($_GET['doing_wp_cron']) )
   200 	if ( defined('DOING_CRON') || isset($_GET['doing_wp_cron']) )
   176 		return;
       
   177 
       
   178 	/*
       
   179 	 * do not even start the cron if local server timer has drifted
       
   180 	 * such as due to power failure, or misconfiguration
       
   181 	 */
       
   182 	$timer_accurate = check_server_timer( $local_time );
       
   183 	if ( !$timer_accurate )
       
   184 		return;
   201 		return;
   185 
   202 
   186 	/*
   203 	/*
   187 	* multiple processes on multiple web servers can run this code concurrently
   204 	* multiple processes on multiple web servers can run this code concurrently
   188 	* try to make this as atomic as possible by setting doing_cron switch
   205 	* try to make this as atomic as possible by setting doing_cron switch
   189 	*/
   206 	*/
   190 	$flag = get_transient('doing_cron');
   207 	$lock = get_transient('doing_cron');
   191 
   208 
   192 	if ( $flag > $local_time + 10*60 )
   209 	if ( $lock > $local_time + 10*60 )
   193 		$flag = 0;
   210 		$lock = 0;
   194 
   211 
   195 	// don't run if another process is currently running it or more than once every 60 sec.
   212 	// don't run if another process is currently running it or more than once every 60 sec.
   196 	if ( $flag + 60 > $local_time )
   213 	if ( $lock + WP_CRON_LOCK_TIMEOUT > $local_time )
   197 		return;
   214 		return;
   198 
   215 
   199 	//sanity check
   216 	//sanity check
   200 	$crons = _get_cron_array();
   217 	$crons = _get_cron_array();
   201 	if ( !is_array($crons) )
   218 	if ( !is_array($crons) )
   207 
   224 
   208 	if ( defined('ALTERNATE_WP_CRON') && ALTERNATE_WP_CRON ) {
   225 	if ( defined('ALTERNATE_WP_CRON') && ALTERNATE_WP_CRON ) {
   209 		if ( !empty($_POST) || defined('DOING_AJAX') )
   226 		if ( !empty($_POST) || defined('DOING_AJAX') )
   210 			return;
   227 			return;
   211 
   228 
   212 		set_transient( 'doing_cron', $local_time );
   229 		$doing_wp_cron = sprintf( '%.22F', $local_time );
       
   230 		set_transient( 'doing_cron', $doing_wp_cron );
   213 
   231 
   214 		ob_start();
   232 		ob_start();
   215 		wp_redirect( add_query_arg('doing_wp_cron', '', stripslashes($_SERVER['REQUEST_URI'])) );
   233 		wp_redirect( add_query_arg('doing_wp_cron', $doing_wp_cron, stripslashes($_SERVER['REQUEST_URI'])) );
   216 		echo ' ';
   234 		echo ' ';
   217 
   235 
   218 		// flush any buffers and send the headers
   236 		// flush any buffers and send the headers
   219 		while ( @ob_end_flush() );
   237 		while ( @ob_end_flush() );
   220 		flush();
   238 		flush();
   221 
   239 
   222 		@include_once(ABSPATH . 'wp-cron.php');
   240 		WP_DEBUG ? include_once( ABSPATH . 'wp-cron.php' ) : @include_once( ABSPATH . 'wp-cron.php' );
   223 		return;
   241 		return;
   224 	}
   242 	}
   225 
   243 
   226 	set_transient( 'doing_cron', $local_time );
   244 	$doing_wp_cron = sprintf( '%.22F', $local_time );
   227 
   245 	set_transient( 'doing_cron', $doing_wp_cron );
   228 	$cron_url = get_option( 'siteurl' ) . '/wp-cron.php?doing_wp_cron';
   246 
   229 	wp_remote_post( $cron_url, array('timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters('https_local_ssl_verify', true)) );
   247 	$cron_url = site_url( 'wp-cron.php?doing_wp_cron=' . $doing_wp_cron );
       
   248 	wp_remote_post( $cron_url, array( 'timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters( 'https_local_ssl_verify', true ) ) );
   230 }
   249 }
   231 
   250 
   232 /**
   251 /**
   233  * Run scheduled callbacks or spawn cron for all scheduled events.
   252  * Run scheduled callbacks or spawn cron for all scheduled events.
   234  *
   253  *
   243 		return;
   262 		return;
   244 
   263 
   245 	if ( false === $crons = _get_cron_array() )
   264 	if ( false === $crons = _get_cron_array() )
   246 		return;
   265 		return;
   247 
   266 
   248 	$local_time = time();
   267 	$local_time = microtime( true );
   249 	$keys = array_keys( $crons );
   268 	$keys = array_keys( $crons );
   250 	if ( isset($keys[0]) && $keys[0] > $local_time )
   269 	if ( isset($keys[0]) && $keys[0] > $local_time )
   251 		return;
   270 		return;
   252 
   271 
   253 	$schedules = wp_get_schedules();
   272 	$schedules = wp_get_schedules();
   386 
   405 
   387 	$new_cron['version'] = 2;
   406 	$new_cron['version'] = 2;
   388 	update_option( 'cron', $new_cron );
   407 	update_option( 'cron', $new_cron );
   389 	return $new_cron;
   408 	return $new_cron;
   390 }
   409 }
   391 
       
   392 // stub for checking server timer accuracy, using outside standard time sources
       
   393 function check_server_timer( $local_time ) {
       
   394 	return true;
       
   395 }