Completed
Push — fix/package-release-script ( 8004a7...315d04 )
by
unknown
06:57
created

packages/sync/src/class-sender.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Sync sender.
4
 *
5
 * @package automattic/jetpack-sync
6
 */
7
8
namespace Automattic\Jetpack\Sync;
9
10
use Automattic\Jetpack\Connection\Manager;
11
use Automattic\Jetpack\Constants;
12
13
/**
14
 * This class grabs pending actions from the queue and sends them
15
 */
16
class Sender {
17
	/**
18
	 * Name of the option that stores the time of the next sync.
19
	 *
20
	 * @access public
21
	 *
22
	 * @var string
23
	 */
24
	const NEXT_SYNC_TIME_OPTION_NAME = 'jetpack_next_sync_time';
25
26
	/**
27
	 * Sync timeout after a WPCOM error.
28
	 *
29
	 * @access public
30
	 *
31
	 * @var int
32
	 */
33
	const WPCOM_ERROR_SYNC_DELAY = 60;
34
35
	/**
36
	 * Sync timeout after a queue has been locked.
37
	 *
38
	 * @access public
39
	 *
40
	 * @var int
41
	 */
42
	const QUEUE_LOCKED_SYNC_DELAY = 10;
43
44
	/**
45
	 * Maximum bytes to checkout without exceeding the memory limit.
46
	 *
47
	 * @access private
48
	 *
49
	 * @var int
50
	 */
51
	private $dequeue_max_bytes;
52
53
	/**
54
	 * Maximum bytes in a single encoded item.
55
	 *
56
	 * @access private
57
	 *
58
	 * @var int
59
	 */
60
	private $upload_max_bytes;
61
62
	/**
63
	 * Maximum number of sync items in a single action.
64
	 *
65
	 * @access private
66
	 *
67
	 * @var int
68
	 */
69
	private $upload_max_rows;
70
71
	/**
72
	 * Maximum time for perfirming a checkout of items from the queue (in seconds).
73
	 *
74
	 * @access private
75
	 *
76
	 * @var int
77
	 */
78
	private $max_dequeue_time;
79
80
	/**
81
	 * How many seconds to wait after sending sync items after exceeding the sync wait threshold (in seconds).
82
	 *
83
	 * @access private
84
	 *
85
	 * @var int
86
	 */
87
	private $sync_wait_time;
88
89
	/**
90
	 * How much maximum time to wait for the checkout to finish (in seconds).
91
	 *
92
	 * @access private
93
	 *
94
	 * @var int
95
	 */
96
	private $sync_wait_threshold;
97
98
	/**
99
	 * How much maximum time to wait for the sync items to be queued for sending (in seconds).
100
	 *
101
	 * @access private
102
	 *
103
	 * @var int
104
	 */
105
	private $enqueue_wait_time;
106
107
	/**
108
	 * Incremental sync queue object.
109
	 *
110
	 * @access private
111
	 *
112
	 * @var Automattic\Jetpack\Sync\Queue
113
	 */
114
	private $sync_queue;
115
116
	/**
117
	 * Full sync queue object.
118
	 *
119
	 * @access private
120
	 *
121
	 * @var Automattic\Jetpack\Sync\Queue
122
	 */
123
	private $full_sync_queue;
124
125
	/**
126
	 * Codec object for encoding and decoding sync items.
127
	 *
128
	 * @access private
129
	 *
130
	 * @var Automattic\Jetpack\Sync\Codec_Interface
131
	 */
132
	private $codec;
133
134
	/**
135
	 * The current user before we change or clear it.
136
	 *
137
	 * @access private
138
	 *
139
	 * @var \WP_User
140
	 */
141
	private $old_user;
142
143
	/**
144
	 * Container for the singleton instance of this class.
145
	 *
146
	 * @access private
147
	 * @static
148
	 *
149
	 * @var Automattic\Jetpack\Sync\Sender
150
	 */
151
	private static $instance;
152
153
	/**
154
	 * Retrieve the singleton instance of this class.
155
	 *
156
	 * @access public
157
	 * @static
158
	 *
159
	 * @return Sender
160
	 */
161
	public static function get_instance() {
162
		if ( null === self::$instance ) {
163
			self::$instance = new self();
164
		}
165
166
		return self::$instance;
167
	}
168
169
	/**
170
	 * Constructor.
171
	 * This is necessary because you can't use "new" when you declare instance properties >:(
172
	 *
173
	 * @access protected
174
	 * @static
175
	 */
176
	protected function __construct() {
177
		$this->set_defaults();
178
		$this->init();
179
	}
180
181
	/**
182
	 * Initialize the sender.
183
	 * Prepares the current user and initializes all sync modules.
184
	 *
185
	 * @access private
186
	 */
187
	private function init() {
188
		add_action( 'jetpack_sync_before_send_queue_sync', array( $this, 'maybe_set_user_from_token' ), 1 );
189
		add_action( 'jetpack_sync_before_send_queue_sync', array( $this, 'maybe_clear_user_from_token' ), 20 );
190
		add_filter( 'jetpack_xmlrpc_methods', array( $this, 'register_jetpack_xmlrpc_methods' ) );
191
		foreach ( Modules::get_modules() as $module ) {
192
			$module->init_before_send();
193
		}
194
	}
195
196
	/**
197
	 * Detect if this is a XMLRPC request with a valid signature.
198
	 * If so, changes the user to the new one.
199
	 *
200
	 * @access public
201
	 */
202
	public function maybe_set_user_from_token() {
203
		$connection    = new Manager();
204
		$verified_user = $connection->verify_xml_rpc_signature();
205
		if ( Constants::is_true( 'XMLRPC_REQUEST' ) &&
206
			! is_wp_error( $verified_user )
207
			&& $verified_user
208
		) {
209
			$old_user       = wp_get_current_user();
210
			$this->old_user = isset( $old_user->ID ) ? $old_user->ID : 0;
211
			wp_set_current_user( $verified_user['user_id'] );
212
		}
213
	}
214
215
	/**
216
	 * If we used to have a previous current user, revert back to it.
217
	 *
218
	 * @access public
219
	 */
220
	public function maybe_clear_user_from_token() {
221
		if ( isset( $this->old_user ) ) {
222
			wp_set_current_user( $this->old_user );
223
		}
224
	}
225
226
	/**
227
	 * Retrieve the next sync time.
228
	 *
229
	 * @access public
230
	 *
231
	 * @param string $queue_name Name of the queue.
232
	 * @return float Timestamp of the next sync.
233
	 */
234
	public function get_next_sync_time( $queue_name ) {
235
		return (float) get_option( self::NEXT_SYNC_TIME_OPTION_NAME . '_' . $queue_name, 0 );
236
	}
237
238
	/**
239
	 * Set the next sync time.
240
	 *
241
	 * @access public
242
	 *
243
	 * @param int    $time       Timestamp of the next sync.
244
	 * @param string $queue_name Name of the queue.
245
	 * @return boolean True if update was successful, false otherwise.
246
	 */
247
	public function set_next_sync_time( $time, $queue_name ) {
248
		return update_option( self::NEXT_SYNC_TIME_OPTION_NAME . '_' . $queue_name, $time, true );
249
	}
250
251
	/**
252
	 * Trigger a full sync.
253
	 *
254
	 * @access public
255
	 *
256
	 * @return boolean|\WP_Error True if this sync sending was successful, error object otherwise.
257
	 */
258
	public function do_full_sync() {
259
		if ( ! Modules::get_module( 'full-sync' ) ) {
260
			return;
261
		}
262
		if ( ! Settings::get_setting( 'full_sync_sender_enabled' ) ) {
263
			return;
264
		}
265
		$this->continue_full_sync_enqueue();
266
		return $this->do_sync_and_set_delays( $this->full_sync_queue );
267
	}
268
269
	/**
270
	 * Enqueue the next sync items for sending.
271
	 * Will not be done if the current request is a WP import one.
272
	 * Will be delayed until the next sync time comes.
273
	 *
274
	 * @access private
275
	 */
276
	private function continue_full_sync_enqueue() {
277
		if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
278
			return false;
279
		}
280
281
		if ( $this->get_next_sync_time( 'full-sync-enqueue' ) > microtime( true ) ) {
282
			return false;
283
		}
284
285
		Modules::get_module( 'full-sync' )->continue_enqueuing();
286
287
		$this->set_next_sync_time( time() + $this->get_enqueue_wait_time(), 'full-sync-enqueue' );
288
	}
