PageRenderTime 25ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/buddypress/bp-forums/bbpress/bb-includes/backpress/functions.wp-cron.php

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