@@ -9,39 +9,39 @@ |
||
9 | 9 | */ |
10 | 10 | class ActionScheduler_DBStoreMigrator extends ActionScheduler_DBStore { |
11 | 11 | |
12 | - /** |
|
13 | - * Save an action with optional last attempt date. |
|
14 | - * |
|
15 | - * Normally, saving an action sets its attempted date to 0000-00-00 00:00:00 because when an action is first saved, |
|
16 | - * it can't have been attempted yet, but migrated completed actions will have an attempted date, so we need to save |
|
17 | - * that when first saving the action. |
|
18 | - * |
|
19 | - * @param ActionScheduler_Action $action |
|
20 | - * @param \DateTime $scheduled_date Optional date of the first instance to store. |
|
21 | - * @param \DateTime $last_attempt_date Optional date the action was last attempted. |
|
22 | - * |
|
23 | - * @return string The action ID |
|
24 | - * @throws \RuntimeException When the action is not saved. |
|
25 | - */ |
|
26 | - public function save_action( ActionScheduler_Action $action, \DateTime $scheduled_date = null, \DateTime $last_attempt_date = null ){ |
|
27 | - try { |
|
28 | - /** @var \wpdb $wpdb */ |
|
29 | - global $wpdb; |
|
12 | + /** |
|
13 | + * Save an action with optional last attempt date. |
|
14 | + * |
|
15 | + * Normally, saving an action sets its attempted date to 0000-00-00 00:00:00 because when an action is first saved, |
|
16 | + * it can't have been attempted yet, but migrated completed actions will have an attempted date, so we need to save |
|
17 | + * that when first saving the action. |
|
18 | + * |
|
19 | + * @param ActionScheduler_Action $action |
|
20 | + * @param \DateTime $scheduled_date Optional date of the first instance to store. |
|
21 | + * @param \DateTime $last_attempt_date Optional date the action was last attempted. |
|
22 | + * |
|
23 | + * @return string The action ID |
|
24 | + * @throws \RuntimeException When the action is not saved. |
|
25 | + */ |
|
26 | + public function save_action( ActionScheduler_Action $action, \DateTime $scheduled_date = null, \DateTime $last_attempt_date = null ){ |
|
27 | + try { |
|
28 | + /** @var \wpdb $wpdb */ |
|
29 | + global $wpdb; |
|
30 | 30 | |
31 | - $action_id = parent::save_action( $action, $scheduled_date ); |
|
31 | + $action_id = parent::save_action( $action, $scheduled_date ); |
|
32 | 32 | |
33 | - if ( null !== $last_attempt_date ) { |
|
34 | - $data = [ |
|
35 | - 'last_attempt_gmt' => $this->get_scheduled_date_string( $action, $last_attempt_date ), |
|
36 | - 'last_attempt_local' => $this->get_scheduled_date_string_local( $action, $last_attempt_date ), |
|
37 | - ]; |
|
33 | + if ( null !== $last_attempt_date ) { |
|
34 | + $data = [ |
|
35 | + 'last_attempt_gmt' => $this->get_scheduled_date_string( $action, $last_attempt_date ), |
|
36 | + 'last_attempt_local' => $this->get_scheduled_date_string_local( $action, $last_attempt_date ), |
|
37 | + ]; |
|
38 | 38 | |
39 | - $wpdb->update( $wpdb->actionscheduler_actions, $data, array( 'action_id' => $action_id ), array( '%s', '%s' ), array( '%d' ) ); |
|
40 | - } |
|
39 | + $wpdb->update( $wpdb->actionscheduler_actions, $data, array( 'action_id' => $action_id ), array( '%s', '%s' ), array( '%d' ) ); |
|
40 | + } |
|
41 | 41 | |
42 | - return $action_id; |
|
43 | - } catch ( \Exception $e ) { |
|
44 | - throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 ); |
|
45 | - } |
|
46 | - } |
|
42 | + return $action_id; |
|
43 | + } catch ( \Exception $e ) { |
|
44 | + throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 ); |
|
45 | + } |
|
46 | + } |
|
47 | 47 | } |
@@ -17,190 +17,190 @@ |
||
17 | 17 | * @codeCoverageIgnore |
18 | 18 | */ |
19 | 19 | class Controller { |
20 | - private static $instance; |
|
21 | - |
|
22 | - /** @var Action_Scheduler\Migration\Scheduler */ |
|
23 | - private $migration_scheduler; |
|
24 | - |
|
25 | - /** @var string */ |
|
26 | - private $store_classname; |
|
27 | - |
|
28 | - /** @var string */ |
|
29 | - private $logger_classname; |
|
30 | - |
|
31 | - /** @var bool */ |
|
32 | - private $migrate_custom_store; |
|
33 | - |
|
34 | - /** |
|
35 | - * Controller constructor. |
|
36 | - * |
|
37 | - * @param Scheduler $migration_scheduler Migration scheduler object. |
|
38 | - */ |
|
39 | - protected function __construct( Scheduler $migration_scheduler ) { |
|
40 | - $this->migration_scheduler = $migration_scheduler; |
|
41 | - $this->store_classname = ''; |
|
42 | - } |
|
43 | - |
|
44 | - /** |
|
45 | - * Set the action store class name. |
|
46 | - * |
|
47 | - * @param string $class Classname of the store class. |
|
48 | - * |
|
49 | - * @return string |
|
50 | - */ |
|
51 | - public function get_store_class( $class ) { |
|
52 | - if ( \ActionScheduler_DataController::is_migration_complete() ) { |
|
53 | - return \ActionScheduler_DataController::DATASTORE_CLASS; |
|
54 | - } elseif ( \ActionScheduler_Store::DEFAULT_CLASS !== $class ) { |
|
55 | - $this->store_classname = $class; |
|
56 | - return $class; |
|
57 | - } else { |
|
58 | - return 'ActionScheduler_HybridStore'; |
|
59 | - } |
|
60 | - } |
|
61 | - |
|
62 | - /** |
|
63 | - * Set the action logger class name. |
|
64 | - * |
|
65 | - * @param string $class Classname of the logger class. |
|
66 | - * |
|
67 | - * @return string |
|
68 | - */ |
|
69 | - public function get_logger_class( $class ) { |
|
70 | - \ActionScheduler_Store::instance(); |
|
71 | - |
|
72 | - if ( $this->has_custom_datastore() ) { |
|
73 | - $this->logger_classname = $class; |
|
74 | - return $class; |
|
75 | - } else { |
|
76 | - return \ActionScheduler_DataController::LOGGER_CLASS; |
|
77 | - } |
|
78 | - } |
|
79 | - |
|
80 | - /** |
|
81 | - * Get flag indicating whether a custom datastore is in use. |
|
82 | - * |
|
83 | - * @return bool |
|
84 | - */ |
|
85 | - public function has_custom_datastore() { |
|
86 | - return (bool) $this->store_classname; |
|
87 | - } |
|
88 | - |
|
89 | - /** |
|
90 | - * Set up the background migration process |
|
91 | - * |
|
92 | - * @return void |
|
93 | - */ |
|
94 | - public function schedule_migration() { |
|
95 | - if ( \ActionScheduler_DataController::is_migration_complete() || $this->migration_scheduler->is_migration_scheduled() ) { |
|
96 | - return; |
|
97 | - } |
|
98 | - |
|
99 | - $this->migration_scheduler->schedule_migration(); |
|
100 | - } |
|
101 | - |
|
102 | - /** |
|
103 | - * Get the default migration config object |
|
104 | - * |
|
105 | - * @return ActionScheduler\Migration\Config |
|
106 | - */ |
|
107 | - public function get_migration_config_object() { |
|
108 | - static $config = null; |
|
109 | - |
|
110 | - if ( ! $config ) { |
|
111 | - $source_store = $this->store_classname ? new $this->store_classname() : new \ActionScheduler_wpPostStore(); |
|
112 | - $source_logger = $this->logger_classname ? new $this->logger_classname() : new \ActionScheduler_wpCommentLogger(); |
|
113 | - |
|
114 | - $config = new Config(); |
|
115 | - $config->set_source_store( $source_store ); |
|
116 | - $config->set_source_logger( $source_logger ); |
|
117 | - $config->set_destination_store( new \ActionScheduler_DBStoreMigrator() ); |
|
118 | - $config->set_destination_logger( new \ActionScheduler_DBLogger() ); |
|
119 | - |
|
120 | - if ( defined( 'WP_CLI' ) && WP_CLI ) { |
|
121 | - $config->set_progress_bar( new ProgressBar( '', 0 ) ); |
|
122 | - } |
|
123 | - } |
|
124 | - |
|
125 | - return apply_filters( 'action_scheduler/migration_config', $config ); |
|
126 | - } |
|
127 | - |
|
128 | - /** |
|
129 | - * Hook dashboard migration notice. |
|
130 | - */ |
|
131 | - public function hook_admin_notices() { |
|
132 | - if ( ! $this->allow_migration() || \ActionScheduler_DataController::is_migration_complete() ) { |
|
133 | - return; |
|
134 | - } |
|
135 | - add_action( 'admin_notices', array( $this, 'display_migration_notice' ), 10, 0 ); |
|
136 | - } |
|
137 | - |
|
138 | - /** |
|
139 | - * Show a dashboard notice that migration is in progress. |
|
140 | - */ |
|
141 | - public function display_migration_notice() { |
|
142 | - printf( '<div class="notice notice-warning"><p>%s</p></div>', __( 'Action Scheduler migration in progress. The list of scheduled actions may be incomplete.', 'action-scheduler' ) ); |
|
143 | - } |
|
144 | - |
|
145 | - /** |
|
146 | - * Add store classes. Hook migration. |
|
147 | - */ |
|
148 | - private function hook() { |
|
149 | - add_filter( 'action_scheduler_store_class', array( $this, 'get_store_class' ), 100, 1 ); |
|
150 | - add_filter( 'action_scheduler_logger_class', array( $this, 'get_logger_class' ), 100, 1 ); |
|
151 | - add_action( 'init', array( $this, 'maybe_hook_migration' ) ); |
|
152 | - add_action( 'shutdown', array( $this, 'schedule_migration' ), 0, 0 ); |
|
153 | - |
|
154 | - // Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen |
|
155 | - add_action( 'load-tools_page_action-scheduler', array( $this, 'hook_admin_notices' ), 10, 0 ); |
|
156 | - add_action( 'load-woocommerce_page_wc-status', array( $this, 'hook_admin_notices' ), 10, 0 ); |
|
157 | - } |
|
158 | - |
|
159 | - /** |
|
160 | - * Possibly hook the migration scheduler action. |
|
161 | - * |
|
162 | - * @author Jeremy Pry |
|
163 | - */ |
|
164 | - public function maybe_hook_migration() { |
|
165 | - if ( ! $this->allow_migration() || \ActionScheduler_DataController::is_migration_complete() ) { |
|
166 | - return; |
|
167 | - } |
|
168 | - |
|
169 | - $this->migration_scheduler->hook(); |
|
170 | - } |
|
171 | - |
|
172 | - /** |
|
173 | - * Allow datastores to enable migration to AS tables. |
|
174 | - */ |
|
175 | - public function allow_migration() { |
|
176 | - if ( ! \ActionScheduler_DataController::dependencies_met() ) { |
|
177 | - return false; |
|
178 | - } |
|
179 | - |
|
180 | - if ( null === $this->migrate_custom_store ) { |
|
181 | - $this->migrate_custom_store = apply_filters( 'action_scheduler_migrate_data_store', false ); |
|
182 | - } |
|
183 | - |
|
184 | - return ( ! $this->has_custom_datastore() ) || $this->migrate_custom_store; |
|
185 | - } |
|
186 | - |
|
187 | - /** |
|
188 | - * Proceed with the migration if the dependencies have been met. |
|
189 | - */ |
|
190 | - public static function init() { |
|
191 | - if ( \ActionScheduler_DataController::dependencies_met() ) { |
|
192 | - self::instance()->hook(); |
|
193 | - } |
|
194 | - } |
|
195 | - |
|
196 | - /** |
|
197 | - * Singleton factory. |
|
198 | - */ |
|
199 | - public static function instance() { |
|
200 | - if ( ! isset( self::$instance ) ) { |
|
201 | - self::$instance = new static( new Scheduler() ); |
|
202 | - } |
|
203 | - |
|
204 | - return self::$instance; |
|
205 | - } |
|
20 | + private static $instance; |
|
21 | + |
|
22 | + /** @var Action_Scheduler\Migration\Scheduler */ |
|
23 | + private $migration_scheduler; |
|
24 | + |
|
25 | + /** @var string */ |
|
26 | + private $store_classname; |
|
27 | + |
|
28 | + /** @var string */ |
|
29 | + private $logger_classname; |
|
30 | + |
|
31 | + /** @var bool */ |
|
32 | + private $migrate_custom_store; |
|
33 | + |
|
34 | + /** |
|
35 | + * Controller constructor. |
|
36 | + * |
|
37 | + * @param Scheduler $migration_scheduler Migration scheduler object. |
|
38 | + */ |
|
39 | + protected function __construct( Scheduler $migration_scheduler ) { |
|
40 | + $this->migration_scheduler = $migration_scheduler; |
|
41 | + $this->store_classname = ''; |
|
42 | + } |
|
43 | + |
|
44 | + /** |
|
45 | + * Set the action store class name. |
|
46 | + * |
|
47 | + * @param string $class Classname of the store class. |
|
48 | + * |
|
49 | + * @return string |
|
50 | + */ |
|
51 | + public function get_store_class( $class ) { |
|
52 | + if ( \ActionScheduler_DataController::is_migration_complete() ) { |
|
53 | + return \ActionScheduler_DataController::DATASTORE_CLASS; |
|
54 | + } elseif ( \ActionScheduler_Store::DEFAULT_CLASS !== $class ) { |
|
55 | + $this->store_classname = $class; |
|
56 | + return $class; |
|
57 | + } else { |
|
58 | + return 'ActionScheduler_HybridStore'; |
|
59 | + } |
|
60 | + } |
|
61 | + |
|
62 | + /** |
|
63 | + * Set the action logger class name. |
|
64 | + * |
|
65 | + * @param string $class Classname of the logger class. |
|
66 | + * |
|
67 | + * @return string |
|
68 | + */ |
|
69 | + public function get_logger_class( $class ) { |
|
70 | + \ActionScheduler_Store::instance(); |
|
71 | + |
|
72 | + if ( $this->has_custom_datastore() ) { |
|
73 | + $this->logger_classname = $class; |
|
74 | + return $class; |
|
75 | + } else { |
|
76 | + return \ActionScheduler_DataController::LOGGER_CLASS; |
|
77 | + } |
|
78 | + } |
|
79 | + |
|
80 | + /** |
|
81 | + * Get flag indicating whether a custom datastore is in use. |
|
82 | + * |
|
83 | + * @return bool |
|
84 | + */ |
|
85 | + public function has_custom_datastore() { |
|
86 | + return (bool) $this->store_classname; |
|
87 | + } |
|
88 | + |
|
89 | + /** |
|
90 | + * Set up the background migration process |
|
91 | + * |
|
92 | + * @return void |
|
93 | + */ |
|
94 | + public function schedule_migration() { |
|
95 | + if ( \ActionScheduler_DataController::is_migration_complete() || $this->migration_scheduler->is_migration_scheduled() ) { |
|
96 | + return; |
|
97 | + } |
|
98 | + |
|
99 | + $this->migration_scheduler->schedule_migration(); |
|
100 | + } |
|
101 | + |
|
102 | + /** |
|
103 | + * Get the default migration config object |
|
104 | + * |
|
105 | + * @return ActionScheduler\Migration\Config |
|
106 | + */ |
|
107 | + public function get_migration_config_object() { |
|
108 | + static $config = null; |
|
109 | + |
|
110 | + if ( ! $config ) { |
|
111 | + $source_store = $this->store_classname ? new $this->store_classname() : new \ActionScheduler_wpPostStore(); |
|
112 | + $source_logger = $this->logger_classname ? new $this->logger_classname() : new \ActionScheduler_wpCommentLogger(); |
|
113 | + |
|
114 | + $config = new Config(); |
|
115 | + $config->set_source_store( $source_store ); |
|
116 | + $config->set_source_logger( $source_logger ); |
|
117 | + $config->set_destination_store( new \ActionScheduler_DBStoreMigrator() ); |
|
118 | + $config->set_destination_logger( new \ActionScheduler_DBLogger() ); |
|
119 | + |
|
120 | + if ( defined( 'WP_CLI' ) && WP_CLI ) { |
|
121 | + $config->set_progress_bar( new ProgressBar( '', 0 ) ); |
|
122 | + } |
|
123 | + } |
|
124 | + |
|
125 | + return apply_filters( 'action_scheduler/migration_config', $config ); |
|
126 | + } |
|
127 | + |
|
128 | + /** |
|
129 | + * Hook dashboard migration notice. |
|
130 | + */ |
|
131 | + public function hook_admin_notices() { |
|
132 | + if ( ! $this->allow_migration() || \ActionScheduler_DataController::is_migration_complete() ) { |
|
133 | + return; |
|
134 | + } |
|
135 | + add_action( 'admin_notices', array( $this, 'display_migration_notice' ), 10, 0 ); |
|
136 | + } |
|
137 | + |
|
138 | + /** |
|
139 | + * Show a dashboard notice that migration is in progress. |
|
140 | + */ |
|
141 | + public function display_migration_notice() { |
|
142 | + printf( '<div class="notice notice-warning"><p>%s</p></div>', __( 'Action Scheduler migration in progress. The list of scheduled actions may be incomplete.', 'action-scheduler' ) ); |
|
143 | + } |
|
144 | + |
|
145 | + /** |
|
146 | + * Add store classes. Hook migration. |
|
147 | + */ |
|
148 | + private function hook() { |
|
149 | + add_filter( 'action_scheduler_store_class', array( $this, 'get_store_class' ), 100, 1 ); |
|
150 | + add_filter( 'action_scheduler_logger_class', array( $this, 'get_logger_class' ), 100, 1 ); |
|
151 | + add_action( 'init', array( $this, 'maybe_hook_migration' ) ); |
|
152 | + add_action( 'shutdown', array( $this, 'schedule_migration' ), 0, 0 ); |
|
153 | + |
|
154 | + // Action Scheduler may be displayed as a Tools screen or WooCommerce > Status administration screen |
|
155 | + add_action( 'load-tools_page_action-scheduler', array( $this, 'hook_admin_notices' ), 10, 0 ); |
|
156 | + add_action( 'load-woocommerce_page_wc-status', array( $this, 'hook_admin_notices' ), 10, 0 ); |
|
157 | + } |
|
158 | + |
|
159 | + /** |
|
160 | + * Possibly hook the migration scheduler action. |
|
161 | + * |
|
162 | + * @author Jeremy Pry |
|
163 | + */ |
|
164 | + public function maybe_hook_migration() { |
|
165 | + if ( ! $this->allow_migration() || \ActionScheduler_DataController::is_migration_complete() ) { |
|
166 | + return; |
|
167 | + } |
|
168 | + |
|
169 | + $this->migration_scheduler->hook(); |
|
170 | + } |
|
171 | + |
|
172 | + /** |
|
173 | + * Allow datastores to enable migration to AS tables. |
|
174 | + */ |
|
175 | + public function allow_migration() { |
|
176 | + if ( ! \ActionScheduler_DataController::dependencies_met() ) { |
|
177 | + return false; |
|
178 | + } |
|
179 | + |
|
180 | + if ( null === $this->migrate_custom_store ) { |
|
181 | + $this->migrate_custom_store = apply_filters( 'action_scheduler_migrate_data_store', false ); |
|
182 | + } |
|
183 | + |
|
184 | + return ( ! $this->has_custom_datastore() ) || $this->migrate_custom_store; |
|
185 | + } |
|
186 | + |
|
187 | + /** |
|
188 | + * Proceed with the migration if the dependencies have been met. |
|
189 | + */ |
|
190 | + public static function init() { |
|
191 | + if ( \ActionScheduler_DataController::dependencies_met() ) { |
|
192 | + self::instance()->hook(); |
|
193 | + } |
|
194 | + } |
|
195 | + |
|
196 | + /** |
|
197 | + * Singleton factory. |
|
198 | + */ |
|
199 | + public static function instance() { |
|
200 | + if ( ! isset( self::$instance ) ) { |
|
201 | + self::$instance = new static( new Scheduler() ); |
|
202 | + } |
|
203 | + |
|
204 | + return self::$instance; |
|
205 | + } |
|
206 | 206 | } |
@@ -13,97 +13,97 @@ |
||
13 | 13 | * @codeCoverageIgnore |
14 | 14 | */ |
15 | 15 | class ActionMigrator { |
16 | - /** var ActionScheduler_Store */ |
|
17 | - private $source; |
|
18 | - |
|
19 | - /** var ActionScheduler_Store */ |
|
20 | - private $destination; |
|
21 | - |
|
22 | - /** var LogMigrator */ |
|
23 | - private $log_migrator; |
|
24 | - |
|
25 | - /** |
|
26 | - * ActionMigrator constructor. |
|
27 | - * |
|
28 | - * @param ActionScheduler_Store $source_store Source store object. |
|
29 | - * @param ActionScheduler_Store $destination_store Destination store object. |
|
30 | - * @param LogMigrator $log_migrator Log migrator object. |
|
31 | - */ |
|
32 | - public function __construct( \ActionScheduler_Store $source_store, \ActionScheduler_Store $destination_store, LogMigrator $log_migrator ) { |
|
33 | - $this->source = $source_store; |
|
34 | - $this->destination = $destination_store; |
|
35 | - $this->log_migrator = $log_migrator; |
|
36 | - } |
|
37 | - |
|
38 | - /** |
|
39 | - * Migrate an action. |
|
40 | - * |
|
41 | - * @param int $source_action_id Action ID. |
|
42 | - * |
|
43 | - * @return int 0|new action ID |
|
44 | - */ |
|
45 | - public function migrate( $source_action_id ) { |
|
46 | - try { |
|
47 | - $action = $this->source->fetch_action( $source_action_id ); |
|
48 | - $status = $this->source->get_status( $source_action_id ); |
|
49 | - } catch ( \Exception $e ) { |
|
50 | - $action = null; |
|
51 | - $status = ''; |
|
52 | - } |
|
53 | - |
|
54 | - if ( is_null( $action ) || empty( $status ) || ! $action->get_schedule()->get_date() ) { |
|
55 | - // null action or empty status means the fetch operation failed or the action didn't exist |
|
56 | - // null schedule means it's missing vital data |
|
57 | - // delete it and move on |
|
58 | - try { |
|
59 | - $this->source->delete_action( $source_action_id ); |
|
60 | - } catch ( \Exception $e ) { |
|
61 | - // nothing to do, it didn't exist in the first place |
|
62 | - } |
|
63 | - do_action( 'action_scheduler/no_action_to_migrate', $source_action_id, $this->source, $this->destination ); |
|
64 | - |
|
65 | - return 0; |
|
66 | - } |
|
67 | - |
|
68 | - try { |
|
69 | - |
|
70 | - // Make sure the last attempt date is set correctly for completed and failed actions |
|
71 | - $last_attempt_date = ( $status !== \ActionScheduler_Store::STATUS_PENDING ) ? $this->source->get_date( $source_action_id ) : null; |
|
72 | - |
|
73 | - $destination_action_id = $this->destination->save_action( $action, null, $last_attempt_date ); |
|
74 | - } catch ( \Exception $e ) { |
|
75 | - do_action( 'action_scheduler/migrate_action_failed', $source_action_id, $this->source, $this->destination ); |
|
76 | - |
|
77 | - return 0; // could not save the action in the new store |
|
78 | - } |
|
79 | - |
|
80 | - try { |
|
81 | - switch ( $status ) { |
|
82 | - case \ActionScheduler_Store::STATUS_FAILED : |
|
83 | - $this->destination->mark_failure( $destination_action_id ); |
|
84 | - break; |
|
85 | - case \ActionScheduler_Store::STATUS_CANCELED : |
|
86 | - $this->destination->cancel_action( $destination_action_id ); |
|
87 | - break; |
|
88 | - } |
|
89 | - |
|
90 | - $this->log_migrator->migrate( $source_action_id, $destination_action_id ); |
|
91 | - $this->source->delete_action( $source_action_id ); |
|
92 | - |
|
93 | - $test_action = $this->source->fetch_action( $source_action_id ); |
|
94 | - if ( ! is_a( $test_action, 'ActionScheduler_NullAction' ) ) { |
|
95 | - throw new \RuntimeException( sprintf( __( 'Unable to remove source migrated action %s', 'action-scheduler' ), $source_action_id ) ); |
|
96 | - } |
|
97 | - do_action( 'action_scheduler/migrated_action', $source_action_id, $destination_action_id, $this->source, $this->destination ); |
|
98 | - |
|
99 | - return $destination_action_id; |
|
100 | - } catch ( \Exception $e ) { |
|
101 | - // could not delete from the old store |
|
102 | - $this->source->mark_migrated( $source_action_id ); |
|
103 | - do_action( 'action_scheduler/migrate_action_incomplete', $source_action_id, $destination_action_id, $this->source, $this->destination ); |
|
104 | - do_action( 'action_scheduler/migrated_action', $source_action_id, $destination_action_id, $this->source, $this->destination ); |
|
105 | - |
|
106 | - return $destination_action_id; |
|
107 | - } |
|
108 | - } |
|
16 | + /** var ActionScheduler_Store */ |
|
17 | + private $source; |
|
18 | + |
|
19 | + /** var ActionScheduler_Store */ |
|
20 | + private $destination; |
|
21 | + |
|
22 | + /** var LogMigrator */ |
|
23 | + private $log_migrator; |
|
24 | + |
|
25 | + /** |
|
26 | + * ActionMigrator constructor. |
|
27 | + * |
|
28 | + * @param ActionScheduler_Store $source_store Source store object. |
|
29 | + * @param ActionScheduler_Store $destination_store Destination store object. |
|
30 | + * @param LogMigrator $log_migrator Log migrator object. |
|
31 | + */ |
|
32 | + public function __construct( \ActionScheduler_Store $source_store, \ActionScheduler_Store $destination_store, LogMigrator $log_migrator ) { |
|
33 | + $this->source = $source_store; |
|
34 | + $this->destination = $destination_store; |
|
35 | + $this->log_migrator = $log_migrator; |
|
36 | + } |
|
37 | + |
|
38 | + /** |
|
39 | + * Migrate an action. |
|
40 | + * |
|
41 | + * @param int $source_action_id Action ID. |
|
42 | + * |
|
43 | + * @return int 0|new action ID |
|
44 | + */ |
|
45 | + public function migrate( $source_action_id ) { |
|
46 | + try { |
|
47 | + $action = $this->source->fetch_action( $source_action_id ); |
|
48 | + $status = $this->source->get_status( $source_action_id ); |
|
49 | + } catch ( \Exception $e ) { |
|
50 | + $action = null; |
|
51 | + $status = ''; |
|
52 | + } |
|
53 | + |
|
54 | + if ( is_null( $action ) || empty( $status ) || ! $action->get_schedule()->get_date() ) { |
|
55 | + // null action or empty status means the fetch operation failed or the action didn't exist |
|
56 | + // null schedule means it's missing vital data |
|
57 | + // delete it and move on |
|
58 | + try { |
|
59 | + $this->source->delete_action( $source_action_id ); |
|
60 | + } catch ( \Exception $e ) { |
|
61 | + // nothing to do, it didn't exist in the first place |
|
62 | + } |
|
63 | + do_action( 'action_scheduler/no_action_to_migrate', $source_action_id, $this->source, $this->destination ); |
|
64 | + |
|
65 | + return 0; |
|
66 | + } |
|
67 | + |
|
68 | + try { |
|
69 | + |
|
70 | + // Make sure the last attempt date is set correctly for completed and failed actions |
|
71 | + $last_attempt_date = ( $status !== \ActionScheduler_Store::STATUS_PENDING ) ? $this->source->get_date( $source_action_id ) : null; |
|
72 | + |
|
73 | + $destination_action_id = $this->destination->save_action( $action, null, $last_attempt_date ); |
|
74 | + } catch ( \Exception $e ) { |
|
75 | + do_action( 'action_scheduler/migrate_action_failed', $source_action_id, $this->source, $this->destination ); |
|
76 | + |
|
77 | + return 0; // could not save the action in the new store |
|
78 | + } |
|
79 | + |
|
80 | + try { |
|
81 | + switch ( $status ) { |
|
82 | + case \ActionScheduler_Store::STATUS_FAILED : |
|
83 | + $this->destination->mark_failure( $destination_action_id ); |
|
84 | + break; |
|
85 | + case \ActionScheduler_Store::STATUS_CANCELED : |
|
86 | + $this->destination->cancel_action( $destination_action_id ); |
|
87 | + break; |
|
88 | + } |
|
89 | + |
|
90 | + $this->log_migrator->migrate( $source_action_id, $destination_action_id ); |
|
91 | + $this->source->delete_action( $source_action_id ); |
|
92 | + |
|
93 | + $test_action = $this->source->fetch_action( $source_action_id ); |
|
94 | + if ( ! is_a( $test_action, 'ActionScheduler_NullAction' ) ) { |
|
95 | + throw new \RuntimeException( sprintf( __( 'Unable to remove source migrated action %s', 'action-scheduler' ), $source_action_id ) ); |
|
96 | + } |
|
97 | + do_action( 'action_scheduler/migrated_action', $source_action_id, $destination_action_id, $this->source, $this->destination ); |
|
98 | + |
|
99 | + return $destination_action_id; |
|
100 | + } catch ( \Exception $e ) { |
|
101 | + // could not delete from the old store |
|
102 | + $this->source->mark_migrated( $source_action_id ); |
|
103 | + do_action( 'action_scheduler/migrate_action_incomplete', $source_action_id, $destination_action_id, $this->source, $this->destination ); |
|
104 | + do_action( 'action_scheduler/migrated_action', $source_action_id, $destination_action_id, $this->source, $this->destination ); |
|
105 | + |
|
106 | + return $destination_action_id; |
|
107 | + } |
|
108 | + } |
|
109 | 109 | } |
@@ -5,77 +5,77 @@ |
||
5 | 5 | */ |
6 | 6 | class ActionScheduler_IntervalSchedule extends ActionScheduler_Abstract_RecurringSchedule implements ActionScheduler_Schedule { |
7 | 7 | |
8 | - /** |
|
9 | - * Deprecated property @see $this->__wakeup() for details. |
|
10 | - **/ |
|
11 | - private $start_timestamp = NULL; |
|
8 | + /** |
|
9 | + * Deprecated property @see $this->__wakeup() for details. |
|
10 | + **/ |
|
11 | + private $start_timestamp = NULL; |
|
12 | 12 | |
13 | - /** |
|
14 | - * Deprecated property @see $this->__wakeup() for details. |
|
15 | - **/ |
|
16 | - private $interval_in_seconds = NULL; |
|
13 | + /** |
|
14 | + * Deprecated property @see $this->__wakeup() for details. |
|
15 | + **/ |
|
16 | + private $interval_in_seconds = NULL; |
|
17 | 17 | |
18 | - /** |
|
19 | - * Calculate when this schedule should start after a given date & time using |
|
20 | - * the number of seconds between recurrences. |
|
21 | - * |
|
22 | - * @param DateTime $after |
|
23 | - * @return DateTime |
|
24 | - */ |
|
25 | - protected function calculate_next( DateTime $after ) { |
|
26 | - $after->modify( '+' . (int) $this->get_recurrence() . ' seconds' ); |
|
27 | - return $after; |
|
28 | - } |
|
18 | + /** |
|
19 | + * Calculate when this schedule should start after a given date & time using |
|
20 | + * the number of seconds between recurrences. |
|
21 | + * |
|
22 | + * @param DateTime $after |
|
23 | + * @return DateTime |
|
24 | + */ |
|
25 | + protected function calculate_next( DateTime $after ) { |
|
26 | + $after->modify( '+' . (int) $this->get_recurrence() . ' seconds' ); |
|
27 | + return $after; |
|
28 | + } |
|
29 | 29 | |
30 | - /** |
|
31 | - * @return int |
|
32 | - */ |
|
33 | - public function interval_in_seconds() { |
|
34 | - _deprecated_function( __METHOD__, '3.0.0', '(int)ActionScheduler_Abstract_RecurringSchedule::get_recurrence()' ); |
|
35 | - return (int) $this->get_recurrence(); |
|
36 | - } |
|
30 | + /** |
|
31 | + * @return int |
|
32 | + */ |
|
33 | + public function interval_in_seconds() { |
|
34 | + _deprecated_function( __METHOD__, '3.0.0', '(int)ActionScheduler_Abstract_RecurringSchedule::get_recurrence()' ); |
|
35 | + return (int) $this->get_recurrence(); |
|
36 | + } |
|
37 | 37 | |
38 | - /** |
|
39 | - * Serialize interval schedules with data required prior to AS 3.0.0 |
|
40 | - * |
|
41 | - * Prior to Action Scheduler 3.0.0, reccuring schedules used different property names to |
|
42 | - * refer to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp |
|
43 | - * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 |
|
44 | - * aligned properties and property names for better inheritance. To guard against the |
|
45 | - * possibility of infinite loops if downgrading to Action Scheduler < 3.0.0, we need to |
|
46 | - * also store the data with the old property names so if it's unserialized in AS < 3.0, |
|
47 | - * the schedule doesn't end up with a null/false/0 recurrence. |
|
48 | - * |
|
49 | - * @return array |
|
50 | - */ |
|
51 | - public function __sleep() { |
|
38 | + /** |
|
39 | + * Serialize interval schedules with data required prior to AS 3.0.0 |
|
40 | + * |
|
41 | + * Prior to Action Scheduler 3.0.0, reccuring schedules used different property names to |
|
42 | + * refer to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp |
|
43 | + * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 |
|
44 | + * aligned properties and property names for better inheritance. To guard against the |
|
45 | + * possibility of infinite loops if downgrading to Action Scheduler < 3.0.0, we need to |
|
46 | + * also store the data with the old property names so if it's unserialized in AS < 3.0, |
|
47 | + * the schedule doesn't end up with a null/false/0 recurrence. |
|
48 | + * |
|
49 | + * @return array |
|
50 | + */ |
|
51 | + public function __sleep() { |
|
52 | 52 | |
53 | - $sleep_params = parent::__sleep(); |
|
53 | + $sleep_params = parent::__sleep(); |
|
54 | 54 | |
55 | - $this->start_timestamp = $this->scheduled_timestamp; |
|
56 | - $this->interval_in_seconds = $this->recurrence; |
|
55 | + $this->start_timestamp = $this->scheduled_timestamp; |
|
56 | + $this->interval_in_seconds = $this->recurrence; |
|
57 | 57 | |
58 | - return array_merge( $sleep_params, array( |
|
59 | - 'start_timestamp', |
|
60 | - 'interval_in_seconds' |
|
61 | - ) ); |
|
62 | - } |
|
58 | + return array_merge( $sleep_params, array( |
|
59 | + 'start_timestamp', |
|
60 | + 'interval_in_seconds' |
|
61 | + ) ); |
|
62 | + } |
|
63 | 63 | |
64 | - /** |
|
65 | - * Unserialize interval schedules serialized/stored prior to AS 3.0.0 |
|
66 | - * |
|
67 | - * For more background, @see ActionScheduler_Abstract_RecurringSchedule::__wakeup(). |
|
68 | - */ |
|
69 | - public function __wakeup() { |
|
70 | - if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->start_timestamp ) ) { |
|
71 | - $this->scheduled_timestamp = $this->start_timestamp; |
|
72 | - unset( $this->start_timestamp ); |
|
73 | - } |
|
64 | + /** |
|
65 | + * Unserialize interval schedules serialized/stored prior to AS 3.0.0 |
|
66 | + * |
|
67 | + * For more background, @see ActionScheduler_Abstract_RecurringSchedule::__wakeup(). |
|
68 | + */ |
|
69 | + public function __wakeup() { |
|
70 | + if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->start_timestamp ) ) { |
|
71 | + $this->scheduled_timestamp = $this->start_timestamp; |
|
72 | + unset( $this->start_timestamp ); |
|
73 | + } |
|
74 | 74 | |
75 | - if ( is_null( $this->recurrence ) && ! is_null( $this->interval_in_seconds ) ) { |
|
76 | - $this->recurrence = $this->interval_in_seconds; |
|
77 | - unset( $this->interval_in_seconds ); |
|
78 | - } |
|
79 | - parent::__wakeup(); |
|
80 | - } |
|
75 | + if ( is_null( $this->recurrence ) && ! is_null( $this->interval_in_seconds ) ) { |
|
76 | + $this->recurrence = $this->interval_in_seconds; |
|
77 | + unset( $this->interval_in_seconds ); |
|
78 | + } |
|
79 | + parent::__wakeup(); |
|
80 | + } |
|
81 | 81 | } |
@@ -5,67 +5,67 @@ |
||
5 | 5 | */ |
6 | 6 | class ActionScheduler_SimpleSchedule extends ActionScheduler_Abstract_Schedule { |
7 | 7 | |
8 | - /** |
|
9 | - * Deprecated property @see $this->__wakeup() for details. |
|
10 | - **/ |
|
11 | - private $timestamp = NULL; |
|
8 | + /** |
|
9 | + * Deprecated property @see $this->__wakeup() for details. |
|
10 | + **/ |
|
11 | + private $timestamp = NULL; |
|
12 | 12 | |
13 | - /** |
|
14 | - * @param DateTime $after |
|
15 | - * |
|
16 | - * @return DateTime|null |
|
17 | - */ |
|
18 | - public function calculate_next( DateTime $after ) { |
|
19 | - return null; |
|
20 | - } |
|
13 | + /** |
|
14 | + * @param DateTime $after |
|
15 | + * |
|
16 | + * @return DateTime|null |
|
17 | + */ |
|
18 | + public function calculate_next( DateTime $after ) { |
|
19 | + return null; |
|
20 | + } |
|
21 | 21 | |
22 | - /** |
|
23 | - * @return bool |
|
24 | - */ |
|
25 | - public function is_recurring() { |
|
26 | - return false; |
|
27 | - } |
|
22 | + /** |
|
23 | + * @return bool |
|
24 | + */ |
|
25 | + public function is_recurring() { |
|
26 | + return false; |
|
27 | + } |
|
28 | 28 | |
29 | - /** |
|
30 | - * Serialize schedule with data required prior to AS 3.0.0 |
|
31 | - * |
|
32 | - * Prior to Action Scheduler 3.0.0, schedules used different property names to refer |
|
33 | - * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp |
|
34 | - * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 |
|
35 | - * aligned properties and property names for better inheritance. To guard against the |
|
36 | - * scheduled date for single actions always being seen as "now" if downgrading to |
|
37 | - * Action Scheduler < 3.0.0, we need to also store the data with the old property names |
|
38 | - * so if it's unserialized in AS < 3.0, the schedule doesn't end up with a null recurrence. |
|
39 | - * |
|
40 | - * @return array |
|
41 | - */ |
|
42 | - public function __sleep() { |
|
29 | + /** |
|
30 | + * Serialize schedule with data required prior to AS 3.0.0 |
|
31 | + * |
|
32 | + * Prior to Action Scheduler 3.0.0, schedules used different property names to refer |
|
33 | + * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp |
|
34 | + * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 |
|
35 | + * aligned properties and property names for better inheritance. To guard against the |
|
36 | + * scheduled date for single actions always being seen as "now" if downgrading to |
|
37 | + * Action Scheduler < 3.0.0, we need to also store the data with the old property names |
|
38 | + * so if it's unserialized in AS < 3.0, the schedule doesn't end up with a null recurrence. |
|
39 | + * |
|
40 | + * @return array |
|
41 | + */ |
|
42 | + public function __sleep() { |
|
43 | 43 | |
44 | - $sleep_params = parent::__sleep(); |
|
44 | + $sleep_params = parent::__sleep(); |
|
45 | 45 | |
46 | - $this->timestamp = $this->scheduled_timestamp; |
|
46 | + $this->timestamp = $this->scheduled_timestamp; |
|
47 | 47 | |
48 | - return array_merge( $sleep_params, array( |
|
49 | - 'timestamp', |
|
50 | - ) ); |
|
51 | - } |
|
48 | + return array_merge( $sleep_params, array( |
|
49 | + 'timestamp', |
|
50 | + ) ); |
|
51 | + } |
|
52 | 52 | |
53 | - /** |
|
54 | - * Unserialize recurring schedules serialized/stored prior to AS 3.0.0 |
|
55 | - * |
|
56 | - * Prior to Action Scheduler 3.0.0, schedules used different property names to refer |
|
57 | - * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp |
|
58 | - * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 |
|
59 | - * aligned properties and property names for better inheritance. To maintain backward |
|
60 | - * compatibility with schedules serialized and stored prior to 3.0, we need to correctly |
|
61 | - * map the old property names with matching visibility. |
|
62 | - */ |
|
63 | - public function __wakeup() { |
|
53 | + /** |
|
54 | + * Unserialize recurring schedules serialized/stored prior to AS 3.0.0 |
|
55 | + * |
|
56 | + * Prior to Action Scheduler 3.0.0, schedules used different property names to refer |
|
57 | + * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp |
|
58 | + * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 |
|
59 | + * aligned properties and property names for better inheritance. To maintain backward |
|
60 | + * compatibility with schedules serialized and stored prior to 3.0, we need to correctly |
|
61 | + * map the old property names with matching visibility. |
|
62 | + */ |
|
63 | + public function __wakeup() { |
|
64 | 64 | |
65 | - if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->timestamp ) ) { |
|
66 | - $this->scheduled_timestamp = $this->timestamp; |
|
67 | - unset( $this->timestamp ); |
|
68 | - } |
|
69 | - parent::__wakeup(); |
|
70 | - } |
|
65 | + if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->timestamp ) ) { |
|
66 | + $this->scheduled_timestamp = $this->timestamp; |
|
67 | + unset( $this->timestamp ); |
|
68 | + } |
|
69 | + parent::__wakeup(); |
|
70 | + } |
|
71 | 71 | } |
@@ -4,15 +4,15 @@ |
||
4 | 4 | * Class ActionScheduler_Schedule |
5 | 5 | */ |
6 | 6 | interface ActionScheduler_Schedule { |
7 | - /** |
|
8 | - * @param DateTime $after |
|
9 | - * @return DateTime|null |
|
10 | - */ |
|
11 | - public function next( DateTime $after = NULL ); |
|
7 | + /** |
|
8 | + * @param DateTime $after |
|
9 | + * @return DateTime|null |
|
10 | + */ |
|
11 | + public function next( DateTime $after = NULL ); |
|
12 | 12 | |
13 | - /** |
|
14 | - * @return bool |
|
15 | - */ |
|
16 | - public function is_recurring(); |
|
13 | + /** |
|
14 | + * @return bool |
|
15 | + */ |
|
16 | + public function is_recurring(); |
|
17 | 17 | } |
18 | - |
|
19 | 18 | \ No newline at end of file |
19 | + |
|
20 | 20 | \ No newline at end of file |
@@ -5,24 +5,24 @@ |
||
5 | 5 | */ |
6 | 6 | class ActionScheduler_NullSchedule extends ActionScheduler_SimpleSchedule { |
7 | 7 | |
8 | - /** |
|
9 | - * Make the $date param optional and default to null. |
|
10 | - * |
|
11 | - * @param null $date The date & time to run the action. |
|
12 | - */ |
|
13 | - public function __construct( DateTime $date = null ) { |
|
14 | - $this->scheduled_date = null; |
|
15 | - } |
|
8 | + /** |
|
9 | + * Make the $date param optional and default to null. |
|
10 | + * |
|
11 | + * @param null $date The date & time to run the action. |
|
12 | + */ |
|
13 | + public function __construct( DateTime $date = null ) { |
|
14 | + $this->scheduled_date = null; |
|
15 | + } |
|
16 | 16 | |
17 | - /** |
|
18 | - * This schedule has no scheduled DateTime, so we need to override the parent __sleep() |
|
19 | - * @return array |
|
20 | - */ |
|
21 | - public function __sleep() { |
|
22 | - return array(); |
|
23 | - } |
|
17 | + /** |
|
18 | + * This schedule has no scheduled DateTime, so we need to override the parent __sleep() |
|
19 | + * @return array |
|
20 | + */ |
|
21 | + public function __sleep() { |
|
22 | + return array(); |
|
23 | + } |
|
24 | 24 | |
25 | - public function __wakeup() { |
|
26 | - $this->scheduled_date = null; |
|
27 | - } |
|
25 | + public function __wakeup() { |
|
26 | + $this->scheduled_date = null; |
|
27 | + } |
|
28 | 28 | } |
@@ -5,53 +5,53 @@ |
||
5 | 5 | */ |
6 | 6 | class ActionScheduler_CanceledSchedule extends ActionScheduler_SimpleSchedule { |
7 | 7 | |
8 | - /** |
|
9 | - * Deprecated property @see $this->__wakeup() for details. |
|
10 | - **/ |
|
11 | - private $timestamp = NULL; |
|
8 | + /** |
|
9 | + * Deprecated property @see $this->__wakeup() for details. |
|
10 | + **/ |
|
11 | + private $timestamp = NULL; |
|
12 | 12 | |
13 | - /** |
|
14 | - * @param DateTime $after |
|
15 | - * |
|
16 | - * @return DateTime|null |
|
17 | - */ |
|
18 | - public function calculate_next( DateTime $after ) { |
|
19 | - return null; |
|
20 | - } |
|
13 | + /** |
|
14 | + * @param DateTime $after |
|
15 | + * |
|
16 | + * @return DateTime|null |
|
17 | + */ |
|
18 | + public function calculate_next( DateTime $after ) { |
|
19 | + return null; |
|
20 | + } |
|
21 | 21 | |
22 | - /** |
|
23 | - * Cancelled actions should never have a next schedule, even if get_next() |
|
24 | - * is called with $after < $this->scheduled_date. |
|
25 | - * |
|
26 | - * @param DateTime $after |
|
27 | - * @return DateTime|null |
|
28 | - */ |
|
29 | - public function get_next( DateTime $after ) { |
|
30 | - return null; |
|
31 | - } |
|
22 | + /** |
|
23 | + * Cancelled actions should never have a next schedule, even if get_next() |
|
24 | + * is called with $after < $this->scheduled_date. |
|
25 | + * |
|
26 | + * @param DateTime $after |
|
27 | + * @return DateTime|null |
|
28 | + */ |
|
29 | + public function get_next( DateTime $after ) { |
|
30 | + return null; |
|
31 | + } |
|
32 | 32 | |
33 | - /** |
|
34 | - * @return bool |
|
35 | - */ |
|
36 | - public function is_recurring() { |
|
37 | - return false; |
|
38 | - } |
|
33 | + /** |
|
34 | + * @return bool |
|
35 | + */ |
|
36 | + public function is_recurring() { |
|
37 | + return false; |
|
38 | + } |
|
39 | 39 | |
40 | - /** |
|
41 | - * Unserialize recurring schedules serialized/stored prior to AS 3.0.0 |
|
42 | - * |
|
43 | - * Prior to Action Scheduler 3.0.0, schedules used different property names to refer |
|
44 | - * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp |
|
45 | - * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 |
|
46 | - * aligned properties and property names for better inheritance. To maintain backward |
|
47 | - * compatibility with schedules serialized and stored prior to 3.0, we need to correctly |
|
48 | - * map the old property names with matching visibility. |
|
49 | - */ |
|
50 | - public function __wakeup() { |
|
51 | - if ( ! is_null( $this->timestamp ) ) { |
|
52 | - $this->scheduled_timestamp = $this->timestamp; |
|
53 | - unset( $this->timestamp ); |
|
54 | - } |
|
55 | - parent::__wakeup(); |
|
56 | - } |
|
40 | + /** |
|
41 | + * Unserialize recurring schedules serialized/stored prior to AS 3.0.0 |
|
42 | + * |
|
43 | + * Prior to Action Scheduler 3.0.0, schedules used different property names to refer |
|
44 | + * to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp |
|
45 | + * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 |
|
46 | + * aligned properties and property names for better inheritance. To maintain backward |
|
47 | + * compatibility with schedules serialized and stored prior to 3.0, we need to correctly |
|
48 | + * map the old property names with matching visibility. |
|
49 | + */ |
|
50 | + public function __wakeup() { |
|
51 | + if ( ! is_null( $this->timestamp ) ) { |
|
52 | + $this->scheduled_timestamp = $this->timestamp; |
|
53 | + unset( $this->timestamp ); |
|
54 | + } |
|
55 | + parent::__wakeup(); |
|
56 | + } |
|
57 | 57 | } |
@@ -5,98 +5,98 @@ |
||
5 | 5 | */ |
6 | 6 | class ActionScheduler_CronSchedule extends ActionScheduler_Abstract_RecurringSchedule implements ActionScheduler_Schedule { |
7 | 7 | |
8 | - /** |
|
9 | - * Deprecated property @see $this->__wakeup() for details. |
|
10 | - **/ |
|
11 | - private $start_timestamp = NULL; |
|
12 | - |
|
13 | - /** |
|
14 | - * Deprecated property @see $this->__wakeup() for details. |
|
15 | - **/ |
|
16 | - private $cron = NULL; |
|
17 | - |
|
18 | - /** |
|
19 | - * Wrapper for parent constructor to accept a cron expression string and map it to a CronExpression for this |
|
20 | - * objects $recurrence property. |
|
21 | - * |
|
22 | - * @param DateTime $start The date & time to run the action at or after. If $start aligns with the CronSchedule passed via $recurrence, it will be used. If it does not align, the first matching date after it will be used. |
|
23 | - * @param CronExpression|string $recurrence The CronExpression used to calculate the schedule's next instance. |
|
24 | - * @param DateTime|null $first (Optional) The date & time the first instance of this interval schedule ran. Default null, meaning this is the first instance. |
|
25 | - */ |
|
26 | - public function __construct( DateTime $start, $recurrence, DateTime $first = null ) { |
|
27 | - if ( ! is_a( $recurrence, 'CronExpression' ) ) { |
|
28 | - $recurrence = CronExpression::factory( $recurrence ); |
|
29 | - } |
|
30 | - |
|
31 | - // For backward compatibility, we need to make sure the date is set to the first matching cron date, not whatever date is passed in. Importantly, by passing true as the 3rd param, if $start matches the cron expression, then it will be used. This was previously handled in the now deprecated next() method. |
|
32 | - $date = $recurrence->getNextRunDate( $start, 0, true ); |
|
33 | - |
|
34 | - // parent::__construct() will set this to $date by default, but that may be different to $start now. |
|
35 | - $first = empty( $first ) ? $start : $first; |
|
36 | - |
|
37 | - parent::__construct( $date, $recurrence, $first ); |
|
38 | - } |
|
39 | - |
|
40 | - /** |
|
41 | - * Calculate when an instance of this schedule would start based on a given |
|
42 | - * date & time using its the CronExpression. |
|
43 | - * |
|
44 | - * @param DateTime $after |
|
45 | - * @return DateTime |
|
46 | - */ |
|
47 | - protected function calculate_next( DateTime $after ) { |
|
48 | - return $this->recurrence->getNextRunDate( $after, 0, false ); |
|
49 | - } |
|
50 | - |
|
51 | - /** |
|
52 | - * @return string |
|
53 | - */ |
|
54 | - public function get_recurrence() { |
|
55 | - return strval( $this->recurrence ); |
|
56 | - } |
|
57 | - |
|
58 | - /** |
|
59 | - * Serialize cron schedules with data required prior to AS 3.0.0 |
|
60 | - * |
|
61 | - * Prior to Action Scheduler 3.0.0, reccuring schedules used different property names to |
|
62 | - * refer to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp |
|
63 | - * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 |
|
64 | - * aligned properties and property names for better inheritance. To guard against the |
|
65 | - * possibility of infinite loops if downgrading to Action Scheduler < 3.0.0, we need to |
|
66 | - * also store the data with the old property names so if it's unserialized in AS < 3.0, |
|
67 | - * the schedule doesn't end up with a null recurrence. |
|
68 | - * |
|
69 | - * @return array |
|
70 | - */ |
|
71 | - public function __sleep() { |
|
72 | - |
|
73 | - $sleep_params = parent::__sleep(); |
|
74 | - |
|
75 | - $this->start_timestamp = $this->scheduled_timestamp; |
|
76 | - $this->cron = $this->recurrence; |
|
77 | - |
|
78 | - return array_merge( $sleep_params, array( |
|
79 | - 'start_timestamp', |
|
80 | - 'cron' |
|
81 | - ) ); |
|
82 | - } |
|
83 | - |
|
84 | - /** |
|
85 | - * Unserialize cron schedules serialized/stored prior to AS 3.0.0 |
|
86 | - * |
|
87 | - * For more background, @see ActionScheduler_Abstract_RecurringSchedule::__wakeup(). |
|
88 | - */ |
|
89 | - public function __wakeup() { |
|
90 | - if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->start_timestamp ) ) { |
|
91 | - $this->scheduled_timestamp = $this->start_timestamp; |
|
92 | - unset( $this->start_timestamp ); |
|
93 | - } |
|
94 | - |
|
95 | - if ( is_null( $this->recurrence ) && ! is_null( $this->cron ) ) { |
|
96 | - $this->recurrence = $this->cron; |
|
97 | - unset( $this->cron ); |
|
98 | - } |
|
99 | - parent::__wakeup(); |
|
100 | - } |
|
8 | + /** |
|
9 | + * Deprecated property @see $this->__wakeup() for details. |
|
10 | + **/ |
|
11 | + private $start_timestamp = NULL; |
|
12 | + |
|
13 | + /** |
|
14 | + * Deprecated property @see $this->__wakeup() for details. |
|
15 | + **/ |
|
16 | + private $cron = NULL; |
|
17 | + |
|
18 | + /** |
|
19 | + * Wrapper for parent constructor to accept a cron expression string and map it to a CronExpression for this |
|
20 | + * objects $recurrence property. |
|
21 | + * |
|
22 | + * @param DateTime $start The date & time to run the action at or after. If $start aligns with the CronSchedule passed via $recurrence, it will be used. If it does not align, the first matching date after it will be used. |
|
23 | + * @param CronExpression|string $recurrence The CronExpression used to calculate the schedule's next instance. |
|
24 | + * @param DateTime|null $first (Optional) The date & time the first instance of this interval schedule ran. Default null, meaning this is the first instance. |
|
25 | + */ |
|
26 | + public function __construct( DateTime $start, $recurrence, DateTime $first = null ) { |
|
27 | + if ( ! is_a( $recurrence, 'CronExpression' ) ) { |
|
28 | + $recurrence = CronExpression::factory( $recurrence ); |
|
29 | + } |
|
30 | + |
|
31 | + // For backward compatibility, we need to make sure the date is set to the first matching cron date, not whatever date is passed in. Importantly, by passing true as the 3rd param, if $start matches the cron expression, then it will be used. This was previously handled in the now deprecated next() method. |
|
32 | + $date = $recurrence->getNextRunDate( $start, 0, true ); |
|
33 | + |
|
34 | + // parent::__construct() will set this to $date by default, but that may be different to $start now. |
|
35 | + $first = empty( $first ) ? $start : $first; |
|
36 | + |
|
37 | + parent::__construct( $date, $recurrence, $first ); |
|
38 | + } |
|
39 | + |
|
40 | + /** |
|
41 | + * Calculate when an instance of this schedule would start based on a given |
|
42 | + * date & time using its the CronExpression. |
|
43 | + * |
|
44 | + * @param DateTime $after |
|
45 | + * @return DateTime |
|
46 | + */ |
|
47 | + protected function calculate_next( DateTime $after ) { |
|
48 | + return $this->recurrence->getNextRunDate( $after, 0, false ); |
|
49 | + } |
|
50 | + |
|
51 | + /** |
|
52 | + * @return string |
|
53 | + */ |
|
54 | + public function get_recurrence() { |
|
55 | + return strval( $this->recurrence ); |
|
56 | + } |
|
57 | + |
|
58 | + /** |
|
59 | + * Serialize cron schedules with data required prior to AS 3.0.0 |
|
60 | + * |
|
61 | + * Prior to Action Scheduler 3.0.0, reccuring schedules used different property names to |
|
62 | + * refer to equivalent data. For example, ActionScheduler_IntervalSchedule::start_timestamp |
|
63 | + * was the same as ActionScheduler_SimpleSchedule::timestamp. Action Scheduler 3.0.0 |
|
64 | + * aligned properties and property names for better inheritance. To guard against the |
|
65 | + * possibility of infinite loops if downgrading to Action Scheduler < 3.0.0, we need to |
|
66 | + * also store the data with the old property names so if it's unserialized in AS < 3.0, |
|
67 | + * the schedule doesn't end up with a null recurrence. |
|
68 | + * |
|
69 | + * @return array |
|
70 | + */ |
|
71 | + public function __sleep() { |
|
72 | + |
|
73 | + $sleep_params = parent::__sleep(); |
|
74 | + |
|
75 | + $this->start_timestamp = $this->scheduled_timestamp; |
|
76 | + $this->cron = $this->recurrence; |
|
77 | + |
|
78 | + return array_merge( $sleep_params, array( |
|
79 | + 'start_timestamp', |
|
80 | + 'cron' |
|
81 | + ) ); |
|
82 | + } |
|
83 | + |
|
84 | + /** |
|
85 | + * Unserialize cron schedules serialized/stored prior to AS 3.0.0 |
|
86 | + * |
|
87 | + * For more background, @see ActionScheduler_Abstract_RecurringSchedule::__wakeup(). |
|
88 | + */ |
|
89 | + public function __wakeup() { |
|
90 | + if ( is_null( $this->scheduled_timestamp ) && ! is_null( $this->start_timestamp ) ) { |
|
91 | + $this->scheduled_timestamp = $this->start_timestamp; |
|
92 | + unset( $this->start_timestamp ); |
|
93 | + } |
|
94 | + |
|
95 | + if ( is_null( $this->recurrence ) && ! is_null( $this->cron ) ) { |
|
96 | + $this->recurrence = $this->cron; |
|
97 | + unset( $this->cron ); |
|
98 | + } |
|
99 | + parent::__wakeup(); |
|
100 | + } |
|
101 | 101 | } |
102 | 102 |