289
290
	/**
291
	 * Trigger incremental sync.
292
	 *
293
	 * @access public
294
	 *
295
	 * @return boolean|\WP_Error True if this sync sending was successful, error object otherwise.
296
	 */
297
	public function do_sync() {
298
		return $this->do_sync_and_set_delays( $this->sync_queue );
299
	}
300
301
	/**
302
	 * Trigger sync for a certain sync queue.
303
	 * Responsible for setting next sync time.
304
	 * Will not be delayed if the current request is a WP import one.
305
	 * Will be delayed until the next sync time comes.
306
	 *
307
	 * @access public
308
	 *
309
	 * @param Automattic\Jetpack\Sync\Queue $queue Queue object.
310
	 * @return boolean|\WP_Error True if this sync sending was successful, error object otherwise.
311
	 */
312
	public function do_sync_and_set_delays( $queue ) {
313
		// Don't sync if importing.
314
		if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
315
			return new \WP_Error( 'is_importing' );
316
		}
317
318
		if ( ! Settings::is_sender_enabled( $queue->id ) ) {
319
			return new \WP_Error( 'sender_disabled_for_queue_' . $queue->id );
320
		}
321
322
		// Don't sync if we are throttled.
323
		if ( $this->get_next_sync_time( $queue->id ) > microtime( true ) ) {
324
			return new \WP_Error( 'sync_throttled' );
325
		}
