[ Index ]

WordPress Cross Reference

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 + 10 * MINUTE_IN_SECONDS )
  26          return;
  27  
  28      $crons = _get_cron_array();
  29      $event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => false, 'args' => $args );
  30      /**
  31       * Filter a single event before it is scheduled.
  32       *
  33       * @since 3.1.0
  34       *
  35       * @param object $event An object containing an event's data.
  36       */
  37      $event = apply_filters( 'schedule_event', $event );
  38  
  39      // A plugin disallowed this event
  40      if ( ! $event )
  41          return false;
  42  
  43      $key = md5(serialize($event->args));
  44  
  45      $crons[$event->timestamp][$event->hook][$key] = array( 'schedule' => $event->schedule, 'args' => $event->args );
  46      uksort( $crons, "strnatcasecmp" );
  47      _set_cron_array( $crons );
  48  }
  49  
  50  /**
  51   * Schedule a periodic event.
  52   *
  53   * Schedules a hook which will be executed by the WordPress actions core on a
  54   * specific interval, specified by you. The action will trigger when someone
  55   * visits your WordPress site, if the scheduled time has passed.
  56   *
  57   * Valid values for the recurrence are hourly, daily and twicedaily. These can
  58   * be extended using the cron_schedules filter in wp_get_schedules().
  59   *
  60   * Use wp_next_scheduled() to prevent duplicates
  61   *
  62   * @since 2.1.0
  63   *
  64   * @param int $timestamp Timestamp for when to run the event.
  65   * @param string $recurrence How often the event should recur.
  66   * @param string $hook Action hook to execute when cron is run.
  67   * @param array $args Optional. Arguments to pass to the hook's callback function.
  68   * @return bool|null False on failure, null when complete with scheduling event.
  69   */
  70  function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) {
  71      $crons = _get_cron_array();
  72      $schedules = wp_get_schedules();
  73  
  74      if ( !isset( $schedules[$recurrence] ) )
  75          return false;
  76  
  77      $event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => $recurrence, 'args' => $args, 'interval' => $schedules[$recurrence]['interval'] );
  78      /** This filter is documented in wp-includes/cron.php */
  79      $event = apply_filters( 'schedule_event', $event );
  80  
  81      // A plugin disallowed this event
  82      if ( ! $event )
  83          return false;
  84  
  85      $key = md5(serialize($event->args));
  86  
  87      $crons[$event->timestamp][$event->hook][$key] = array( 'schedule' => $event->schedule, 'args' => $event->args, 'interval' => $event->interval );
  88      uksort( $crons, "strnatcasecmp" );
  89      _set_cron_array( $crons );
  90  }
  91  
  92  /**
  93   * Reschedule a recurring event.
  94   *
  95   * @since 2.1.0
  96   *
  97   * @param int $timestamp Timestamp for when to run the event.
  98   * @param string $recurrence How often the event should recur.
  99   * @param string $hook Action hook to execute when cron is run.
 100   * @param array $args Optional. Arguments to pass to the hook's callback function.
 101   * @return bool|null False on failure. Null when event is rescheduled.
 102   */
 103  function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array()) {
 104      $crons = _get_cron_array();
 105      $schedules = wp_get_schedules();
 106      $key = md5(serialize($args));
 107      $interval = 0;
 108  
 109      // First we try to get it from the schedule
 110      if ( 0 == $interval )
 111          $interval = $schedules[$recurrence]['interval'];
 112      // Now we try to get it from the saved interval in case the schedule disappears
 113      if ( 0 == $interval )
 114          $interval = $crons[$timestamp][$hook][$key]['interval'];
 115      // Now we assume something is wrong and fail to schedule
 116      if ( 0 == $interval )
 117          return false;
 118  
 119      $now = time();
 120  
 121      if ( $timestamp >= $now )
 122          $timestamp = $now + $interval;
 123      else
 124          $timestamp = $now + ($interval - (($now - $timestamp) % $interval));
 125  
 126      wp_schedule_event( $timestamp, $recurrence, $hook, $args );
 127  }
 128  
 129  /**
 130   * Unschedule a previously scheduled cron job.
 131   *
 132   * The $timestamp and $hook parameters are required, so that the event can be
 133   * identified.
 134   *
 135   * @since 2.1.0
 136   *
 137   * @param int $timestamp Timestamp for when to run the event.
 138   * @param string $hook Action hook, the execution of which will be unscheduled.
 139   * @param array $args Arguments to pass to the hook's callback function.
 140   * Although not passed to a callback function, these arguments are used
 141   * to uniquely identify the scheduled event, so they should be the same
 142   * as those used when originally scheduling the event.
 143   */
 144  function wp_unschedule_event( $timestamp, $hook, $args = array() ) {
 145      $crons = _get_cron_array();
 146      $key = md5(serialize($args));
 147      unset( $crons[$timestamp][$hook][$key] );
 148      if ( empty($crons[$timestamp][$hook]) )
 149          unset( $crons[$timestamp][$hook] );
 150      if ( empty($crons[$timestamp]) )
 151          unset( $crons[$timestamp] );
 152      _set_cron_array( $crons );
 153  }
 154  
 155  /**
 156   * Unschedule all cron jobs attached to a specific hook.
 157   *
 158   * @since 2.1.0
 159   *
 160   * @param string $hook Action hook, the execution of which will be unscheduled.
 161   * @param array $args Optional. Arguments that were to be pass to the hook's callback function.
 162   */
 163  function wp_clear_scheduled_hook( $hook, $args = array() ) {
 164      // Backward compatibility
 165      // Previously this function took the arguments as discrete vars rather than an array like the rest of the API
 166      if ( !is_array($args) ) {
 167          _deprecated_argument( __FUNCTION__, '3.0', __('This argument has changed to an array to match the behavior of the other cron functions.') );
 168          $args = array_slice( func_get_args(), 1 );
 169      }
 170  
 171      // This logic duplicates wp_next_scheduled()
 172      // It's required due to a scenario where wp_unschedule_event() fails due to update_option() failing,
 173      // and, wp_next_scheduled() returns the same schedule in an infinite loop.
 174      $crons = _get_cron_array();
 175      if ( empty( $crons ) )
 176          return;
 177  
 178      $key = md5( serialize( $args ) );
 179      foreach ( $crons as $timestamp => $cron ) {
 180          if ( isset( $cron[ $hook ][ $key ] ) ) {
 181              wp_unschedule_event( $timestamp, $hook, $args );
 182          }
 183      }
 184  }
 185  
 186  /**
 187   * Retrieve the next timestamp for a cron event.
 188   *
 189   * @since 2.1.0
 190   *
 191   * @param string $hook Action hook to execute when cron is run.
 192   * @param array $args Optional. Arguments to pass to the hook's callback function.
 193   * @return bool|int The UNIX timestamp of the next time the scheduled event will occur.
 194   */
 195  function wp_next_scheduled( $hook, $args = array() ) {
 196      $crons = _get_cron_array();
 197      $key = md5(serialize($args));
 198      if ( empty($crons) )
 199          return false;
 200      foreach ( $crons as $timestamp => $cron ) {
 201          if ( isset( $cron[$hook][$key] ) )
 202              return $timestamp;
 203      }
 204      return false;
 205  }
 206  
 207  /**
 208   * Send request to run cron through HTTP request that doesn't halt page loading.
 209   *
 210   * @since 2.1.0
 211   *
 212   * @return null Cron could not be spawned, because it is not needed to run.
 213   */
 214  function spawn_cron( $gmt_time = 0 ) {
 215  
 216      if ( ! $gmt_time )
 217          $gmt_time = microtime( true );
 218  
 219      if ( defined('DOING_CRON') || isset($_GET['doing_wp_cron']) )
 220          return;
 221  
 222      /*
 223      * multiple processes on multiple web servers can run this code concurrently
 224      * try to make this as atomic as possible by setting doing_cron switch
 225      */
 226      $lock = get_transient('doing_cron');
 227  
 228      if ( $lock > $gmt_time + 10 * MINUTE_IN_SECONDS )
 229          $lock = 0;
 230  
 231      // don't run if another process is currently running it or more than once every 60 sec.
 232      if ( $lock + WP_CRON_LOCK_TIMEOUT > $gmt_time )
 233          return;
 234  
 235      //sanity check
 236      $crons = _get_cron_array();
 237      if ( !is_array($crons) )
 238          return;
 239  
 240      $keys = array_keys( $crons );
 241      if ( isset($keys[0]) && $keys[0] > $gmt_time )
 242          return;
 243  
 244      if ( defined('ALTERNATE_WP_CRON') && ALTERNATE_WP_CRON ) {
 245          if ( !empty($_POST) || defined('DOING_AJAX') )
 246              return;
 247  
 248          $doing_wp_cron = sprintf( '%.22F', $gmt_time );
 249          set_transient( 'doing_cron', $doing_wp_cron );
 250  
 251          ob_start();
 252          wp_redirect( add_query_arg( 'doing_wp_cron', $doing_wp_cron, wp_unslash( $_SERVER['REQUEST_URI'] ) ) );
 253          echo ' ';
 254  
 255          // flush any buffers and send the headers
 256          while ( @ob_end_flush() );
 257          flush();
 258  
 259          WP_DEBUG ? include_once ( ABSPATH . 'wp-cron.php' ) : @include_once( ABSPATH . 'wp-cron.php' );
 260          return;
 261      }
 262  
 263      $doing_wp_cron = sprintf( '%.22F', $gmt_time );
 264      set_transient( 'doing_cron', $doing_wp_cron );
 265  
 266      /**
 267       * Filter the cron request arguments.
 268       *
 269       * @since 3.5.0
 270       *
 271       * @param array $cron_request_array {
 272       *     An array of cron request URL arguments.
 273       *
 274       *     @type string $url  The cron request URL.
 275       *     @type int    $key  The 22 digit GMT microtime.
 276       *     @type array  $args {
 277       *         An array of cron request arguments.
 278       *
 279       *         @type int  $timeout   The request timeout in seconds. Default .01 seconds.
 280       *         @type bool $blocking  Whether to set blocking for the request. Default false.
 281       *         @type bool $sslverify Whether to sslverify. Default true.
 282       *     }
 283       * }
 284       */
 285      $cron_request = apply_filters( 'cron_request', array(
 286          'url'  => add_query_arg( 'doing_wp_cron', $doing_wp_cron, site_url( 'wp-cron.php' ) ),
 287          'key'  => $doing_wp_cron,
 288          'args' => array(
 289              'timeout'   => 0.01,
 290              'blocking'  => false,
 291              /** This filter is documented in wp-includes/class-http.php */
 292              'sslverify' => apply_filters( 'https_local_ssl_verify', true )
 293          )
 294      ) );
 295  
 296      wp_remote_post( $cron_request['url'], $cron_request['args'] );
 297  }
 298  
 299  /**
 300   * Run scheduled callbacks or spawn cron for all scheduled events.
 301   *
 302   * @since 2.1.0
 303   *
 304   * @return null When doesn't need to run Cron.
 305   */
 306  function wp_cron() {
 307  
 308      // Prevent infinite loops caused by lack of wp-cron.php
 309      if ( strpos($_SERVER['REQUEST_URI'], '/wp-cron.php') !== false || ( defined('DISABLE_WP_CRON') && DISABLE_WP_CRON ) )
 310          return;
 311  
 312      if ( false === $crons = _get_cron_array() )
 313          return;
 314  
 315      $gmt_time = microtime( true );
 316      $keys = array_keys( $crons );
 317      if ( isset($keys[0]) && $keys[0] > $gmt_time )
 318          return;
 319  
 320      $schedules = wp_get_schedules();
 321      foreach ( $crons as $timestamp => $cronhooks ) {
 322          if ( $timestamp > $gmt_time ) break;
 323          foreach ( (array) $cronhooks as $hook => $args ) {
 324              if ( isset($schedules[$hook]['callback']) && !call_user_func( $schedules[$hook]['callback'] ) )
 325                  continue;
 326              spawn_cron( $gmt_time );
 327              break 2;
 328          }
 329      }
 330  }
 331  
 332  /**
 333   * Retrieve supported and filtered Cron recurrences.
 334   *
 335   * The supported recurrences are 'hourly' and 'daily'. A plugin may add more by
 336   * hooking into the 'cron_schedules' filter. The filter accepts an array of
 337   * arrays. The outer array has a key that is the name of the schedule or for
 338   * example 'weekly'. The value is an array with two keys, one is 'interval' and
 339   * the other is 'display'.
 340   *
 341   * The 'interval' is a number in seconds of when the cron job should run. So for
 342   * 'hourly', the time is 3600 or 60*60. For weekly, the value would be
 343   * 60*60*24*7 or 604800. The value of 'interval' would then be 604800.
 344   *
 345   * The 'display' is the description. For the 'weekly' key, the 'display' would
 346   * be <code>__('Once Weekly')</code>.
 347   *
 348   * For your plugin, you will be passed an array. you can easily add your
 349   * schedule by doing the following.
 350   * <code>
 351   * // filter parameter variable name is 'array'
 352   *    $array['weekly'] = array(
 353   *        'interval' => 604800,
 354   *        'display' => __('Once Weekly')
 355   *    );
 356   * </code>
 357   *
 358   * @since 2.1.0
 359   *
 360   * @return array
 361   */
 362  function wp_get_schedules() {
 363      $schedules = array(
 364          'hourly'     => array( 'interval' => HOUR_IN_SECONDS,      'display' => __( 'Once Hourly' ) ),
 365          'twicedaily' => array( 'interval' => 12 * HOUR_IN_SECONDS, 'display' => __( 'Twice Daily' ) ),
 366          'daily'      => array( 'interval' => DAY_IN_SECONDS,       'display' => __( 'Once Daily' ) ),
 367      );
 368      /**
 369       * Filter the non-default cron schedules.
 370       *
 371       * @since 2.1.0
 372       *
 373       * @param array $new_schedules An array of non-default cron schedules. Default empty.
 374       */
 375      return array_merge( apply_filters( 'cron_schedules', array() ), $schedules );
 376  }
 377  
 378  /**
 379   * Retrieve Cron schedule for hook with arguments.
 380   *
 381   * @since 2.1.0
 382   *
 383   * @param string $hook Action hook to execute when cron is run.
 384   * @param array $args Optional. Arguments to pass to the hook's callback function.
 385   * @return string|bool False, if no schedule. Schedule on success.
 386   */
 387  function wp_get_schedule($hook, $args = array()) {
 388      $crons = _get_cron_array();
 389      $key = md5(serialize($args));
 390      if ( empty($crons) )
 391          return false;
 392      foreach ( $crons as $timestamp => $cron ) {
 393          if ( isset( $cron[$hook][$key] ) )
 394              return $cron[$hook][$key]['schedule'];
 395      }
 396      return false;
 397  }
 398  
 399  //
 400  // Private functions
 401  //
 402  
 403  /**
 404   * Retrieve cron info array option.
 405   *
 406   * @since 2.1.0
 407   * @access private
 408   *
 409   * @return array CRON info array.
 410   */
 411  function _get_cron_array()  {
 412      $cron = get_option('cron');
 413      if ( ! is_array($cron) )
 414          return false;
 415  
 416      if ( !isset($cron['version']) )
 417          $cron = _upgrade_cron_array($cron);
 418  
 419      unset($cron['version']);
 420  
 421      return $cron;
 422  }
 423  
 424  /**
 425   * Updates the CRON option with the new CRON array.
 426   *
 427   * @since 2.1.0
 428   * @access private
 429   *
 430   * @param array $cron Cron info array from {@link _get_cron_array()}.
 431   */
 432  function _set_cron_array($cron) {
 433      $cron['version'] = 2;
 434      update_option( 'cron', $cron );
 435  }
 436  
 437  /**
 438   * Upgrade a Cron info array.
 439   *
 440   * This function upgrades the Cron info array to version 2.
 441   *
 442   * @since 2.1.0
 443   * @access private
 444   *
 445   * @param array $cron Cron info array from {@link _get_cron_array()}.
 446   * @return array An upgraded Cron info array.
 447   */
 448  function _upgrade_cron_array($cron) {
 449      if ( isset($cron['version']) && 2 == $cron['version'])
 450          return $cron;
 451  
 452      $new_cron = array();
 453  
 454      foreach ( (array) $cron as $timestamp => $hooks) {
 455          foreach ( (array) $hooks as $hook => $args ) {
 456              $key = md5(serialize($args['args']));
 457              $new_cron[$timestamp][$hook][$key] = $args;
 458          }
 459      }
 460  
 461      $new_cron['version'] = 2;
 462      update_option( 'cron', $new_cron );
 463      return $new_cron;
 464  }


Generated: Tue Mar 25 01:41:18 2014 WordPress honlapkészítés: online1.hu