Completed
Push — add/jetpack-75-release-changel... ( be7ef8...25f28e )
by Jeremy
367:57 queued 358:58
created

Themes   F

Complexity

Total Complexity 102

Size/Duplication

Total Lines 610
Duplicated Lines 3.77 %

Coupling/Cohesion

Components 2
Dependencies 2

Importance

Changes 0
Metric Value
dl 23
loc 610
rs 1.99
c 0
b 0
f 0
wmc 102
lcom 2
cbo 2

25 Methods

Rating   Name   Duplication   Size   Complexity  
A name() 0 3 1
A init_listeners() 0 26 1
B sync_widget_edit() 0 26 6
A sync_network_allowed_themes_change() 0 37 3
A get_theme_details_for_slugs() 9 13 2
B detect_theme_edit() 0 37 6
F theme_edit_ajax() 0 105 21
A detect_theme_deletion() 0 26 2
C check_upgrader() 14 70 13
A init_full_sync_listeners() 0 3 1
A sync_theme_support() 0 14 1
A enqueue_full_sync_actions() 0 13 1
A estimate_full_sync_actions() 0 3 1
A init_before_send() 0 3 1
A get_full_sync_actions() 0 3 1
A expand_theme_data() 0 3 1
A get_widget_name() 0 4 2
A get_sidebar_name() 0 4 2
A sync_add_widgets_to_sidebar() 0 30 4
A sync_remove_widgets_from_sidebar() 0 32 5
A sync_widgets_reordered() 0 24 4
C sync_sidebar_widgets_actions() 0 62 14
A get_theme_support_info() 0 24 4
A get_delete_theme_call() 0 11 4
A is_theme_switch() 0 3 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 Themes 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 Themes, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Automattic\Jetpack\Sync\Modules;
4
5
class Themes extends \Jetpack_Sync_Module {
6
	function name() {
7
		return 'themes';
8
	}
9
10
	public function init_listeners( $callable ) {
11
		add_action( 'switch_theme', array( $this, 'sync_theme_support' ), 10, 3 );
12
		add_action( 'jetpack_sync_current_theme_support', $callable, 10, 2 );
13
		add_action( 'upgrader_process_complete', array( $this, 'check_upgrader' ), 10, 2 );
14
		add_action( 'jetpack_installed_theme', $callable, 10, 2 );
15
		add_action( 'jetpack_updated_themes', $callable, 10, 2 );
16
		add_action( 'delete_site_transient_update_themes', array( $this, 'detect_theme_deletion' ) );
17
		add_action( 'jetpack_deleted_theme', $callable, 10, 2 );
18
		add_filter( 'wp_redirect', array( $this, 'detect_theme_edit' ) );
19
		add_action( 'jetpack_edited_theme', $callable, 10, 2 );
20
		add_action( 'wp_ajax_edit-theme-plugin-file', array( $this, 'theme_edit_ajax' ), 0 );
21
		add_action( 'update_site_option_allowedthemes', array( $this, 'sync_network_allowed_themes_change' ), 10, 4 );
22
		add_action( 'jetpack_network_disabled_themes', $callable, 10, 2 );
23
		add_action( 'jetpack_network_enabled_themes', $callable, 10, 2 );
24
25
		// Sidebar updates.
26
		add_action( 'update_option_sidebars_widgets', array( $this, 'sync_sidebar_widgets_actions' ), 10, 2 );
27
28
		add_action( 'jetpack_widget_added', $callable, 10, 4 );
29
		add_action( 'jetpack_widget_removed', $callable, 10, 4 );
30
		add_action( 'jetpack_widget_moved_to_inactive', $callable, 10, 2 );
31
		add_action( 'jetpack_cleared_inactive_widgets', $callable );
32
		add_action( 'jetpack_widget_reordered', $callable, 10, 2 );
33
		add_filter( 'widget_update_callback', array( $this, 'sync_widget_edit' ), 10, 4 );
34
		add_action( 'jetpack_widget_edited', $callable );
35
	}
36
37
	public function sync_widget_edit( $instance, $new_instance, $old_instance, $widget_object ) {
38
		if ( empty( $old_instance ) ) {
39
			return $instance;
40
		}
41
42
		// Don't trigger sync action if this is an ajax request, because Customizer makes them during preview before saving changes
43
		if ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_POST['customized'] ) ) {
44
			return $instance;
45
		}