326
327
		$start_time = microtime( true );
328
329
		Settings::set_is_syncing( true );
330
331
		$sync_result = $this->do_sync_for_queue( $queue );
332
333
		Settings::set_is_syncing( false );
334
335
		$exceeded_sync_wait_threshold = ( microtime( true ) - $start_time ) > (float) $this->get_sync_wait_threshold();
336
337
		if ( is_wp_error( $sync_result ) ) {
338
			if ( 'unclosed_buffer' === $sync_result->get_error_code() ) {
339
				$this->set_next_sync_time( time() + self::QUEUE_LOCKED_SYNC_DELAY, $queue->id );
340
			}
341
			if ( 'wpcom_error' === $sync_result->get_error_code() ) {
342
				$this->set_next_sync_time( time() + self::WPCOM_ERROR_SYNC_DELAY, $queue->id );
343
			}
344
		} elseif ( $exceeded_sync_wait_threshold ) {
345
			// If we actually sent data and it took a while, wait before sending again.
346
			$this->set_next_sync_time( time() + $this->get_sync_wait_time(), $queue->id );
347
		}
348
349
		return $sync_result;
350
	}
351
352
	/**
353
	 * Retrieve the next sync items to send.
354
	 *
355
	 * @access public
356
	 *
357
	 * @param (array|Automattic\Jetpack\Sync\Queue_Buffer) $buffer_or_items Queue buffer or array of objects.
358
	 * @param boolean                                      $encode Whether to encode the items.
359
	 * @return array Sync items to send.
360
	 */
361
	public function get_items_to_send( $buffer_or_items, $encode = true ) {
362
		// Track how long we've been processing so we can avoid request timeouts.
363
		$start_time    = microtime( true );
364
		$upload_size   = 0;
365
		$items_to_send = array();
366
		$items         = is_array( $buffer_or_items ) ? $buffer_or_items : $buffer_or_items->get_items();
367
		// Set up current screen to avoid errors rendering content.
368
		require_once ABSPATH . 'wp-admin/includes/class-wp-screen.php';
369
		require_once ABSPATH . 'wp-admin/includes/screen.php';
370
		set_current_screen( 'sync' );
371
		$skipped_items_ids = array();
372
		/**
373
		 * We estimate the total encoded size as we go by encoding each item individually.
374
		 * This is expensive, but the only way to really know :/
375
		 */
376
		foreach ( $items as $key => $item ) {
377
			// Suspending cache addition help prevent overloading in memory cache of large sites.
378
			wp_suspend_cache_addition( true );
379
			/**
380
			 * Modify the data within an action before it is serialized and sent to the server
381
			 * For example, during full sync this expands Post ID's into full Post objects,
382
			 * so that we don't have to serialize the whole object into the queue.
383
			 *
384
			 * @since 4.2.0
385
			 *
386
			 * @param array The action parameters
387
			 * @param int The ID of the user who triggered the action
388
			 */
389
			$item[1] = apply_filters( 'jetpack_sync_before_send_' . $item[0], $item[1], $item[2] );
390
			wp_suspend_cache_addition( false );
391
			if ( false === $item[1] ) {
392
				$skipped_items_ids[] = $key;
393
				continue;
394
			}
395
			$encoded_item = $encode ? $this->codec->encode( $item ) : $item;
396
			$upload_size += strlen( $encoded_item );
397
			if ( $upload_size > $this->upload_max_bytes && count( $items_to_send ) > 0 ) {
398
				break;
399
			}
400
			$items_to_send[ $key ] = $encoded_item;
401
			if ( microtime( true ) - $start_time > $this->max_dequeue_time ) {
402
				break;
403
			}
404
		}
405
406
		return array( $items_to_send, $skipped_items_ids, $items, microtime( true ) - $start_time );
407
	}
