[ XREF Home ] [ Index ]

PHP Cross Reference of WordPress Trunk

Provided by Yoast

title

Body

[close]

/wp-includes/ -> cron.php (source)

   1  <?php
   2  /**
   3   * WordPress CRON API
   4   *
   5   * @package WordPress
   6   */
   7  
   8  /**
   9   * Schedules a hook to run only once.
  10   *
  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
  13   * WordPress site, if the schedule time has passed.
  14   *
  15   * @since 2.1.0
  16   * @link http://codex.wordpress.org/Function_Reference/wp_schedule_single_event
  17   *
  18   * @param int $timestamp Timestamp for when to run the event.
  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.
  21   */
  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
  24      $next = wp_next_scheduled($hook, $args);
  25      if ( $next && $next <= $timestamp + 600 )
  26          return;
  27  
  28      $crons = _get_cron_array();
  29      $event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, '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 );
  39      uksort( $crons, "strnatcasecmp" );
  40      _set_cron_array( $crons );
  41  }
  42  
  43  /**
  44   * Schedule a periodic event.
  45   *
  46   * Schedules a hook which will be executed by the WordPress actions core on a
  47   * specific interval, specified by you. The action will trigger when someone
  48   * visits your WordPress site, if the scheduled time has passed.
  49   *
  50   * Valid values for the recurrence are hourly, daily and twicedaily.  These can
  51   * be extended using the cron_schedules filter in wp_get_schedules().
  52   *
  53   * Use wp_next_scheduled() to prevent duplicates
  54   *
  55   * @since 2.1.0
  56   *
  57   * @param int $timestamp Timestamp for when to run the event.
  58   * @param string $recurrence How often the event should recur.
  59   * @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.
  61   * @return bool|null False on failure, null when complete with scheduling event.
  62   */
  63  function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) {
  64      $crons = _get_cron_array();
  65      $schedules = wp_get_schedules();
  66  
  67      if ( !isset( $schedules[$recurrence] ) )
  68          return false;
  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 );
  80      uksort( $crons, "strnatcasecmp" );
  81      _set_cron_array( $crons );
  82  }
  83  
  84  /**
  85   * Reschedule a recurring event.
  86   *
  87   * @since 2.1.0
  88   *
  89   * @param int $timestamp Timestamp for when to run the event.
  90   * @param string $recurrence How often the event should recur.
  91   * @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.
  93   * @return bool|null False on failure. Null when event is rescheduled.
  94   */
  95  function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array()) {
  96      $crons = _get_cron_array();
  97      $schedules = wp_get_schedules();
  98      $key = md5(serialize($args));
  99      $interval = 0;
 100  
 101      // First we try to get it from the schedule
 102      if ( 0 == $interval )
 103          $interval = $schedules[$recurrence]['interval'];
 104      // Now we try to get it from the saved interval in case the schedule disappears
 105      if ( 0 == $interval )
 106          $interval = $crons[$timestamp][$hook][$key]['interval'];
 107      // Now we assume something is wrong and fail to schedule
 108      if ( 0 == $interval )
 109          return false;
 110  
 111      $now = time();
 112  
 113      if ( $timestamp >= $now )
 114          $timestamp = $now + $interval;
 115      else
 116          $timestamp = $now + ($interval - (($now - $timestamp) % $interval));
 117  
 118      wp_schedule_event( $timestamp, $recurrence, $hook, $args );
 119  }
 120  
 121  /**
 122   * Unschedule a previously scheduled cron job.
 123   *
 124   * The $timestamp and $hook parameters are required, so that the event can be
 125   * identified.
 126   *
 127   * @since 2.1.0
 128   *
 129   * @param int $timestamp Timestamp for when to run the event.
 130   * @param string $hook Action hook, the execution of which will be unscheduled.
 131   * @param array $args Arguments to pass to the hook's callback function.
 132   * Although not passed to a callback function, these arguments are used
 133   * to uniquely identify the scheduled event, so they should be the same
 134   * as those used when originally scheduling the event.
 135   */
 136  function wp_unschedule_event( $timestamp, $hook, $args = array() ) {
 137      $crons = _get_cron_array();
 138      $key = md5(serialize($args));
 139      unset( $crons[$timestamp][$hook][$key] );
 140      if ( empty($crons[$timestamp][$hook]) )
 141          unset( $crons[$timestamp][$hook] );
 142      if ( empty($crons[$timestamp]) )
 143          unset( $crons[$timestamp] );
 144      _set_cron_array( $crons );
 145  }
 146  
 147  /**
 148   * Unschedule all cron jobs attached to a specific hook.
 149   *
 150   * @since 2.1.0
 151   *
 152   * @param string $hook Action hook, the execution of which will be unscheduled.
 153   * @param array $args Optional. Arguments that were to be pass to the hook's callback function.
 154   */
 155  function wp_clear_scheduled_hook( $hook, $args = array() ) {
 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      }
 162  
 163      while ( $timestamp = wp_next_scheduled( $hook, $args ) )
 164          wp_unschedule_event( $timestamp, $hook, $args );
 165  }
 166  
 167  /**
 168   * Retrieve the next timestamp for a cron event.
 169   *
 170   * @since 2.1.0
 171   *
 172   * @param string $hook Action hook to execute when cron is run.
 173   * @param array $args Optional. Arguments to pass to the hook's callback function.
 174   * @return bool|int The UNIX timestamp of the next time the scheduled event will occur.
 175   */
 176  function wp_next_scheduled( $hook, $args = array() ) {
 177      $crons = _get_cron_array();
 178      $key = md5(serialize($args));
 179      if ( empty($crons) )
 180          return false;
 181      foreach ( $crons as $timestamp => $cron ) {
 182          if ( isset( $cron[$hook][$key] ) )
 183              return $timestamp;
 184      }
 185      return false;
 186  }
 187  
 188  /**
 189   * Send request to run cron through HTTP request that doesn't halt page loading.
 190   *
 191   * @since 2.1.0
 192   *
 193   * @return null Cron could not be spawned, because it is not needed to run.
 194   */
 195  function spawn_cron( $local_time = 0 ) {
 196  
 197      if ( !$local_time )
 198          $local_time = time();
 199  
 200      if ( defined('DOING_CRON') || isset($_GET['doing_wp_cron']) )
 201          return;
 202  
 203      /*
 204      * multiple processes on multiple web servers can run this code concurrently
 205      * try to make this as atomic as possible by setting doing_cron switch
 206      */
 207      $flag = get_transient('doing_cron');
 208  
 209      if ( $flag > $local_time + 10*60 )
 210          $flag = 0;
 211  
 212      // don't run if another process is currently running it or more than once every 60 sec.
 213      if ( $flag + 60 > $local_time )
 214          return;
 215  
 216      //sanity check
 217      $crons = _get_cron_array();
 218      if ( !is_array($crons) )
 219          return;
 220  
 221      $keys = array_keys( $crons );
 222      if ( isset($keys[0]) && $keys[0] > $local_time )
 223          return;
 224  
 225      if ( defined('ALTERNATE_WP_CRON') && ALTERNATE_WP_CRON ) {
 226          if ( !empty($_POST) || defined('DOING_AJAX') )
 227              return;
 228  
 229          set_transient( 'doing_cron', $local_time );
 230  
 231          ob_start();
 232          wp_redirect( add_query_arg('doing_wp_cron', '', stripslashes($_SERVER['REQUEST_URI'])) );
 233          echo ' ';
 234  
 235          // flush any buffers and send the headers
 236          while ( @ob_end_flush() );
 237          flush();
 238  
 239          WP_DEBUG ? include_once ( ABSPATH . 'wp-cron.php' ) : @include_once( ABSPATH . 'wp-cron.php' );
 240          return;
 241      }
 242  
 243      set_transient( 'doing_cron', $local_time );
 244  
 245      $cron_url = get_option( 'siteurl' ) . '/wp-cron.php?doing_wp_cron';
 246      wp_remote_post( $cron_url, array('timeout' => 0.01, 'blocking' => false, 'sslverify' => apply_filters('https_local_ssl_verify', true)) );
 247  }
 248  
 249  /**
 250   * Run scheduled callbacks or spawn cron for all scheduled events.
 251   *
 252   * @since 2.1.0
 253   *
 254   * @return null When doesn't need to run Cron.
 255   */
 256  function wp_cron() {
 257  
 258      // Prevent infinite loops caused by lack of wp-cron.php
 259      if ( strpos($_SERVER['REQUEST_URI'], '/wp-cron.php') !== false || ( defined('DISABLE_WP_CRON') && DISABLE_WP_CRON ) )
 260          return;
 261  
 262      if ( false === $crons = _get_cron_array() )
 263          return;
 264  
 265      $local_time = time();
 266      $keys = array_keys( $crons );
 267      if ( isset($keys[0]) && $keys[0] > $local_time )
 268          return;
 269  
 270      $schedules = wp_get_schedules();
 271      foreach ( $crons as $timestamp => $cronhooks ) {
 272          if ( $timestamp > $local_time ) break;
 273          foreach ( (array) $cronhooks as $hook => $args ) {
 274              if ( isset($schedules[$hook]['callback']) && !call_user_func( $schedules[$hook]['callback'] ) )
 275                  continue;
 276              spawn_cron( $local_time );
 277              break 2;
 278          }
 279      }
 280  }
 281  
 282  /**
 283   * Retrieve supported and filtered Cron recurrences.
 284   *
 285   * The supported recurrences are 'hourly' and 'daily'. A plugin may add more by
 286   * hooking into the 'cron_schedules' filter. The filter accepts an array of
 287   * arrays. The outer array has a key that is the name of the schedule or for
 288   * example 'weekly'. The value is an array with two keys, one is 'interval' and
 289   * the other is 'display'.
 290   *
 291   * The 'interval' is a number in seconds of when the cron job should run. So for
 292   * 'hourly', the time is 3600 or 60*60. For weekly, the value would be
 293   * 60*60*24*7 or 604800. The value of 'interval' would then be 604800.
 294   *
 295   * The 'display' is the description. For the 'weekly' key, the 'display' would
 296   * be <code>__('Once Weekly')</code>.
 297   *
 298   * For your plugin, you will be passed an array. you can easily add your
 299   * schedule by doing the following.
 300   * <code>
 301   * // filter parameter variable name is 'array'
 302   *    $array['weekly'] = array(
 303   *        'interval' => 604800,
 304   *        'display' => __('Once Weekly')
 305   *    );
 306   * </code>
 307   *
 308   * @since 2.1.0
 309   *
 310   * @return array
 311   */
 312  function wp_get_schedules() {
 313      $schedules = array(
 314          'hourly' => array( 'interval' => 3600, 'display' => __('Once Hourly') ),
 315          'twicedaily' => array( 'interval' => 43200, 'display' => __('Twice Daily') ),
 316          'daily' => array( 'interval' => 86400, 'display' => __('Once Daily') ),
 317      );
 318      return array_merge( apply_filters( 'cron_schedules', array() ), $schedules );
 319  }
 320  
 321  /**
 322   * Retrieve Cron schedule for hook with arguments.
 323   *
 324   * @since 2.1.0
 325   *
 326   * @param string $hook Action hook to execute when cron is run.
 327   * @param array $args Optional. Arguments to pass to the hook's callback function.
 328   * @return string|bool False, if no schedule. Schedule on success.
 329   */
 330  function wp_get_schedule($hook, $args = array()) {
 331      $crons = _get_cron_array();
 332      $key = md5(serialize($args));
 333      if ( empty($crons) )
 334          return false;
 335      foreach ( $crons as $timestamp => $cron ) {
 336          if ( isset( $cron[$hook][$key] ) )
 337              return $cron[$hook][$key]['schedule'];
 338      }
 339      return false;
 340  }
 341  
 342  //
 343  // Private functions
 344  //
 345  
 346  /**
 347   * Retrieve cron info array option.
 348   *
 349   * @since 2.1.0
 350   * @access private
 351   *
 352   * @return array CRON info array.
 353   */
 354  function _get_cron_array()  {
 355      $cron = get_option('cron');
 356      if ( ! is_array($cron) )
 357          return false;
 358  
 359      if ( !isset($cron['version']) )
 360          $cron = _upgrade_cron_array($cron);
 361  
 362      unset($cron['version']);
 363  
 364      return $cron;
 365  }
 366  
 367  /**
 368   * Updates the CRON option with the new CRON array.
 369   *
 370   * @since 2.1.0
 371   * @access private
 372   *
 373   * @param array $cron Cron info array from {@link _get_cron_array()}.
 374   */
 375  function _set_cron_array($cron) {
 376      $cron['version'] = 2;
 377      update_option( 'cron', $cron );
 378  }
 379  
 380  /**
 381   * Upgrade a Cron info array.
 382   *
 383   * This function upgrades the Cron info array to version 2.
 384   *
 385   * @since 2.1.0
 386   * @access private
 387   *
 388   * @param array $cron Cron info array from {@link _get_cron_array()}.
 389   * @return array An upgraded Cron info array.
 390   */
 391  function _upgrade_cron_array($cron) {
 392      if ( isset($cron['version']) && 2 == $cron['version'])
 393          return $cron;
 394  
 395      $new_cron = array();
 396  
 397      foreach ( (array) $cron as $timestamp => $hooks) {
 398          foreach ( (array) $hooks as $hook => $args ) {
 399              $key = md5(serialize($args['args']));
 400              $new_cron[$timestamp][$hook][$key] = $args;
 401          }
 402      }
 403  
 404      $new_cron['version'] = 2;
 405      update_option( 'cron', $new_cron );
 406      return $new_cron;
 407  }


Generated: Wed Jun 1 08:30:02 2011 Cross-referenced by PHPXref 0.7
Provided by Yoast and awesome WordPress Hosting