Completed
Push — add/sync-action ( 3d72dc...49cf40 )
by
unknown
11:21
created

Jetpack_Sync_Client   D

Complexity

Total Complexity 103

Size/Duplication

Total Lines 578
Duplicated Lines 6.57 %

Coupling/Cohesion

Components 3
Dependencies 7

Importance

Changes 4
Bugs 0 Features 3
Metric Value
c 4
b 0
f 3
dl 38
loc 578
rs 4.8717
wmc 103
lcom 3
cbo 7

48 Methods

Rating   Name   Duplication   Size   Complexity  
A getInstance() 0 7 2
A __construct() 0 4 1
B init() 0 125 6
A set_options_whitelist() 0 3 1
A set_constants_whitelist() 0 3 1
A get_callable_whitelist() 0 3 1
A set_callable_whitelist() 0 3 1
A set_network_options_whitelist() 0 3 1
A set_send_buffer_size() 0 6 2
A set_taxonomy_whitelist() 0 3 1
A is_whitelisted_option() 0 3 1
A is_whitelisted_network_option() 0 3 2
A set_codec() 0 3 1
A set_full_sync_client() 0 12 2
A get_full_sync_client() 0 3 1
C action_handler() 0 42 12
A send_theme_info() 0 14 3
A send_wp_version() 0 6 3
A save_term_handler() 0 9 2
A send_attachment_info() 0 4 1
A save_user_handler() 0 18 4
A save_user_role_handler() 0 4 1
A save_user_cap_handler() 0 6 2
A sanitize_user() 0 4 1
C do_sync() 0 72 12
A filter_items_before_send() 0 6 1
A buffer_includes_action() 0 9 3
A expand_wp_insert_post() 0 4 1
A filter_post_content() 0 4 1
A schedule_sync() 0 3 1
A force_sync_constants() 0 4 1
A force_sync_options() 0 3 1
A force_sync_network_options() 0 3 1
A maybe_sync_constants() 11 11 3
A get_all_constants() 0 6 1
A get_constant() 0 7 2
A force_sync_callables() 0 4 1
A maybe_sync_callables() 11 11 3
A get_all_callables() 0 6 1
A get_callable() 0 3 1
A get_all_options() 0 7 2
A get_all_network_options() 0 7 2
A get_check_sum() 0 3 1
B jetpack_sync_core_icon() 16 16 6
A get_sync_queue() 0 3 1
A reset_sync_queue() 0 3 1
A set_defaults() 0 18 2
A reset_data() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Jetpack_Sync_Client often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Jetpack_Sync_Client, and based on these observations, apply Extract Interface, too.

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
	static $constants_checksum_option_name = 'jetpack_constants_sync_checksum';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $constants_checksum_option_name.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
11
	static $functions_checksum_option_name = 'jetpack_functions_sync_checksum';
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $functions_checksum_option_name.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
12
13
	private $sync_queue;
14
	private $full_sync_client;
15
	private $codec;
16
	private $options_whitelist;
17
	private $constants_whitelist;
18
	private $meta_types = array( 'post', 'comment' );
19
	private $callable_whitelist;
20
	private $network_options_whitelist;
21
	private $taxonomy_whitelist;
22
23
	// singleton functions
24
	private static $instance;
25
26
	public static function getInstance() {
27
		if ( null === self::$instance ) {
28
			self::$instance = new self();
29
		}
30
31
		return self::$instance;
32
	}
33
34
	// this is necessary because you can't use "new" when you declare instance properties >:(
35
	protected function __construct() {
36
		$this->set_defaults();
37
		$this->init();
38
	}