408
409
	/**
410
	 * If supported, flush all response data to the client and finish the request.
411
	 * This allows for time consuming tasks to be performed without leaving the connection open.
412
	 *
413
	 * @access private
414
	 */
415
	private function fastcgi_finish_request() {
416
		if ( function_exists( 'fastcgi_finish_request' ) && version_compare( phpversion(), '7.0.16', '>=' ) ) {
417
			fastcgi_finish_request();
418
		}
419
	}
420
421
	/**
422
	 * Perform sync for a certain sync queue.
423
	 *
424
	 * @access public
425
	 *
426
	 * @param Automattic\Jetpack\Sync\Queue $queue Queue object.
427
	 * @return boolean|\WP_Error True if this sync sending was successful, error object otherwise.
428
	 */
429
	public function do_sync_for_queue( $queue ) {
430
		do_action( 'jetpack_sync_before_send_queue_' . $queue->id );
431
		if ( $queue->size() === 0 ) {
432
			return new \WP_Error( 'empty_queue_' . $queue->id );
433
		}
434
		/**
435
		 * Now that we're sure we are about to sync, try to ignore user abort
436
		 * so we can avoid getting into a bad state.
437
		 */
438
		if ( function_exists( 'ignore_user_abort' ) ) {
439
			ignore_user_abort( true );
440
		}
441
442
		/* Don't make the request block till we finish, if possible. */
443
		if ( Constants::is_true( 'REST_REQUEST' ) || Constants::is_true( 'XMLRPC_REQUEST' ) ) {
444
			$this->fastcgi_finish_request();
445
		}
446
447
		$checkout_start_time = microtime( true );
448
449
		$buffer = $queue->checkout_with_memory_limit( $this->dequeue_max_bytes, $this->upload_max_rows );
450
451
		if ( ! $buffer ) {
452
			// Buffer has no items.
453
			return new \WP_Error( 'empty_buffer' );
454
		}
455
456
		if ( is_wp_error( $buffer ) ) {
457
			return $buffer;
458
		}
459
460
		$checkout_duration = microtime( true ) - $checkout_start_time;
461
462
		list( $items_to_send, $skipped_items_ids, $items, $preprocess_duration ) = $this->get_items_to_send( $buffer, true );
463
		if ( ! empty( $items_to_send ) ) {
464
			/**
465
			 * Fires when data is ready to send to the server.
466
			 * Return false or WP_Error to abort the sync (e.g. if there's an error)
467
			 * The items will be automatically re-sent later
468
			 *
469
			 * @since 4.2.0
470
			 *
471
			 * @param array $data The action buffer
472
			 * @param string $codec The codec name used to encode the data
473
			 * @param double $time The current time
474
			 * @param string $queue The queue used to send ('sync' or 'full_sync')
475
			 */
476
			Settings::set_is_sending( true );
477
			$processed_item_ids = apply_filters( 'jetpack_sync_send_data', $items_to_send, $this->codec->name(), microtime( true ), $queue->id, $checkout_duration, $preprocess_duration );
478
			Settings::set_is_sending( false );
479
		} else {
480
			$processed_item_ids = $skipped_items_ids;
481
			$skipped_items_ids  = array();
482
		}
483
484
		if ( ! $processed_item_ids || is_wp_error( $processed_item_ids ) ) {
485
			$checked_in_item_ids = $queue->checkin( $buffer );
486
			if ( is_wp_error( $checked_in_item_ids ) ) {
487
				// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
488
				error_log( 'Error checking in buffer: ' . $checked_in_item_ids->get_error_message() );
489
				$queue->force_checkin();
490
			}
491
			if ( is_wp_error( $processed_item_ids ) ) {
492
				return new \WP_Error( 'wpcom_error', $processed_item_ids->get_error_code() );
493
			}
494
			// Returning a wpcom_error is a sign to the caller that we should wait a while before syncing again.
495
			return new \WP_Error( 'wpcom_error', 'jetpack_sync_send_data_false' );
496
		} else {
497
			// Detect if the last item ID was an error.
498
			$had_wp_error = is_wp_error( end( $processed_item_ids ) );
499
			if ( $had_wp_error ) {
500
				$wp_error = array_pop( $processed_item_ids );
501
			}
502
			// Also checkin any items that were skipped.
503
			if ( count( $skipped_items_ids ) > 0 ) {
504
				$processed_item_ids = array_merge( $processed_item_ids, $skipped_items_ids );
505
			}
506
			$processed_items = array_intersect_key( $items, array_flip( $processed_item_ids ) );
507
			/**
508
			 * Allows us to keep track of all the actions that have been sent.
509
			 * Allows us to calculate the progress of specific actions.
510
			 *
511
			 * @since 4.2.0
512
			 *
513
			 * @param array $processed_actions The actions that we send successfully.
514
			 */
515
			do_action( 'jetpack_sync_processed_actions', $processed_items );
516
			$queue->close( $buffer, $processed_item_ids );
517
			// Returning a WP_Error is a sign to the caller that we should wait a while before syncing again.
518
			if ( $had_wp_error ) {
519
				return new \WP_Error( 'wpcom_error', $wp_error->get_error_code() );
520
			}
521
		}
522
		return true;
523
	}
