Completed
Push — renovate/gridicons-3.x ( c004c1...f8ccd4 )
by
unknown
284:06 queued 275:32
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
wmc 102
lcom 2
cbo 2
dl 23
loc 610
rs 1.99
c 0
b 0
f 0

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
use Automattic\Jetpack\Sync\Defaults;
6
7
class Themes extends Module {
8
	function name() {
9
		return 'themes';
10
	}
11
12
	public function init_listeners( $callable ) {
13
		add_action( 'switch_theme', array( $this, 'sync_theme_support' ), 10, 3 );
14
		add_action( 'jetpack_sync_current_theme_support', $callable, 10, 2 );
15
		add_action( 'upgrader_process_complete', array( $this, 'check_upgrader' ), 10, 2 );
16
		add_action( 'jetpack_installed_theme', $callable, 10, 2 );
17
		add_action( 'jetpack_updated_themes', $callable, 10, 2 );
18
		add_action( 'delete_site_transient_update_themes', array( $this, 'detect_theme_deletion' ) );
19
		add_action( 'jetpack_deleted_theme', $callable, 10, 2 );
20
		add_filter( 'wp_redirect', array( $this, 'detect_theme_edit' ) );
21
		add_action( 'jetpack_edited_theme', $callable, 10, 2 );
22
		add_action( 'wp_ajax_edit-theme-plugin-file', array( $this, 'theme_edit_ajax' ), 0 );
23
		add_action( 'update_site_option_allowedthemes', array( $this, 'sync_network_allowed_themes_change' ), 10, 4 );
24
		add_action( 'jetpack_network_disabled_themes', $callable, 10, 2 );
25
		add_action( 'jetpack_network_enabled_themes', $callable, 10, 2 );
26
27
		// Sidebar updates.
28
		add_action( 'update_option_sidebars_widgets', array( $this, 'sync_sidebar_widgets_actions' ), 10, 2 );
29
30
		add_action( 'jetpack_widget_added', $callable, 10, 4 );
31
		add_action( 'jetpack_widget_removed', $callable, 10, 4 );
32
		add_action( 'jetpack_widget_moved_to_inactive', $callable, 10, 2 );
33
		add_action( 'jetpack_cleared_inactive_widgets', $callable );
34
		add_action( 'jetpack_widget_reordered', $callable, 10, 2 );
35
		add_filter( 'widget_update_callback', array( $this, 'sync_widget_edit' ), 10, 4 );
36
		add_action( 'jetpack_widget_edited', $callable );
37
	}
38
39
	public function sync_widget_edit( $instance, $new_instance, $old_instance, $widget_object ) {
40
		if ( empty( $old_instance ) ) {
41
			return $instance;
42
		}
43
44
		// Don't trigger sync action if this is an ajax request, because Customizer makes them during preview before saving changes
45
		if ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_POST['customized'] ) ) {
46
			return $instance;
47
		}
48
49
		$widget = array(
50
			'name'  => $widget_object->name,
51
			'id'    => $widget_object->id,
52
			'title' => isset( $new_instance['title'] ) ? $new_instance['title'] : '',
53
		);
54
		/**
55
		 * Trigger action to alert $callable sync listener that a widget was edited
56
		 *
57
		 * @since 5.0.0
58
		 *
59
		 * @param string $widget_name , Name of edited widget
60
		 */
61
		do_action( 'jetpack_widget_edited', $widget );
62
63
		return $instance;
64
	}