39
40
	private function init() {
41
42
		$handler = array( $this, 'action_handler' );
43
44
		/**
45
		 * Most of the following hooks are sent to the same $handler 
46
		 * for immediate serialization and queuing be sent to the server.
47
		 * The only exceptions are actions which need additional processing.
48
		 */
49
50
		// constants
51
		add_action( 'jetpack_sync_current_constants', $handler, 10 );
52
53
		// functions
54
		add_action( 'jetpack_sync_current_callables', $handler, 10 );
55
56
		// posts
57
		add_action( 'wp_insert_post', $handler, 10, 3 );
58
		add_action( 'deleted_post', $handler, 10 );
59
		add_filter( 'jetpack_sync_before_send_wp_insert_post', array( $this, 'expand_wp_insert_post' ) );
60
61
		// attachments
62
63
		add_action( 'edit_attachment', array( $this, 'send_attachment_info' ) );
64
		// Once we don't have to support 4.3 we can start using add_action( 'attachment_updated', $handler, 10, 3 ); instead
65
		add_action( 'add_attachment', array( $this, 'send_attachment_info' ) );
66
		add_action( 'jetpack_sync_save_add_attachment', $handler, 10, 2 );
67
68
		// comments
69
		add_action( 'wp_insert_comment', $handler, 10, 2 );
70
		add_action( 'deleted_comment', $handler, 10 );
71
		add_action( 'trashed_comment', $handler, 10 );
72
		add_action( 'spammed_comment', $handler, 10 );
73
74
		// even though it's messy, we implement these hooks because 
75
		// the edit_comment hook doesn't include the data
76
		// so this saves us a DB read for every comment event
77
		foreach ( array( '', 'trackback', 'pingback' ) as $comment_type ) {
78
			foreach ( array( 'unapproved', 'approved' ) as $comment_status ) {
79
				add_action( "comment_{$comment_status}_{$comment_type}", $handler, 10, 2 );
80
			}
81
		}
82
83
		// options
84
		add_action( 'added_option', $handler, 10, 2 );
85
		add_action( 'updated_option', $handler, 10, 3 );
86
		add_action( 'deleted_option', $handler, 10, 1 );
87
88
		// Sync Core Icon: Detect changes in Core's Site Icon and make it syncable.
89
		add_action( 'add_option_site_icon', array( $this, 'jetpack_sync_core_icon' ) );
90
		add_action( 'update_option_site_icon', array( $this, 'jetpack_sync_core_icon' ) );
91
		add_action( 'delete_option_site_icon', array( $this, 'jetpack_sync_core_icon' ) );
92
93
		// wordpress version
94
		add_action( 'upgrader_process_complete', array( $this, 'send_wp_version' ), 10, 2 );
95
		add_action( 'jetpack_sync_wp_version', $handler );
96
97
		// themes
98
		add_action( 'switch_theme', array( $this, 'send_theme_info' ) );
99
		add_action( 'jetpack_sync_current_theme_support', $handler, 10 ); // custom hook, see meta-hooks below
100
101
		// post-meta, and in the future - other meta?
102
		foreach ( $this->meta_types as $meta_type ) {
103
			add_action( "added_{$meta_type}_meta", $handler, 10, 4 );
104
			add_action( "updated_{$meta_type}_meta", $handler, 10, 4 );
105
			add_action( "deleted_{$meta_type}_meta", $handler, 10, 4 );
106
		}
107
108
		// terms
109
		add_action( 'created_term', array( $this, 'save_term_handler' ), 10, 3 );
110
		add_action( 'edited_term', array( $this, 'save_term_handler' ), 10, 3 );
111
		add_action( 'jetpack_sync_save_term', $handler, 10, 4 );
112
		add_action( 'delete_term', $handler, 10, 4 );
113
		add_action( 'set_object_terms', $handler, 10, 5 );
114
		add_action( 'deleted_term_relationships', $handler, 10 , 2 );
115
116
		// users
117
		add_action( 'user_register', array( $this, 'save_user_handler' ) );
118
		add_action( 'profile_update', array( $this, 'save_user_handler' ), 10, 2 );
119
		add_action( 'jetpack_sync_save_user', $handler, 10, 2 );
120
		add_action( 'deleted_user', $handler, 10, 2 );
121
122
		// user roles
123
		add_action( 'add_user_role', array( $this,'save_user_role_handler' ), 10, 2 );
124
		add_action( 'set_user_role', array( $this,'save_user_role_handler' ), 10, 3 );
125
		add_action( 'remove_user_role', array( $this,'save_user_role_handler' ), 10, 2 );
126
127
128
		// user capabilities
129
		add_action( 'added_user_meta', array( $this, 'save_user_cap_handler' ), 10, 4 );
130
		add_action( 'updated_user_meta', array( $this, 'save_user_cap_handler' ), 10, 4 );
131
		add_action( 'deleted_user_meta', array( $this, 'save_user_cap_handler' ), 10, 4 );
132
133
		// themes
134
		add_action( 'set_site_transient_update_plugins', $handler, 10, 1 );
135
		add_action( 'set_site_transient_update_themes', $handler, 10, 1 );
136
		add_action( 'set_site_transient_update_core', $handler, 10, 1 );
137
138
		// multi site network options
139
		if ( $this->is_multisite ) {
0 ignored issues
show
Bug introduced by
The property is_multisite does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
140
			add_action( 'add_site_option', $handler, 10, 2 );
141
			add_action( 'update_site_option', $handler, 10, 3 );
142
			add_action( 'delete_site_option', $handler, 10, 1 );
143
		}
144
145
		// synthetic actions for full sync
146
		add_action( 'jetpack_full_sync_start', $handler );
147
		add_action( 'jetpack_full_sync_end', $handler );
148
		add_action( 'jetpack_full_sync_options', $handler );
149
		add_action( 'jetpack_full_sync_posts', $handler ); // also sends post meta
150
		add_action( 'jetpack_full_sync_comments', $handler ); // also send comments meta
151
		add_action( 'jetpack_full_sync_users', $handler );
152
		add_action( 'jetpack_full_sync_terms', $handler, 10, 2 );
153
		if ( is_multisite() ) {
154
			add_action( 'jetpack_full_sync_network_options', $handler );
155
		}
156
157
158
		// 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...
159
160
		/**
161
		 * Sync all pending actions with server
162
		 */
163
		add_action( 'jetpack_sync_actions', array( $this, 'do_sync' ) );
164
	}
