Completed
Push — add/sync-rest-2 ( 59fd01...a434af )
by
unknown
66:44 queued 57:55
created

Jetpack_Sync_Client::group_metadata_by_post_id()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 3
rs 10
c 1
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
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_option', $handler, 10, 2 );
234
		
235
		add_action( 'jetpack_full_sync_posts', $handler ); // also sends post meta and terms 
236
		add_action( 'jetpack_full_sync_comments', $handler ); // also send comments meta
237
238
		add_filter( 'jetpack_full_sync_posts_data', array( $this, 'post_ids_to_posts' ) ); // converts post ids to all post data
239
		add_filter( 'jetpack_full_sync_comments_data', array( $this, 'comment_ids_to_comments' ) ); // converts post ids to all post data
240
241
		/**
242
		 * Other hooks - fire synthetic hooks for all the properties we need to sync,
243
		 * e.g. when a theme changes
244
		 */
245
246
		// themes
247
		add_action( 'set_site_transient_update_plugins', $handler, 10, 1 );
248
		add_action( 'set_site_transient_update_themes', $handler, 10, 1 );
249
		add_action( 'set_site_transient_update_core', $handler, 10, 1 );
250
251
		// multi site network options
252
		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...
253
			add_action( 'add_site_option', $handler, 10, 2 );
254
			add_action( 'update_site_option', $handler, 10, 3 );
255
			add_action( 'delete_site_option', $handler, 10, 1 );
256
		}
257
258
		/**
259
		 * Sync all pending actions with server
260
		 */
261
		add_action( 'jetpack_sync_actions', array( $this, 'do_sync' ) );
262
263
		// terms
264
		add_action( 'created_term', array( $this, 'save_term_handler' ), 10, 3 );
265
		add_action( 'edited_term', array( $this, 'save_term_handler' ), 10, 3 );
266
		add_action( 'jetapack_sync_save_term', $handler, 10, 4 );
267
		add_action( 'delete_term', $handler, 10, 5 );
268
269
		// users
270
		add_action( 'user_register', array( $this, 'save_user_handler' ) );
271
		add_action( 'profile_update', array( $this, 'save_user_handler' ), 10, 2 );
272
		add_action( 'jetapack_sync_save_user', $handler, 10, 2 );
273
		add_action( 'deleted_user', $handler, 10 ,2 );
274
	}
275
276
	// 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...
277
	function set_options_whitelist( $options ) {
278
		$this->options_whitelist = $options;
279
	}
280
281
	function set_constants_whitelist( $constants ) {
282
		$this->constants_whitelist = $constants;
283
	}
284
285
	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...
286
		return $this->callable_whitelist;
287
	}
288
289
	function set_callable_whitelist( $functions ) {
290
		$this->callable_whitelist = $functions;
291
	}
292
293
	function set_network_options_whitelist( $options ) {
294
		$this->network_options_whitelist = $options;
295
	}
296
297
	function set_send_buffer_size( $size ) {
298
		$this->sync_queue->set_checkout_size( $size );
299
	}
300
301
	function set_taxonomy_whitelist( $taxonomies ) {
302
		$this->taxonomy_whitelist = $taxonomies;
303
	}
304
305
	function is_whitelisted_option( $option ) {
306
		foreach ( $this->options_whitelist as $whitelisted_option ) {
307
			if ( $whitelisted_option[0] === '/' && preg_match( $whitelisted_option, $option ) ) {
308
				return true;
309
			} elseif ( $whitelisted_option === $option ) {
310
				return true;
311
			}
312
		}
313
314
		return false;
315
	}
316
317
	function is_whitelisted_network_option( $option ) {
318
		return $this->is_multisite && in_array( $option, $this->network_options_whitelist );
319
	}
320
321
	function set_codec( iJetpack_Sync_Codec $codec ) {
322
		$this->codec = $codec;
323
	}
324
325
	function set_full_sync_client( $full_sync_client ) {
326
		if ( $this->full_sync_client ) {
327
			remove_action( 'jetpack_sync_full', array( $this->full_sync_client, 'start' ) );
328
		}
329
330
		$this->full_sync_client = $full_sync_client;
331
332
		/**
333
		 * Sync all objects in the database with the server
334
		 */
335
		add_action( 'jetpack_sync_full', array( $this->full_sync_client, 'start' ) );
336
	}