65
66
	public function sync_network_allowed_themes_change( $option, $value, $old_value, $network_id ) {
67
		$all_enabled_theme_slugs = array_keys( $value );
68
69
		if ( count( $old_value ) > count( $value ) ) {
70
71
			// Suppress jetpack_network_disabled_themes sync action when theme is deleted
72
			$delete_theme_call = $this->get_delete_theme_call();
73
			if ( ! empty( $delete_theme_call ) ) {
74
				return;
75
			}
76
77
			$newly_disabled_theme_names = array_keys( array_diff_key( $old_value, $value ) );
78
			$newly_disabled_themes      = $this->get_theme_details_for_slugs( $newly_disabled_theme_names );
79
			/**
80
			 * Trigger action to alert $callable sync listener that network themes were disabled
81
			 *
82
			 * @since 5.0.0
83
			 *
84
			 * @param mixed $newly_disabled_themes, Array of info about network disabled themes
85
			 * @param mixed $all_enabled_theme_slugs, Array of slugs of all enabled themes
86
			 */
87
			do_action( 'jetpack_network_disabled_themes', $newly_disabled_themes, $all_enabled_theme_slugs );
88
			return;
89
		}
90
91
		$newly_enabled_theme_names = array_keys( array_diff_key( $value, $old_value ) );
92
		$newly_enabled_themes      = $this->get_theme_details_for_slugs( $newly_enabled_theme_names );
93
		/**
94
		 * Trigger action to alert $callable sync listener that network themes were enabled
95
		 *
96
		 * @since 5.0.0
97
		 *
98
		 * @param mixed $newly_enabled_themes , Array of info about network enabled themes
99
		 * @param mixed $all_enabled_theme_slugs, Array of slugs of all enabled themes
100
		 */
101
		do_action( 'jetpack_network_enabled_themes', $newly_enabled_themes, $all_enabled_theme_slugs );
102
	}
103
104
	private function get_theme_details_for_slugs( $theme_slugs ) {
105
		$theme_data = array();
106 View Code Duplication
		foreach ( $theme_slugs as $slug ) {
107
			$theme               = wp_get_theme( $slug );
108
			$theme_data[ $slug ] = array(
109
				'name'    => $theme->get( 'Name' ),
110
				'version' => $theme->get( 'Version' ),
111
				'uri'     => $theme->get( 'ThemeURI' ),
112
				'slug'    => $slug,
113
			);
114
		}
115
		return $theme_data;
116
	}
117
118
	public function detect_theme_edit( $redirect_url ) {
119
		$url              = wp_parse_url( admin_url( $redirect_url ) );
120
		$theme_editor_url = wp_parse_url( admin_url( 'theme-editor.php' ) );
121
122
		if ( $theme_editor_url['path'] !== $url['path'] ) {
123
			return $redirect_url;
124
		}
125
126
		$query_params = array();
127
		wp_parse_str( $url['query'], $query_params );
128
		if (
129
			! isset( $_POST['newcontent'] ) ||
130
			! isset( $query_params['file'] ) ||
131
			! isset( $query_params['theme'] ) ||
132
			! isset( $query_params['updated'] )
133
		) {
134
			return $redirect_url;
135
		}
136
		$theme      = wp_get_theme( $query_params['theme'] );
137
		$theme_data = array(
138
			'name'    => $theme->get( 'Name' ),
139
			'version' => $theme->get( 'Version' ),
140
			'uri'     => $theme->get( 'ThemeURI' ),
141
		);
142
143
		/**
144
		 * Trigger action to alert $callable sync listener that a theme was edited
145
		 *
146
		 * @since 5.0.0
147
		 *
148
		 * @param string $query_params['theme'], Slug of edited theme
149
		 * @param string $theme_data, Information about edited them
150
		 */
151
		do_action( 'jetpack_edited_theme', $query_params['theme'], $theme_data );
152
153
		return $redirect_url;
154
	}