165
166
	// 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...
167
	function set_options_whitelist( $options ) {
168
		$this->options_whitelist = $options;
169
	}
170
171
	function set_constants_whitelist( $constants ) {
172
		$this->constants_whitelist = $constants;
173
	}
174
175
	function get_callable_whitelist( $functions ) {
0 ignored issues
show
Unused Code introduced by
The parameter $functions 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...
176
		return $this->callable_whitelist;
177
	}
178
179
	function set_callable_whitelist( $functions ) {
180
		$this->callable_whitelist = $functions;
181
	}
182
183
	function set_network_options_whitelist( $options ) {
184
		$this->network_options_whitelist = $options;
185
	}
186
187
	function set_send_buffer_size( $size, $memory_limit = null ) {
188
		$this->sync_queue->set_checkout_size( $size );
189
		if ( $memory_limit ) {
190
			$this->sync_queue->set_memory_limit(  $memory_limit );
191
		}
192
	}
193
194
	function set_taxonomy_whitelist( $taxonomies ) {
195
		$this->taxonomy_whitelist = $taxonomies;
196
	}
197
198
	function is_whitelisted_option( $option ) {
199
		return in_array( $option, $this->options_whitelist );
200
	}
201
202
	function is_whitelisted_network_option( $option ) {
203
		return $this->is_multisite && in_array( $option, $this->network_options_whitelist );
204
	}
205
206
	function set_codec( iJetpack_Sync_Codec $codec ) {
207
		$this->codec = $codec;
208
	}
209
210
	function set_full_sync_client( $full_sync_client ) {
211
		if ( $this->full_sync_client ) {
212
			remove_action( 'jetpack_sync_full', array( $this->full_sync_client, 'start' ) );
213
		}
214
215
		$this->full_sync_client = $full_sync_client;
216
217
		/**
218
		 * Sync all objects in the database with the server
219
		 */
220
		add_action( 'jetpack_sync_full', array( $this->full_sync_client, 'start' ) );
221
	}
222
223
	function get_full_sync_client() {
224
		return $this->full_sync_client;
225
	}