524
525
	/**
526
	 * Immediately sends a single item without firing or enqueuing it
527
	 *
528
	 * @param string $action_name The action.
529
	 * @param array  $data The data associated with the action.
0 ignored issues
show
Should the type for parameter $data not be array|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
530
	 *
531
	 * @return Items processed. TODO: this doesn't make much sense anymore, it should probably be just a bool.
532
	 */
533
	public function send_action( $action_name, $data = null ) {
534
		if ( ! Settings::is_sender_enabled( 'full_sync' ) ) {
535
			return array();
536
		}
537
538
		// Compose the data to be sent.
539
		$action_to_send = $this->create_action_to_send( $action_name, $data );
540
541
		list( $items_to_send, $skipped_items_ids, $items, $preprocess_duration ) = $this->get_items_to_send( $action_to_send, true ); // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
542
		Settings::set_is_sending( true );
543
		$processed_item_ids = apply_filters( 'jetpack_sync_send_data', $items_to_send, $this->get_codec()->name(), microtime( true ), 'immediate-send', 0, $preprocess_duration );
544
		Settings::set_is_sending( false );
545
546
		/**
547
		 * Allows us to keep track of all the actions that have been sent.
548
		 * Allows us to calculate the progress of specific actions.
549
		 *
550
		 * @param array $processed_actions The actions that we send successfully.
551
		 *
552
		 * @since 4.2.0
553
		 */
554
		do_action( 'jetpack_sync_processed_actions', $action_to_send );
555
556
		return $processed_item_ids;
557
	}
558
559
	/**
560
	 * Create an synthetic action for direct sending to WPCOM during full sync (for example)
561
	 *
562
	 * @access private
563
	 *
564
	 * @param string $action_name The action.
565
	 * @param array  $data The data associated with the action.
566
	 * @return array An array of synthetic sync actions keyed by current microtime(true)
567
	 */
568
	private function create_action_to_send( $action_name, $data ) {
569
		return array(
570
			(string) microtime( true ) => array(
571
				$action_name,
572
				$data,
573
				get_current_user_id(),
574
				microtime( true ),
575
				Settings::is_importing(),
576
			),
577
		);
578
	}
579
580
	/**
581
	 * Returns any object that is able to be synced.
582
	 *
583
	 * @access public
584
	 *
585
	 * @param array $args the synchronized object parameters.
586
	 * @return string Encoded sync object.
587
	 */