155
156
	public function theme_edit_ajax() {
157
		$args = wp_unslash( $_POST );
158
159
		if ( empty( $args['theme'] ) ) {
160
			return;
161
		}
162
163
		if ( empty( $args['file'] ) ) {
164
			return;
165
		}
166
		$file = $args['file'];
167
		if ( 0 !== validate_file( $file ) ) {
168
			return;
169
		}
170
171
		if ( ! isset( $args['newcontent'] ) ) {
172
			return;
173
		}
174
175
		if ( ! isset( $args['nonce'] ) ) {
176
			return;
177
		}
178
179
		$stylesheet = $args['theme'];
180
		if ( 0 !== validate_file( $stylesheet ) ) {
181
			return;
182
		}
183
184
		if ( ! current_user_can( 'edit_themes' ) ) {
185
			return;
186
		}
187
188
		$theme = wp_get_theme( $stylesheet );
189
		if ( ! $theme->exists() ) {
190
			return;
191
		}
192
193
		$real_file = $theme->get_stylesheet_directory() . '/' . $file;
194
		if ( ! wp_verify_nonce( $args['nonce'], 'edit-theme_' . $real_file . $stylesheet ) ) {
195
			return;
196
		}
197
198
		if ( $theme->errors() && 'theme_no_stylesheet' === $theme->errors()->get_error_code() ) {
199
			return;
200
		}
201
202
		$editable_extensions = wp_get_theme_file_editable_extensions( $theme );
203
204
		$allowed_files = array();
205
		foreach ( $editable_extensions as $type ) {
206
			switch ( $type ) {
207
				case 'php':
208
					$allowed_files = array_merge( $allowed_files, $theme->get_files( 'php', -1 ) );
209
					break;
210
				case 'css':
211
					$style_files                = $theme->get_files( 'css', -1 );
212
					$allowed_files['style.css'] = $style_files['style.css'];
213
					$allowed_files              = array_merge( $allowed_files, $style_files );
214
					break;
215
				default:
216
					$allowed_files = array_merge( $allowed_files, $theme->get_files( $type, -1 ) );
217
					break;
218
			}
219
		}
220
221
		if ( 0 !== validate_file( $real_file, $allowed_files ) ) {
222
			return;
223
		}
224
225
		// Ensure file is real.
226
		if ( ! is_file( $real_file ) ) {
227
			return;
228
		}
229
230
		// Ensure file extension is allowed.
231
		$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...
232
		if ( preg_match( '/\.([^.]+)$/', $real_file, $matches ) ) {
233
			$extension = strtolower( $matches[1] );
234
			if ( ! in_array( $extension, $editable_extensions, true ) ) {
235
				return;
236
			}
237
		}
238
239
		if ( ! is_writeable( $real_file ) ) {
240
			return;
241
		}
242
243
		$file_pointer = fopen( $real_file, 'w+' );
244
		if ( false === $file_pointer ) {
245
			return;
246
		}
247
		fclose( $file_pointer );
248
249
		$theme_data = array(
250
			'name'    => $theme->get( 'Name' ),
251
			'version' => $theme->get( 'Version' ),
252
			'uri'     => $theme->get( 'ThemeURI' ),
253
		);
254
255
		/**
256
		 * This action is documented already in this file
257
		 */
258
		do_action( 'jetpack_edited_theme', $stylesheet, $theme_data );
259
260
	}
261
262
	public function detect_theme_deletion() {
263
		$delete_theme_call = $this->get_delete_theme_call();
264
		if ( empty( $delete_theme_call ) ) {
265
			return;
266
		}
267
268
		$slug       = $delete_theme_call['args'][0];
269
		$theme      = wp_get_theme( $slug );
270
		$theme_data = array(
271
			'name'    => $theme->get( 'Name' ),
272
			'version' => $theme->get( 'Version' ),
273
			'uri'     => $theme->get( 'ThemeURI' ),
274
			'slug'    => $slug,
275
		);
276
277
		/**
278
		 * Signals to the sync listener that a theme was deleted and a sync action
279
		 * reflecting the deletion and theme slug should be sent
280
		 *
281
		 * @since 5.0.0
282
		 *
283
		 * @param string $slug Theme slug
284
		 * @param array $theme_data Theme info Since 5.3
285
		 */
286
		do_action( 'jetpack_deleted_theme', $slug, $theme_data );
287
	}
288
289
	public function check_upgrader( $upgrader, $details ) {
290
		if ( ! isset( $details['type'] ) ||
291
			 'theme' !== $details['type'] ||
292
			 is_wp_error( $upgrader->skin->result ) ||
293
			 ! method_exists( $upgrader, 'theme_info' )
294
		) {
295
			return;
296
		}
297
298
		if ( 'install' === $details['action'] ) {
299
			$theme = $upgrader->theme_info();
300
			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...
301
				return;
302
			}
303
			$theme_info = array(
304
				'name'    => $theme->get( 'Name' ),
305
				'version' => $theme->get( 'Version' ),
306
				'uri'     => $theme->get( 'ThemeURI' ),
307
			);
308
309
			/**
310
			 * Signals to the sync listener that a theme was installed and a sync action
311
			 * reflecting the installation and the theme info should be sent
312
			 *
313
			 * @since 4.9.0
314
			 *
315
			 * @param string $theme->theme_root Text domain of the theme
316
			 * @param mixed $theme_info Array of abbreviated theme info
317
			 */
318
			do_action( 'jetpack_installed_theme', $theme->stylesheet, $theme_info );
319
		}
