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