46
47
		$widget = array(
48
			'name'  => $widget_object->name,
49
			'id'    => $widget_object->id,
50
			'title' => isset( $new_instance['title'] ) ? $new_instance['title'] : '',
51
		);
52
		/**
53
		 * Trigger action to alert $callable sync listener that a widget was edited
54
		 *
55
		 * @since 5.0.0
56
		 *
57
		 * @param string $widget_name , Name of edited widget
58
		 */
59
		do_action( 'jetpack_widget_edited', $widget );
60
61
		return $instance;
62
	}
63
64
	public function sync_network_allowed_themes_change( $option, $value, $old_value, $network_id ) {
65
		$all_enabled_theme_slugs = array_keys( $value );
66
67
		if ( count( $old_value ) > count( $value ) ) {
68
69
			// Suppress jetpack_network_disabled_themes sync action when theme is deleted
70
			$delete_theme_call = $this->get_delete_theme_call();
71
			if ( ! empty( $delete_theme_call ) ) {
72
				return;
73
			}
74
75
			$newly_disabled_theme_names = array_keys( array_diff_key( $old_value, $value ) );
76
			$newly_disabled_themes      = $this->get_theme_details_for_slugs( $newly_disabled_theme_names );
77
			/**
78
			 * Trigger action to alert $callable sync listener that network themes were disabled
79
			 *
80
			 * @since 5.0.0
81
			 *
82
			 * @param mixed $newly_disabled_themes, Array of info about network disabled themes
83
			 * @param mixed $all_enabled_theme_slugs, Array of slugs of all enabled themes
84
			 */
85
			do_action( 'jetpack_network_disabled_themes', $newly_disabled_themes, $all_enabled_theme_slugs );
86
			return;
87
		}
88
89
		$newly_enabled_theme_names = array_keys( array_diff_key( $value, $old_value ) );
90
		$newly_enabled_themes      = $this->get_theme_details_for_slugs( $newly_enabled_theme_names );
91
		/**
92
		 * Trigger action to alert $callable sync listener that network themes were enabled
93
		 *
94
		 * @since 5.0.0
95
		 *
96
		 * @param mixed $newly_enabled_themes , Array of info about network enabled themes
97
		 * @param mixed $all_enabled_theme_slugs, Array of slugs of all enabled themes
98
		 */
99
		do_action( 'jetpack_network_enabled_themes', $newly_enabled_themes, $all_enabled_theme_slugs );
100
	}
101
102
	private function get_theme_details_for_slugs( $theme_slugs ) {
103
		$theme_data = array();
104 View Code Duplication
		foreach ( $theme_slugs as $slug ) {
105
			$theme               = wp_get_theme( $slug );
106
			$theme_data[ $slug ] = array(
107
				'name'    => $theme->get( 'Name' ),
108
				'version' => $theme->get( 'Version' ),
109
				'uri'     => $theme->get( 'ThemeURI' ),
110
				'slug'    => $slug,
111
			);
112
		}
113
		return $theme_data;
114
	}
115
116
	public function detect_theme_edit( $redirect_url ) {
117
		$url              = wp_parse_url( admin_url( $redirect_url ) );
118
		$theme_editor_url = wp_parse_url( admin_url( 'theme-editor.php' ) );
119
120
		if ( $theme_editor_url['path'] !== $url['path'] ) {
121
			return $redirect_url;
122
		}
123
124
		$query_params = array();
125
		wp_parse_str( $url['query'], $query_params );
126
		if (
127
			! isset( $_POST['newcontent'] ) ||
128
			! isset( $query_params['file'] ) ||
129
			! isset( $query_params['theme'] ) ||
130
			! isset( $query_params['updated'] )
131
		) {
132
			return $redirect_url;
133
		}
134
		$theme      = wp_get_theme( $query_params['theme'] );
135
		$theme_data = array(
136
			'name'    => $theme->get( 'Name' ),
137
			'version' => $theme->get( 'Version' ),
138
			'uri'     => $theme->get( 'ThemeURI' ),
139
		);
140
141
		/**
142
		 * Trigger action to alert $callable sync listener that a theme was edited
143
		 *
144
		 * @since 5.0.0
145
		 *
146
		 * @param string $query_params['theme'], Slug of edited theme
147
		 * @param string $theme_data, Information about edited them
148
		 */
149
		do_action( 'jetpack_edited_theme', $query_params['theme'], $theme_data );
150
151
		return $redirect_url;
152
	}
