Completed
Push — add/sync-action ( ba7a9e...af7401 )
by
unknown
57:04 queued 47:46
created

Jetpack_Sync_Client::maybe_sync_callables()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 5
eloc 12
c 3
b 1
f 0
nc 5
nop 0
dl 0
loc 21
rs 8.7624
1
<?php
2
require_once dirname( __FILE__ ) . '/class.jetpack-sync-deflate-codec.php';
3
require_once dirname( __FILE__ ) . '/class.jetpack-sync-queue.php';
4
require_once dirname( __FILE__ ) . '/class.jetpack-sync-functions.php';
5
require_once dirname( __FILE__ ) . '/class.jetpack-sync-full.php';
6
require_once dirname( __FILE__ ) . '/class.jetpack-sync-defaults.php';
7
8
class Jetpack_Sync_Client {
9
10
	const CONSTANTS_CHECKSUM_OPTION_NAME = 'jetpack_constants_sync_checksum';
11
	const CALLABLES_CHECKSUM_OPTION_NAME = 'jetpack_callables_sync_checksum';
12
	const SYNC_THROTTLE_OPTION_NAME = 'jetpack_sync_min_wait';
13
	const LAST_SYNC_TIME_OPTION_NAME = 'jetpack_last_sync_time';
14
	const CALLABLES_AWAIT_TRANSIENT_NAME = 'jetpack_sync_callables_await';
15
16
	private $checkout_memory_size;
17
	private $upload_max_bytes;
18
	private $upload_max_rows;
19
	private $sync_queue;
20
	private $full_sync_client;
21
	private $codec;
22
	private $options_whitelist;
23
	private $constants_whitelist;
24
	private $meta_types = array( 'post', 'comment' );
25
	private $callable_whitelist;
26
	private $network_options_whitelist;
27
	private $taxonomy_whitelist;
28
	private $is_multisite;
29
30
	// singleton functions
31
	private static $instance;
32
33
	public static function getInstance() {
34
		if ( null === self::$instance ) {
35
			self::$instance = new self();
36
		}
37
38
		return self::$instance;
39
	}
40
41
	// this is necessary because you can't use "new" when you declare instance properties >:(
42
	protected function __construct() {
43
		$this->set_defaults();
44
		$this->init();
45
	}
46
47
	private function init() {
48
49
		$handler = array( $this, 'action_handler' );
50
51
		/**
52
		 * Most of the following hooks are sent to the same $handler
53
		 * for immediate serialization and queuing be sent to the server.
54
		 * The only exceptions are actions which need additional processing.
55
		 */
56
57
		// constants
58
		add_action( 'jetpack_sync_current_constants', $handler, 10 );
59
60
		// callables
61
		add_action( 'jetpack_sync_current_callable', $handler, 10, 2 );
62
63
		// posts
64
		add_action( 'wp_insert_post', $handler, 10, 3 );
65
		add_action( 'deleted_post', $handler, 10 );
66
		add_filter( 'jetpack_sync_before_send_wp_insert_post', array( $this, 'expand_wp_insert_post' ) );
67
68
		// attachments
69
70
		add_action( 'edit_attachment', array( $this, 'send_attachment_info' ) );
71
		// Once we don't have to support 4.3 we can start using add_action( 'attachment_updated', $handler, 10, 3 ); instead
72
		add_action( 'add_attachment', array( $this, 'send_attachment_info' ) );
73
		add_action( 'jetpack_sync_save_add_attachment', $handler, 10, 2 );
74
75
		// comments
76
		add_action( 'wp_insert_comment', $handler, 10, 2 );
77
		add_action( 'deleted_comment', $handler, 10 );
78
		add_action( 'trashed_comment', $handler, 10 );
79
		add_action( 'spammed_comment', $handler, 10 );
80
81
		// even though it's messy, we implement these hooks because 
82
		// the edit_comment hook doesn't include the data
83
		// so this saves us a DB read for every comment event
84
		foreach ( array( '', 'trackback', 'pingback' ) as $comment_type ) {
85
			foreach ( array( 'unapproved', 'approved' ) as $comment_status ) {
86
				add_action( "comment_{$comment_status}_{$comment_type}", $handler, 10, 2 );
87
			}
88
		}
89
90
		// options
91
		add_action( 'added_option', $handler, 10, 2 );
92
		add_action( 'updated_option', $handler, 10, 3 );
93
		add_action( 'deleted_option', $handler, 10, 1 );
94
95
		// Sync Core Icon: Detect changes in Core's Site Icon and make it syncable.
96
		add_action( 'add_option_site_icon', array( $this, 'jetpack_sync_core_icon' ) );
97
		add_action( 'update_option_site_icon', array( $this, 'jetpack_sync_core_icon' ) );
98
		add_action( 'delete_option_site_icon', array( $this, 'jetpack_sync_core_icon' ) );
99
100
		// wordpress version
101
		add_action( 'upgrader_process_complete', array( $this, 'send_wp_version' ), 10, 2 );
102
		add_action( 'jetpack_sync_wp_version', $handler );
103
104
		// themes
105
		add_action( 'switch_theme', array( $this, 'send_theme_info' ) );
106
		add_action( 'jetpack_sync_current_theme_support', $handler, 10 ); // custom hook, see meta-hooks below
107
108
		// post-meta, and in the future - other meta?
109
		foreach ( $this->meta_types as $meta_type ) {
110
			add_action( "added_{$meta_type}_meta", $handler, 10, 4 );
111
			add_action( "updated_{$meta_type}_meta", $handler, 10, 4 );
112
			add_action( "deleted_{$meta_type}_meta", $handler, 10, 4 );
113
		}
114
115
		// terms
116
		add_action( 'created_term', array( $this, 'save_term_handler' ), 10, 3 );
117
		add_action( 'edited_term', array( $this, 'save_term_handler' ), 10, 3 );
118
		add_action( 'jetpack_sync_save_term', $handler, 10, 4 );
119
		add_action( 'delete_term', $handler, 10, 4 );
120
		add_action( 'set_object_terms', $handler, 10, 6 );
121
		add_action( 'deleted_term_relationships', $handler, 10, 2 );
122
123
		// users
124
		add_action( 'user_register', array( $this, 'save_user_handler' ) );
125
		add_action( 'profile_update', array( $this, 'save_user_handler' ), 10, 2 );
126
		add_action( 'jetpack_sync_save_user', $handler, 10, 2 );
127
		add_action( 'deleted_user', $handler, 10, 2 );
128
129
		// user roles
130
		add_action( 'add_user_role', array( $this, 'save_user_role_handler' ), 10, 2 );
131
		add_action( 'set_user_role', array( $this, 'save_user_role_handler' ), 10, 3 );
132
		add_action( 'remove_user_role', array( $this, 'save_user_role_handler' ), 10, 2 );
133
134
135
		// user capabilities
136
		add_action( 'added_user_meta', array( $this, 'save_user_cap_handler' ), 10, 4 );
137
		add_action( 'updated_user_meta', array( $this, 'save_user_cap_handler' ), 10, 4 );
138
		add_action( 'deleted_user_meta', array( $this, 'save_user_cap_handler' ), 10, 4 );
139
140
		// themes
141
		add_action( 'set_site_transient_update_plugins', $handler, 10, 1 );
142
		add_action( 'set_site_transient_update_themes', $handler, 10, 1 );
143
		add_action( 'set_site_transient_update_core', $handler, 10, 1 );
144
145
		// multi site network options
146
		if ( $this->is_multisite ) {
147
			add_action( 'add_site_option', $handler, 10, 2 );
148
			add_action( 'update_site_option', $handler, 10, 3 );
149
			add_action( 'delete_site_option', $handler, 10, 1 );
150
		}
151
152
		// synthetic actions for full sync
153
		add_action( 'jetpack_full_sync_start', $handler );
154
		add_action( 'jetpack_full_sync_end', $handler );
155
		add_action( 'jetpack_full_sync_options', $handler );
156
		add_action( 'jetpack_full_sync_posts', $handler ); // also sends post meta
157
		add_action( 'jetpack_full_sync_comments', $handler ); // also send comments meta
158
		add_action( 'jetpack_full_sync_users', $handler );
159
		add_action( 'jetpack_full_sync_terms', $handler, 10, 2 );
160
		if ( is_multisite() ) {
161
			add_action( 'jetpack_full_sync_network_options', $handler );
162
		}
163
164
165
		// TODO: Callables, Constanst, Network Options, Users, Terms
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
166
167
		/**
168
		 * Sync all pending actions with server
169
		 */
170
		add_action( 'jetpack_sync_actions', array( $this, 'do_sync' ) );
171
	}
172
173
	// TODO: Refactor to use one set whitelist function, with one is_whitelisted.
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
174
	function set_options_whitelist( $options ) {
175
		$this->options_whitelist = $options;
176
	}
177
178
	function set_constants_whitelist( $constants ) {
179
		$this->constants_whitelist = $constants;
180
	}
181
182
	function get_callable_whitelist() {
183
		return $this->callable_whitelist;
184
	}
185
186
	function set_callable_whitelist( $callables ) {
187
		$this->callable_whitelist = $callables;
188
	}
189
190
	function set_network_options_whitelist( $options ) {
191
		$this->network_options_whitelist = $options;
192
	}
193
194
	function set_send_buffer_memory_size( $size ) {
195
		$this->checkout_memory_size = $size;
196
	}
197
198
	// in bytes
199
	function set_upload_max_bytes( $max_bytes ) {
200
		$this->upload_max_bytes = $max_bytes;
201
	}
202
203
	// in rows
204
	function set_upload_max_rows( $max_rows ) {
205
		$this->upload_max_rows = $max_rows;
206
	}
207
208
	// in seconds
209
	function set_min_sync_wait_time( $seconds ) {
210
		update_option( self::SYNC_THROTTLE_OPTION_NAME, $seconds, true );
211
	}
212
213
	function get_min_sync_wait_time() {
214
		return get_option( self::SYNC_THROTTLE_OPTION_NAME );
215
	}
216
217
	private function get_last_sync_time() {
218
		return (double) get_option( self::LAST_SYNC_TIME_OPTION_NAME );
219
	}
220
221
	private function set_last_sync_time() {
222
		return update_option( self::LAST_SYNC_TIME_OPTION_NAME, microtime(true), true );
223
	}
224
225
	function set_taxonomy_whitelist( $taxonomies ) {
226
		$this->taxonomy_whitelist = $taxonomies;
227
	}
228
229
	function is_whitelisted_option( $option ) {
230
		return in_array( $option, $this->options_whitelist );
231
	}
232
233
	function is_whitelisted_network_option( $option ) {
234
		return $this->is_multisite && in_array( $option, $this->network_options_whitelist );
235
	}
236
237
	function set_codec( iJetpack_Sync_Codec $codec ) {
238
		$this->codec = $codec;
239
	}
240
241
	function set_full_sync_client( $full_sync_client ) {
242
		if ( $this->full_sync_client ) {
243
			remove_action( 'jetpack_sync_full', array( $this->full_sync_client, 'start' ) );
244
		}
245
246
		$this->full_sync_client = $full_sync_client;
247
248
		/**
249
		 * Sync all objects in the database with the server
250
		 */
251
		add_action( 'jetpack_sync_full', array( $this->full_sync_client, 'start' ) );
252
	}
253
254
	function get_full_sync_client() {
255
		return $this->full_sync_client;
256
	}
257
258
	function action_handler() {
259
		// TODO: it's really silly to have this function here - it should be
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
260
		// wherever we initialize the action listeners or we're just wasting cycles
261
		if ( Jetpack::is_development_mode() || Jetpack::is_staging_site() ) {
262
			return false;
263
		}
264
265
		$current_filter = current_filter();
266
		$args           = func_get_args();
267
268
		if ( $current_filter === 'wp_insert_post' && $args[1]->post_type === 'revision' ) {
269
			return;
270
		}
271
272
		if ( in_array( $current_filter, array( 'deleted_option', 'added_option', 'updated_option' ) )
273
		     &&
274
		     ! $this->is_whitelisted_option( $args[0] )
275
		) {
276
			return;
277
		}
278
279
		if ( in_array( $current_filter, array( 'delete_site_option', 'add_site_option', 'update_site_option' ) )
280
		     &&
281
		     ! $this->is_whitelisted_network_option( $args[0] )
282
		) {
283
			return;
284
		}
285
286
		// don't sync private meta
287
		if ( preg_match( '/^(added|updated|deleted)_.*_meta$/', $current_filter )
288
		     && $args[2][0] === '_'
289
		     && ! in_array( $args[2], Jetpack_Sync_Defaults::$default_whitelist_meta_keys )
0 ignored issues
show
Bug introduced by
The property default_whitelist_meta_keys cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
290
		) {
291
			return;
292
		}
293
294
		$this->sync_queue->add( array(
295
			$current_filter,
296
			$args,
297
			get_current_user_id(),
298
			microtime( true )
299
		) );
300
	}
301
302
	function send_theme_info() {
303
		global $_wp_theme_features;
304
305
		$theme_support = array();
306
307
		foreach ( Jetpack_Sync_Defaults::$default_theme_support_whitelist as $theme_feature ) {
0 ignored issues
show
Bug introduced by
The property default_theme_support_whitelist cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
308
			$has_support = current_theme_supports( $theme_feature );
309
			if ( $has_support ) {
310
				$theme_support[ $theme_feature ] = $_wp_theme_features[ $theme_feature ];
311
			}
312
313
		}
314
		do_action( 'jetpack_sync_current_theme_support', $theme_support );
315
	}
316
317
	function send_wp_version( $update, $meta_data ) {
318
		if ( 'update' === $meta_data['action'] && 'core' === $meta_data['type'] ) {
319
			global $wp_version;
320
			do_action( 'jetpack_sync_wp_version', $wp_version );
321
		}
322
	}
323
324
	function save_term_handler( $term_id, $tt_id, $taxonomy ) {
325
		if ( class_exists( 'WP_Term' ) ) {
326
			$term_object = WP_Term::get_instance( $term_id, $taxonomy );
327
		} else {
328
			$term_object = get_term_by( 'id', $term_id, $taxonomy );
329
		}
330
331
		do_action( 'jetpack_sync_save_term', $term_object );
332
	}
333
334
	function send_attachment_info( $attachment_id ) {
335
		$attachment = get_post( $attachment_id );
336
		do_action( 'jetpack_sync_save_add_attachment', $attachment_id, $attachment );
337
	}
338
339
	function save_user_handler( $user_id, $old_user_data = null ) {
340
		$user = $this->sanitize_user( get_user_by( 'id', $user_id ) );
341
342
		// Older versions of WP don't pass the old_user_data in ->data
343
		if ( isset( $old_user_data->data ) ) {
344
			$old_user = $old_user_data->data;
345
		} else {
346
			$old_user = $old_user_data;
347
		}
348
349
		if ( $old_user !== null ) {
350
			unset( $old_user->user_pass );
351
			if ( serialize( $old_user ) === serialize( $user->data ) ) {
352
				return;
353
			}
354
		}
355
		do_action( 'jetpack_sync_save_user', $user );
356
	}
357
358
	function save_user_role_handler( $user_id, $role, $old_roles = null ) {
0 ignored issues
show
Unused Code introduced by
The parameter $role is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $old_roles is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
359
		$user = $this->sanitize_user( get_user_by( 'id', $user_id ) );
360
		do_action( 'jetpack_sync_save_user', $user );
361
	}
362
363
	function save_user_cap_handler( $meta_id, $user_id, $meta_key, $capabilities ) {
0 ignored issues
show
Unused Code introduced by
The parameter $capabilities is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
364
		$user = $this->sanitize_user( get_user_by( 'id', $user_id ) );
365
		if ( $meta_key === $user->cap_key ) {
366
			do_action( 'jetpack_sync_save_user', $user );
367
		}
368
	}
369
370
	public function sanitize_user( $user ) {
371
		unset( $user->data->user_pass );
372
373
		return $user;
374
	}
375
376
377
	function do_sync() {
378
		// don't sync if importing
379
		if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
380
			$this->schedule_sync( "+1 minute" );
381
382
			return false;
383
		}
384
385
		// don't sync if we are throttled
386
		$sync_wait = $this->get_min_sync_wait_time();
387
		$last_sync = $this->get_last_sync_time();
388
389
		if ( $last_sync && $sync_wait && $last_sync + $sync_wait > microtime( true ) ) {
390
			return false;
391
		}
392
393
		$this->set_last_sync_time();
394
		$this->maybe_sync_constants();
395
		$this->maybe_sync_callables();
396
397
		if ( $this->sync_queue->size() === 0 ) {
398
			return false;
399
		}
400
401
		$buffer = $this->sync_queue->checkout_with_memory_limit( $this->checkout_memory_size, $this->upload_max_rows );
402
403
		if ( ! $buffer ) {
404
			// buffer has no items
405
			return false;
406
		}
407
408
		if ( is_wp_error( $buffer ) ) {
409
			// another buffer is currently sending
410
			return false;
411
		}
412
413
		$upload_size   = 0;
414
		$items_to_send = array();
415
416
		// we estimate the total encoded size as we go by encoding each item individually
417
		// this is expensive, but the only way to really know :/
418
		foreach ( $buffer->get_items() as $key => $item ) {
419
420
			// expand item data, e.g. IDs into posts (for full sync)
421
			$item[1] = apply_filters( "jetpack_sync_before_send_" . $item[0], $item[1] );
422
423
			$encoded_item = $this->codec->encode( $item );
424
			$upload_size += strlen( $encoded_item );
425
426
			if ( $upload_size > $this->upload_max_bytes && count( $items_to_send ) > 0 ) {
427
				break;
428
			}
429
430
			$items_to_send[ $key ] = $encoded_item;
431
		}
432
433
		/**
434
		 * Fires when data is ready to send to the server.
435
		 * Return false or WP_Error to abort the sync (e.g. if there's an error)
436
		 * The items will be automatically re-sent later
437
		 *
438
		 * @since 4.1
439
		 *
440
		 * @param array $data The action buffer
441
		 */
442
443
		$result = apply_filters( 'jetpack_sync_client_send_data', $items_to_send );
444
445
		if ( ! $result || is_wp_error( $result ) ) {
446
			// error_log("There was an error sending data:");
447
			// error_log(print_r($result, 1));
448
			$result = $this->sync_queue->checkin( $buffer );
449
450
			if ( is_wp_error( $result ) ) {
451
				error_log( "Error checking in buffer: " . $result->get_error_message() );
452
				$this->sync_queue->force_checkin();
453
			}
454
			// try again in 1 minute
455
			$this->schedule_sync( "+1 minute" );
456
		} else {
457
458
			// scan the sent data to see if a full sync started or finished
459
			if ( $this->buffer_includes_action( $buffer, 'jetpack_full_sync_start' ) ) {
460
				$this->full_sync_client->set_status_sending_started();
461
			}
462
463
			if ( $this->buffer_includes_action( $buffer, 'jetpack_full_sync_end' ) ) {
464
				$this->full_sync_client->set_status_sending_finished();
465
			}
466
467
			$this->sync_queue->close( $buffer, $result );
468
			// check if there are any more events in the buffer
469
			// if so, schedule a cron job to happen soon
470
			if ( $this->sync_queue->has_any_items() ) {
471
				$this->schedule_sync( "+1 minute" );
472
			}
473
		}
474
	}
