Completed
Push — add/sync-rest-2 ( a434af...d8d9e1 )
by
unknown
77:18 queued 68:04
created

Jetpack_Sync_Client::action_handler()   C

Complexity

Conditions 11
Paths 6

Size

Total Lines 38
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 17
Bugs 2 Features 5
Metric Value
c 17
b 2
f 5
dl 0
loc 38
rs 5.2653
cc 11
eloc 20
nc 6
nop 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
7
class Jetpack_Sync_Client {
8
	static $default_options_whitelist = array( 
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $default_options_whitelist.

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...
9
		'stylesheet', 
10
		'/^theme_mods_.*$/',
11
		'blogname',
12
		'home',
13
		'siteurl',
14
		'blogdescription',
15
		'blog_charset',
16
		'permalink_structure',
17
		'category_base',
18
		'tag_base',
19
		'comment_moderation',
20
		'default_comment_status',
21
		'thread_comments',
22
		'thread_comments_depth',
23
		'jetpack_site_icon_url',
24
		'social_notifications_like',
25
		'page_on_front',
26
		'rss_use_excerpt',
27
		'subscription_options',
28
		'stb_enabled',
29
		'stc_enabled',
30
		'comment_registration',
31
		'require_name_email',
32
		'show_avatars',
33
		'avatar_default',
34
		'avatar_rating',
35
		'highlander_comment_form_prompt',
36
		'jetpack_comment_form_color_scheme',
37
		'stats_options',
38
		'gmt_offset',
39
		'timezone_string',
40
		'jetpack_sync_non_public_post_stati',
41
		'jetpack_options',
42
		'site_icon', // (int) - ID of core's Site Icon attachment ID
43
		'default_post_format',
44
		'default_category',
45
		'large_size_w',
46
		'large_size_h',
47
		'thumbnail_size_w',
48
		'thumbnail_size_h',
49
		'medium_size_w',
50
		'medium_size_h',
51
		'thumbnail_crop',
52
		'image_default_link_type',
53
		'site_logo',
54
		'sharing-options',
55
		'sharing-services',
56
		'post_count',
57
		'default_ping_status',
58
		'sticky_posts',
59
		'disabled_likes',
60
		'blog_public',
61
		'default_pingback_flag',
62
		'require_name_email',
63
		'close_comments_for_old_posts',
64
		'close_comments_days_old',
65
		'thread_comments',
66
		'thread_comments_depth',
67
		'page_comments',
68
		'comments_per_page',
69
		'default_comments_page',
70
		'comment_order',
71
		'comments_notify',
72
		'moderation_notify',
73
		'social_notifications_like',
74
		'social_notifications_reblog',
75
		'social_notifications_subscribe',
76
		'comment_whitelist',
77
		'comment_max_links',
78
		'moderation_keys',
79
		'blacklist_keys',
80
		'lang_id',
81
		'wga',
82
		'disabled_likes',
83
		'disabled_reblogs',
84
		'jetpack_comment_likes_enabled',
85
		'twitter_via',
86
		'twitter-cards-site-tag' );
87
88
	static $default_constants_whitelist = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $default_constants_whitelist.

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...
89
		'EMPTY_TRASH_DAYS',
90
		'WP_POST_REVISIONS',
91
		'AUTOMATIC_UPDATER_DISABLED',
92
		'ABSPATH',
93
		'WP_CONTENT_DIR',
94
		'FS_METHOD',
95
		'DISALLOW_FILE_EDIT',
96
		'DISALLOW_FILE_MODS',
97
		'WP_AUTO_UPDATE_CORE',
98
		'WP_HTTP_BLOCK_EXTERNAL',
99
		'WP_ACCESSIBLE_HOSTS',
100
		'JETPACK__VERSION'
101
	);
102
103
	static $default_callable_whitelist = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $default_callable_whitelist.

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...
104
		'wp_max_upload_size' => 'wp_max_upload_size',
105
		'is_main_network' => array( 'Jetpack', 'is_multi_network' ),
106
		'is_multi_site' => 'is_multisite',
107
		'main_network_site' => 'network_site_url',
108
		'single_user_site' => array( 'Jetpack', 'is_single_user_site' ),
109
		'has_file_system_write_access' => array( 'Jetpack_Sync_Functions', 'file_system_write_access' ),
