Нет описания

functions.php 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. <?php
  2. /**
  3. * General API functions for scheduling actions
  4. */
  5. /**
  6. * Enqueue an action to run one time, as soon as possible
  7. *
  8. * @param string $hook The hook to trigger.
  9. * @param array $args Arguments to pass when the hook triggers.
  10. * @param string $group The group to assign this job to.
  11. * @return int The action ID.
  12. */
  13. function as_enqueue_async_action( $hook, $args = array(), $group = '' ) {
  14. if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
  15. return 0;
  16. }
  17. return ActionScheduler::factory()->async( $hook, $args, $group );
  18. }
  19. /**
  20. * Schedule an action to run one time
  21. *
  22. * @param int $timestamp When the job will run.
  23. * @param string $hook The hook to trigger.
  24. * @param array $args Arguments to pass when the hook triggers.
  25. * @param string $group The group to assign this job to.
  26. *
  27. * @return int The action ID.
  28. */
  29. function as_schedule_single_action( $timestamp, $hook, $args = array(), $group = '' ) {
  30. if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
  31. return 0;
  32. }
  33. return ActionScheduler::factory()->single( $hook, $args, $timestamp, $group );
  34. }
  35. /**
  36. * Schedule a recurring action
  37. *
  38. * @param int $timestamp When the first instance of the job will run.
  39. * @param int $interval_in_seconds How long to wait between runs.
  40. * @param string $hook The hook to trigger.
  41. * @param array $args Arguments to pass when the hook triggers.
  42. * @param string $group The group to assign this job to.
  43. *
  44. * @return int The action ID.
  45. */
  46. function as_schedule_recurring_action( $timestamp, $interval_in_seconds, $hook, $args = array(), $group = '' ) {
  47. if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
  48. return 0;
  49. }
  50. return ActionScheduler::factory()->recurring( $hook, $args, $timestamp, $interval_in_seconds, $group );
  51. }
  52. /**
  53. * Schedule an action that recurs on a cron-like schedule.
  54. *
  55. * @param int $base_timestamp The first instance of the action will be scheduled
  56. * to run at a time calculated after this timestamp matching the cron
  57. * expression. This can be used to delay the first instance of the action.
  58. * @param string $schedule A cron-link schedule string
  59. * @see http://en.wikipedia.org/wiki/Cron
  60. * * * * * * *
  61. * ┬ ┬ ┬ ┬ ┬ ┬
  62. * | | | | | |
  63. * | | | | | + year [optional]
  64. * | | | | +----- day of week (0 - 7) (Sunday=0 or 7)
  65. * | | | +---------- month (1 - 12)
  66. * | | +--------------- day of month (1 - 31)
  67. * | +-------------------- hour (0 - 23)
  68. * +------------------------- min (0 - 59)
  69. * @param string $hook The hook to trigger.
  70. * @param array $args Arguments to pass when the hook triggers.
  71. * @param string $group The group to assign this job to.
  72. *
  73. * @return int The action ID.
  74. */
  75. function as_schedule_cron_action( $timestamp, $schedule, $hook, $args = array(), $group = '' ) {
  76. if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
  77. return 0;
  78. }
  79. return ActionScheduler::factory()->cron( $hook, $args, $timestamp, $schedule, $group );
  80. }
  81. /**
  82. * Cancel the next occurrence of a scheduled action.
  83. *
  84. * While only the next instance of a recurring or cron action is unscheduled by this method, that will also prevent
  85. * all future instances of that recurring or cron action from being run. Recurring and cron actions are scheduled in
  86. * a sequence instead of all being scheduled at once. Each successive occurrence of a recurring action is scheduled
  87. * only after the former action is run. If the next instance is never run, because it's unscheduled by this function,
  88. * then the following instance will never be scheduled (or exist), which is effectively the same as being unscheduled
  89. * by this method also.
  90. *
  91. * @param string $hook The hook that the job will trigger.
  92. * @param array $args Args that would have been passed to the job.
  93. * @param string $group The group the job is assigned to.
  94. *
  95. * @return string|null The scheduled action ID if a scheduled action was found, or null if no matching action found.
  96. */
  97. function as_unschedule_action( $hook, $args = array(), $group = '' ) {
  98. if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
  99. return 0;
  100. }
  101. $params = array();
  102. if ( is_array($args) ) {
  103. $params['args'] = $args;
  104. }
  105. if ( !empty($group) ) {
  106. $params['group'] = $group;
  107. }
  108. $job_id = ActionScheduler::store()->find_action( $hook, $params );
  109. if ( ! empty( $job_id ) ) {
  110. ActionScheduler::store()->cancel_action( $job_id );
  111. }
  112. return $job_id;
  113. }
  114. /**
  115. * Cancel all occurrences of a scheduled action.
  116. *
  117. * @param string $hook The hook that the job will trigger.
  118. * @param array $args Args that would have been passed to the job.
  119. * @param string $group The group the job is assigned to.
  120. */
  121. function as_unschedule_all_actions( $hook, $args = array(), $group = '' ) {
  122. if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
  123. return;
  124. }
  125. if ( empty( $args ) ) {
  126. if ( ! empty( $hook ) && empty( $group ) ) {
  127. ActionScheduler_Store::instance()->cancel_actions_by_hook( $hook );
  128. return;
  129. }
  130. if ( ! empty( $group ) && empty( $hook ) ) {
  131. ActionScheduler_Store::instance()->cancel_actions_by_group( $group );
  132. return;
  133. }
  134. }
  135. do {
  136. $unscheduled_action = as_unschedule_action( $hook, $args, $group );
  137. } while ( ! empty( $unscheduled_action ) );
  138. }
  139. /**
  140. * Check if there is an existing action in the queue with a given hook, args and group combination.
  141. *
  142. * An action in the queue could be pending, in-progress or async. If the is pending for a time in
  143. * future, its scheduled date will be returned as a timestamp. If it is currently being run, or an
  144. * async action sitting in the queue waiting to be processed, in which case boolean true will be
  145. * returned. Or there may be no async, in-progress or pending action for this hook, in which case,
  146. * boolean false will be the return value.
  147. *
  148. * @param string $hook
  149. * @param array $args
  150. * @param string $group
  151. *
  152. * @return int|bool The timestamp for the next occurrence of a pending scheduled action, true for an async or in-progress action or false if there is no matching action.
  153. */
  154. function as_next_scheduled_action( $hook, $args = NULL, $group = '' ) {
  155. if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
  156. return false;
  157. }
  158. $params = array();
  159. if ( is_array($args) ) {
  160. $params['args'] = $args;
  161. }
  162. if ( !empty($group) ) {
  163. $params['group'] = $group;
  164. }
  165. $params['status'] = ActionScheduler_Store::STATUS_RUNNING;
  166. $job_id = ActionScheduler::store()->find_action( $hook, $params );
  167. if ( ! empty( $job_id ) ) {
  168. return true;
  169. }
  170. $params['status'] = ActionScheduler_Store::STATUS_PENDING;
  171. $job_id = ActionScheduler::store()->find_action( $hook, $params );
  172. if ( empty($job_id) ) {
  173. return false;
  174. }
  175. $job = ActionScheduler::store()->fetch_action( $job_id );
  176. $scheduled_date = $job->get_schedule()->get_date();
  177. if ( $scheduled_date ) {
  178. return (int) $scheduled_date->format( 'U' );
  179. } elseif ( NULL === $scheduled_date ) { // pending async action with NullSchedule
  180. return true;
  181. }
  182. return false;
  183. }
  184. /**
  185. * Find scheduled actions
  186. *
  187. * @param array $args Possible arguments, with their default values:
  188. * 'hook' => '' - the name of the action that will be triggered
  189. * 'args' => NULL - the args array that will be passed with the action
  190. * 'date' => NULL - the scheduled date of the action. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
  191. * 'date_compare' => '<=' - operator for testing "date". accepted values are '!=', '>', '>=', '<', '<=', '='
  192. * 'modified' => NULL - the date the action was last updated. Expects a DateTime object, a unix timestamp, or a string that can parsed with strtotime(). Used in UTC timezone.
  193. * 'modified_compare' => '<=' - operator for testing "modified". accepted values are '!=', '>', '>=', '<', '<=', '='
  194. * 'group' => '' - the group the action belongs to
  195. * 'status' => '' - ActionScheduler_Store::STATUS_COMPLETE or ActionScheduler_Store::STATUS_PENDING
  196. * 'claimed' => NULL - TRUE to find claimed actions, FALSE to find unclaimed actions, a string to find a specific claim ID
  197. * 'per_page' => 5 - Number of results to return
  198. * 'offset' => 0
  199. * 'orderby' => 'date' - accepted values are 'hook', 'group', 'modified', 'date' or 'none'
  200. * 'order' => 'ASC'
  201. *
  202. * @param string $return_format OBJECT, ARRAY_A, or ids.
  203. *
  204. * @return array
  205. */
  206. function as_get_scheduled_actions( $args = array(), $return_format = OBJECT ) {
  207. if ( ! ActionScheduler::is_initialized( __FUNCTION__ ) ) {
  208. return array();
  209. }
  210. $store = ActionScheduler::store();
  211. foreach ( array('date', 'modified') as $key ) {
  212. if ( isset($args[$key]) ) {
  213. $args[$key] = as_get_datetime_object($args[$key]);
  214. }
  215. }
  216. $ids = $store->query_actions( $args );
  217. if ( $return_format == 'ids' || $return_format == 'int' ) {
  218. return $ids;
  219. }
  220. $actions = array();
  221. foreach ( $ids as $action_id ) {
  222. $actions[$action_id] = $store->fetch_action( $action_id );
  223. }
  224. if ( $return_format == ARRAY_A ) {
  225. foreach ( $actions as $action_id => $action_object ) {
  226. $actions[$action_id] = get_object_vars($action_object);
  227. }
  228. }
  229. return $actions;
  230. }
  231. /**
  232. * Helper function to create an instance of DateTime based on a given
  233. * string and timezone. By default, will return the current date/time
  234. * in the UTC timezone.
  235. *
  236. * Needed because new DateTime() called without an explicit timezone
  237. * will create a date/time in PHP's timezone, but we need to have
  238. * assurance that a date/time uses the right timezone (which we almost
  239. * always want to be UTC), which means we need to always include the
  240. * timezone when instantiating datetimes rather than leaving it up to
  241. * the PHP default.
  242. *
  243. * @param mixed $date_string A date/time string. Valid formats are explained in http://php.net/manual/en/datetime.formats.php.
  244. * @param string $timezone A timezone identifier, like UTC or Europe/Lisbon. The list of valid identifiers is available http://php.net/manual/en/timezones.php.
  245. *
  246. * @return ActionScheduler_DateTime
  247. */
  248. function as_get_datetime_object( $date_string = null, $timezone = 'UTC' ) {
  249. if ( is_object( $date_string ) && $date_string instanceof DateTime ) {
  250. $date = new ActionScheduler_DateTime( $date_string->format( 'Y-m-d H:i:s' ), new DateTimeZone( $timezone ) );
  251. } elseif ( is_numeric( $date_string ) ) {
  252. $date = new ActionScheduler_DateTime( '@' . $date_string, new DateTimeZone( $timezone ) );
  253. } else {
  254. $date = new ActionScheduler_DateTime( $date_string, new DateTimeZone( $timezone ) );
  255. }
  256. return $date;
  257. }