153
154
	public function theme_edit_ajax() {
155
		$args = wp_unslash( $_POST );
156
157
		if ( empty( $args['theme'] ) ) {
158
			return;
159
		}
160
161
		if ( empty( $args['file'] ) ) {
162
			return;
163
		}
164
		$file = $args['file'];
165
		if ( 0 !== validate_file( $file ) ) {
166
			return;
167
		}
168
169
		if ( ! isset( $args['newcontent'] ) ) {
170
			return;
171
		}
172
173
		if ( ! isset( $args['nonce'] ) ) {
174
			return;
175
		}
176
177
		$stylesheet = $args['theme'];
178
		if ( 0 !== validate_file( $stylesheet ) ) {
179
			return;
180
		}
181
182
		if ( ! current_user_can( 'edit_themes' ) ) {
183
			return;
184
		}
185
186
		$theme = wp_get_theme( $stylesheet );
187
		if ( ! $theme->exists() ) {
188
			return;
189
		}
190
191
		$real_file = $theme->get_stylesheet_directory() . '/' . $file;
192
		if ( ! wp_verify_nonce( $args['nonce'], 'edit-theme_' . $real_file . $stylesheet ) ) {
193
			return;
194
		}
195
196
		if ( $theme->errors() && 'theme_no_stylesheet' === $theme->errors()->get_error_code() ) {
197
			return;
198
		}
199
200
		$editable_extensions = wp_get_theme_file_editable_extensions( $theme );
201
202
		$allowed_files = array();
203
		foreach ( $editable_extensions as $type ) {
204
			switch ( $type ) {
205
				case 'php':
206
					$allowed_files = array_merge( $allowed_files, $theme->get_files( 'php', -1 ) );
207
					break;
208
				case 'css':
209
					$style_files                = $theme->get_files( 'css', -1 );
210
					$allowed_files['style.css'] = $style_files['style.css'];
211
					$allowed_files              = array_merge( $allowed_files, $style_files );
212
					break;
213
				default:
214
					$allowed_files = array_merge( $allowed_files, $theme->get_files( $type, -1 ) );
215
					break;
216
			}
217
		}
218
219
		if ( 0 !== validate_file( $real_file, $allowed_files ) ) {
220
			return;
221
		}
222
223
		// Ensure file is real.
224
		if ( ! is_file( $real_file ) ) {
225
			return;
226
		}
227
228
		// Ensure file extension is allowed.
229
		$extension = null;
0 ignored issues
show
Unused Code introduced by
$extension is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
230
		if ( preg_match( '/\.([^.]+)$/', $real_file, $matches ) ) {
231
			$extension = strtolower( $matches[1] );
232
			if ( ! in_array( $extension, $editable_extensions, true ) ) {
233
				return;
234
			}
235
		}
236
237
		if ( ! is_writeable( $real_file ) ) {
238
			return;
239
		}
240
241
		$file_pointer = fopen( $real_file, 'w+' );
242
		if ( false === $file_pointer ) {
243
			return;
244
		}
245
		fclose( $file_pointer );
246
247
		$theme_data = array(
248
			'name'    => $theme->get( 'Name' ),
249
			'version' => $theme->get( 'Version' ),
250
			'uri'     => $theme->get( 'ThemeURI' ),
251
		);
252
253
		/**
254
		 * This action is documented already in this file
255
		 */
256
		do_action( 'jetpack_edited_theme', $stylesheet, $theme_data );
257
258
	}
259
260
	public function detect_theme_deletion() {
261
		$delete_theme_call = $this->get_delete_theme_call();
262
		if ( empty( $delete_theme_call ) ) {
263
			return;
264
		}
265
266
		$slug       = $delete_theme_call['args'][0];
267
		$theme      = wp_get_theme( $slug );
268
		$theme_data = array(
269
			'name'    => $theme->get( 'Name' ),
270
			'version' => $theme->get( 'Version' ),
271
			'uri'     => $theme->get( 'ThemeURI' ),
272
			'slug'    => $slug,
273
		);
274
275
		/**
276
		 * Signals to the sync listener that a theme was deleted and a sync action
277
		 * reflecting the deletion and theme slug should be sent
278
		 *
279
		 * @since 5.0.0
280
		 *
281
		 * @param string $slug Theme slug
282
		 * @param array $theme_data Theme info Since 5.3
283
		 */
284
		do_action( 'jetpack_deleted_theme', $slug, $theme_data );
285
	}