226
227
	function action_handler() {
228
		// 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...
229
		// wherever we initialize the action listeners or we're just wasting cycles
230
		if ( Jetpack::is_development_mode() || Jetpack::is_staging_site() ) {
231
			return false;
232
		}
233
234
		$current_filter = current_filter();
235
		$args           = func_get_args();
236
237
		if ( $current_filter === 'wp_insert_post' && $args[1]->post_type === 'revision' ) {
238
			return;
239
		}
240
241
		if ( in_array( $current_filter, array( 'deleted_option', 'added_option', 'updated_option' ) )
242
		     &&
243
		     ! $this->is_whitelisted_option( $args[0] )
244
		) {
245
			return;
246
		}
247
248
		if ( in_array( $current_filter, array( 'delete_site_option', 'add_site_option', 'update_site_option' ) )
249
		     &&
250
		     ! $this->is_whitelisted_network_option( $args[0] )
251
		) {
252
			return;
253
		}
254
255
		// don't sync private meta
256
		if ( preg_match( '/^(added|updated|deleted)_.*_meta$/', $current_filter )
257
		     && $args[2][0] === '_'
258
		     && ! 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...
259
			return;
260
		}
261
262
		$this->sync_queue->add( array(
263
			$current_filter,
264
			$args,
265
			get_current_user_id(),
266
			microtime(true)
267
		) );
268
	}
269
270
	function send_theme_info() {
271
		global $_wp_theme_features;
272
273
		$theme_support = array();
274
275
		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...
276
			$has_support = current_theme_supports( $theme_feature );
277
			if ( $has_support ) {
278
				$theme_support[ $theme_feature ] = $_wp_theme_features[ $theme_feature ];
279
			}
280
281
		}
282
		do_action( 'jetpack_sync_current_theme_support', $theme_support );
283
	}
284
285
	function send_wp_version( $update, $meta_data ) {
286
		if ( 'update' === $meta_data['action'] && 'core' === $meta_data['type'] ) {
287
			global $wp_version;
288
			do_action( 'jetpack_sync_wp_version', $wp_version );
289
		}
290
	}
291
292
	function save_term_handler( $term_id, $tt_id, $taxonomy ) {
293
		if ( class_exists('WP_Term') ) {
294
			$term_object = WP_Term::get_instance( $term_id, $taxonomy );
295
		} else {
296
			$term_object = get_term_by( 'id', $term_id, $taxonomy );
297
		}
298
299
		do_action( 'jetpack_sync_save_term', $term_object );
300
	}
301
302
	function send_attachment_info( $attachment_id ) {
303
		$attachment = get_post( $attachment_id );
304
		do_action( 'jetpack_sync_save_add_attachment', $attachment_id, $attachment );
305
	}
306
307
	function save_user_handler( $user_id, $old_user_data = null ) {
308
		$user = $this->sanitize_user( get_user_by( 'id', $user_id ) );
309
310
		// Older versions of WP don't pass the old_user_data in ->data
311
		if ( isset( $old_user_data->data ) ) {
312
			$old_user = $old_user_data->data;
313
		} else {
314
			$old_user = $old_user_data;
315
		}
316
317
		if ( $old_user !== null ) {
318
			unset( $old_user->user_pass );
319
			if ( serialize( $old_user ) === serialize( $user->data ) ) {
320
				return;
321
			}
322
		}
323
		do_action( 'jetpack_sync_save_user', $user );
324
	}
325
326
	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...
327
		$user = $this->sanitize_user( get_user_by( 'id', $user_id ) );
328
		do_action( 'jetpack_sync_save_user', $user );
329
	}
330
331
	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...
332
		$user = $this->sanitize_user( get_user_by( 'id', $user_id ) );
333
		if ( $meta_key === $user->cap_key ) {
334
			do_action( 'jetpack_sync_save_user', $user );
335
		}
336
	}
337
338
	public function sanitize_user( $user ) {
339
		unset( $user->data->user_pass );
340
		return $user;
341
	}
342
343
344
	function do_sync() {
345
		if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
346
			$this->schedule_sync( "+1 minute" );
347
			return false;
348
		}
349
350
		$this->maybe_sync_constants();
351
		$this->maybe_sync_callables();
352
353
		if ( $this->sync_queue->size() === 0 ) {
354
			return false;
355
		}