320
321
		if ( 'update' === $details['action'] ) {
322
			$themes = array();
323
324
			if ( empty( $details['themes'] ) && isset( $details['theme'] ) ) {
325
				$details['themes'] = array( $details['theme'] );
326
			}
327
328 View Code Duplication
			foreach ( $details['themes'] as $theme_slug ) {
329
				$theme = wp_get_theme( $theme_slug );
330
331
				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...
332
					continue;
333
				}
334
335
				$themes[ $theme_slug ] = array(
336
					'name'       => $theme->get( 'Name' ),
337
					'version'    => $theme->get( 'Version' ),
338
					'uri'        => $theme->get( 'ThemeURI' ),
339
					'stylesheet' => $theme->stylesheet,
340
				);
341
			}
342
343
			if ( empty( $themes ) ) {
344
				return;
345
			}
346
347
			/**
348
			 * Signals to the sync listener that one or more themes was updated and a sync action
349
			 * reflecting the update and the theme info should be sent
350
			 *
351
			 * @since 6.2.0
352
			 *
353
			 * @param mixed $themes Array of abbreviated theme info
354
			 */
355
			do_action( 'jetpack_updated_themes', $themes );
356
		}
357
358
	}
359
360
	public function init_full_sync_listeners( $callable ) {
361
		add_action( 'jetpack_full_sync_theme_data', $callable );
362
	}
363
364
	public function sync_theme_support( $new_name, $new_theme = null, $old_theme = null ) {
365
		$previous_theme = $this->get_theme_support_info( $old_theme );
366
367
		/**
368
		 * Fires when the client needs to sync theme support info
369
		 * Only sends theme support attributes whitelisted in Defaults::$default_theme_support_whitelist
370
		 *
371
		 * @since 4.2.0
372
		 *
373
		 * @param array the theme support array
374
		 * @param array the previous theme since Jetpack 6.5.0
375
		 */
376
		do_action( 'jetpack_sync_current_theme_support', $this->get_theme_support_info(), $previous_theme );
377
	}
378
379
	public function enqueue_full_sync_actions( $config, $max_items_to_enqueue, $state ) {
380
		/**
381
		 * Tells the client to sync all theme data to the server
382
		 *
383
		 * @since 4.2.0
384
		 *
385
		 * @param boolean Whether to expand theme data (should always be true)
386
		 */
387
		do_action( 'jetpack_full_sync_theme_data', true );
388
389
		// The number of actions enqueued, and next module state (true == done)
390
		return array( 1, true );
391
	}
392
393
	public function estimate_full_sync_actions( $config ) {
394
		return 1;
395
	}
396
397
	public function init_before_send() {
398
		add_filter( 'jetpack_sync_before_send_jetpack_full_sync_theme_data', array( $this, 'expand_theme_data' ) );
399
	}
400
401
	function get_full_sync_actions() {
402
		return array( 'jetpack_full_sync_theme_data' );
403
	}
404
405
	function expand_theme_data() {
406
		return array( $this->get_theme_support_info() );
407
	}
408
409
	function get_widget_name( $widget_id ) {
410
		global $wp_registered_widgets;
411
		return ( isset( $wp_registered_widgets[ $widget_id ] ) ? $wp_registered_widgets[ $widget_id ]['name'] : null );
412
	}
413
414
	function get_sidebar_name( $sidebar_id ) {
415
		global $wp_registered_sidebars;
416
		return ( isset( $wp_registered_sidebars[ $sidebar_id ] ) ? $wp_registered_sidebars[ $sidebar_id ]['name'] : null );
417
	}