286
287
	public function check_upgrader( $upgrader, $details ) {
288
		if ( ! isset( $details['type'] ) ||
289
			 'theme' !== $details['type'] ||
290
			 is_wp_error( $upgrader->skin->result ) ||
291
			 ! method_exists( $upgrader, 'theme_info' )
292
		) {
293
			return;
294
		}
295
296
		if ( 'install' === $details['action'] ) {
297
			$theme = $upgrader->theme_info();
298
			if ( ! $theme instanceof \WP_Theme ) {
0 ignored issues
show
Bug introduced by
The class WP_Theme does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
299
				return;
300
			}
301
			$theme_info = array(
302
				'name'    => $theme->get( 'Name' ),
303
				'version' => $theme->get( 'Version' ),
304
				'uri'     => $theme->get( 'ThemeURI' ),
305
			);
306
307
			/**
308
			 * Signals to the sync listener that a theme was installed and a sync action
309
			 * reflecting the installation and the theme info should be sent
310
			 *
311
			 * @since 4.9.0
312
			 *
313
			 * @param string $theme->theme_root Text domain of the theme
314
			 * @param mixed $theme_info Array of abbreviated theme info
315
			 */
316
			do_action( 'jetpack_installed_theme', $theme->stylesheet, $theme_info );
317
		}
318
319
		if ( 'update' === $details['action'] ) {
320
			$themes = array();
321
322
			if ( empty( $details['themes'] ) && isset( $details['theme'] ) ) {
323
				$details['themes'] = array( $details['theme'] );
324
			}
325
326 View Code Duplication
			foreach ( $details['themes'] as $theme_slug ) {
327
				$theme = wp_get_theme( $theme_slug );
328
329
				if ( ! $theme instanceof \WP_Theme ) {
0 ignored issues
show
Bug introduced by
The class WP_Theme does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
330
					continue;
331
				}
332
333
				$themes[ $theme_slug ] = array(
334
					'name'       => $theme->get( 'Name' ),
335
					'version'    => $theme->get( 'Version' ),
336
					'uri'        => $theme->get( 'ThemeURI' ),
337
					'stylesheet' => $theme->stylesheet,
338
				);
339
			}
340
341
			if ( empty( $themes ) ) {
342
				return;
343
			}
344
345
			/**
346
			 * Signals to the sync listener that one or more themes was updated and a sync action
347
			 * reflecting the update and the theme info should be sent
348
			 *
349
			 * @since 6.2.0
350
			 *
351
			 * @param mixed $themes Array of abbreviated theme info
352
			 */
353
			do_action( 'jetpack_updated_themes', $themes );
354
		}
355
356
	}
357
358
	public function init_full_sync_listeners( $callable ) {
359
		add_action( 'jetpack_full_sync_theme_data', $callable );
360
	}
361
362
	public function sync_theme_support( $new_name, $new_theme = null, $old_theme = null ) {
363
		$previous_theme = $this->get_theme_support_info( $old_theme );
364
365
		/**
366
		 * Fires when the client needs to sync theme support info
367
		 * Only sends theme support attributes whitelisted in Jetpack_Sync_Defaults::$default_theme_support_whitelist
368
		 *
369
		 * @since 4.2.0
370
		 *
371
		 * @param array the theme support array
372
		 * @param array the previous theme since Jetpack 6.5.0
373
		 */
374
		do_action( 'jetpack_sync_current_theme_support', $this->get_theme_support_info(), $previous_theme );
375
	}
376
377
	public function enqueue_full_sync_actions( $config, $max_items_to_enqueue, $state ) {
378
		/**
379
		 * Tells the client to sync all theme data to the server
380
		 *
381
		 * @since 4.2.0
382
		 *
383
		 * @param boolean Whether to expand theme data (should always be true)
384
		 */
385
		do_action( 'jetpack_full_sync_theme_data', true );
386
387
		// The number of actions enqueued, and next module state (true == done)
388
		return array( 1, true );
389
	}
390
391
	public function estimate_full_sync_actions( $config ) {
392
		return 1;
393
	}
394
395
	public function init_before_send() {
396
		add_filter( 'jetpack_sync_before_send_jetpack_full_sync_theme_data', array( $this, 'expand_theme_data' ) );
397
	}
398
399
	function get_full_sync_actions() {
400
		return array( 'jetpack_full_sync_theme_data' );
401
	}
402
403
	function expand_theme_data() {
404
		return array( $this->get_theme_support_info() );
405
	}