588
	public function sync_object( $args ) {
589
		// For example: posts, post, 5.
590
		list( $module_name, $object_type, $id ) = $args;
591
592
		$sync_module = Modules::get_module( $module_name );
593
		$codec       = $this->get_codec();
594
595
		return $codec->encode( $sync_module->get_object_by_id( $object_type, $id ) );
596
	}
597
598
	/**
599
	 * Register additional sync XML-RPC methods available to Jetpack for authenticated users.
600
	 *
601
	 * @access public
602
	 * @since 7.8
603
	 *
604
	 * @param array $jetpack_methods XML-RPC methods available to the Jetpack Server.
605
	 * @return array Filtered XML-RPC methods.
606
	 */
607
	public function register_jetpack_xmlrpc_methods( $jetpack_methods ) {
608
		$jetpack_methods['jetpack.syncObject'] = array( $this, 'sync_object' );
609
		return $jetpack_methods;
610
	}
611
612
	/**
613
	 * Get the incremental sync queue object.
614
	 *
615
	 * @access public
616
	 *
617
	 * @return Automattic\Jetpack\Sync\Queue Queue object.
618
	 */
619
	public function get_sync_queue() {
620
		return $this->sync_queue;
621
	}
622
623
	/**
624
	 * Get the full sync queue object.
625
	 *
626
	 * @access public
627
	 *
628
	 * @return Automattic\Jetpack\Sync\Queue Queue object.
629
	 */
630
	public function get_full_sync_queue() {
631
		return $this->full_sync_queue;
632
	}
633
634
	/**
635
	 * Get the codec object.
636
	 *
637
	 * @access public
638
	 *
639
	 * @return Automattic\Jetpack\Sync\Codec_Interface Codec object.
640
	 */
641
	public function get_codec() {
642
		return $this->codec;
643
	}
644
645
	/**
646
	 * Determine the codec object.
647
	 * Use gzip deflate if supported.
648
	 *
649
	 * @access public
650
	 */
651
	public function set_codec() {
652
		if ( function_exists( 'gzinflate' ) ) {
653
			$this->codec = new JSON_Deflate_Array_Codec();
654
		} else {
655
			$this->codec = new Simple_Codec();
656
		}
657
	}
658
659
	/**
660
	 * Compute and send all the checksums.
661
	 *
662
	 * @access public
663
	 */
664
	public function send_checksum() {
665
		$store = new Replicastore();
666
		do_action( 'jetpack_sync_checksum', $store->checksum_all() );
667
	}
668
669
	/**
670
	 * Reset the incremental sync queue.
671
	 *
672
	 * @access public
673
	 */
674
	public function reset_sync_queue() {
675
		$this->sync_queue->reset();
676
	}
677
678
	/**
679
	 * Reset the full sync queue.
680
	 *
681
	 * @access public
682
	 */
683
	public function reset_full_sync_queue() {
684
		$this->full_sync_queue->reset();
685
	}
686
687
	/**
688
	 * Set the maximum bytes to checkout without exceeding the memory limit.
689
	 *
690
	 * @access public
691
	 *
692
	 * @param int $size Maximum bytes to checkout.
693
	 */
694
	public function set_dequeue_max_bytes( $size ) {
695
		$this->dequeue_max_bytes = $size;
696
	}
697
698
	/**
699
	 * Set the maximum bytes in a single encoded item.
700
	 *
701
	 * @access public
702
	 *
703
	 * @param int $max_bytes Maximum bytes in a single encoded item.
704
	 */
705
	public function set_upload_max_bytes( $max_bytes ) {
706
		$this->upload_max_bytes = $max_bytes;
707
	}
708
709
	/**
710
	 * Set the maximum number of sync items in a single action.
711
	 *
712
	 * @access public
713
	 *
714
	 * @param int $max_rows Maximum number of sync items.
715
	 */
716
	public function set_upload_max_rows( $max_rows ) {
717
		$this->upload_max_rows = $max_rows;
718
	}
719
720
	/**
721
	 * Set the sync wait time (in seconds).
722
	 *
723
	 * @access public
724
	 *
725
	 * @param int $seconds Sync wait time.
726
	 */