110
		'is_version_controlled' => array( 'Jetpack_Sync_Functions', 'is_version_controlled' ),
111
		'modules' => array( 'Jetpack_Sync_Functions', 'get_modules' )
112
	);
113
114
	static $default_multisite_callable_whitelist = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $default_multisite_callable_whitelist.

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...
115
		'network_name'                        => array( 'Jetpack', 'network_name' ),
116
		'network_allow_new_registrations'     => array( 'Jetpack', 'network_allow_new_registrations' ),
117
		'network_add_new_users'               => array( 'Jetpack', 'network_add_new_users' ),
118
		'network_site_upload_space'           => array( 'Jetpack', 'network_site_upload_space' ),
119
		'network_upload_file_types'           => array( 'Jetpack', 'network_upload_file_types' ),
120
		'network_enable_administration_menus' => array( 'Jetpack', 'network_enable_administration_menus' ),
121
	);
122
123
	// TODO: move this to server? - these are theme support values
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...
124
	// that should be synced as jetpack_current_theme_supports_foo option values
125
	static $default_theme_support_whitelist = array(
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $default_theme_support_whitelist.

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...
126
		'post-thumbnails',          
127
		'post-formats',
128
		'custom-header',
129
		'custom-background',
130
		'custom-logo',
131
		'menus',
132
		'automatic-feed-links',
133
		'editor-style',
134
		'widgets',
135
		'html5',
136
		'title-tag',
137
		'jetpack-social-menu',
138
		'jetpack-responsive-videos',
139
		'infinite-scroll',
140
		'site-logo',
141
	);
142
143
	static $default_network_options_whitelist = array( 'site_name' );
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $default_network_options_whitelist.

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...
144
	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...
145
	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...
146
	static $default_send_buffer_size = 20;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $default_send_buffer_size.

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...
147
	static $default_taxonomy_whitelist = array();
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $default_taxonomy_whitelist.

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...
148
149
	private $sync_queue;
150
	private $full_sync_client;
151
	private $codec;
152
	private $options_whitelist;
153
	private $constants_whitelist;
154
	private $meta_types = array( 'post' );
155
	private $callable_whitelist;
156
	private $network_options_whitelist;
157
	private $taxonomy_whitelist;
158
159
	// singleton functions
160
	private static $instance;
161
162
	public static function getInstance() {
163
		if ( null === self::$instance ) {
164
			self::$instance = new self();
165
		}
166
167
		return self::$instance;
168
	}
169
170
	// this is necessary because you can't use "new" when you declare instance properties >:(
171
	protected function __construct() {
172
		$this->set_defaults();
173
		$this->init();
174
	}