406
407
	function get_widget_name( $widget_id ) {
408
		global $wp_registered_widgets;
409
		return ( isset( $wp_registered_widgets[ $widget_id ] ) ? $wp_registered_widgets[ $widget_id ]['name'] : null );
410
	}
411
412
	function get_sidebar_name( $sidebar_id ) {
413
		global $wp_registered_sidebars;
414
		return ( isset( $wp_registered_sidebars[ $sidebar_id ] ) ? $wp_registered_sidebars[ $sidebar_id ]['name'] : null );
415
	}
416
417
	function sync_add_widgets_to_sidebar( $new_widgets, $old_widgets, $sidebar ) {
418
		$added_widgets = array_diff( $new_widgets, $old_widgets );
419
		if ( empty( $added_widgets ) ) {
420
			return array();
421
		}
422
		$moved_to_sidebar = array();
423
		$sidebar_name     = $this->get_sidebar_name( $sidebar );
424
425
		// Don't sync jetpack_widget_added if theme was switched
426
		if ( $this->is_theme_switch() ) {
427
			return array();
428
		}
429
430
		foreach ( $added_widgets as $added_widget ) {
431
			$moved_to_sidebar[] = $added_widget;
432
			$added_widget_name  = $this->get_widget_name( $added_widget );
433
			/**
434
			 * Helps Sync log that a widget got added
435
			 *
436
			 * @since 4.9.0
437
			 *
438
			 * @param string $sidebar, Sidebar id got changed
439
			 * @param string $added_widget, Widget id got added
440
			 * @param string $sidebar_name, Sidebar id got changed Since 5.0.0
441
			 * @param string $added_widget_name, Widget id got added Since 5.0.0
442
			 */
443
			do_action( 'jetpack_widget_added', $sidebar, $added_widget, $sidebar_name, $added_widget_name );
444
		}
445
		return $moved_to_sidebar;
446
	}
447
448
	function sync_remove_widgets_from_sidebar( $new_widgets, $old_widgets, $sidebar, $inactive_widgets ) {
449
		$removed_widgets = array_diff( $old_widgets, $new_widgets );
450
451
		if ( empty( $removed_widgets ) ) {
452
			return array();
453
		}
454
455
		$moved_to_inactive = array();
456
		$sidebar_name      = $this->get_sidebar_name( $sidebar );
457
458
		foreach ( $removed_widgets as $removed_widget ) {
459
			// Lets check if we didn't move the widget to in_active_widgets
460
			if ( isset( $inactive_widgets ) && ! in_array( $removed_widget, $inactive_widgets ) ) {
461
				$removed_widget_name = $this->get_widget_name( $removed_widget );
462
				/**
463
				 * Helps Sync log that a widgte got removed
464
				 *
465
				 * @since 4.9.0
466
				 *
467
				 * @param string $sidebar, Sidebar id got changed
468
				 * @param string $removed_widget, Widget id got removed
469
				 * @param string $sidebar_name, Name of the sidebar that changed  Since 5.0.0
470
				 * @param string $removed_widget_name, Name of the widget that got removed Since 5.0.0
471
				 */
472
				do_action( 'jetpack_widget_removed', $sidebar, $removed_widget, $sidebar_name, $removed_widget_name );
473
			} else {
474
				$moved_to_inactive[] = $removed_widget;
475
			}
476
		}
477
		return $moved_to_inactive;
478
479
	}
480
481
	function sync_widgets_reordered( $new_widgets, $old_widgets, $sidebar ) {
482
		$added_widgets = array_diff( $new_widgets, $old_widgets );
483
		if ( ! empty( $added_widgets ) ) {
484
			return;
485
		}
486
		$removed_widgets = array_diff( $old_widgets, $new_widgets );
487
		if ( ! empty( $removed_widgets ) ) {
488
			return;
489
		}
490
491
		if ( serialize( $old_widgets ) !== serialize( $new_widgets ) ) {
492
			$sidebar_name = $this->get_sidebar_name( $sidebar );
493
			/**
494
			 * Helps Sync log that a sidebar id got reordered
495
			 *
496
			 * @since 4.9.0
497
			 *
498
			 * @param string $sidebar, Sidebar id got changed
499
			 * @param string $sidebar_name, Name of the sidebar that changed  Since 5.0.0
500
			 */
501
			do_action( 'jetpack_widget_reordered', $sidebar, $sidebar_name );
502
		}
503
504
	}
