Completed
Push — update/grunion-personal-data ( beacb7...22114a )
by
unknown
14:02
created

Jetpack_Sync_Module_Themes::expand_theme_data()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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