337
338
	function action_handler() {
339
		// 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...
340
		// wherever we initialize the action listeners or we're just wasting cycles
341
		if ( Jetpack::is_development_mode() || Jetpack::is_staging_site() ) {
342
			return false;
343
		}
344
345
		$current_filter = current_filter();
346
		$args           = func_get_args();
347
348
		if ( $current_filter === 'wp_insert_post' && $args[1]->post_type === 'revision' ) {
349
			return;
350
		}
351
352
		if ( in_array( $current_filter, array( 'deleted_option', 'added_option', 'updated_option' ) )
353
		     &&
354
		     ! $this->is_whitelisted_option( $args[0] )
355
		) {
356
			return;
357
		}
358
359
		if ( in_array( $current_filter, array( 'delete_site_option', 'add_site_option', 'update_site_option' ) )
360
		     &&
361
		     ! $this->is_whitelisted_network_option( $args[0] )
362
		) {
363
			return;
364
		}
365
366
		$this->sync_queue->add( array(
367
			$current_filter,
368
			$args
369
		) );
370
	}
371
372
	function send_theme_info() {
373
		global $_wp_theme_features;
374
		do_action( 'jetpack_sync_current_theme_support', $_wp_theme_features );
375
	}
376
377
	function send_wp_version( $update, $meta_data ) {
378
		if ( 'update' === $meta_data['action'] && 'core' === $meta_data['type'] ) {
379
			global $wp_version;
380
			do_action( 'jetpack_sync_wp_version', $wp_version );
381
		}
382
	}
383
384
	function save_term_handler( $term_id, $tt_id, $taxonomy ) {
385
		$term_object = WP_Term::get_instance( $term_id, $taxonomy );
386
		do_action( 'jetapack_sync_save_term', $term_id, $tt_id, $taxonomy, $term_object );
387
	}
388
389
	function save_user_handler( $user_id, $old_user_data = null ) {
390
		$user = get_user_by( 'id', $user_id );
391
		unset( $user->data->user_pass );
392
		if ( $old_user_data !== null ) {
393
			unset( $old_user_data->data->user_pass );
394
			if ( json_encode( $old_user_data->data ) === json_encode( $user->data ) ) {
395
				return;
396
			}
397
		}
398
		do_action( 'jetapack_sync_save_user', $user_id, $user );
399
	}
400
401
	function post_ids_to_posts( $args ) {
402
		$all_posts_data = array();
403
404
		list( $post_ids ) = $args;
405
406
		$posts = get_posts( array(
407
			'include'          => $post_ids,
408
			'post_type'        => 'any',
409
			'post_status'      => 'any',
410
			'suppress_filters' => true ) );
411
412
		$meta_data = $this->get_post_metadata( $post_ids );
413
		foreach( $meta_data as $meta) {
414
			$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...
415
		}
416
		unset( $meta_data );
417
418
		// also add post mete and terms
419
		foreach( $posts as $post ) {
420
			$all_posts_data[] = array(
421
				'post' => $post,
422
				'meta' => isset( $mapped_meta_data[ $post->ID ] ) ? $mapped_meta_data[ $post->ID ] : false,
423
			);
424
		}
425
426
		return array( $all_posts_data );
427
	}
428
429
	function group_metadata_by_post_id( $meta ) {
430
		return array( $meta->post_id => $meta );
431
	}
432
433
	function get_post_metadata( $post_ids ) {
434
		global $wpdb;
435
		return $wpdb->get_results( "SELECT * FROM $wpdb->postmeta WHERE post_id IN ( " . implode( ',', wp_parse_id_list( $post_ids ) ) . " )", OBJECT );
436
	}
437
438
	function comment_ids_to_comments( $args ) {
439
		list( $comment_ids ) = $args;
440
		$comments = get_comments( array(
441
			'include_unapproved' => true,
442
			'comment__in' => $comment_ids,
443
			) );
444
		return array( $comments );
445
	}
446
	
447
	function do_sync() {
448
		if ( defined( 'WP_IMPORTING' ) && WP_IMPORTING ) {
449
			$this->schedule_sync( "+1 minute" );
450
451
			return false;
452
		}
453
454
		$this->maybe_sync_constants();
455
		$this->maybe_sync_callables();
456
457
		$buffer = $this->sync_queue->checkout();
458
459
		if ( ! $buffer ) {
460
			// buffer has no items
461
			return;
462
		}
463
464
		if ( is_wp_error( $buffer ) ) {
465
			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...
466
467
			return;
468
		}
469
470
		$data = $this->codec->encode( $buffer->get_items() );
471
472
		/**
473
		 * Fires when data is ready to send to the server.
474
		 * Return false or WP_Error to abort the sync (e.g. if there's an error)
475
		 * The items will be automatically re-sent later
476
		 *
477
		 * @since 4.1
478
		 *
479
		 * @param array $data The action buffer
480
		 */
481
		$result = apply_filters( 'jetpack_sync_client_send_data', $data );
482
483
		if ( ! $result || is_wp_error( $result ) ) {
484
			$this->sync_queue->checkin( $buffer );
485
			// try again in 1 minute
486
			$this->schedule_sync( "+1 minute" );
487
		} else {
488
			$this->sync_queue->close( $buffer );
489
			// check if there are any more events in the buffer
490
			// if so, schedule a cron job to happen soon
491
			if ( $this->sync_queue->has_any_items() ) {
492
				$this->schedule_sync( "+1 minute" );
493
			}
494
		}
495
	}