505
506
	function sync_sidebar_widgets_actions( $old_value, $new_value ) {
507
		// Don't really know how to deal with different array_values yet.
508
		if (
509
			( isset( $old_value['array_version'] ) && $old_value['array_version'] !== 3 ) ||
510
			( isset( $new_value['array_version'] ) && $new_value['array_version'] !== 3 )
511
		) {
512
			return;
513
		}
514
515
		$moved_to_inactive_ids = array();
516
		$moved_to_sidebar      = array();
517
518
		foreach ( $new_value as $sidebar => $new_widgets ) {
519
			if ( in_array( $sidebar, array( 'array_version', 'wp_inactive_widgets' ) ) ) {
520
				continue;
521
			}
522
			$old_widgets = isset( $old_value[ $sidebar ] )
523
				? $old_value[ $sidebar ]
524
				: array();
525
526
			if ( ! is_array( $new_widgets ) ) {
527
				$new_widgets = array();
528
			}
529
530
			$moved_to_inactive_recently = $this->sync_remove_widgets_from_sidebar( $new_widgets, $old_widgets, $sidebar, $new_value['wp_inactive_widgets'] );
531
			$moved_to_inactive_ids      = array_merge( $moved_to_inactive_ids, $moved_to_inactive_recently );
532
533
			$moved_to_sidebar_recently = $this->sync_add_widgets_to_sidebar( $new_widgets, $old_widgets, $sidebar );
534
			$moved_to_sidebar          = array_merge( $moved_to_sidebar, $moved_to_sidebar_recently );
535
536
			$this->sync_widgets_reordered( $new_widgets, $old_widgets, $sidebar );
537
538
		}
539
540
		// Don't sync either jetpack_widget_moved_to_inactive or jetpack_cleared_inactive_widgets if theme was switched
541
		if ( $this->is_theme_switch() ) {
542
			return;
543
		}
544
545
		// Treat inactive sidebar a bit differently
546
		if ( ! empty( $moved_to_inactive_ids ) ) {
547
			$moved_to_inactive_name = array_map( array( $this, 'get_widget_name' ), $moved_to_inactive_ids );
548
			/**
549
			 * Helps Sync log that a widgets IDs got moved to in active
550
			 *
551
			 * @since 4.9.0
552
			 *
553
			 * @param array $moved_to_inactive_ids, Array of widgets id that moved to inactive id got changed
554
			 * @param array $moved_to_inactive_names, Array of widgets names that moved to inactive id got changed Since 5.0.0
555
			 */
556
			do_action( 'jetpack_widget_moved_to_inactive', $moved_to_inactive_ids, $moved_to_inactive_name );
557
		} elseif ( empty( $moved_to_sidebar ) &&
558
				   empty( $new_value['wp_inactive_widgets'] ) &&
559
				   ! empty( $old_value['wp_inactive_widgets'] ) ) {
560
			/**
561
			 * Helps Sync log that a got cleared from inactive.
562
			 *
563
			 * @since 4.9.0
564
			 */
565
			do_action( 'jetpack_cleared_inactive_widgets' );
566
		}
567
	}
568
569
	/**
570
	 * @param null $theme or the theme object
571
	 *
572
	 * @return array
573
	 */
574
	private function get_theme_support_info( $theme = null ) {
575
		global $_wp_theme_features;
576
577
		$theme_support = array();
578
579
		// We are trying to get the current theme info.
580
		if ( $theme === null ) {
581
			$theme = wp_get_theme();
582
583
			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...
584
				$has_support = current_theme_supports( $theme_feature );
585
				if ( $has_support ) {
586
					$theme_support[ $theme_feature ] = $_wp_theme_features[ $theme_feature ];
587
				}
588
			}
589
		}
590
591
		$theme_support['name']    = $theme->get( 'Name' );
592
		$theme_support['version'] = $theme->get( 'Version' );
593
		$theme_support['slug']    = $theme->get_stylesheet();
594
		$theme_support['uri']     = $theme->get( 'ThemeURI' );
595
596
		return $theme_support;
597
	}
598
599
	private function get_delete_theme_call() {
600
		$backtrace         = debug_backtrace();
601
		$delete_theme_call = null;
602
		foreach ( $backtrace as $call ) {
603
			if ( isset( $call['function'] ) && 'delete_theme' === $call['function'] ) {
604
				$delete_theme_call = $call;
605
				break;
606
			}
607
		}
608
		return $delete_theme_call;
609
	}
610
611
	private function is_theme_switch() {
612
		return did_action( 'after_switch_theme' );
613
	}
614
}
615