475
476
	private function buffer_includes_action( $buffer, $action_name ) {
477
		foreach ( $buffer->get_items() as $item ) {
478
			if ( $item[0] === $action_name ) {
479
				return true;
480
			}
481
		}
482
483
		return false;
484
	}
485
486
	function expand_wp_insert_post( $args ) {
487
		// list( $post_ID, $post, $update ) = $args;
488
		return array( $args[0], $this->filter_post_content( $args[1] ), $args[2] );
489
	}
490
491
	// Expands wp_insert_post to include filteredpl
492
	function filter_post_content( $post ) {
493
		if ( 0 < strlen( $post->post_password ) ) {
494
			$post->post_password = 'auto-' . wp_generate_password( 10, false );
495
		}
496
		$post->post_content_filtered = apply_filters( 'the_content', $post->post_content );
497
498
		return $post;
499
	}
500
501
	private function schedule_sync( $when ) {
502
		wp_schedule_single_event( strtotime( $when ), 'jetpack_sync_actions' );
503
	}
504
505
	function force_sync_constants() {
506
		delete_option( self::CONSTANTS_CHECKSUM_OPTION_NAME );
507
		$this->maybe_sync_constants();
508
	}
509
510
	function force_sync_options() {
511
		do_action( 'jetpack_full_sync_options', true );
512
	}