175
176
	private function init() {
177
178
		$handler = array( $this, 'action_handler' );
179
180
		// constants
181
		add_action( 'jetpack_sync_current_constants', $handler, 10 );
182
183
		// functions
184
		add_action( 'jetpack_sync_current_callables', $handler, 10 );
185
186
		// posts
187
		add_action( 'wp_insert_post', $handler, 10, 3 );
188
		add_action( 'deleted_post', $handler, 10 );
189
190
		// comments
191
		add_action( 'wp_insert_comment', $handler, 10, 2 );
192
		add_action( 'deleted_comment', $handler, 10 );
193
		add_action( 'trashed_comment', $handler, 10 );
194
		add_action( 'spammed_comment', $handler, 10 );
195
196
		// even though it's messy, we implement these hooks because 
197
		// the edit_comment hook doesn't include the data
198
		// so this saves us a DB read for every comment event
199
		foreach ( array( '', 'trackback', 'pingback' ) as $comment_type ) {
200
			foreach ( array( 'unapproved', 'approved' ) as $comment_status ) {
201
				add_action( "comment_{$comment_status}_{$comment_type}", $handler, 10, 2 );
202
			}
203
		}
204
205
		// options
206
		add_action( 'added_option', $handler, 10, 2 );
207
		add_action( 'updated_option', $handler, 10, 3 );
208
		add_action( 'deleted_option', $handler, 10, 1 );
209
210
		// Sync Core Icon: Detect changes in Core's Site Icon and make it syncable.
211
		add_action( 'add_option_site_icon',    array( $this, 'jetpack_sync_core_icon' ) );
212
		add_action( 'update_option_site_icon', array( $this, 'jetpack_sync_core_icon' ) );
213
		add_action( 'delete_option_site_icon', array( $this, 'jetpack_sync_core_icon' ) );
214
215
		// wordpress version
216
		add_action( 'upgrader_process_complete', array( $this, 'send_wp_version' ), 10, 2 );
217
		add_action( 'jetpack_sync_wp_version', $handler );
218
		// themes
219
		add_action( 'switch_theme', array( $this, 'send_theme_info' ) );
220
		add_action( 'jetpack_sync_current_theme_support', $handler, 10 ); // custom hook, see meta-hooks below
221
222
		// post-meta, and in the future - other meta?
223
		foreach ( $this->meta_types as $meta_type ) {
224
			// we need to make sure we don't commit before we receive these,
225
			// because they're invoked after meta changes are saved to the DB
226
			add_action( "added_{$meta_type}_meta", $handler, 99, 4 );
227
			add_action( "updated_{$meta_type}_meta", $handler, 99, 4 );
228
			add_action( "deleted_{$meta_type}_meta", $handler, 99, 4 );
229
		}
230
231
		// synthetic actions for full sync
232
		add_action( 'jetpack_full_sync_start', $handler );
233
		add_action( 'jetpack_full_sync_end', $handler );
234
		add_action( 'jetpack_full_sync_option', $handler, 10, 2 );
235
		
236
		add_action( 'jetpack_full_sync_posts', $handler ); // also sends post meta and terms 
237
		add_action( 'jetpack_full_sync_comments', $handler ); // also send comments meta
238
239
		add_filter( 'jetpack_full_sync_posts_data', array( $this, 'post_ids_to_posts' ) ); // converts post ids to all post data
240
		add_filter( 'jetpack_full_sync_comments_data', array( $this, 'comment_ids_to_comments' ) ); // converts post ids to all post data
241
242
		/**
243
		 * Other hooks - fire synthetic hooks for all the properties we need to sync,
244
		 * e.g. when a theme changes
245
		 */
246
247
		// themes
248
		add_action( 'set_site_transient_update_plugins', $handler, 10, 1 );
249
		add_action( 'set_site_transient_update_themes', $handler, 10, 1 );
250
		add_action( 'set_site_transient_update_core', $handler, 10, 1 );
251
252
		// multi site network options
253
		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...
254
			add_action( 'add_site_option', $handler, 10, 2 );
255
			add_action( 'update_site_option', $handler, 10, 3 );
256
			add_action( 'delete_site_option', $handler, 10, 1 );
257
		}
258
259
		/**
260
		 * Sync all pending actions with server
261
		 */
262
		add_action( 'jetpack_sync_actions', array( $this, 'do_sync' ) );
263
264
		// terms
265
		add_action( 'created_term', array( $this, 'save_term_handler' ), 10, 3 );
266
		add_action( 'edited_term', array( $this, 'save_term_handler' ), 10, 3 );
267
		add_action( 'jetapack_sync_save_term', $handler, 10, 4 );
268
		add_action( 'delete_term', $handler, 10, 5 );
269
270
		// users
271
		add_action( 'user_register', array( $this, 'save_user_handler' ) );
272
		add_action( 'profile_update', array( $this, 'save_user_handler' ), 10, 2 );
273
		add_action( 'jetapack_sync_save_user', $handler, 10, 2 );
274
		add_action( 'deleted_user', $handler, 10 ,2 );
275
	}
276
277
	// 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...
278
	function set_options_whitelist( $options ) {
279
		$this->options_whitelist = $options;
280
	}
281
282
	function set_constants_whitelist( $constants ) {
283
		$this->constants_whitelist = $constants;
284
	}
285
286
	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...
287
		return $this->callable_whitelist;
288
	}
289
290
	function set_callable_whitelist( $functions ) {
291
		$this->callable_whitelist = $functions;
292
	}
293
294
	function set_network_options_whitelist( $options ) {
295
		$this->network_options_whitelist = $options;
296
	}
297
298
	function set_send_buffer_size( $size ) {
299
		$this->sync_queue->set_checkout_size( $size );
300
	}