356
357
		$buffer = $this->sync_queue->checkout();
358
359
		if ( ! $buffer ) {
360
			// buffer has no items
361
			return;
362
		}
363
364
		if ( is_wp_error( $buffer ) ) {
365
			// another buffer is currently sending
366
			return;
367
		}
368
369
		$items = array_map( array( $this, 'filter_items_before_send' ), $buffer->get_items() );
370
371
		$data = $this->codec->encode( $items );
372
373
		/**
374
		 * Fires when data is ready to send to the server.
375
		 * Return false or WP_Error to abort the sync (e.g. if there's an error)
376
		 * The items will be automatically re-sent later
377
		 *
378
		 * @since 4.1
379
		 *
380
		 * @param array $data The action buffer
381
		 */
382
		$result = apply_filters( 'jetpack_sync_client_send_data', $data );
383
384
		if ( ! $result || is_wp_error( $result ) ) {
385
			// error_log("There was an error sending data:");
386
			// error_log(print_r($result, 1));
387
			$result = $this->sync_queue->checkin( $buffer );
388
389
			if ( is_wp_error( $result ) ) {
390
				error_log("Error checking in buffer: ".$result->get_error_message());
391
				$this->sync_queue->force_checkin();
392
			}
393
			// try again in 1 minute
394
			$this->schedule_sync( "+1 minute" );
395
		} else {
396
397
			// scan the sent data to see if a full sync started or finished
398
			if ( $this->buffer_includes_action( $buffer, 'jetpack_full_sync_start' ) ) {
399
				do_action( 'jetpack_full_sync_start_sent' );
400
				$this->full_sync_client->set_status_sending_started();
401
			}
402
403
			if ( $this->buffer_includes_action( $buffer, 'jetpack_full_sync_end' ) ) {
404
				do_action( 'jetpack_full_sync_end_sent' );
405
				$this->full_sync_client->set_status_sending_finished();
406
			}
407
408
			$this->sync_queue->close( $buffer );
409
			// check if there are any more events in the buffer
410
			// if so, schedule a cron job to happen soon
411
			if ( $this->sync_queue->has_any_items() ) {
412
				$this->schedule_sync( "+1 minute" );
413
			}
414
		}
415
	}
416
417
	private function filter_items_before_send( $item ) {
418
		$current_filter = $item[0];
419
		$item[1]        = apply_filters( "jetpack_sync_before_send_$current_filter", $item[1] );
420
421
		return $item;
422
	}
423
424
	private function buffer_includes_action( $buffer, $action_name ) {
425
		foreach ( $buffer->get_items() as $item ) {
426
			if ( $item[0] === $action_name ) {
427
				return true;
428
			}
429
		}
430
431
		return false;
432
	}
433
	
434
	function expand_wp_insert_post( $args ) {
435
		// list( $post_ID, $post, $update ) = $args;
436
		return array( $args[0], $this->filter_post_content( $args[1] ), $args[2] );
437
	}
438
	// Expands wp_insert_post to include filteredpl
439
	function filter_post_content( $post ) {
440
		$post->post_content_filtered = apply_filters( 'the_content', $post->post_content );
441
		return $post;
442
	}
443
444
	private function schedule_sync( $when ) {
445
		wp_schedule_single_event( strtotime( $when ), 'jetpack_sync_actions' );
446
	}
447
448
	function force_sync_constants() {
449
		delete_option( self::$constants_checksum_option_name );
450
		$this->maybe_sync_constants();
451
	}
452
453
	function force_sync_options() {
454
		do_action( 'jetpack_full_sync_options', true );
455
	}
456
457
	function force_sync_network_options() {
458
		do_action( 'jetpack_full_sync_network_options', true );
459
	}
460
461 View Code Duplication
	private function maybe_sync_constants() {
462
		$constants = $this->get_all_constants();
463
		if ( empty( $constants ) ) {
464
			return;
465
		}
466
		$constants_check_sum = $this->get_check_sum( $constants );
467
		if ( $constants_check_sum !== (int) get_option( self::$constants_checksum_option_name ) ) {
468
			do_action( 'jetpack_sync_current_constants', $constants );
469
			update_option( self::$constants_checksum_option_name, $constants_check_sum );
470
		}
471
	}