513
514
	function force_sync_network_options() {
515
		do_action( 'jetpack_full_sync_network_options', true );
516
	}
517
518
	private function maybe_sync_constants() {
519
		$constants = $this->get_all_constants();
520
		if ( empty( $constants ) ) {
521
			return;
522
		}
523
		$constants_check_sum = $this->get_check_sum( $constants );
524
		if ( $constants_check_sum !== (int) get_option( self::CONSTANTS_CHECKSUM_OPTION_NAME ) ) {
525
			do_action( 'jetpack_sync_current_constants', $constants );
526
			update_option( self::CONSTANTS_CHECKSUM_OPTION_NAME, $constants_check_sum );
527
		}
528
	}
529
530
	private function get_all_constants() {
531
		return array_combine(
532
			$this->constants_whitelist,
533
			array_map( array( $this, 'get_constant' ), $this->constants_whitelist )
534
		);
535
	}
536
537
	private function get_constant( $constant ) {
538
		if ( defined( $constant ) ) {
539
			return constant( $constant );
540
		}
541
542
		return null;
543
	}
544
545
	public function force_sync_callables() {
546
		foreach ( $this->callable_whitelist as $name => $config ) {
547
			delete_option( self::CALLABLES_CHECKSUM_OPTION_NAME."_$name" );
548
		}
549
550
		delete_transient( Jetpack_Sync_Defaults::$default_sync_callables_wait_time );
0 ignored issues
show
Bug introduced by
The property default_sync_callables_wait_time cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
551
		$this->maybe_sync_callables();
552
	}