496
497
498
	private function schedule_sync( $when ) {
499
		wp_schedule_single_event( strtotime( $when ), 'jetpack_sync_actions' );
500
	}
501
502
	function force_sync_constants() {
503
		delete_option( self::$constants_checksum_option_name );
504
		$this->maybe_sync_constants();
505
	}
506
507 View Code Duplication
	private function maybe_sync_constants() {
508
		$constants = $this->get_all_constants();
509
		if ( empty( $constants ) ) {
510
			return;
511
		}
512
		$constants_check_sum = $this->get_check_sum( $constants );
513
		if ( $constants_check_sum !== (int) get_option( self::$constants_checksum_option_name ) ) {
514
			do_action( 'jetpack_sync_current_constants', $constants );
515
			update_option( self::$constants_checksum_option_name, $constants_check_sum );
516
		}
517
	}
518
519
	private function get_all_constants() {
520
		return array_combine(
521
			$this->constants_whitelist,
522
			array_map( array( $this, 'get_constant' ), $this->constants_whitelist )
523
		);
524
	}
525
526
	private function get_constant( $constant ) {
527
		if ( defined( $constant ) ) {
528
			return constant( $constant );
529
		}
530
531
		return null;
532
	}
533
534
	public function force_sync_callables() {
535
		delete_option( self::$functions_checksum_option_name );
536
		$this->maybe_sync_callables();
537
	}
538
539 View Code Duplication
	private function maybe_sync_callables() {
540
		$callables = $this->get_all_callables();
541
		if ( empty( $callables ) ) {
542
			return;
543
		}
544
		$callables_check_sum = $this->get_check_sum( $callables );
545
		if ( $callables_check_sum !== (int) get_option( self::$functions_checksum_option_name ) ) {
546
			do_action( 'jetpack_sync_current_callables', $callables );
547
			update_option( self::$functions_checksum_option_name, $callables_check_sum );
548
		}
549
	}
550
551
	private function get_all_callables() {
552
		return array_combine(
553
			array_keys( $this->callable_whitelist ),
554
			array_map( array( $this, 'get_callable' ), array_values( $this->callable_whitelist ) )
555
		);
556
	}
557
558
	private function get_callable( $callable ) {
559
		return call_user_func( $callable );
560
	}
561
562
	private function get_check_sum( $values ) {
563
		return crc32( serialize( $values ) );
564
	}
565
566
	function jetpack_sync_core_icon() {
567
		error_log("syncing core icon");
568
		if ( function_exists( 'get_site_icon_url' ) ) {
569
			$url = get_site_icon_url();
570
		} else {
571
			return;
572
		}
573
574
		require_once( JETPACK__PLUGIN_DIR . 'modules/site-icon/site-icon-functions.php' );
575
		// If there's a core icon, maybe update the option.  If not, fall back to Jetpack's.
576
		if ( ! empty( $url ) && $url !== jetpack_site_icon_url() ) {
577
			// This is the option that is synced with dotcom
578
			Jetpack_Options::update_option( 'site_icon_url', $url );
579
		} else if ( empty( $url ) && did_action( 'delete_option_site_icon' ) ) {
580
			Jetpack_Options::delete_option( 'site_icon_url' );
581
		}
582
	}
583
584
	function get_sync_queue() {
585
		return $this->sync_queue;
586
	}
587
588
	function reset_sync_queue() {
589
		$this->sync_queue->reset();
590
	}
591
592
	function set_defaults() {
593
		$this->sync_queue = new Jetpack_Sync_Queue( 'sync', self::$default_send_buffer_size );
594
		$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...
595
		$this->codec                     = new Jetpack_Sync_Deflate_Codec();
596
		$this->constants_whitelist       = self::$default_constants_whitelist;
597
		$this->options_whitelist         = self::$default_options_whitelist;
598
		$this->network_options_whitelist = self::$default_network_options_whitelist;
599
		$this->taxonomy_whitelist        = self::$default_taxonomy_whitelist;
600
		$this->is_multisite              = is_multisite();
601
602
		if ( $this->is_multisite ) {
603
			$this->callable_whitelist = array_merge( self::$default_callable_whitelist, self::$default_multisite_callable_whitelist );
604
		} else {
605
			$this->callable_whitelist = self::$default_callable_whitelist;
606
		}
607
	}
608
609
	function reset_data() {
610
		delete_option( self::$constants_checksum_option_name );
611
		$this->reset_sync_queue();
612
	}
613
}