472
473
	private function get_all_constants() {
474
		return array_combine(
475
			$this->constants_whitelist,
476
			array_map( array( $this, 'get_constant' ), $this->constants_whitelist )
477
		);
478
	}
479
480
	private function get_constant( $constant ) {
481
		if ( defined( $constant ) ) {
482
			return constant( $constant );
483
		}
484
485
		return null;
486
	}
487
488
	public function force_sync_callables() {
489
		delete_option( self::$functions_checksum_option_name );
490
		$this->maybe_sync_callables();
491
	}
492
493 View Code Duplication
	private function maybe_sync_callables() {
494
		$callables = $this->get_all_callables();
495
		if ( empty( $callables ) ) {
496
			return;
497
		}
498
		$callables_check_sum = $this->get_check_sum( $callables );
499
		if ( $callables_check_sum !== (int) get_option( self::$functions_checksum_option_name ) ) {
500
			do_action( 'jetpack_sync_current_callables', $callables );
501
			update_option( self::$functions_checksum_option_name, $callables_check_sum );
502
		}
503
	}
504
505
	private function get_all_callables() {
506
		return array_combine(
507
			array_keys( $this->callable_whitelist ),
508
			array_map( array( $this, 'get_callable' ), array_values( $this->callable_whitelist ) )
509
		);
510
	}
511
512
	private function get_callable( $callable ) {
513
		return call_user_func( $callable );
514
	}
515
516
	// Is public so that we don't have to store so much data all the options twice.
517
	function get_all_options() {
518
		$options = array();
519
		foreach( $this->options_whitelist as $option ) {
520
			$options[ $option ] = get_option( $option );
521
		}
522
		return $options;
523
	}
524
525
	function get_all_network_options() {
526
		$options = array();
527
		foreach( $this->network_options_whitelist as $option ) {
528
			$options[ $option ] = get_site_option( $option );
529
		}
530
		return $options;
531
	}
532
533
	private function get_check_sum( $values ) {
534
		return crc32( serialize( $values ) );
535
	}
536
537 View Code Duplication
	function jetpack_sync_core_icon() {
538
		if ( function_exists( 'get_site_icon_url' ) ) {
539
			$url = get_site_icon_url();
540
		} else {
541
			return;
542
		}
543
544
		require_once( JETPACK__PLUGIN_DIR . 'modules/site-icon/site-icon-functions.php' );
545
		// If there's a core icon, maybe update the option.  If not, fall back to Jetpack's.
546
		if ( ! empty( $url ) && $url !== jetpack_site_icon_url() ) {
547
			// This is the option that is synced with dotcom
548
			Jetpack_Options::update_option( 'site_icon_url', $url );
549
		} else if ( empty( $url ) && did_action( 'delete_option_site_icon' ) ) {
550
			Jetpack_Options::delete_option( 'site_icon_url' );
551
		}
552
	}
553
554
	function get_sync_queue() {
555
		return $this->sync_queue;
556
	}
557
558
	function reset_sync_queue() {
559
		$this->sync_queue->reset();
560
	}
561
562
	function set_defaults() {
563
		$this->sync_queue = new Jetpack_Sync_Queue( 'sync', Jetpack_Sync_Defaults::$default_send_buffer_size );
0 ignored issues
show
Bug introduced by
The property default_send_buffer_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...
564
		$this->set_full_sync_client( Jetpack_Sync_Full::getInstance() );
565
		$this->codec                     = new Jetpack_Sync_Deflate_Codec();
566
		$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...
567
		$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...
568
		$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...
569
		$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...
570
		$this->is_multisite              = is_multisite();
571
		
572
		// theme mod varies from theme to theme.
573
		$this->options_whitelist[] =  'theme_mods_' . get_option( 'stylesheet' );
574
		if ( $this->is_multisite ) {
575
			$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...
576
		} else {
577
			$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...
578
		}
579
	}
580
581
	function reset_data() {
582
		delete_option( self::$constants_checksum_option_name );
583
		$this->reset_sync_queue();
584
	}
585
}
586