301
302
	function set_taxonomy_whitelist( $taxonomies ) {
303
		$this->taxonomy_whitelist = $taxonomies;
304
	}
305
306
	function is_whitelisted_option( $option ) {
307
		foreach ( $this->options_whitelist as $whitelisted_option ) {
308
			if ( $whitelisted_option[0] === '/' && preg_match( $whitelisted_option, $option ) ) {
309
				return true;
310
			} elseif ( $whitelisted_option === $option ) {
311
				return true;
312
			}
313
		}
314
315
		return false;
316
	}
317
318
	function is_whitelisted_network_option( $option ) {
319
		return $this->is_multisite && in_array( $option, $this->network_options_whitelist );
320
	}
321
322
	function set_codec( iJetpack_Sync_Codec $codec ) {
323
		$this->codec = $codec;
324
	}
325
326
	function set_full_sync_client( $full_sync_client ) {
327
		if ( $this->full_sync_client ) {
328
			remove_action( 'jetpack_sync_full', array( $this->full_sync_client, 'start' ) );
329
		}
330
331
		$this->full_sync_client = $full_sync_client;
332
333
		/**
334
		 * Sync all objects in the database with the server
335
		 */
336
		add_action( 'jetpack_sync_full', array( $this->full_sync_client, 'start' ) );
337
	}
338
339
	function get_full_sync_client() {
340
		return $this->full_sync_client;
341
	}
342
343
	function action_handler() {
344
		// 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...
345
		// wherever we initialize the action listeners or we're just wasting cycles
346
		if ( Jetpack::is_development_mode() || Jetpack::is_staging_site() ) {
347
			return false;
348
		}
349
350
		$current_filter = current_filter();
351
		$args           = func_get_args();
352
353
		if ( $current_filter === 'wp_insert_post' && $args[1]->post_type === 'revision' ) {
354
			return;
355
		}
356
357
		if ( in_array( $current_filter, array( 'deleted_option', 'added_option', 'updated_option' ) )
358
		     &&
359
		     ! $this->is_whitelisted_option( $args[0] )
360
		) {
361
			return;
362
		}
363
364
		if ( in_array( $current_filter, array( 'delete_site_option', 'add_site_option', 'update_site_option' ) )
365
		     &&
366
		     ! $this->is_whitelisted_network_option( $args[0] )
367
		) {
368
			return;
369
		}
370
371
		// don't sync private meta
372
		if ( preg_match( '/^(added|updated|deleted)_.*_meta$/', $current_filter ) && $args[2][0] === '_' ) {
373
			return;
374
		}
375
376
		$this->sync_queue->add( array(
377
			$current_filter,
378
			$args
379
		) );
380
	}
381
382
	function send_theme_info() {
383
		global $_wp_theme_features;
384
		do_action( 'jetpack_sync_current_theme_support', $_wp_theme_features );
385
	}
386
387
	function send_wp_version( $update, $meta_data ) {
388
		if ( 'update' === $meta_data['action'] && 'core' === $meta_data['type'] ) {
389
			global $wp_version;
390
			do_action( 'jetpack_sync_wp_version', $wp_version );
391
		}
392
	}
393
394
	function save_term_handler( $term_id, $tt_id, $taxonomy ) {
395
		$term_object = WP_Term::get_instance( $term_id, $taxonomy );
396
		do_action( 'jetapack_sync_save_term', $term_id, $tt_id, $taxonomy, $term_object );
397
	}
398
399
	function save_user_handler( $user_id, $old_user_data = null ) {
400
		$user = get_user_by( 'id', $user_id );
401
		unset( $user->data->user_pass );
402
		if ( $old_user_data !== null ) {
403
			unset( $old_user_data->data->user_pass );
404
			if ( serialize( $old_user_data->data ) === serialize( $user->data ) ) {
405
				return;
406
			}
407
		}
408
		do_action( 'jetapack_sync_save_user', $user_id, $user );
409
	}