553
554
	private function maybe_sync_callables() {
555
		if ( get_transient( self::CALLABLES_AWAIT_TRANSIENT_NAME ) ) {
556
			return;
557
		}
558
559
		$callables = $this->get_all_callables();
560
		if ( empty( $callables ) ) {
561
			return;
562
		}
563
564
		set_transient( 'self::CALLABLES_AWAIT_TRANSIENT_NAME', microtime(true), Jetpack_Sync_Defaults::$default_sync_callables_wait_time );
0 ignored issues
show
Bug introduced by
The property default_sync_callables_wait_time cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
565
		// only send the callables that have changed
566
		foreach ( $callables as $name => $value ) {
567
			$checksum = $this->get_check_sum( $value );
568
			// explicitly not using Identical comparison as get_option returns a string
569
			if ( $checksum != get_option( self::CALLABLES_CHECKSUM_OPTION_NAME . "_$name" ) ) {
570
				do_action( 'jetpack_sync_current_callable', $name, $value );
571
				update_option( self::CALLABLES_CHECKSUM_OPTION_NAME . "_$name", $checksum );
572
			}
573
		}
574
	}
575
576
	private function get_all_callables() {
577
		return array_combine(
578
			array_keys( $this->callable_whitelist ),
579
			array_map( array( $this, 'get_callable' ), array_values( $this->callable_whitelist ) )
580
		);
581
	}
