You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

130 lines
3.2 KiB

  1. <?php
  2. /**
  3. * WordPress Cron Implementation for hosts, which do not offer CRON or for which
  4. * the user has not set up a CRON job pointing to this file.
  5. *
  6. * The HTTP request to this file will not slow down the visitor who happens to
  7. * visit when the cron job is needed to run.
  8. *
  9. * @package WordPress
  10. */
  11. ignore_user_abort(true);
  12. if ( !empty($_POST) || defined('DOING_AJAX') || defined('DOING_CRON') )
  13. die();
  14. /**
  15. * Tell WordPress we are doing the CRON task.
  16. *
  17. * @var bool
  18. */
  19. define('DOING_CRON', true);
  20. if ( !defined('ABSPATH') ) {
  21. /** Set up WordPress environment */
  22. require_once( dirname( __FILE__ ) . '/wp-load.php' );
  23. }
  24. /**
  25. * Retrieves the cron lock.
  26. *
  27. * Returns the uncached `doing_cron` transient.
  28. *
  29. * @ignore
  30. * @since 3.3.0
  31. *
  32. * @return string|false Value of the `doing_cron` transient, 0|false otherwise.
  33. */
  34. function _get_cron_lock() {
  35. global $wpdb;
  36. $value = 0;
  37. if ( wp_using_ext_object_cache() ) {
  38. /*
  39. * Skip local cache and force re-fetch of doing_cron transient
  40. * in case another process updated the cache.
  41. */
  42. $value = wp_cache_get( 'doing_cron', 'transient', true );
  43. } else {
  44. $row = $wpdb->get_row( $wpdb->prepare( "SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", '_transient_doing_cron' ) );
  45. if ( is_object( $row ) )
  46. $value = $row->option_value;
  47. }
  48. return $value;
  49. }
  50. if ( false === $crons = _get_cron_array() )
  51. die();
  52. $keys = array_keys( $crons );
  53. $gmt_time = microtime( true );
  54. if ( isset($keys[0]) && $keys[0] > $gmt_time )
  55. die();
  56. // The cron lock: a unix timestamp from when the cron was spawned.
  57. $doing_cron_transient = get_transient( 'doing_cron' );
  58. // Use global $doing_wp_cron lock otherwise use the GET lock. If no lock, trying grabbing a new lock.
  59. if ( empty( $doing_wp_cron ) ) {
  60. if ( empty( $_GET[ 'doing_wp_cron' ] ) ) {
  61. // Called from external script/job. Try setting a lock.
  62. if ( $doing_cron_transient && ( $doing_cron_transient + WP_CRON_LOCK_TIMEOUT > $gmt_time ) )
  63. return;
  64. $doing_cron_transient = $doing_wp_cron = sprintf( '%.22F', microtime( true ) );
  65. set_transient( 'doing_cron', $doing_wp_cron );
  66. } else {
  67. $doing_wp_cron = $_GET[ 'doing_wp_cron' ];
  68. }
  69. }
  70. /*
  71. * The cron lock (a unix timestamp set when the cron was spawned),
  72. * must match $doing_wp_cron (the "key").
  73. */
  74. if ( $doing_cron_transient != $doing_wp_cron )
  75. return;
  76. foreach ( $crons as $timestamp => $cronhooks ) {
  77. if ( $timestamp > $gmt_time )
  78. break;
  79. foreach ( $cronhooks as $hook => $keys ) {
  80. foreach ( $keys as $k => $v ) {
  81. $schedule = $v['schedule'];
  82. if ( $schedule != false ) {
  83. $new_args = array($timestamp, $schedule, $hook, $v['args']);
  84. call_user_func_array('wp_reschedule_event', $new_args);
  85. }
  86. wp_unschedule_event( $timestamp, $hook, $v['args'] );
  87. /**
  88. * Fires scheduled events.
  89. *
  90. * @ignore
  91. * @since 2.1.0
  92. *
  93. * @param string $hook Name of the hook that was scheduled to be fired.
  94. * @param array $args The arguments to be passed to the hook.
  95. */
  96. do_action_ref_array( $hook, $v['args'] );
  97. // If the hook ran too long and another cron process stole the lock, quit.
  98. if ( _get_cron_lock() != $doing_wp_cron )
  99. return;
  100. }
  101. }
  102. }
  103. if ( _get_cron_lock() == $doing_wp_cron )
  104. delete_transient( 'doing_cron' );
  105. die();