@@ -10,10 +10,10 @@ |
||
| 10 | 10 | */ |
| 11 | 11 | class RWMB_Post_Storage extends RWMB_Base_Storage { |
| 12 | 12 | |
| 13 | - /** |
|
| 14 | - * Object type. |
|
| 15 | - * |
|
| 16 | - * @var string |
|
| 17 | - */ |
|
| 18 | - protected $object_type = 'post'; |
|
| 13 | + /** |
|
| 14 | + * Object type. |
|
| 15 | + * |
|
| 16 | + * @var string |
|
| 17 | + */ |
|
| 18 | + protected $object_type = 'post'; |
|
| 19 | 19 | } |
@@ -9,41 +9,41 @@ |
||
| 9 | 9 | */ |
| 10 | 10 | class ActionScheduler_OptionLock extends ActionScheduler_Lock { |
| 11 | 11 | |
| 12 | - /** |
|
| 13 | - * Set a lock using options for a given amount of time (60 seconds by default). |
|
| 14 | - * |
|
| 15 | - * Using an autoloaded option avoids running database queries or other resource intensive tasks |
|
| 16 | - * on frequently triggered hooks, like 'init' or 'shutdown'. |
|
| 17 | - * |
|
| 18 | - * For example, ActionScheduler_QueueRunner->maybe_dispatch_async_request() uses a lock to avoid |
|
| 19 | - * calling ActionScheduler_QueueRunner->has_maximum_concurrent_batches() every time the 'shutdown', |
|
| 20 | - * hook is triggered, because that method calls ActionScheduler_QueueRunner->store->get_claim_count() |
|
| 21 | - * to find the current number of claims in the database. |
|
| 22 | - * |
|
| 23 | - * @param string $lock_type A string to identify different lock types. |
|
| 24 | - * @bool True if lock value has changed, false if not or if set failed. |
|
| 25 | - */ |
|
| 26 | - public function set( $lock_type ) { |
|
| 27 | - return update_option( $this->get_key( $lock_type ), time() + $this->get_duration( $lock_type ) ); |
|
| 28 | - } |
|
| 12 | + /** |
|
| 13 | + * Set a lock using options for a given amount of time (60 seconds by default). |
|
| 14 | + * |
|
| 15 | + * Using an autoloaded option avoids running database queries or other resource intensive tasks |
|
| 16 | + * on frequently triggered hooks, like 'init' or 'shutdown'. |
|
| 17 | + * |
|
| 18 | + * For example, ActionScheduler_QueueRunner->maybe_dispatch_async_request() uses a lock to avoid |
|
| 19 | + * calling ActionScheduler_QueueRunner->has_maximum_concurrent_batches() every time the 'shutdown', |
|
| 20 | + * hook is triggered, because that method calls ActionScheduler_QueueRunner->store->get_claim_count() |
|
| 21 | + * to find the current number of claims in the database. |
|
| 22 | + * |
|
| 23 | + * @param string $lock_type A string to identify different lock types. |
|
| 24 | + * @bool True if lock value has changed, false if not or if set failed. |
|
| 25 | + */ |
|
| 26 | + public function set( $lock_type ) { |
|
| 27 | + return update_option( $this->get_key( $lock_type ), time() + $this->get_duration( $lock_type ) ); |
|
| 28 | + } |
|
| 29 | 29 | |
| 30 | - /** |
|
| 31 | - * If a lock is set, return the timestamp it was set to expiry. |
|
| 32 | - * |
|
| 33 | - * @param string $lock_type A string to identify different lock types. |
|
| 34 | - * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire. |
|
| 35 | - */ |
|
| 36 | - public function get_expiration( $lock_type ) { |
|
| 37 | - return get_option( $this->get_key( $lock_type ) ); |
|
| 38 | - } |
|
| 30 | + /** |
|
| 31 | + * If a lock is set, return the timestamp it was set to expiry. |
|
| 32 | + * |
|
| 33 | + * @param string $lock_type A string to identify different lock types. |
|
| 34 | + * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire. |
|
| 35 | + */ |
|
| 36 | + public function get_expiration( $lock_type ) { |
|
| 37 | + return get_option( $this->get_key( $lock_type ) ); |
|
| 38 | + } |
|
| 39 | 39 | |
| 40 | - /** |
|
| 41 | - * Get the key to use for storing the lock in the transient |
|
| 42 | - * |
|
| 43 | - * @param string $lock_type A string to identify different lock types. |
|
| 44 | - * @return string |
|
| 45 | - */ |
|
| 46 | - protected function get_key( $lock_type ) { |
|
| 47 | - return sprintf( 'action_scheduler_lock_%s', $lock_type ); |
|
| 48 | - } |
|
| 40 | + /** |
|
| 41 | + * Get the key to use for storing the lock in the transient |
|
| 42 | + * |
|
| 43 | + * @param string $lock_type A string to identify different lock types. |
|
| 44 | + * @return string |
|
| 45 | + */ |
|
| 46 | + protected function get_key( $lock_type ) { |
|
| 47 | + return sprintf( 'action_scheduler_lock_%s', $lock_type ); |
|
| 48 | + } |
|
| 49 | 49 | } |
@@ -5,154 +5,154 @@ |
||
| 5 | 5 | */ |
| 6 | 6 | class ActionScheduler_QueueCleaner { |
| 7 | 7 | |
| 8 | - /** @var int */ |
|
| 9 | - protected $batch_size; |
|
| 10 | - |
|
| 11 | - /** @var ActionScheduler_Store */ |
|
| 12 | - private $store = null; |
|
| 13 | - |
|
| 14 | - /** |
|
| 15 | - * 31 days in seconds. |
|
| 16 | - * |
|
| 17 | - * @var int |
|
| 18 | - */ |
|
| 19 | - private $month_in_seconds = 2678400; |
|
| 20 | - |
|
| 21 | - /** |
|
| 22 | - * ActionScheduler_QueueCleaner constructor. |
|
| 23 | - * |
|
| 24 | - * @param ActionScheduler_Store $store The store instance. |
|
| 25 | - * @param int $batch_size The batch size. |
|
| 26 | - */ |
|
| 27 | - public function __construct( ActionScheduler_Store $store = null, $batch_size = 20 ) { |
|
| 28 | - $this->store = $store ? $store : ActionScheduler_Store::instance(); |
|
| 29 | - $this->batch_size = $batch_size; |
|
| 30 | - } |
|
| 31 | - |
|
| 32 | - public function delete_old_actions() { |
|
| 33 | - $lifespan = apply_filters( 'action_scheduler_retention_period', $this->month_in_seconds ); |
|
| 34 | - $cutoff = as_get_datetime_object($lifespan.' seconds ago'); |
|
| 35 | - |
|
| 36 | - $statuses_to_purge = array( |
|
| 37 | - ActionScheduler_Store::STATUS_COMPLETE, |
|
| 38 | - ActionScheduler_Store::STATUS_CANCELED, |
|
| 39 | - ); |
|
| 40 | - |
|
| 41 | - foreach ( $statuses_to_purge as $status ) { |
|
| 42 | - $actions_to_delete = $this->store->query_actions( array( |
|
| 43 | - 'status' => $status, |
|
| 44 | - 'modified' => $cutoff, |
|
| 45 | - 'modified_compare' => '<=', |
|
| 46 | - 'per_page' => $this->get_batch_size(), |
|
| 47 | - 'orderby' => 'none', |
|
| 48 | - ) ); |
|
| 49 | - |
|
| 50 | - foreach ( $actions_to_delete as $action_id ) { |
|
| 51 | - try { |
|
| 52 | - $this->store->delete_action( $action_id ); |
|
| 53 | - } catch ( Exception $e ) { |
|
| 54 | - |
|
| 55 | - /** |
|
| 56 | - * Notify 3rd party code of exceptions when deleting a completed action older than the retention period |
|
| 57 | - * |
|
| 58 | - * This hook provides a way for 3rd party code to log or otherwise handle exceptions relating to their |
|
| 59 | - * actions. |
|
| 60 | - * |
|
| 61 | - * @since 2.0.0 |
|
| 62 | - * |
|
| 63 | - * @param int $action_id The scheduled actions ID in the data store |
|
| 64 | - * @param Exception $e The exception thrown when attempting to delete the action from the data store |
|
| 65 | - * @param int $lifespan The retention period, in seconds, for old actions |
|
| 66 | - * @param int $count_of_actions_to_delete The number of old actions being deleted in this batch |
|
| 67 | - */ |
|
| 68 | - do_action( 'action_scheduler_failed_old_action_deletion', $action_id, $e, $lifespan, count( $actions_to_delete ) ); |
|
| 69 | - } |
|
| 70 | - } |
|
| 71 | - } |
|
| 72 | - } |
|
| 73 | - |
|
| 74 | - /** |
|
| 75 | - * Unclaim pending actions that have not been run within a given time limit. |
|
| 76 | - * |
|
| 77 | - * When called by ActionScheduler_Abstract_QueueRunner::run_cleanup(), the time limit passed |
|
| 78 | - * as a parameter is 10x the time limit used for queue processing. |
|
| 79 | - * |
|
| 80 | - * @param int $time_limit The number of seconds to allow a queue to run before unclaiming its pending actions. Default 300 (5 minutes). |
|
| 81 | - */ |
|
| 82 | - public function reset_timeouts( $time_limit = 300 ) { |
|
| 83 | - $timeout = apply_filters( 'action_scheduler_timeout_period', $time_limit ); |
|
| 84 | - if ( $timeout < 0 ) { |
|
| 85 | - return; |
|
| 86 | - } |
|
| 87 | - $cutoff = as_get_datetime_object($timeout.' seconds ago'); |
|
| 88 | - $actions_to_reset = $this->store->query_actions( array( |
|
| 89 | - 'status' => ActionScheduler_Store::STATUS_PENDING, |
|
| 90 | - 'modified' => $cutoff, |
|
| 91 | - 'modified_compare' => '<=', |
|
| 92 | - 'claimed' => true, |
|
| 93 | - 'per_page' => $this->get_batch_size(), |
|
| 94 | - 'orderby' => 'none', |
|
| 95 | - ) ); |
|
| 96 | - |
|
| 97 | - foreach ( $actions_to_reset as $action_id ) { |
|
| 98 | - $this->store->unclaim_action( $action_id ); |
|
| 99 | - do_action( 'action_scheduler_reset_action', $action_id ); |
|
| 100 | - } |
|
| 101 | - } |
|
| 102 | - |
|
| 103 | - /** |
|
| 104 | - * Mark actions that have been running for more than a given time limit as failed, based on |
|
| 105 | - * the assumption some uncatachable and unloggable fatal error occurred during processing. |
|
| 106 | - * |
|
| 107 | - * When called by ActionScheduler_Abstract_QueueRunner::run_cleanup(), the time limit passed |
|
| 108 | - * as a parameter is 10x the time limit used for queue processing. |
|
| 109 | - * |
|
| 110 | - * @param int $time_limit The number of seconds to allow an action to run before it is considered to have failed. Default 300 (5 minutes). |
|
| 111 | - */ |
|
| 112 | - public function mark_failures( $time_limit = 300 ) { |
|
| 113 | - $timeout = apply_filters( 'action_scheduler_failure_period', $time_limit ); |
|
| 114 | - if ( $timeout < 0 ) { |
|
| 115 | - return; |
|
| 116 | - } |
|
| 117 | - $cutoff = as_get_datetime_object($timeout.' seconds ago'); |
|
| 118 | - $actions_to_reset = $this->store->query_actions( array( |
|
| 119 | - 'status' => ActionScheduler_Store::STATUS_RUNNING, |
|
| 120 | - 'modified' => $cutoff, |
|
| 121 | - 'modified_compare' => '<=', |
|
| 122 | - 'per_page' => $this->get_batch_size(), |
|
| 123 | - 'orderby' => 'none', |
|
| 124 | - ) ); |
|
| 125 | - |
|
| 126 | - foreach ( $actions_to_reset as $action_id ) { |
|
| 127 | - $this->store->mark_failure( $action_id ); |
|
| 128 | - do_action( 'action_scheduler_failed_action', $action_id, $timeout ); |
|
| 129 | - } |
|
| 130 | - } |
|
| 131 | - |
|
| 132 | - /** |
|
| 133 | - * Do all of the cleaning actions. |
|
| 134 | - * |
|
| 135 | - * @param int $time_limit The number of seconds to use as the timeout and failure period. Default 300 (5 minutes). |
|
| 136 | - * @author Jeremy Pry |
|
| 137 | - */ |
|
| 138 | - public function clean( $time_limit = 300 ) { |
|
| 139 | - $this->delete_old_actions(); |
|
| 140 | - $this->reset_timeouts( $time_limit ); |
|
| 141 | - $this->mark_failures( $time_limit ); |
|
| 142 | - } |
|
| 143 | - |
|
| 144 | - /** |
|
| 145 | - * Get the batch size for cleaning the queue. |
|
| 146 | - * |
|
| 147 | - * @author Jeremy Pry |
|
| 148 | - * @return int |
|
| 149 | - */ |
|
| 150 | - protected function get_batch_size() { |
|
| 151 | - /** |
|
| 152 | - * Filter the batch size when cleaning the queue. |
|
| 153 | - * |
|
| 154 | - * @param int $batch_size The number of actions to clean in one batch. |
|
| 155 | - */ |
|
| 156 | - return absint( apply_filters( 'action_scheduler_cleanup_batch_size', $this->batch_size ) ); |
|
| 157 | - } |
|
| 8 | + /** @var int */ |
|
| 9 | + protected $batch_size; |
|
| 10 | + |
|
| 11 | + /** @var ActionScheduler_Store */ |
|
| 12 | + private $store = null; |
|
| 13 | + |
|
| 14 | + /** |
|
| 15 | + * 31 days in seconds. |
|
| 16 | + * |
|
| 17 | + * @var int |
|
| 18 | + */ |
|
| 19 | + private $month_in_seconds = 2678400; |
|
| 20 | + |
|
| 21 | + /** |
|
| 22 | + * ActionScheduler_QueueCleaner constructor. |
|
| 23 | + * |
|
| 24 | + * @param ActionScheduler_Store $store The store instance. |
|
| 25 | + * @param int $batch_size The batch size. |
|
| 26 | + */ |
|
| 27 | + public function __construct( ActionScheduler_Store $store = null, $batch_size = 20 ) { |
|
| 28 | + $this->store = $store ? $store : ActionScheduler_Store::instance(); |
|
| 29 | + $this->batch_size = $batch_size; |
|
| 30 | + } |
|
| 31 | + |
|
| 32 | + public function delete_old_actions() { |
|
| 33 | + $lifespan = apply_filters( 'action_scheduler_retention_period', $this->month_in_seconds ); |
|
| 34 | + $cutoff = as_get_datetime_object($lifespan.' seconds ago'); |
|
| 35 | + |
|
| 36 | + $statuses_to_purge = array( |
|
| 37 | + ActionScheduler_Store::STATUS_COMPLETE, |
|
| 38 | + ActionScheduler_Store::STATUS_CANCELED, |
|
| 39 | + ); |
|
| 40 | + |
|
| 41 | + foreach ( $statuses_to_purge as $status ) { |
|
| 42 | + $actions_to_delete = $this->store->query_actions( array( |
|
| 43 | + 'status' => $status, |
|
| 44 | + 'modified' => $cutoff, |
|
| 45 | + 'modified_compare' => '<=', |
|
| 46 | + 'per_page' => $this->get_batch_size(), |
|
| 47 | + 'orderby' => 'none', |
|
| 48 | + ) ); |
|
| 49 | + |
|
| 50 | + foreach ( $actions_to_delete as $action_id ) { |
|
| 51 | + try { |
|
| 52 | + $this->store->delete_action( $action_id ); |
|
| 53 | + } catch ( Exception $e ) { |
|
| 54 | + |
|
| 55 | + /** |
|
| 56 | + * Notify 3rd party code of exceptions when deleting a completed action older than the retention period |
|
| 57 | + * |
|
| 58 | + * This hook provides a way for 3rd party code to log or otherwise handle exceptions relating to their |
|
| 59 | + * actions. |
|
| 60 | + * |
|
| 61 | + * @since 2.0.0 |
|
| 62 | + * |
|
| 63 | + * @param int $action_id The scheduled actions ID in the data store |
|
| 64 | + * @param Exception $e The exception thrown when attempting to delete the action from the data store |
|
| 65 | + * @param int $lifespan The retention period, in seconds, for old actions |
|
| 66 | + * @param int $count_of_actions_to_delete The number of old actions being deleted in this batch |
|
| 67 | + */ |
|
| 68 | + do_action( 'action_scheduler_failed_old_action_deletion', $action_id, $e, $lifespan, count( $actions_to_delete ) ); |
|
| 69 | + } |
|
| 70 | + } |
|
| 71 | + } |
|
| 72 | + } |
|
| 73 | + |
|
| 74 | + /** |
|
| 75 | + * Unclaim pending actions that have not been run within a given time limit. |
|
| 76 | + * |
|
| 77 | + * When called by ActionScheduler_Abstract_QueueRunner::run_cleanup(), the time limit passed |
|
| 78 | + * as a parameter is 10x the time limit used for queue processing. |
|
| 79 | + * |
|
| 80 | + * @param int $time_limit The number of seconds to allow a queue to run before unclaiming its pending actions. Default 300 (5 minutes). |
|
| 81 | + */ |
|
| 82 | + public function reset_timeouts( $time_limit = 300 ) { |
|
| 83 | + $timeout = apply_filters( 'action_scheduler_timeout_period', $time_limit ); |
|
| 84 | + if ( $timeout < 0 ) { |
|
| 85 | + return; |
|
| 86 | + } |
|
| 87 | + $cutoff = as_get_datetime_object($timeout.' seconds ago'); |
|
| 88 | + $actions_to_reset = $this->store->query_actions( array( |
|
| 89 | + 'status' => ActionScheduler_Store::STATUS_PENDING, |
|
| 90 | + 'modified' => $cutoff, |
|
| 91 | + 'modified_compare' => '<=', |
|
| 92 | + 'claimed' => true, |
|
| 93 | + 'per_page' => $this->get_batch_size(), |
|
| 94 | + 'orderby' => 'none', |
|
| 95 | + ) ); |
|
| 96 | + |
|
| 97 | + foreach ( $actions_to_reset as $action_id ) { |
|
| 98 | + $this->store->unclaim_action( $action_id ); |
|
| 99 | + do_action( 'action_scheduler_reset_action', $action_id ); |
|
| 100 | + } |
|
| 101 | + } |
|
| 102 | + |
|
| 103 | + /** |
|
| 104 | + * Mark actions that have been running for more than a given time limit as failed, based on |
|
| 105 | + * the assumption some uncatachable and unloggable fatal error occurred during processing. |
|
| 106 | + * |
|
| 107 | + * When called by ActionScheduler_Abstract_QueueRunner::run_cleanup(), the time limit passed |
|
| 108 | + * as a parameter is 10x the time limit used for queue processing. |
|
| 109 | + * |
|
| 110 | + * @param int $time_limit The number of seconds to allow an action to run before it is considered to have failed. Default 300 (5 minutes). |
|
| 111 | + */ |
|
| 112 | + public function mark_failures( $time_limit = 300 ) { |
|
| 113 | + $timeout = apply_filters( 'action_scheduler_failure_period', $time_limit ); |
|
| 114 | + if ( $timeout < 0 ) { |
|
| 115 | + return; |
|
| 116 | + } |
|
| 117 | + $cutoff = as_get_datetime_object($timeout.' seconds ago'); |
|
| 118 | + $actions_to_reset = $this->store->query_actions( array( |
|
| 119 | + 'status' => ActionScheduler_Store::STATUS_RUNNING, |
|
| 120 | + 'modified' => $cutoff, |
|
| 121 | + 'modified_compare' => '<=', |
|
| 122 | + 'per_page' => $this->get_batch_size(), |
|
| 123 | + 'orderby' => 'none', |
|
| 124 | + ) ); |
|
| 125 | + |
|
| 126 | + foreach ( $actions_to_reset as $action_id ) { |
|
| 127 | + $this->store->mark_failure( $action_id ); |
|
| 128 | + do_action( 'action_scheduler_failed_action', $action_id, $timeout ); |
|
| 129 | + } |
|
| 130 | + } |
|
| 131 | + |
|
| 132 | + /** |
|
| 133 | + * Do all of the cleaning actions. |
|
| 134 | + * |
|
| 135 | + * @param int $time_limit The number of seconds to use as the timeout and failure period. Default 300 (5 minutes). |
|
| 136 | + * @author Jeremy Pry |
|
| 137 | + */ |
|
| 138 | + public function clean( $time_limit = 300 ) { |
|
| 139 | + $this->delete_old_actions(); |
|
| 140 | + $this->reset_timeouts( $time_limit ); |
|
| 141 | + $this->mark_failures( $time_limit ); |
|
| 142 | + } |
|
| 143 | + |
|
| 144 | + /** |
|
| 145 | + * Get the batch size for cleaning the queue. |
|
| 146 | + * |
|
| 147 | + * @author Jeremy Pry |
|
| 148 | + * @return int |
|
| 149 | + */ |
|
| 150 | + protected function get_batch_size() { |
|
| 151 | + /** |
|
| 152 | + * Filter the batch size when cleaning the queue. |
|
| 153 | + * |
|
| 154 | + * @param int $batch_size The number of actions to clean in one batch. |
|
| 155 | + */ |
|
| 156 | + return absint( apply_filters( 'action_scheduler_cleanup_batch_size', $this->batch_size ) ); |
|
| 157 | + } |
|
| 158 | 158 | } |
@@ -14,174 +14,174 @@ |
||
| 14 | 14 | * @since 3.0.0 |
| 15 | 15 | */ |
| 16 | 16 | class ActionScheduler_DataController { |
| 17 | - /** Action data store class name. */ |
|
| 18 | - const DATASTORE_CLASS = 'ActionScheduler_DBStore'; |
|
| 19 | - |
|
| 20 | - /** Logger data store class name. */ |
|
| 21 | - const LOGGER_CLASS = 'ActionScheduler_DBLogger'; |
|
| 22 | - |
|
| 23 | - /** Migration status option name. */ |
|
| 24 | - const STATUS_FLAG = 'action_scheduler_migration_status'; |
|
| 25 | - |
|
| 26 | - /** Migration status option value. */ |
|
| 27 | - const STATUS_COMPLETE = 'complete'; |
|
| 28 | - |
|
| 29 | - /** Migration minimum required PHP version. */ |
|
| 30 | - const MIN_PHP_VERSION = '5.5'; |
|
| 31 | - |
|
| 32 | - /** @var ActionScheduler_DataController */ |
|
| 33 | - private static $instance; |
|
| 34 | - |
|
| 35 | - /** @var int */ |
|
| 36 | - private static $sleep_time = 0; |
|
| 37 | - |
|
| 38 | - /** @var int */ |
|
| 39 | - private static $free_ticks = 50; |
|
| 40 | - |
|
| 41 | - /** |
|
| 42 | - * Get a flag indicating whether the migration environment dependencies are met. |
|
| 43 | - * |
|
| 44 | - * @return bool |
|
| 45 | - */ |
|
| 46 | - public static function dependencies_met() { |
|
| 47 | - $php_support = version_compare( PHP_VERSION, self::MIN_PHP_VERSION, '>=' ); |
|
| 48 | - return $php_support && apply_filters( 'action_scheduler_migration_dependencies_met', true ); |
|
| 49 | - } |
|
| 50 | - |
|
| 51 | - /** |
|
| 52 | - * Get a flag indicating whether the migration is complete. |
|
| 53 | - * |
|
| 54 | - * @return bool Whether the flag has been set marking the migration as complete |
|
| 55 | - */ |
|
| 56 | - public static function is_migration_complete() { |
|
| 57 | - return get_option( self::STATUS_FLAG ) === self::STATUS_COMPLETE; |
|
| 58 | - } |
|
| 59 | - |
|
| 60 | - /** |
|
| 61 | - * Mark the migration as complete. |
|
| 62 | - */ |
|
| 63 | - public static function mark_migration_complete() { |
|
| 64 | - update_option( self::STATUS_FLAG, self::STATUS_COMPLETE ); |
|
| 65 | - } |
|
| 66 | - |
|
| 67 | - /** |
|
| 68 | - * Unmark migration when a plugin is de-activated. Will not work in case of silent activation, for example in an update. |
|
| 69 | - * We do this to mitigate the bug of lost actions which happens if there was an AS 2.x to AS 3.x migration in the past, but that plugin is now |
|
| 70 | - * deactivated and the site was running on AS 2.x again. |
|
| 71 | - */ |
|
| 72 | - public static function mark_migration_incomplete() { |
|
| 73 | - delete_option( self::STATUS_FLAG ); |
|
| 74 | - } |
|
| 75 | - |
|
| 76 | - /** |
|
| 77 | - * Set the action store class name. |
|
| 78 | - * |
|
| 79 | - * @param string $class Classname of the store class. |
|
| 80 | - * |
|
| 81 | - * @return string |
|
| 82 | - */ |
|
| 83 | - public static function set_store_class( $class ) { |
|
| 84 | - return self::DATASTORE_CLASS; |
|
| 85 | - } |
|
| 86 | - |
|
| 87 | - /** |
|
| 88 | - * Set the action logger class name. |
|
| 89 | - * |
|
| 90 | - * @param string $class Classname of the logger class. |
|
| 91 | - * |
|
| 92 | - * @return string |
|
| 93 | - */ |
|
| 94 | - public static function set_logger_class( $class ) { |
|
| 95 | - return self::LOGGER_CLASS; |
|
| 96 | - } |
|
| 97 | - |
|
| 98 | - /** |
|
| 99 | - * Set the sleep time in seconds. |
|
| 100 | - * |
|
| 101 | - * @param integer $sleep_time The number of seconds to pause before resuming operation. |
|
| 102 | - */ |
|
| 103 | - public static function set_sleep_time( $sleep_time ) { |
|
| 104 | - self::$sleep_time = (int) $sleep_time; |
|
| 105 | - } |
|
| 106 | - |
|
| 107 | - /** |
|
| 108 | - * Set the tick count required for freeing memory. |
|
| 109 | - * |
|
| 110 | - * @param integer $free_ticks The number of ticks to free memory on. |
|
| 111 | - */ |
|
| 112 | - public static function set_free_ticks( $free_ticks ) { |
|
| 113 | - self::$free_ticks = (int) $free_ticks; |
|
| 114 | - } |
|
| 115 | - |
|
| 116 | - /** |
|
| 117 | - * Free memory if conditions are met. |
|
| 118 | - * |
|
| 119 | - * @param int $ticks Current tick count. |
|
| 120 | - */ |
|
| 121 | - public static function maybe_free_memory( $ticks ) { |
|
| 122 | - if ( self::$free_ticks && 0 === $ticks % self::$free_ticks ) { |
|
| 123 | - self::free_memory(); |
|
| 124 | - } |
|
| 125 | - } |
|
| 126 | - |
|
| 127 | - /** |
|
| 128 | - * Reduce memory footprint by clearing the database query and object caches. |
|
| 129 | - */ |
|
| 130 | - public static function free_memory() { |
|
| 131 | - if ( 0 < self::$sleep_time ) { |
|
| 132 | - /* translators: %d: amount of time */ |
|
| 133 | - \WP_CLI::warning( sprintf( _n( 'Stopped the insanity for %d second', 'Stopped the insanity for %d seconds', self::$sleep_time, 'woocommerce' ), self::$sleep_time ) ); |
|
| 134 | - sleep( self::$sleep_time ); |
|
| 135 | - } |
|
| 136 | - |
|
| 137 | - \WP_CLI::warning( __( 'Attempting to reduce used memory...', 'woocommerce' ) ); |
|
| 138 | - |
|
| 139 | - /** |
|
| 140 | - * @var $wpdb \wpdb |
|
| 141 | - * @var $wp_object_cache \WP_Object_Cache |
|
| 142 | - */ |
|
| 143 | - global $wpdb, $wp_object_cache; |
|
| 144 | - |
|
| 145 | - $wpdb->queries = array(); |
|
| 146 | - |
|
| 147 | - if ( ! is_a( $wp_object_cache, 'WP_Object_Cache' ) ) { |
|
| 148 | - return; |
|
| 149 | - } |
|
| 150 | - |
|
| 151 | - $wp_object_cache->group_ops = array(); |
|
| 152 | - $wp_object_cache->stats = array(); |
|
| 153 | - $wp_object_cache->memcache_debug = array(); |
|
| 154 | - $wp_object_cache->cache = array(); |
|
| 155 | - |
|
| 156 | - if ( is_callable( array( $wp_object_cache, '__remoteset' ) ) ) { |
|
| 157 | - call_user_func( array( $wp_object_cache, '__remoteset' ) ); // important |
|
| 158 | - } |
|
| 159 | - } |
|
| 160 | - |
|
| 161 | - /** |
|
| 162 | - * Connect to table datastores if migration is complete. |
|
| 163 | - * Otherwise, proceed with the migration if the dependencies have been met. |
|
| 164 | - */ |
|
| 165 | - public static function init() { |
|
| 166 | - if ( self::is_migration_complete() ) { |
|
| 167 | - add_filter( 'action_scheduler_store_class', array( 'ActionScheduler_DataController', 'set_store_class' ), 100 ); |
|
| 168 | - add_filter( 'action_scheduler_logger_class', array( 'ActionScheduler_DataController', 'set_logger_class' ), 100 ); |
|
| 169 | - add_action( 'deactivate_plugin', array( 'ActionScheduler_DataController', 'mark_migration_incomplete' ) ); |
|
| 170 | - } elseif ( self::dependencies_met() ) { |
|
| 171 | - Controller::init(); |
|
| 172 | - } |
|
| 173 | - |
|
| 174 | - add_action( 'action_scheduler/progress_tick', array( 'ActionScheduler_DataController', 'maybe_free_memory' ) ); |
|
| 175 | - } |
|
| 176 | - |
|
| 177 | - /** |
|
| 178 | - * Singleton factory. |
|
| 179 | - */ |
|
| 180 | - public static function instance() { |
|
| 181 | - if ( ! isset( self::$instance ) ) { |
|
| 182 | - self::$instance = new static(); |
|
| 183 | - } |
|
| 184 | - |
|
| 185 | - return self::$instance; |
|
| 186 | - } |
|
| 17 | + /** Action data store class name. */ |
|
| 18 | + const DATASTORE_CLASS = 'ActionScheduler_DBStore'; |
|
| 19 | + |
|
| 20 | + /** Logger data store class name. */ |
|
| 21 | + const LOGGER_CLASS = 'ActionScheduler_DBLogger'; |
|
| 22 | + |
|
| 23 | + /** Migration status option name. */ |
|
| 24 | + const STATUS_FLAG = 'action_scheduler_migration_status'; |
|
| 25 | + |
|
| 26 | + /** Migration status option value. */ |
|
| 27 | + const STATUS_COMPLETE = 'complete'; |
|
| 28 | + |
|
| 29 | + /** Migration minimum required PHP version. */ |
|
| 30 | + const MIN_PHP_VERSION = '5.5'; |
|
| 31 | + |
|
| 32 | + /** @var ActionScheduler_DataController */ |
|
| 33 | + private static $instance; |
|
| 34 | + |
|
| 35 | + /** @var int */ |
|
| 36 | + private static $sleep_time = 0; |
|
| 37 | + |
|
| 38 | + /** @var int */ |
|
| 39 | + private static $free_ticks = 50; |
|
| 40 | + |
|
| 41 | + /** |
|
| 42 | + * Get a flag indicating whether the migration environment dependencies are met. |
|
| 43 | + * |
|
| 44 | + * @return bool |
|
| 45 | + */ |
|
| 46 | + public static function dependencies_met() { |
|
| 47 | + $php_support = version_compare( PHP_VERSION, self::MIN_PHP_VERSION, '>=' ); |
|
| 48 | + return $php_support && apply_filters( 'action_scheduler_migration_dependencies_met', true ); |
|
| 49 | + } |
|
| 50 | + |
|
| 51 | + /** |
|
| 52 | + * Get a flag indicating whether the migration is complete. |
|
| 53 | + * |
|
| 54 | + * @return bool Whether the flag has been set marking the migration as complete |
|
| 55 | + */ |
|
| 56 | + public static function is_migration_complete() { |
|
| 57 | + return get_option( self::STATUS_FLAG ) === self::STATUS_COMPLETE; |
|
| 58 | + } |
|
| 59 | + |
|
| 60 | + /** |
|
| 61 | + * Mark the migration as complete. |
|
| 62 | + */ |
|
| 63 | + public static function mark_migration_complete() { |
|
| 64 | + update_option( self::STATUS_FLAG, self::STATUS_COMPLETE ); |
|
| 65 | + } |
|
| 66 | + |
|
| 67 | + /** |
|
| 68 | + * Unmark migration when a plugin is de-activated. Will not work in case of silent activation, for example in an update. |
|
| 69 | + * We do this to mitigate the bug of lost actions which happens if there was an AS 2.x to AS 3.x migration in the past, but that plugin is now |
|
| 70 | + * deactivated and the site was running on AS 2.x again. |
|
| 71 | + */ |
|
| 72 | + public static function mark_migration_incomplete() { |
|
| 73 | + delete_option( self::STATUS_FLAG ); |
|
| 74 | + } |
|
| 75 | + |
|
| 76 | + /** |
|
| 77 | + * Set the action store class name. |
|
| 78 | + * |
|
| 79 | + * @param string $class Classname of the store class. |
|
| 80 | + * |
|
| 81 | + * @return string |
|
| 82 | + */ |
|
| 83 | + public static function set_store_class( $class ) { |
|
| 84 | + return self::DATASTORE_CLASS; |
|
| 85 | + } |
|
| 86 | + |
|
| 87 | + /** |
|
| 88 | + * Set the action logger class name. |
|
| 89 | + * |
|
| 90 | + * @param string $class Classname of the logger class. |
|
| 91 | + * |
|
| 92 | + * @return string |
|
| 93 | + */ |
|
| 94 | + public static function set_logger_class( $class ) { |
|
| 95 | + return self::LOGGER_CLASS; |
|
| 96 | + } |
|
| 97 | + |
|
| 98 | + /** |
|
| 99 | + * Set the sleep time in seconds. |
|
| 100 | + * |
|
| 101 | + * @param integer $sleep_time The number of seconds to pause before resuming operation. |
|
| 102 | + */ |
|
| 103 | + public static function set_sleep_time( $sleep_time ) { |
|
| 104 | + self::$sleep_time = (int) $sleep_time; |
|
| 105 | + } |
|
| 106 | + |
|
| 107 | + /** |
|
| 108 | + * Set the tick count required for freeing memory. |
|
| 109 | + * |
|
| 110 | + * @param integer $free_ticks The number of ticks to free memory on. |
|
| 111 | + */ |
|
| 112 | + public static function set_free_ticks( $free_ticks ) { |
|
| 113 | + self::$free_ticks = (int) $free_ticks; |
|
| 114 | + } |
|
| 115 | + |
|
| 116 | + /** |
|
| 117 | + * Free memory if conditions are met. |
|
| 118 | + * |
|
| 119 | + * @param int $ticks Current tick count. |
|
| 120 | + */ |
|
| 121 | + public static function maybe_free_memory( $ticks ) { |
|
| 122 | + if ( self::$free_ticks && 0 === $ticks % self::$free_ticks ) { |
|
| 123 | + self::free_memory(); |
|
| 124 | + } |
|
| 125 | + } |
|
| 126 | + |
|
| 127 | + /** |
|
| 128 | + * Reduce memory footprint by clearing the database query and object caches. |
|
| 129 | + */ |
|
| 130 | + public static function free_memory() { |
|
| 131 | + if ( 0 < self::$sleep_time ) { |
|
| 132 | + /* translators: %d: amount of time */ |
|
| 133 | + \WP_CLI::warning( sprintf( _n( 'Stopped the insanity for %d second', 'Stopped the insanity for %d seconds', self::$sleep_time, 'woocommerce' ), self::$sleep_time ) ); |
|
| 134 | + sleep( self::$sleep_time ); |
|
| 135 | + } |
|
| 136 | + |
|
| 137 | + \WP_CLI::warning( __( 'Attempting to reduce used memory...', 'woocommerce' ) ); |
|
| 138 | + |
|
| 139 | + /** |
|
| 140 | + * @var $wpdb \wpdb |
|
| 141 | + * @var $wp_object_cache \WP_Object_Cache |
|
| 142 | + */ |
|
| 143 | + global $wpdb, $wp_object_cache; |
|
| 144 | + |
|
| 145 | + $wpdb->queries = array(); |
|
| 146 | + |
|
| 147 | + if ( ! is_a( $wp_object_cache, 'WP_Object_Cache' ) ) { |
|
| 148 | + return; |
|
| 149 | + } |
|
| 150 | + |
|
| 151 | + $wp_object_cache->group_ops = array(); |
|
| 152 | + $wp_object_cache->stats = array(); |
|
| 153 | + $wp_object_cache->memcache_debug = array(); |
|
| 154 | + $wp_object_cache->cache = array(); |
|
| 155 | + |
|
| 156 | + if ( is_callable( array( $wp_object_cache, '__remoteset' ) ) ) { |
|
| 157 | + call_user_func( array( $wp_object_cache, '__remoteset' ) ); // important |
|
| 158 | + } |
|
| 159 | + } |
|
| 160 | + |
|
| 161 | + /** |
|
| 162 | + * Connect to table datastores if migration is complete. |
|
| 163 | + * Otherwise, proceed with the migration if the dependencies have been met. |
|
| 164 | + */ |
|
| 165 | + public static function init() { |
|
| 166 | + if ( self::is_migration_complete() ) { |
|
| 167 | + add_filter( 'action_scheduler_store_class', array( 'ActionScheduler_DataController', 'set_store_class' ), 100 ); |
|
| 168 | + add_filter( 'action_scheduler_logger_class', array( 'ActionScheduler_DataController', 'set_logger_class' ), 100 ); |
|
| 169 | + add_action( 'deactivate_plugin', array( 'ActionScheduler_DataController', 'mark_migration_incomplete' ) ); |
|
| 170 | + } elseif ( self::dependencies_met() ) { |
|
| 171 | + Controller::init(); |
|
| 172 | + } |
|
| 173 | + |
|
| 174 | + add_action( 'action_scheduler/progress_tick', array( 'ActionScheduler_DataController', 'maybe_free_memory' ) ); |
|
| 175 | + } |
|
| 176 | + |
|
| 177 | + /** |
|
| 178 | + * Singleton factory. |
|
| 179 | + */ |
|
| 180 | + public static function instance() { |
|
| 181 | + if ( ! isset( self::$instance ) ) { |
|
| 182 | + self::$instance = new static(); |
|
| 183 | + } |
|
| 184 | + |
|
| 185 | + return self::$instance; |
|
| 186 | + } |
|
| 187 | 187 | } |
@@ -6,149 +6,149 @@ |
||
| 6 | 6 | */ |
| 7 | 7 | class ActionScheduler_AdminView extends ActionScheduler_AdminView_Deprecated { |
| 8 | 8 | |
| 9 | - private static $admin_view = NULL; |
|
| 10 | - |
|
| 11 | - private static $screen_id = 'tools_page_action-scheduler'; |
|
| 12 | - |
|
| 13 | - /** @var ActionScheduler_ListTable */ |
|
| 14 | - protected $list_table; |
|
| 15 | - |
|
| 16 | - /** |
|
| 17 | - * @return ActionScheduler_AdminView |
|
| 18 | - * @codeCoverageIgnore |
|
| 19 | - */ |
|
| 20 | - public static function instance() { |
|
| 21 | - |
|
| 22 | - if ( empty( self::$admin_view ) ) { |
|
| 23 | - $class = apply_filters('action_scheduler_admin_view_class', 'ActionScheduler_AdminView'); |
|
| 24 | - self::$admin_view = new $class(); |
|
| 25 | - } |
|
| 26 | - |
|
| 27 | - return self::$admin_view; |
|
| 28 | - } |
|
| 29 | - |
|
| 30 | - /** |
|
| 31 | - * @codeCoverageIgnore |
|
| 32 | - */ |
|
| 33 | - public function init() { |
|
| 34 | - if ( is_admin() && ( ! defined( 'DOING_AJAX' ) || false == DOING_AJAX ) ) { |
|
| 35 | - |
|
| 36 | - if ( class_exists( 'WooCommerce' ) ) { |
|
| 37 | - add_action( 'woocommerce_admin_status_content_action-scheduler', array( $this, 'render_admin_ui' ) ); |
|
| 38 | - add_action( 'woocommerce_system_status_report', array( $this, 'system_status_report' ) ); |
|
| 39 | - add_filter( 'woocommerce_admin_status_tabs', array( $this, 'register_system_status_tab' ) ); |
|
| 40 | - } |
|
| 41 | - |
|
| 42 | - add_action( 'admin_menu', array( $this, 'register_menu' ) ); |
|
| 43 | - |
|
| 44 | - add_action( 'current_screen', array( $this, 'add_help_tabs' ) ); |
|
| 45 | - } |
|
| 46 | - } |
|
| 47 | - |
|
| 48 | - public function system_status_report() { |
|
| 49 | - $table = new ActionScheduler_wcSystemStatus( ActionScheduler::store() ); |
|
| 50 | - $table->render(); |
|
| 51 | - } |
|
| 52 | - |
|
| 53 | - /** |
|
| 54 | - * Registers action-scheduler into WooCommerce > System status. |
|
| 55 | - * |
|
| 56 | - * @param array $tabs An associative array of tab key => label. |
|
| 57 | - * @return array $tabs An associative array of tab key => label, including Action Scheduler's tabs |
|
| 58 | - */ |
|
| 59 | - public function register_system_status_tab( array $tabs ) { |
|
| 60 | - $tabs['action-scheduler'] = __( 'Scheduled Actions', 'woocommerce' ); |
|
| 61 | - |
|
| 62 | - return $tabs; |
|
| 63 | - } |
|
| 64 | - |
|
| 65 | - /** |
|
| 66 | - * Include Action Scheduler's administration under the Tools menu. |
|
| 67 | - * |
|
| 68 | - * A menu under the Tools menu is important for backward compatibility (as that's |
|
| 69 | - * where it started), and also provides more convenient access than the WooCommerce |
|
| 70 | - * System Status page, and for sites where WooCommerce isn't active. |
|
| 71 | - */ |
|
| 72 | - public function register_menu() { |
|
| 73 | - $hook_suffix = add_submenu_page( |
|
| 74 | - 'tools.php', |
|
| 75 | - __( 'Scheduled Actions', 'woocommerce' ), |
|
| 76 | - __( 'Scheduled Actions', 'woocommerce' ), |
|
| 77 | - 'manage_options', |
|
| 78 | - 'action-scheduler', |
|
| 79 | - array( $this, 'render_admin_ui' ) |
|
| 80 | - ); |
|
| 81 | - add_action( 'load-' . $hook_suffix , array( $this, 'process_admin_ui' ) ); |
|
| 82 | - } |
|
| 83 | - |
|
| 84 | - /** |
|
| 85 | - * Triggers processing of any pending actions. |
|
| 86 | - */ |
|
| 87 | - public function process_admin_ui() { |
|
| 88 | - $this->get_list_table(); |
|
| 89 | - } |
|
| 90 | - |
|
| 91 | - /** |
|
| 92 | - * Renders the Admin UI |
|
| 93 | - */ |
|
| 94 | - public function render_admin_ui() { |
|
| 95 | - $table = $this->get_list_table(); |
|
| 96 | - $table->display_page(); |
|
| 97 | - } |
|
| 98 | - |
|
| 99 | - /** |
|
| 100 | - * Get the admin UI object and process any requested actions. |
|
| 101 | - * |
|
| 102 | - * @return ActionScheduler_ListTable |
|
| 103 | - */ |
|
| 104 | - protected function get_list_table() { |
|
| 105 | - if ( null === $this->list_table ) { |
|
| 106 | - $this->list_table = new ActionScheduler_ListTable( ActionScheduler::store(), ActionScheduler::logger(), ActionScheduler::runner() ); |
|
| 107 | - $this->list_table->process_actions(); |
|
| 108 | - } |
|
| 109 | - |
|
| 110 | - return $this->list_table; |
|
| 111 | - } |
|
| 112 | - |
|
| 113 | - /** |
|
| 114 | - * Provide more information about the screen and its data in the help tab. |
|
| 115 | - */ |
|
| 116 | - public function add_help_tabs() { |
|
| 117 | - $screen = get_current_screen(); |
|
| 118 | - |
|
| 119 | - if ( ! $screen || self::$screen_id != $screen->id ) { |
|
| 120 | - return; |
|
| 121 | - } |
|
| 122 | - |
|
| 123 | - $as_version = ActionScheduler_Versions::instance()->latest_version(); |
|
| 124 | - $screen->add_help_tab( |
|
| 125 | - array( |
|
| 126 | - 'id' => 'action_scheduler_about', |
|
| 127 | - 'title' => __( 'About', 'woocommerce' ), |
|
| 128 | - 'content' => |
|
| 129 | - '<h2>' . sprintf( __( 'About Action Scheduler %s', 'woocommerce' ), $as_version ) . '</h2>' . |
|
| 130 | - '<p>' . |
|
| 131 | - __( 'Action Scheduler is a scalable, traceable job queue for background processing large sets of actions. Action Scheduler works by triggering an action hook to run at some time in the future. Scheduled actions can also be scheduled to run on a recurring schedule.', 'woocommerce' ) . |
|
| 132 | - '</p>', |
|
| 133 | - ) |
|
| 134 | - ); |
|
| 135 | - |
|
| 136 | - $screen->add_help_tab( |
|
| 137 | - array( |
|
| 138 | - 'id' => 'action_scheduler_columns', |
|
| 139 | - 'title' => __( 'Columns', 'woocommerce' ), |
|
| 140 | - 'content' => |
|
| 141 | - '<h2>' . __( 'Scheduled Action Columns', 'woocommerce' ) . '</h2>' . |
|
| 142 | - '<ul>' . |
|
| 143 | - sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Hook', 'woocommerce' ), __( 'Name of the action hook that will be triggered.', 'woocommerce' ) ) . |
|
| 144 | - sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Status', 'woocommerce' ), __( 'Action statuses are Pending, Complete, Canceled, Failed', 'woocommerce' ) ) . |
|
| 145 | - sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Arguments', 'woocommerce' ), __( 'Optional data array passed to the action hook.', 'woocommerce' ) ) . |
|
| 146 | - sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Group', 'woocommerce' ), __( 'Optional action group.', 'woocommerce' ) ) . |
|
| 147 | - sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Recurrence', 'woocommerce' ), __( 'The action\'s schedule frequency.', 'woocommerce' ) ) . |
|
| 148 | - sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Scheduled', 'woocommerce' ), __( 'The date/time the action is/was scheduled to run.', 'woocommerce' ) ) . |
|
| 149 | - sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Log', 'woocommerce' ), __( 'Activity log for the action.', 'woocommerce' ) ) . |
|
| 150 | - '</ul>', |
|
| 151 | - ) |
|
| 152 | - ); |
|
| 153 | - } |
|
| 9 | + private static $admin_view = NULL; |
|
| 10 | + |
|
| 11 | + private static $screen_id = 'tools_page_action-scheduler'; |
|
| 12 | + |
|
| 13 | + /** @var ActionScheduler_ListTable */ |
|
| 14 | + protected $list_table; |
|
| 15 | + |
|
| 16 | + /** |
|
| 17 | + * @return ActionScheduler_AdminView |
|
| 18 | + * @codeCoverageIgnore |
|
| 19 | + */ |
|
| 20 | + public static function instance() { |
|
| 21 | + |
|
| 22 | + if ( empty( self::$admin_view ) ) { |
|
| 23 | + $class = apply_filters('action_scheduler_admin_view_class', 'ActionScheduler_AdminView'); |
|
| 24 | + self::$admin_view = new $class(); |
|
| 25 | + } |
|
| 26 | + |
|
| 27 | + return self::$admin_view; |
|
| 28 | + } |
|
| 29 | + |
|
| 30 | + /** |
|
| 31 | + * @codeCoverageIgnore |
|
| 32 | + */ |
|
| 33 | + public function init() { |
|
| 34 | + if ( is_admin() && ( ! defined( 'DOING_AJAX' ) || false == DOING_AJAX ) ) { |
|
| 35 | + |
|
| 36 | + if ( class_exists( 'WooCommerce' ) ) { |
|
| 37 | + add_action( 'woocommerce_admin_status_content_action-scheduler', array( $this, 'render_admin_ui' ) ); |
|
| 38 | + add_action( 'woocommerce_system_status_report', array( $this, 'system_status_report' ) ); |
|
| 39 | + add_filter( 'woocommerce_admin_status_tabs', array( $this, 'register_system_status_tab' ) ); |
|
| 40 | + } |
|
| 41 | + |
|
| 42 | + add_action( 'admin_menu', array( $this, 'register_menu' ) ); |
|
| 43 | + |
|
| 44 | + add_action( 'current_screen', array( $this, 'add_help_tabs' ) ); |
|
| 45 | + } |
|
| 46 | + } |
|
| 47 | + |
|
| 48 | + public function system_status_report() { |
|
| 49 | + $table = new ActionScheduler_wcSystemStatus( ActionScheduler::store() ); |
|
| 50 | + $table->render(); |
|
| 51 | + } |
|
| 52 | + |
|
| 53 | + /** |
|
| 54 | + * Registers action-scheduler into WooCommerce > System status. |
|
| 55 | + * |
|
| 56 | + * @param array $tabs An associative array of tab key => label. |
|
| 57 | + * @return array $tabs An associative array of tab key => label, including Action Scheduler's tabs |
|
| 58 | + */ |
|
| 59 | + public function register_system_status_tab( array $tabs ) { |
|
| 60 | + $tabs['action-scheduler'] = __( 'Scheduled Actions', 'woocommerce' ); |
|
| 61 | + |
|
| 62 | + return $tabs; |
|
| 63 | + } |
|
| 64 | + |
|
| 65 | + /** |
|
| 66 | + * Include Action Scheduler's administration under the Tools menu. |
|
| 67 | + * |
|
| 68 | + * A menu under the Tools menu is important for backward compatibility (as that's |
|
| 69 | + * where it started), and also provides more convenient access than the WooCommerce |
|
| 70 | + * System Status page, and for sites where WooCommerce isn't active. |
|
| 71 | + */ |
|
| 72 | + public function register_menu() { |
|
| 73 | + $hook_suffix = add_submenu_page( |
|
| 74 | + 'tools.php', |
|
| 75 | + __( 'Scheduled Actions', 'woocommerce' ), |
|
| 76 | + __( 'Scheduled Actions', 'woocommerce' ), |
|
| 77 | + 'manage_options', |
|
| 78 | + 'action-scheduler', |
|
| 79 | + array( $this, 'render_admin_ui' ) |
|
| 80 | + ); |
|
| 81 | + add_action( 'load-' . $hook_suffix , array( $this, 'process_admin_ui' ) ); |
|
| 82 | + } |
|
| 83 | + |
|
| 84 | + /** |
|
| 85 | + * Triggers processing of any pending actions. |
|
| 86 | + */ |
|
| 87 | + public function process_admin_ui() { |
|
| 88 | + $this->get_list_table(); |
|
| 89 | + } |
|
| 90 | + |
|
| 91 | + /** |
|
| 92 | + * Renders the Admin UI |
|
| 93 | + */ |
|
| 94 | + public function render_admin_ui() { |
|
| 95 | + $table = $this->get_list_table(); |
|
| 96 | + $table->display_page(); |
|
| 97 | + } |
|
| 98 | + |
|
| 99 | + /** |
|
| 100 | + * Get the admin UI object and process any requested actions. |
|
| 101 | + * |
|
| 102 | + * @return ActionScheduler_ListTable |
|
| 103 | + */ |
|
| 104 | + protected function get_list_table() { |
|
| 105 | + if ( null === $this->list_table ) { |
|
| 106 | + $this->list_table = new ActionScheduler_ListTable( ActionScheduler::store(), ActionScheduler::logger(), ActionScheduler::runner() ); |
|
| 107 | + $this->list_table->process_actions(); |
|
| 108 | + } |
|
| 109 | + |
|
| 110 | + return $this->list_table; |
|
| 111 | + } |
|
| 112 | + |
|
| 113 | + /** |
|
| 114 | + * Provide more information about the screen and its data in the help tab. |
|
| 115 | + */ |
|
| 116 | + public function add_help_tabs() { |
|
| 117 | + $screen = get_current_screen(); |
|
| 118 | + |
|
| 119 | + if ( ! $screen || self::$screen_id != $screen->id ) { |
|
| 120 | + return; |
|
| 121 | + } |
|
| 122 | + |
|
| 123 | + $as_version = ActionScheduler_Versions::instance()->latest_version(); |
|
| 124 | + $screen->add_help_tab( |
|
| 125 | + array( |
|
| 126 | + 'id' => 'action_scheduler_about', |
|
| 127 | + 'title' => __( 'About', 'woocommerce' ), |
|
| 128 | + 'content' => |
|
| 129 | + '<h2>' . sprintf( __( 'About Action Scheduler %s', 'woocommerce' ), $as_version ) . '</h2>' . |
|
| 130 | + '<p>' . |
|
| 131 | + __( 'Action Scheduler is a scalable, traceable job queue for background processing large sets of actions. Action Scheduler works by triggering an action hook to run at some time in the future. Scheduled actions can also be scheduled to run on a recurring schedule.', 'woocommerce' ) . |
|
| 132 | + '</p>', |
|
| 133 | + ) |
|
| 134 | + ); |
|
| 135 | + |
|
| 136 | + $screen->add_help_tab( |
|
| 137 | + array( |
|
| 138 | + 'id' => 'action_scheduler_columns', |
|
| 139 | + 'title' => __( 'Columns', 'woocommerce' ), |
|
| 140 | + 'content' => |
|
| 141 | + '<h2>' . __( 'Scheduled Action Columns', 'woocommerce' ) . '</h2>' . |
|
| 142 | + '<ul>' . |
|
| 143 | + sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Hook', 'woocommerce' ), __( 'Name of the action hook that will be triggered.', 'woocommerce' ) ) . |
|
| 144 | + sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Status', 'woocommerce' ), __( 'Action statuses are Pending, Complete, Canceled, Failed', 'woocommerce' ) ) . |
|
| 145 | + sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Arguments', 'woocommerce' ), __( 'Optional data array passed to the action hook.', 'woocommerce' ) ) . |
|
| 146 | + sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Group', 'woocommerce' ), __( 'Optional action group.', 'woocommerce' ) ) . |
|
| 147 | + sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Recurrence', 'woocommerce' ), __( 'The action\'s schedule frequency.', 'woocommerce' ) ) . |
|
| 148 | + sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Scheduled', 'woocommerce' ), __( 'The date/time the action is/was scheduled to run.', 'woocommerce' ) ) . |
|
| 149 | + sprintf( '<li><strong>%1$s</strong>: %2$s</li>', __( 'Log', 'woocommerce' ), __( 'Activity log for the action.', 'woocommerce' ) ) . |
|
| 150 | + '</ul>', |
|
| 151 | + ) |
|
| 152 | + ); |
|
| 153 | + } |
|
| 154 | 154 | } |
@@ -4,72 +4,72 @@ |
||
| 4 | 4 | * Class ActionScheduler_Action |
| 5 | 5 | */ |
| 6 | 6 | class ActionScheduler_Action { |
| 7 | - protected $hook = ''; |
|
| 8 | - protected $args = array(); |
|
| 9 | - /** @var ActionScheduler_Schedule */ |
|
| 10 | - protected $schedule = NULL; |
|
| 11 | - protected $group = ''; |
|
| 7 | + protected $hook = ''; |
|
| 8 | + protected $args = array(); |
|
| 9 | + /** @var ActionScheduler_Schedule */ |
|
| 10 | + protected $schedule = NULL; |
|
| 11 | + protected $group = ''; |
|
| 12 | 12 | |
| 13 | - public function __construct( $hook, array $args = array(), ActionScheduler_Schedule $schedule = NULL, $group = '' ) { |
|
| 14 | - $schedule = empty( $schedule ) ? new ActionScheduler_NullSchedule() : $schedule; |
|
| 15 | - $this->set_hook($hook); |
|
| 16 | - $this->set_schedule($schedule); |
|
| 17 | - $this->set_args($args); |
|
| 18 | - $this->set_group($group); |
|
| 19 | - } |
|
| 13 | + public function __construct( $hook, array $args = array(), ActionScheduler_Schedule $schedule = NULL, $group = '' ) { |
|
| 14 | + $schedule = empty( $schedule ) ? new ActionScheduler_NullSchedule() : $schedule; |
|
| 15 | + $this->set_hook($hook); |
|
| 16 | + $this->set_schedule($schedule); |
|
| 17 | + $this->set_args($args); |
|
| 18 | + $this->set_group($group); |
|
| 19 | + } |
|
| 20 | 20 | |
| 21 | - public function execute() { |
|
| 22 | - return do_action_ref_array( $this->get_hook(), array_values( $this->get_args() ) ); |
|
| 23 | - } |
|
| 21 | + public function execute() { |
|
| 22 | + return do_action_ref_array( $this->get_hook(), array_values( $this->get_args() ) ); |
|
| 23 | + } |
|
| 24 | 24 | |
| 25 | - /** |
|
| 26 | - * @param string $hook |
|
| 27 | - */ |
|
| 28 | - protected function set_hook( $hook ) { |
|
| 29 | - $this->hook = $hook; |
|
| 30 | - } |
|
| 25 | + /** |
|
| 26 | + * @param string $hook |
|
| 27 | + */ |
|
| 28 | + protected function set_hook( $hook ) { |
|
| 29 | + $this->hook = $hook; |
|
| 30 | + } |
|
| 31 | 31 | |
| 32 | - public function get_hook() { |
|
| 33 | - return $this->hook; |
|
| 34 | - } |
|
| 32 | + public function get_hook() { |
|
| 33 | + return $this->hook; |
|
| 34 | + } |
|
| 35 | 35 | |
| 36 | - protected function set_schedule( ActionScheduler_Schedule $schedule ) { |
|
| 37 | - $this->schedule = $schedule; |
|
| 38 | - } |
|
| 36 | + protected function set_schedule( ActionScheduler_Schedule $schedule ) { |
|
| 37 | + $this->schedule = $schedule; |
|
| 38 | + } |
|
| 39 | 39 | |
| 40 | - /** |
|
| 41 | - * @return ActionScheduler_Schedule |
|
| 42 | - */ |
|
| 43 | - public function get_schedule() { |
|
| 44 | - return $this->schedule; |
|
| 45 | - } |
|
| 40 | + /** |
|
| 41 | + * @return ActionScheduler_Schedule |
|
| 42 | + */ |
|
| 43 | + public function get_schedule() { |
|
| 44 | + return $this->schedule; |
|
| 45 | + } |
|
| 46 | 46 | |
| 47 | - protected function set_args( array $args ) { |
|
| 48 | - $this->args = $args; |
|
| 49 | - } |
|
| 47 | + protected function set_args( array $args ) { |
|
| 48 | + $this->args = $args; |
|
| 49 | + } |
|
| 50 | 50 | |
| 51 | - public function get_args() { |
|
| 52 | - return $this->args; |
|
| 53 | - } |
|
| 51 | + public function get_args() { |
|
| 52 | + return $this->args; |
|
| 53 | + } |
|
| 54 | 54 | |
| 55 | - /** |
|
| 56 | - * @param string $group |
|
| 57 | - */ |
|
| 58 | - protected function set_group( $group ) { |
|
| 59 | - $this->group = $group; |
|
| 60 | - } |
|
| 55 | + /** |
|
| 56 | + * @param string $group |
|
| 57 | + */ |
|
| 58 | + protected function set_group( $group ) { |
|
| 59 | + $this->group = $group; |
|
| 60 | + } |
|
| 61 | 61 | |
| 62 | - /** |
|
| 63 | - * @return string |
|
| 64 | - */ |
|
| 65 | - public function get_group() { |
|
| 66 | - return $this->group; |
|
| 67 | - } |
|
| 62 | + /** |
|
| 63 | + * @return string |
|
| 64 | + */ |
|
| 65 | + public function get_group() { |
|
| 66 | + return $this->group; |
|
| 67 | + } |
|
| 68 | 68 | |
| 69 | - /** |
|
| 70 | - * @return bool If the action has been finished |
|
| 71 | - */ |
|
| 72 | - public function is_finished() { |
|
| 73 | - return FALSE; |
|
| 74 | - } |
|
| 69 | + /** |
|
| 70 | + * @return bool If the action has been finished |
|
| 71 | + */ |
|
| 72 | + public function is_finished() { |
|
| 73 | + return FALSE; |
|
| 74 | + } |
|
| 75 | 75 | } |
@@ -5,12 +5,12 @@ |
||
| 5 | 5 | */ |
| 6 | 6 | class ActionScheduler_NullAction extends ActionScheduler_Action { |
| 7 | 7 | |
| 8 | - public function __construct( $hook = '', array $args = array(), ActionScheduler_Schedule $schedule = NULL ) { |
|
| 9 | - $this->set_schedule( new ActionScheduler_NullSchedule() ); |
|
| 10 | - } |
|
| 8 | + public function __construct( $hook = '', array $args = array(), ActionScheduler_Schedule $schedule = NULL ) { |
|
| 9 | + $this->set_schedule( new ActionScheduler_NullSchedule() ); |
|
| 10 | + } |
|
| 11 | 11 | |
| 12 | - public function execute() { |
|
| 13 | - // don't execute |
|
| 14 | - } |
|
| 12 | + public function execute() { |
|
| 13 | + // don't execute |
|
| 14 | + } |
|
| 15 | 15 | } |
| 16 | - |
|
| 17 | 16 | \ No newline at end of file |
| 17 | + |
|
| 18 | 18 | \ No newline at end of file |
@@ -8,16 +8,16 @@ |
||
| 8 | 8 | */ |
| 9 | 9 | class ActionScheduler_CanceledAction extends ActionScheduler_FinishedAction { |
| 10 | 10 | |
| 11 | - /** |
|
| 12 | - * @param string $hook |
|
| 13 | - * @param array $args |
|
| 14 | - * @param ActionScheduler_Schedule $schedule |
|
| 15 | - * @param string $group |
|
| 16 | - */ |
|
| 17 | - public function __construct( $hook, array $args = array(), ActionScheduler_Schedule $schedule = null, $group = '' ) { |
|
| 18 | - parent::__construct( $hook, $args, $schedule, $group ); |
|
| 19 | - if ( is_null( $schedule ) ) { |
|
| 20 | - $this->set_schedule( new ActionScheduler_NullSchedule() ); |
|
| 21 | - } |
|
| 22 | - } |
|
| 11 | + /** |
|
| 12 | + * @param string $hook |
|
| 13 | + * @param array $args |
|
| 14 | + * @param ActionScheduler_Schedule $schedule |
|
| 15 | + * @param string $group |
|
| 16 | + */ |
|
| 17 | + public function __construct( $hook, array $args = array(), ActionScheduler_Schedule $schedule = null, $group = '' ) { |
|
| 18 | + parent::__construct( $hook, $args, $schedule, $group ); |
|
| 19 | + if ( is_null( $schedule ) ) { |
|
| 20 | + $this->set_schedule( new ActionScheduler_NullSchedule() ); |
|
| 21 | + } |
|
| 22 | + } |
|
| 23 | 23 | } |
@@ -5,12 +5,12 @@ |
||
| 5 | 5 | */ |
| 6 | 6 | class ActionScheduler_FinishedAction extends ActionScheduler_Action { |
| 7 | 7 | |
| 8 | - public function execute() { |
|
| 9 | - // don't execute |
|
| 10 | - } |
|
| 8 | + public function execute() { |
|
| 9 | + // don't execute |
|
| 10 | + } |
|
| 11 | 11 | |
| 12 | - public function is_finished() { |
|
| 13 | - return TRUE; |
|
| 14 | - } |
|
| 12 | + public function is_finished() { |
|
| 13 | + return TRUE; |
|
| 14 | + } |
|
| 15 | 15 | } |
| 16 | - |
|
| 17 | 16 | \ No newline at end of file |
| 17 | + |
|
| 18 | 18 | \ No newline at end of file |