582
583
	private function get_callable( $callable ) {
584
		return call_user_func( $callable );
585
	}
586
587
	// Is public so that we don't have to store so much data all the options twice.
588
	function get_all_options() {
589
		$options = array();
590
		foreach ( $this->options_whitelist as $option ) {
591
			$options[ $option ] = get_option( $option );
592
		}
593
594
		return $options;
595
	}
596
597
	function get_all_network_options() {
598
		$options = array();
599
		foreach ( $this->network_options_whitelist as $option ) {
600
			$options[ $option ] = get_site_option( $option );
601
		}
602
603
		return $options;
604
	}
605
606
	private function get_check_sum( $values ) {
607
		return crc32( json_encode( $values ) );
608
	}
609
610 View Code Duplication
	function jetpack_sync_core_icon() {
611
		if ( function_exists( 'get_site_icon_url' ) ) {
612
			$url = get_site_icon_url();
613
		} else {
614
			return;
615
		}
616
617
		require_once( JETPACK__PLUGIN_DIR . 'modules/site-icon/site-icon-functions.php' );
618
		// If there's a core icon, maybe update the option.  If not, fall back to Jetpack's.
619
		if ( ! empty( $url ) && $url !== jetpack_site_icon_url() ) {
620
			// This is the option that is synced with dotcom
621
			Jetpack_Options::update_option( 'site_icon_url', $url );
622
		} else if ( empty( $url ) && did_action( 'delete_option_site_icon' ) ) {
623
			Jetpack_Options::delete_option( 'site_icon_url' );
624
		}
625
	}