410
411
	function post_ids_to_posts( $args ) {
412
		$all_posts_data = array();
413
414
		list( $post_ids ) = $args;
415
416
		$posts = get_posts( array(
417
			'include'          => $post_ids,
418
			'post_type'        => 'any',
419
			'post_status'      => 'any',
420
			'suppress_filters' => true ) );
421
422
		$meta_data = $this->get_post_metadata( $post_ids );
423
		foreach( $meta_data as $meta) {
424
			$mapped_meta_data[$meta->post_id][] = $meta;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$mapped_meta_data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $mapped_meta_data = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
425
		}
426
		unset( $meta_data );
427
428
		// also add post mete and terms
429
		foreach( $posts as $post ) {
430
			$all_posts_data[] = array(
431
				'post' => $post,
432
				'meta' => isset( $mapped_meta_data[ $post->ID ] ) ? $mapped_meta_data[ $post->ID ] : false,
433
			);
434
		}
435
436
		return array( $all_posts_data );
437
	}
438
439
	function group_metadata_by_post_id( $meta ) {
440
		return array( $meta->post_id => $meta );
441
	}
442
443
	function get_post_metadata( $post_ids ) {
444
		global $wpdb;
445
		return $wpdb->get_results( "SELECT * FROM $wpdb->postmeta WHERE post_id IN ( " . implode( ',', wp_parse_id_list( $post_ids ) ) . " )", OBJECT );
446
	}
447
448
	function comment_ids_to_comments( $args ) {
449
		list( $comment_ids ) = $args;
450
		$comments = get_comments( array(
451
			'include_unapproved' => true,
452
			'comment__in' => $comment_ids,
453
			) );
454
		return array( $comments );
455
	}
456
	
457
	function do_sync() {
458
		if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
459
			$this->schedule_sync( "+1 minute" );
460
461
			return false;
462
		}
463
464
		$this->maybe_sync_constants();
465
		$this->maybe_sync_callables();
466
467
		$buffer = $this->sync_queue->checkout();
468
469
		if ( ! $buffer ) {
470
			// buffer has no items
471
			return;
472
		}
473
474
		if ( is_wp_error( $buffer ) ) {
475
			error_log( "Error fetching buffer: " . $buffer->get_error_message() );
0 ignored issues
show
Bug introduced by
The method get_error_message() does not seem to exist on object<Jetpack_Sync_Queue_Buffer>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
476
477
			return;
478
		}
479
480
		$data = $this->codec->encode( $buffer->get_items() );
481
482
		/**
483
		 * Fires when data is ready to send to the server.
484
		 * Return false or WP_Error to abort the sync (e.g. if there's an error)
485
		 * The items will be automatically re-sent later
486
		 *
487
		 * @since 4.1
488
		 *
489
		 * @param array $data The action buffer
490
		 */
491
		$result = apply_filters( 'jetpack_sync_client_send_data', $data );
492
493
		if ( ! $result || is_wp_error( $result ) ) {
494
			$this->sync_queue->checkin( $buffer );
495
			// try again in 1 minute
496
			$this->schedule_sync( "+1 minute" );
497
		} else {
498
499
			// scan the sent data to see if a full sync started or finished
500
			if ( $this->buffer_includes_action( $buffer, 'jp_full_sync_start' ) ) {
501
				do_action( 'jp_full_sync_start_sent' );
502
				$this->full_sync_client->set_status_sending_started();
503
			}
504
505
			if ( $this->buffer_includes_action( $buffer, 'jp_full_sync_end' ) ) {
506
				do_action( 'jp_full_sync_end_sent' );
507
				$this->full_sync_client->set_status_sending_finished();
508
			}
509
510
			$this->sync_queue->close( $buffer );
511
			// check if there are any more events in the buffer
512
			// if so, schedule a cron job to happen soon
513
			if ( $this->sync_queue->has_any_items() ) {
514
				$this->schedule_sync( "+1 minute" );
515
			}
516
		}
517
	}
518
519
	private function buffer_includes_action( $buffer, $action_name ) {
520
		foreach( $buffer->get_items() as $item ) {
521
			if ( $item[0] === $action_name ) {
522
				return true;
523
			}
524
		}
525
		return false;
526
	}
527
528
	private function schedule_sync( $when ) {
529
		wp_schedule_single_event( strtotime( $when ), 'jetpack_sync_actions' );
530
	}
531
532
	function force_sync_constants() {
533
		delete_option( self::$constants_checksum_option_name );
534
		$this->maybe_sync_constants();
535
	}