418
419
	function sync_add_widgets_to_sidebar( $new_widgets, $old_widgets, $sidebar ) {
420
		$added_widgets = array_diff( $new_widgets, $old_widgets );
421
		if ( empty( $added_widgets ) ) {
422
			return array();
423
		}
424
		$moved_to_sidebar = array();
425
		$sidebar_name     = $this->get_sidebar_name( $sidebar );
426
427
		// Don't sync jetpack_widget_added if theme was switched
428
		if ( $this->is_theme_switch() ) {
429
			return array();
430
		}
431
432
		foreach ( $added_widgets as $added_widget ) {
433
			$moved_to_sidebar[] = $added_widget;
434
			$added_widget_name  = $this->get_widget_name( $added_widget );
435
			/**
436
			 * Helps Sync log that a widget got added
437
			 *
438
			 * @since 4.9.0
439
			 *
440
			 * @param string $sidebar, Sidebar id got changed
441
			 * @param string $added_widget, Widget id got added
442
			 * @param string $sidebar_name, Sidebar id got changed Since 5.0.0
443
			 * @param string $added_widget_name, Widget id got added Since 5.0.0
444
			 */
445
			do_action( 'jetpack_widget_added', $sidebar, $added_widget, $sidebar_name, $added_widget_name );
446
		}
447
		return $moved_to_sidebar;
448
	}
449
450
	function sync_remove_widgets_from_sidebar( $new_widgets, $old_widgets, $sidebar, $inactive_widgets ) {
451
		$removed_widgets = array_diff( $old_widgets, $new_widgets );
452
453
		if ( empty( $removed_widgets ) ) {
454
			return array();
455
		}
456
457
		$moved_to_inactive = array();
458
		$sidebar_name      = $this->get_sidebar_name( $sidebar );
459
460
		foreach ( $removed_widgets as $removed_widget ) {
461
			// Lets check if we didn't move the widget to in_active_widgets
462
			if ( isset( $inactive_widgets ) && ! in_array( $removed_widget, $inactive_widgets ) ) {
463
				$removed_widget_name = $this->get_widget_name( $removed_widget );
464
				/**
465
				 * Helps Sync log that a widgte got removed
466
				 *
467
				 * @since 4.9.0
468
				 *
469
				 * @param string $sidebar, Sidebar id got changed
470
				 * @param string $removed_widget, Widget id got removed
471
				 * @param string $sidebar_name, Name of the sidebar that changed  Since 5.0.0
472
				 * @param string $removed_widget_name, Name of the widget that got removed Since 5.0.0
473
				 */
474
				do_action( 'jetpack_widget_removed', $sidebar, $removed_widget, $sidebar_name, $removed_widget_name );
475
			} else {
476
				$moved_to_inactive[] = $removed_widget;
477
			}
478
		}
479
		return $moved_to_inactive;
480
481
	}
482
483
	function sync_widgets_reordered( $new_widgets, $old_widgets, $sidebar ) {
484
		$added_widgets = array_diff( $new_widgets, $old_widgets );
485
		if ( ! empty( $added_widgets ) ) {
486
			return;
487
		}
488
		$removed_widgets = array_diff( $old_widgets, $new_widgets );
489
		if ( ! empty( $removed_widgets ) ) {
490
			return;
491
		}
492
493
		if ( serialize( $old_widgets ) !== serialize( $new_widgets ) ) {
494
			$sidebar_name = $this->get_sidebar_name( $sidebar );
495
			/**
496
			 * Helps Sync log that a sidebar id got reordered
497
			 *
498
			 * @since 4.9.0
499
			 *
500
			 * @param string $sidebar, Sidebar id got changed
501
			 * @param string $sidebar_name, Name of the sidebar that changed  Since 5.0.0
502
			 */
503
			do_action( 'jetpack_widget_reordered', $sidebar, $sidebar_name );
504
		}
505
506
	}