626
627
	function get_sync_queue() {
628
		return $this->sync_queue;
629
	}
630
631
	function reset_sync_queue() {
632
		$this->sync_queue->reset();
633
	}
634
635
	function set_defaults() {
636
		$this->sync_queue = new Jetpack_Sync_Queue( 'sync' );
637
		$this->set_send_buffer_memory_size( Jetpack_Sync_Defaults::$default_send_buffer_memory_size );
0 ignored issues
show
Bug introduced by
The property default_send_buffer_memory_size cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
638
		$this->set_upload_max_bytes( Jetpack_Sync_Defaults::$default_upload_max_bytes );
0 ignored issues
show
Bug introduced by
The property default_upload_max_bytes cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
639
		$this->set_upload_max_rows( Jetpack_Sync_Defaults::$default_upload_max_rows );
0 ignored issues
show
Bug introduced by
The property default_upload_max_rows cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
640
641
		if ( $this->get_min_sync_wait_time() === false ) {
642
			$this->set_min_sync_wait_time( Jetpack_Sync_Defaults::$default_sync_wait_time );
0 ignored issues
show
Bug introduced by
The property default_sync_wait_time cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
643
		}
644
645
		$this->set_full_sync_client( Jetpack_Sync_Full::getInstance() );
646
		$this->codec                     = new Jetpack_Sync_Deflate_Codec();
647
		$this->constants_whitelist       = Jetpack_Sync_Defaults::$default_constants_whitelist;
0 ignored issues
show
Bug introduced by
The property default_constants_whitelist cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
648
		$this->options_whitelist         = Jetpack_Sync_Defaults::$default_options_whitelist;
0 ignored issues
show
Bug introduced by
The property default_options_whitelist cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
649
		$this->network_options_whitelist = Jetpack_Sync_Defaults::$default_network_options_whitelist;
0 ignored issues
show
Bug introduced by
The property default_network_options_whitelist cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
650
		$this->taxonomy_whitelist        = Jetpack_Sync_Defaults::$default_taxonomy_whitelist;
0 ignored issues
show
Bug introduced by
The property default_taxonomy_whitelist cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
651
		$this->is_multisite              = is_multisite();
652
653
		// theme mod varies from theme to theme.
654
		$this->options_whitelist[] = 'theme_mods_' . get_option( 'stylesheet' );
655
		if ( $this->is_multisite ) {
656
			$this->callable_whitelist = array_merge( Jetpack_Sync_Defaults::$default_callable_whitelist, Jetpack_Sync_Defaults::$default_multisite_callable_whitelist );
0 ignored issues
show
Bug introduced by
The property default_callable_whitelist cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
Bug introduced by
The property default_multisite_callable_whitelist cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
657
		} else {
658
			$this->callable_whitelist = Jetpack_Sync_Defaults::$default_callable_whitelist;
0 ignored issues
show
Bug introduced by
The property default_callable_whitelist cannot be accessed from this context as it is declared private in class Jetpack_Sync_Defaults.

This check looks for access to properties that are not accessible from the current context.

If you need to make a property accessible to another context you can either raise its visibility level or provide an accessible getter in the defining class.

Loading history...
659
		}
660
	}
661
662
	function reset_data() {
663
		delete_option( self::CONSTANTS_CHECKSUM_OPTION_NAME );
664
		$this->reset_sync_queue();
665
	}
666
}
667