536
537 View Code Duplication
	private function maybe_sync_constants() {
538
		$constants = $this->get_all_constants();
539
		if ( empty( $constants ) ) {
540
			return;
541
		}
542
		$constants_check_sum = $this->get_check_sum( $constants );
543
		if ( $constants_check_sum !== (int) get_option( self::$constants_checksum_option_name ) ) {
544
			do_action( 'jetpack_sync_current_constants', $constants );
545
			update_option( self::$constants_checksum_option_name, $constants_check_sum );
546
		}
547
	}
548
549
	private function get_all_constants() {
550
		return array_combine(
551
			$this->constants_whitelist,
552
			array_map( array( $this, 'get_constant' ), $this->constants_whitelist )
553
		);
554
	}
555
556
	private function get_constant( $constant ) {
557
		if ( defined( $constant ) ) {
558
			return constant( $constant );
559
		}
560
561
		return null;
562
	}
563
564
	public function force_sync_callables() {
565
		delete_option( self::$functions_checksum_option_name );
566
		$this->maybe_sync_callables();
567
	}
568
569 View Code Duplication
	private function maybe_sync_callables() {
570
		$callables = $this->get_all_callables();
571
		if ( empty( $callables ) ) {
572
			return;
573
		}
574
		$callables_check_sum = $this->get_check_sum( $callables );
575
		if ( $callables_check_sum !== (int) get_option( self::$functions_checksum_option_name ) ) {
576
			do_action( 'jetpack_sync_current_callables', $callables );
577
			update_option( self::$functions_checksum_option_name, $callables_check_sum );
578
		}
579
	}
580
581
	private function get_all_callables() {
582
		return array_combine(
583
			array_keys( $this->callable_whitelist ),
584
			array_map( array( $this, 'get_callable' ), array_values( $this->callable_whitelist ) )
585
		);
586
	}
587
588
	private function get_callable( $callable ) {
589
		return call_user_func( $callable );
590
	}
591
592
	private function get_check_sum( $values ) {
593
		return crc32( serialize( $values ) );
594
	}
595
596
	function jetpack_sync_core_icon() {
597
		if ( function_exists( 'get_site_icon_url' ) ) {
598
			$url = get_site_icon_url();
599
		} else {
600
			return;
601
		}
602
603
		require_once( JETPACK__PLUGIN_DIR . 'modules/site-icon/site-icon-functions.php' );
604
		// If there's a core icon, maybe update the option.  If not, fall back to Jetpack's.
605
		if ( ! empty( $url ) && $url !== jetpack_site_icon_url() ) {
606
			// This is the option that is synced with dotcom
607
			Jetpack_Options::update_option( 'site_icon_url', $url );
608
		} else if ( empty( $url ) && did_action( 'delete_option_site_icon' ) ) {
609
			Jetpack_Options::delete_option( 'site_icon_url' );
610
		}
611
	}
612
613
	function get_sync_queue() {
614
		return $this->sync_queue;
615
	}
616
617
	function reset_sync_queue() {
618
		$this->sync_queue->reset();
619
	}
620
621
	function set_defaults() {
622
		$this->sync_queue = new Jetpack_Sync_Queue( 'sync', self::$default_send_buffer_size );
623
		$this->set_full_sync_client( new Jetpack_Sync_Full( $this->sync_queue ) );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Sync_Full::__construct() has too many arguments starting with $this->sync_queue.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
624
		$this->codec                     = new Jetpack_Sync_Deflate_Codec();
625
		$this->constants_whitelist       = self::$default_constants_whitelist;
626
		$this->options_whitelist         = self::$default_options_whitelist;
627
		$this->network_options_whitelist = self::$default_network_options_whitelist;
628
		$this->taxonomy_whitelist        = self::$default_taxonomy_whitelist;
629
		$this->is_multisite              = is_multisite();
630
631
		if ( $this->is_multisite ) {
632
			$this->callable_whitelist = array_merge( self::$default_callable_whitelist, self::$default_multisite_callable_whitelist );
633
		} else {
634
			$this->callable_whitelist = self::$default_callable_whitelist;
635
		}
636
	}
637
638
	function reset_data() {
639
		delete_option( self::$constants_checksum_option_name );
640
		$this->reset_sync_queue();
641
	}
642
}