[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/ -> wp-cron.php (source)

   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  if ( ! headers_sent() ) {
  22      header( 'Expires: Wed, 11 Jan 1984 05:00:00 GMT' );
  23      header( 'Cache-Control: no-cache, must-revalidate, max-age=0' );
  24  }
  25  
  26  // Don't run cron until the request finishes, if possible.
  27  if ( function_exists( 'fastcgi_finish_request' ) ) {
  28      fastcgi_finish_request();
  29  } elseif ( function_exists( 'litespeed_finish_request' ) ) {
  30      litespeed_finish_request();
  31  }
  32  
  33  if ( ! empty( $_POST ) || defined( 'DOING_AJAX' ) || defined( 'DOING_CRON' ) ) {
  34      die();
  35  }
  36  
  37  /**
  38   * Tell WordPress the cron task is running.
  39   *
  40   * @var bool
  41   */
  42  define( 'DOING_CRON', true );
  43  
  44  if ( ! defined( 'ABSPATH' ) ) {
  45      /** Set up WordPress environment */
  46      require_once  __DIR__ . '/wp-load.php';
  47  }
  48  
  49  // Attempt to raise the PHP memory limit for cron event processing.
  50  wp_raise_memory_limit( 'cron' );
  51  
  52  /**
  53   * Retrieves the cron lock.
  54   *
  55   * Returns the uncached `doing_cron` transient.
  56   *
  57   * @ignore
  58   * @since 3.3.0
  59   *
  60   * @global wpdb $wpdb WordPress database abstraction object.
  61   *
  62   * @return string|int|false Value of the `doing_cron` transient, 0|false otherwise.
  63   */
  64  function _get_cron_lock() {
  65      global $wpdb;
  66  
  67      $value = 0;
  68      if ( wp_using_ext_object_cache() ) {
  69          /*
  70           * Skip local cache and force re-fetch of doing_cron transient
  71           * in case another process updated the cache.
  72           */
  73          $value = wp_cache_get( 'doing_cron', 'transient', true );
  74      } else {
  75          $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", '_transient_doing_cron' ) );
  76          if ( is_object( $row ) ) {
  77              $value = $row->option_value;
  78          }
  79      }
  80  
  81      return $value;
  82  }
  83  
  84  $crons = wp_get_ready_cron_jobs();
  85  if ( empty( $crons ) ) {
  86      die();
  87  }
  88  
  89  $gmt_time = microtime( true );
  90  
  91  // The cron lock: a unix timestamp from when the cron was spawned.
  92  $doing_cron_transient = get_transient( 'doing_cron' );
  93  
  94  // Use global $doing_wp_cron lock, otherwise use the GET lock. If no lock, try to grab a new lock.
  95  if ( empty( $doing_wp_cron ) ) {
  96      if ( empty( $_GET['doing_wp_cron'] ) ) {
  97          // Called from external script/job. Try setting a lock.
  98          if ( $doing_cron_transient && ( $doing_cron_transient + WP_CRON_LOCK_TIMEOUT > $gmt_time ) ) {
  99              return;
 100          }
 101          $doing_wp_cron        = sprintf( '%.22F', microtime( true ) );
 102          $doing_cron_transient = $doing_wp_cron;
 103          set_transient( 'doing_cron', $doing_wp_cron );
 104      } else {
 105          $doing_wp_cron = $_GET['doing_wp_cron'];
 106      }
 107  }
 108  
 109  /*
 110   * The cron lock (a unix timestamp set when the cron was spawned),
 111   * must match $doing_wp_cron (the "key").
 112   */
 113  if ( $doing_cron_transient !== $doing_wp_cron ) {
 114      return;
 115  }
 116  
 117  foreach ( $crons as $timestamp => $cronhooks ) {
 118      if ( $timestamp > $gmt_time ) {
 119          break;
 120      }
 121  
 122      foreach ( $cronhooks as $hook => $keys ) {
 123  
 124          foreach ( $keys as $k => $v ) {
 125  
 126              $schedule = $v['schedule'];
 127  
 128              if ( $schedule ) {
 129                  $result = wp_reschedule_event( $timestamp, $schedule, $hook, $v['args'], true );
 130  
 131                  if ( is_wp_error( $result ) ) {
 132                      error_log(
 133                          sprintf(
 134                              /* translators: 1: Hook name, 2: Error code, 3: Error message, 4: Event data. */
 135                              __( 'Cron reschedule event error for hook: %1$s, Error code: %2$s, Error message: %3$s, Data: %4$s' ),
 136                              $hook,
 137                              $result->get_error_code(),
 138                              $result->get_error_message(),
 139                              wp_json_encode( $v )
 140                          )
 141                      );
 142  
 143                      /**
 144                       * Fires if an error happens when rescheduling a cron event.
 145                       *
 146                       * @since 6.1.0
 147                       *
 148                       * @param WP_Error $result The WP_Error object.
 149                       * @param string   $hook   Action hook to execute when the event is run.
 150                       * @param array    $v      Event data.
 151                       */
 152                      do_action( 'cron_reschedule_event_error', $result, $hook, $v );
 153                  }
 154              }
 155  
 156              $result = wp_unschedule_event( $timestamp, $hook, $v['args'], true );
 157  
 158              if ( is_wp_error( $result ) ) {
 159                  error_log(
 160                      sprintf(
 161                          /* translators: 1: Hook name, 2: Error code, 3: Error message, 4: Event data. */
 162                          __( 'Cron unschedule event error for hook: %1$s, Error code: %2$s, Error message: %3$s, Data: %4$s' ),
 163                          $hook,
 164                          $result->get_error_code(),
 165                          $result->get_error_message(),
 166                          wp_json_encode( $v )
 167                      )
 168                  );
 169  
 170                  /**
 171                   * Fires if an error happens when unscheduling a cron event.
 172                   *
 173                   * @since 6.1.0
 174                   *
 175                   * @param WP_Error $result The WP_Error object.
 176                   * @param string   $hook   Action hook to execute when the event is run.
 177                   * @param array    $v      Event data.
 178                   */
 179                  do_action( 'cron_unschedule_event_error', $result, $hook, $v );
 180              }
 181  
 182              /**
 183               * Fires scheduled events.
 184               *
 185               * @ignore
 186               * @since 2.1.0
 187               *
 188               * @param string $hook Name of the hook that was scheduled to be fired.
 189               * @param array  $args The arguments to be passed to the hook.
 190               */
 191              do_action_ref_array( $hook, $v['args'] );
 192  
 193              // If the hook ran too long and another cron process stole the lock, quit.
 194              if ( _get_cron_lock() !== $doing_wp_cron ) {
 195                  return;
 196              }
 197          }
 198      }
 199  }
 200  
 201  if ( _get_cron_lock() === $doing_wp_cron ) {
 202      delete_transient( 'doing_cron' );
 203  }
 204  
 205  die();


Generated : Thu Nov 21 08:20:01 2024 Cross-referenced by PHPXref