727
	public function set_sync_wait_time( $seconds ) {
728
		$this->sync_wait_time = $seconds;
729
	}
730
731
	/**
732
	 * Get current sync wait time (in seconds).
733
	 *
734
	 * @access public
735
	 *
736
	 * @return int Sync wait time.
737
	 */
738
	public function get_sync_wait_time() {
739
		return $this->sync_wait_time;
740
	}
741
742
	/**
743
	 * Set the enqueue wait time (in seconds).
744
	 *
745
	 * @access public
746
	 *
747
	 * @param int $seconds Enqueue wait time.
748
	 */
749
	public function set_enqueue_wait_time( $seconds ) {
750
		$this->enqueue_wait_time = $seconds;
751
	}
752
753
	/**
754
	 * Get current enqueue wait time (in seconds).
755
	 *
756
	 * @access public
757
	 *
758
	 * @return int Enqueue wait time.
759
	 */
760
	public function get_enqueue_wait_time() {
761
		return $this->enqueue_wait_time;
762
	}
763
764
	/**
765
	 * Set the sync wait threshold (in seconds).
766
	 *
767
	 * @access public
768
	 *
769
	 * @param int $seconds Sync wait threshold.
770
	 */
771
	public function set_sync_wait_threshold( $seconds ) {
772
		$this->sync_wait_threshold = $seconds;
773
	}
774
775
	/**
776
	 * Get current sync wait threshold (in seconds).
777
	 *
778
	 * @access public
779
	 *
780
	 * @return int Sync wait threshold.
781
	 */
782
	public function get_sync_wait_threshold() {
783
		return $this->sync_wait_threshold;
784
	}
785
786
	/**
787
	 * Set the maximum time for perfirming a checkout of items from the queue (in seconds).
788
	 *
789
	 * @access public
790
	 *
791
	 * @param int $seconds Maximum dequeue time.
792
	 */
793
	public function set_max_dequeue_time( $seconds ) {
794
		$this->max_dequeue_time = $seconds;
795
	}
796
797
	/**
798
	 * Initialize the sync queues, codec and set the default settings.
799
	 *
800
	 * @access public
801
	 */
802
	public function set_defaults() {
803
		$this->sync_queue      = new Queue( 'sync' );
804
		$this->full_sync_queue = new Queue( 'full_sync' );
805
		$this->set_codec();
806
807
		// Saved settings.
808
		Settings::set_importing( null );
809
		$settings = Settings::get_settings();
810
		$this->set_dequeue_max_bytes( $settings['dequeue_max_bytes'] );
811
		$this->set_upload_max_bytes( $settings['upload_max_bytes'] );
812
		$this->set_upload_max_rows( $settings['upload_max_rows'] );
813
		$this->set_sync_wait_time( $settings['sync_wait_time'] );
814
		$this->set_enqueue_wait_time( $settings['enqueue_wait_time'] );
815
		$this->set_sync_wait_threshold( $settings['sync_wait_threshold'] );
816
		$this->set_max_dequeue_time( Defaults::get_max_sync_execution_time() );
817
	}
818
819
	/**
820
	 * Reset sync queues, modules and settings.
821
	 *
822
	 * @access public
823
	 */
824
	public function reset_data() {
825
		$this->reset_sync_queue();
826
		$this->reset_full_sync_queue();
827
828
		foreach ( Modules::get_modules() as $module ) {
829
			$module->reset_data();
830
		}
831
832
		foreach ( array( 'sync', 'full_sync', 'full-sync-enqueue' ) as $queue_name ) {
833
			delete_option( self::NEXT_SYNC_TIME_OPTION_NAME . '_' . $queue_name );
834
		}
835
836
		Settings::reset_data();
837
	}
838
839
	/**
840
	 * Perform cleanup at the event of plugin uninstallation.
841
	 *
842
	 * @access public
843
	 */
844
	public function uninstall() {
845
		// Lets delete all the other fun stuff like transient and option and the sync queue.
846
		$this->reset_data();
847
848
		// Delete the full sync status.
849
		delete_option( 'jetpack_full_sync_status' );
850
851
		// Clear the sync cron.
852
		wp_clear_scheduled_hook( 'jetpack_sync_cron' );
853
		wp_clear_scheduled_hook( 'jetpack_sync_full_cron' );
854
	}
855
}
856