507
508
	function sync_sidebar_widgets_actions( $old_value, $new_value ) {
509
		// Don't really know how to deal with different array_values yet.
510
		if (
511
			( isset( $old_value['array_version'] ) && $old_value['array_version'] !== 3 ) ||
512
			( isset( $new_value['array_version'] ) && $new_value['array_version'] !== 3 )
513
		) {
514
			return;
515
		}
516
517
		$moved_to_inactive_ids = array();
518
		$moved_to_sidebar      = array();
519
520
		foreach ( $new_value as $sidebar => $new_widgets ) {
521
			if ( in_array( $sidebar, array( 'array_version', 'wp_inactive_widgets' ) ) ) {
522
				continue;
523
			}
524
			$old_widgets = isset( $old_value[ $sidebar ] )
525
				? $old_value[ $sidebar ]
526
				: array();
527
528
			if ( ! is_array( $new_widgets ) ) {
529
				$new_widgets = array();
530
			}
531
532
			$moved_to_inactive_recently = $this->sync_remove_widgets_from_sidebar( $new_widgets, $old_widgets, $sidebar, $new_value['wp_inactive_widgets'] );
533
			$moved_to_inactive_ids      = array_merge( $moved_to_inactive_ids, $moved_to_inactive_recently );
534
535
			$moved_to_sidebar_recently = $this->sync_add_widgets_to_sidebar( $new_widgets, $old_widgets, $sidebar );
536
			$moved_to_sidebar          = array_merge( $moved_to_sidebar, $moved_to_sidebar_recently );
537
538
			$this->sync_widgets_reordered( $new_widgets, $old_widgets, $sidebar );
539
540
		}
541
542
		// Don't sync either jetpack_widget_moved_to_inactive or jetpack_cleared_inactive_widgets if theme was switched
543
		if ( $this->is_theme_switch() ) {
544
			return;
545
		}
546
547
		// Treat inactive sidebar a bit differently
548
		if ( ! empty( $moved_to_inactive_ids ) ) {
549
			$moved_to_inactive_name = array_map( array( $this, 'get_widget_name' ), $moved_to_inactive_ids );
550
			/**
551
			 * Helps Sync log that a widgets IDs got moved to in active
552
			 *
553
			 * @since 4.9.0
554
			 *
555
			 * @param array $moved_to_inactive_ids, Array of widgets id that moved to inactive id got changed
556
			 * @param array $moved_to_inactive_names, Array of widgets names that moved to inactive id got changed Since 5.0.0
557
			 */
558
			do_action( 'jetpack_widget_moved_to_inactive', $moved_to_inactive_ids, $moved_to_inactive_name );
559
		} elseif ( empty( $moved_to_sidebar ) &&
560
				   empty( $new_value['wp_inactive_widgets'] ) &&
561
				   ! empty( $old_value['wp_inactive_widgets'] ) ) {
562
			/**
563
			 * Helps Sync log that a got cleared from inactive.
564
			 *
565
			 * @since 4.9.0
566
			 */
567
			do_action( 'jetpack_cleared_inactive_widgets' );
568
		}
569
	}
570
571
	/**
572
	 * @param null $theme or the theme object
573
	 *
574
	 * @return array
575
	 */
576
	private function get_theme_support_info( $theme = null ) {
577
		global $_wp_theme_features;
578
579
		$theme_support = array();
580
581
		// We are trying to get the current theme info.
582
		if ( $theme === null ) {
583
			$theme = wp_get_theme();
584
585
			foreach ( 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 Automattic\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...
586
				$has_support = current_theme_supports( $theme_feature );
587
				if ( $has_support ) {
588
					$theme_support[ $theme_feature ] = $_wp_theme_features[ $theme_feature ];
589
				}
590
			}
591
		}
592
593
		$theme_support['name']    = $theme->get( 'Name' );
594
		$theme_support['version'] = $theme->get( 'Version' );
595
		$theme_support['slug']    = $theme->get_stylesheet();
596
		$theme_support['uri']     = $theme->get( 'ThemeURI' );
597
598
		return $theme_support;
599
	}
600
601
	private function get_delete_theme_call() {
602
		$backtrace         = debug_backtrace();
603
		$delete_theme_call = null;
604
		foreach ( $backtrace as $call ) {
605
			if ( isset( $call['function'] ) && 'delete_theme' === $call['function'] ) {
606
				$delete_theme_call = $call;
607
				break;
608
			}
609
		}
610
		return $delete_theme_call;
611
	}
612
613
	private function is_theme_switch() {
614
		return did_action( 'after_switch_theme' );
615
	}
616
}
617