PluginProbe ʕ •ᴥ•ʔ
WooCommerce Square / 2.2.5
WooCommerce Square v2.2.5
5.5.0 5.4.3 5.4.2 5.4.1 5.4.0 trunk 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.7.0 2.8.0 2.9.0 2.9.1 3.0.0 3.0.1 3.0.2 3.0.3 3.1.0 3.2.0 3.3.0 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.7.0 3.7.1 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 4.0.0 4.1.0 4.2.0 4.2.1 4.2.2 4.2.3 4.3.0 4.3.1 4.3.2 4.4.0 4.4.1 4.4.2 4.5.0 4.5.1 4.5.2 4.6.0 4.6.1 4.6.2 4.6.3 4.6.4 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.1 4.8.2 4.8.3 4.8.4 4.8.5 4.8.6 4.8.7 4.8.8 4.9.0 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 4.9.6 4.9.7 4.9.8 4.9.9 5.0.0 5.0.1 5.1.0 5.1.1 5.1.2 5.2.0 5.3.0 5.3.1 5.3.2 5.3.3
woocommerce-square / includes / Handlers / Background_Job.php
woocommerce-square / includes / Handlers Last commit date
Product 6 years ago Background_Job.php 6 years ago Category.php 6 years ago Connection.php 6 years ago Email.php 6 years ago Order.php 6 years ago Product.php 5 years ago Products.php 5 years ago Sync.php 5 years ago
Background_Job.php
375 lines
1 <?php
2 /**
3 * WooCommerce Square
4 *
5 * This source file is subject to the GNU General Public License v3.0
6 * that is bundled with this package in the file license.txt.
7 * It is also available through the world-wide-web at this URL:
8 * http://www.gnu.org/licenses/gpl-3.0.html
9 * If you did not receive a copy of the license and are unable to
10 * obtain it through the world-wide-web, please send an email
11 * to license@woocommerce.com so we can send you a copy immediately.
12 *
13 * DISCLAIMER
14 *
15 * Do not edit or add to this file if you wish to upgrade WooCommerce Square to newer
16 * versions in the future. If you wish to customize WooCommerce Square for your
17 * needs please refer to https://docs.woocommerce.com/document/woocommerce-square/
18 *
19 * @author WooCommerce
20 * @copyright Copyright: (c) 2019, Automattic, Inc.
21 * @license http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0
22 */
23
24 namespace WooCommerce\Square\Handlers;
25
26 use SkyVerge\WooCommerce\PluginFramework\v5_4_0 as Framework;
27 use WooCommerce\Square\Sync\Interval_Polling;
28 use WooCommerce\Square\Sync\Job;
29 use WooCommerce\Square\Sync\Manual_Synchronization;
30 use WooCommerce\Square\Sync\Product_Import;
31 use WooCommerce\Square\Sync\Records;
32
33 defined( 'ABSPATH' ) || exit;
34
35 /**
36 * Product and Inventory Synchronization handler class.
37 *
38 * This class handles manual and interval synchronization jobs.
39 * It is a wrapper for the framework background handler and as such it only handles loopback business to keep the queue processing.
40 * See the individual job implementations:
41 *
42 * @see Manual_Synchronization manual jobs re-process ALL synced products
43 * @see Interval_Polling interval (polling) jobs perform API requests for ONLY the latest changes and update the associated products
44 *
45 * @since 2.0.0
46 */
47 class Background_Job extends Framework\SV_WP_Background_Job_Handler {
48
49
50 /**
51 * Initializes the background sync handler.
52 *
53 * @since 2.0.0
54 */
55 public function __construct() {
56
57 $this->prefix = 'wc_square';
58 $this->action = 'background_sync';
59 $this->data_key = 'product_ids';
60
61 parent::__construct();
62
63 $this->maybe_increase_time_limit();
64
65 add_action( "{$this->identifier}_job_complete", array( $this, 'job_complete' ) );
66 add_action( "{$this->identifier}_job_failed", array( $this, 'job_failed' ) );
67 add_filter( "{$this->identifier}_default_time_limit", array( $this, 'set_default_time_limit' ) );
68
69 // ensures the queue lock time never expires before our timeout does
70 add_filter(
71 "{$this->identifier}_queue_lock_time",
72 function( $lock_time ) {
73
74 return $this->set_default_time_limit( $lock_time ) + 10;
75
76 }
77 );
78 }
79
80
81 /**
82 * Creates a new job.
83 *
84 * @since 2.0.0
85 *
86 * @param array $attrs array of job attributes
87 * @return \stdClass|null
88 */
89 public function create_job( $attrs ) {
90
91 $sor = wc_square()->get_settings_handler()->get_system_of_record();
92
93 return parent::create_job(
94 wp_parse_args(
95 $attrs,
96 array(
97 'action' => '', // job action
98 'catalog_processed' => false, // whether the Square catalog has been processed
99 'cursor' => '', // job advancement position
100 'manual' => false, // whether it's a sync job triggered manually
101 'percentage' => 0, // percentage completed
102 'product_ids' => array(), // products to process
103 'processed_product_ids' => array(), // newly imported products processed
104 'updated_product_ids' => array(), // updated products processed
105 'skipped_products' => array(), // remote product IDs that were skipped
106 'system_of_record' => $sor, // system of record used
107 )
108 )
109 );
110 }
111
112
113 /**
114 * Handles job execution.
115 *
116 * Overridden to support our multi-step job structure. There are steps that can take a long time to process, so this
117 * ensures only one step is performed for each background request.
118 *
119 * @since 2.0.0
120 */
121 protected function handle() {
122
123 $this->lock_process();
124
125 // Get next job in the queue
126 $job = $this->get_job();
127
128 // handle PHP errors from here on out
129 register_shutdown_function( array( $this, 'handle_shutdown' ), $job );
130
131 // Start processing
132 $this->process_job( $job );
133
134 $this->unlock_process();
135
136 // Start next job or complete process
137 if ( ! $this->is_queue_empty() ) {
138 $this->dispatch();
139 } else {
140 $this->complete();
141 }
142
143 wp_die();
144 }
145
146
147 /**
148 * Processes a background job.
149 *
150 * @since 2.0.0
151 *
152 * @param object|\stdClass $job
153 * @param null $items_per_batch
154 * @return false|object|\stdClass
155 */
156 public function process_job( $job, $items_per_batch = null ) {
157
158 // indicate that the job has started processing
159 if ( 'processing' !== $job->status ) {
160
161 $job->status = 'processing';
162 $job->started_processing_at = current_time( 'mysql' );
163 $job = $this->update_job( $job );
164 }
165
166 if ( 'poll' === $job->action ) {
167
168 $job = new Interval_Polling( $job );
169
170 } elseif ( 'product_import' === $job->action ) {
171
172 $job = new Product_Import( $job );
173
174 } elseif ( ! empty( $job->manual ) ) {
175
176 $job = new Manual_Synchronization( $job );
177 }
178
179 if ( $job instanceof Job ) {
180 $current_user_id = get_current_user_id();
181 $job = $job->run();
182 wp_set_current_user( $current_user_id );
183 }
184
185 return $job;
186 }
187
188
189 /**
190 * Handles actions after a sync job is complete.
191 *
192 * @since 2.0.0
193 *
194 * @param $job
195 */
196 public function job_complete( $job ) {
197
198 wc_square()->get_sync_handler()->set_last_synced_at();
199
200 wc_square()->get_sync_handler()->record_sync( $job->processed_product_ids, $job );
201
202 wc_square()->get_email_handler()->get_sync_completed_email()->trigger( $job );
203 }
204
205
206 /**
207 * Handles actions after a sync job has failed.
208 *
209 * @since 2.0.0
210 *
211 * @param $job
212 */
213 public function job_failed( $job ) {
214
215 Records::set_record(
216 array(
217 'type' => 'alert',
218 'message' => 'Sync failed. Please try again',
219 )
220 );
221
222 wc_square()->get_email_handler()->get_sync_completed_email()->trigger( $job );
223 }
224
225
226 /**
227 * No-op: implements framework parent abstract method.
228 *
229 * @since 2.0.0
230 *
231 * @param null $item
232 * @param \stdClass $job
233 */
234 protected function process_item( $item, $job ) {}
235
236
237 /**
238 * Clear all background jobs of any status.
239 *
240 * @since 2.0.0
241 */
242 public function clear_all_jobs() {
243
244 $jobs = $this->get_jobs();
245
246 if ( is_array( $jobs ) ) {
247 $this->delete_jobs( $jobs );
248 }
249
250 delete_transient( 'wc_square_background_sync_process_lock' );
251 }
252
253
254 /**
255 * Deletes a set of background jobs.
256 *
257 * @since 2.0.0
258 *
259 * @param object[] $jobs jobs to delete
260 */
261 public function delete_jobs( $jobs ) {
262
263 foreach ( $jobs as $job ) {
264 $this->delete_job( $job );
265 }
266 }
267
268
269 /**
270 * Attempts to increase the script execution time limit to a filtered value -- defaults to 5 minutes.
271 *
272 * @since 2.0.0
273 */
274 protected function maybe_increase_time_limit() {
275
276 /**
277 * Filters the desired time limit for Square requests. Defaults to 5 minutes.
278 *
279 * @since 2.0.0
280 *
281 * @param int time limit
282 */
283 $desired_time_limit = (int) apply_filters( 'wc_square_time_limit', 300 );
284 $server_time_limit = (int) ini_get( 'max_execution_time' );
285
286 if ( $desired_time_limit > $server_time_limit ) {
287
288 \ActionScheduler_Compatibility::raise_time_limit( $desired_time_limit );
289 }
290 }
291
292
293 /**
294 * Sets the default time limit to the server time limit minus a buffer,
295 * to allow us to clean up a request that has exceeded the time limit.
296 *
297 * @internal
298 *
299 * @since 2.0.0
300 *
301 * @param int $default_time_limit time limit (in seconds)
302 * @return int
303 */
304 public function set_default_time_limit( $default_time_limit ) {
305
306 $server_time_limit = (int) ini_get( 'max_execution_time' );
307 $time_limit_buffer = 10;
308
309 if ( isset( $server_time_limit ) && $time_limit_buffer < $server_time_limit ) {
310
311 $default_time_limit = $server_time_limit - $time_limit_buffer;
312 }
313
314 return $default_time_limit;
315 }
316
317
318 /**
319 * Returns whether a sensible time has been exceeded for this request.
320 *
321 * Makes the internal time_exceeded() function publicly accessible.
322 *
323 * @since 2.0.0
324 *
325 * @return bool
326 */
327 public function is_time_exceeded() {
328
329 return $this->time_exceeded();
330 }
331
332
333 /**
334 * Adds some helpful debug tools.
335 *
336 * @since 2.0.0
337 *
338 * @param array $tools existing debug tools
339 * @return array
340 */
341 public function add_debug_tool( $tools ) {
342
343 $tools = parent::add_debug_tool( $tools );
344
345 // this key is not unique to the plugin to avoid duplicate tools
346 $tools['wc_square_clear_background_jobs'] = array(
347 'name' => __( 'Clear Square Sync', 'woocommerce-square' ),
348 'button' => __( 'Clear', 'woocommerce-square' ),
349 'desc' => __( 'This tool will clear any ongoing Square product syncs.', 'woocommerce-square' ),
350 'callback' => array( $this, 'run_clear_background_jobs' ),
351 );
352
353 return $tools;
354 }
355
356
357 /**
358 * Runs the "Clear Square Sync" tool.
359 *
360 * Provides a way for merchants to clear any ongoing or stuck product syncs.
361 *
362 * @since 2.0.0
363 */
364 public function run_clear_background_jobs() {
365
366 $this->clear_all_jobs();
367
368 $this->debug_message = esc_html__( 'Success! You can now sync your products.', 'woocommerce-square' );
369
370 return true;
371 }
372
373
374 }
375