Completed
Push — branch-8.9 ( 7601c8...9d2416 )
by Jeremy
44:31 queued 35:11
created

inject_javascript_options()   F

Complexity

Conditions 13
Paths 320

Size

Total Lines 103

Duplication

Lines 8
Ratio 7.77 %

Importance

Changes 0
Metric Value
cc 13
nc 320
nop 0
dl 8
loc 103
rs 3.4266
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Jetpack Search: Instant Front-End Search and Filtering
4
 *
5
 * @since 8.3.0
6
 * @package jetpack
7
 */
8
9
use Automattic\Jetpack\Connection\Client;
10
use Automattic\Jetpack\Constants;
11
12
/**
13
 * Class to load Instant Search experience on the site.
14
 *
15
 * @since 8.3.0
16
 */
17
class Jetpack_Instant_Search extends Jetpack_Search {
18
19
	/**
20
	 * Loads the php for this version of search
21
	 *
22
	 * @since 8.3.0
23
	 */
24
	public function load_php() {
25
		$this->base_load_php();
26
27
		if ( class_exists( 'WP_Customize_Manager' ) ) {
28
			require_once dirname( __FILE__ ) . '/class-jetpack-search-customize.php';
29
			new Jetpack_Search_Customize();
30
		}
31
	}
32
33
	/**
34
	 * Setup the various hooks needed for the plugin to take over search duties.
35
	 *
36
	 * @since 5.0.0
37
	 */
38 View Code Duplication
	public function init_hooks() {
39
		if ( ! is_admin() ) {
40
			add_filter( 'posts_pre_query', array( $this, 'filter__posts_pre_query' ), 10, 2 );
41
			add_action( 'parse_query', array( $this, 'action__parse_query' ), 10, 1 );
42
43
			add_action( 'init', array( $this, 'set_filters_from_widgets' ) );
44
45
			add_action( 'wp_enqueue_scripts', array( $this, 'load_assets' ) );
46
			add_action( 'wp_footer', array( $this, 'print_instant_search_sidebar' ) );
47
		} else {
48
			add_action( 'update_option', array( $this, 'track_widget_updates' ), 10, 3 );
49
		}
50
51
		add_action( 'widgets_init', array( $this, 'register_jetpack_instant_sidebar' ) );
52
		add_action( 'jetpack_deactivate_module_search', array( $this, 'move_search_widgets_to_inactive' ) );
53
	}
54
55
	/**
56
	 * Loads assets for Jetpack Instant Search Prototype featuring Search As You Type experience.
57
	 */
58
	public function load_assets() {
59
		$script_relative_path = '_inc/build/instant-search/jp-search.bundle.js';
60
		$style_relative_path  = '_inc/build/instant-search/instant-search.min.css';
61
		if ( ! file_exists( JETPACK__PLUGIN_DIR . $script_relative_path ) || ! file_exists( JETPACK__PLUGIN_DIR . $style_relative_path ) ) {
62
			return;
63
		}
64
65
		$script_version = Jetpack_Search_Helpers::get_asset_version( $script_relative_path );
66
		$script_path    = plugins_url( $script_relative_path, JETPACK__PLUGIN_FILE );
67
		wp_enqueue_script( 'jetpack-instant-search', $script_path, array(), $script_version, true );
68
		wp_set_script_translations( 'jetpack-instant-search', 'jetpack' );
69
		$this->load_and_initialize_tracks();
70
		$this->inject_javascript_options();
71
72
		$style_version = Jetpack_Search_Helpers::get_asset_version( $style_relative_path );
73
		$style_path    = plugins_url( $style_relative_path, JETPACK__PLUGIN_FILE );
74
		wp_enqueue_style( 'jetpack-instant-search', $style_path, array(), $style_version );
75
	}
76
77
	/**
78
	 * Passes all options to the JS app.
79
	 */
80
	protected function inject_javascript_options() {
81
		$widget_options = Jetpack_Search_Helpers::get_widgets_from_option();
82
		if ( is_array( $widget_options ) ) {
83
			$widget_options = end( $widget_options );
0 ignored issues
show
Unused Code introduced by
$widget_options 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...
84
		}
85
86
		$overlay_widget_ids      = is_active_sidebar( 'jetpack-instant-search-sidebar' ) ?
87
			wp_get_sidebars_widgets()['jetpack-instant-search-sidebar'] : array();
88
		$filters                 = Jetpack_Search_Helpers::get_filters_from_widgets();
89
		$widgets                 = array();
90
		$widgets_outside_overlay = array();
91
		foreach ( $filters as $key => &$filter ) {
92
			$filter['filter_id'] = $key;
93
94
			if ( in_array( $filter['widget_id'], $overlay_widget_ids, true ) ) {
95 View Code Duplication
				if ( ! isset( $widgets[ $filter['widget_id'] ] ) ) {
96
					$widgets[ $filter['widget_id'] ]['filters']   = array();
97
					$widgets[ $filter['widget_id'] ]['widget_id'] = $filter['widget_id'];
98
				}
99
				$widgets[ $filter['widget_id'] ]['filters'][] = $filter;
100
			} else {
101 View Code Duplication
				if ( ! isset( $widgets_outside_overlay[ $filter['widget_id'] ] ) ) {
102
					$widgets_outside_overlay[ $filter['widget_id'] ]['filters']   = array();
103
					$widgets_outside_overlay[ $filter['widget_id'] ]['widget_id'] = $filter['widget_id'];
104
				}
105
				$widgets_outside_overlay[ $filter['widget_id'] ]['filters'][] = $filter;
106
			}
107
		}
108
		unset( $filter );
109
110
		$post_type_objs   = get_post_types( array( 'exclude_from_search' => false ), 'objects' );
111
		$post_type_labels = array();
112
		foreach ( $post_type_objs as $key => $obj ) {
113
			$post_type_labels[ $key ] = array(
114
				'singular_name' => $obj->labels->singular_name,
115
				'name'          => $obj->labels->name,
116
			);
117
		}
118
119
		$prefix         = Jetpack_Search_Options::OPTION_PREFIX;
120
		$posts_per_page = (int) get_option( 'posts_per_page' );
121
		if ( ( $posts_per_page > 20 ) || ( $posts_per_page <= 0 ) ) {
122
			$posts_per_page = 20;
123
		}
124
125
		$excluded_post_types   = get_option( $prefix . 'excluded_post_types' ) ? explode( ',', get_option( $prefix . 'excluded_post_types', '' ) ) : array();
126
		$post_types            = array_values(
127
			get_post_types(
128
				array(
129
					'exclude_from_search' => false,
130
					'public'              => true,
131
				)
132
			)
133
		);
134
		$unexcluded_post_types = array_diff( $post_types, $excluded_post_types );
135
		// NOTE: If all post types are being excluded, ignore the option value.
136
		if ( count( $unexcluded_post_types ) === 0 ) {
137
			$excluded_post_types = array();
138
		}
139
140
		$options = array(
141
			'overlayOptions'        => array(
142
				'colorTheme'      => get_option( $prefix . 'color_theme', 'light' ),
143
				'enableInfScroll' => get_option( $prefix . 'inf_scroll', '1' ) === '1',
144
				'enableSort'      => get_option( $prefix . 'enable_sort', '1' ) === '1',
145
				'highlightColor'  => get_option( $prefix . 'highlight_color', '#FFC' ),
146
				'opacity'         => (int) get_option( $prefix . 'opacity', 97 ),
147
				'overlayTrigger'  => get_option( $prefix . 'overlay_trigger', 'immediate' ),
148
				'resultFormat'    => get_option( $prefix . 'result_format', 'minimal' ),
149
				'showPoweredBy'   => get_option( $prefix . 'show_powered_by', '1' ) === '1',
150
			),
151
152
			// core config.
153
			'homeUrl'               => home_url(),
154
			'locale'                => str_replace( '_', '-', Jetpack_Search_Helpers::is_valid_locale( get_locale() ) ? get_locale() : 'en_US' ),
155
			'postsPerPage'          => $posts_per_page,
156
			'siteId'                => $this->jetpack_blog_id,
157
			'postTypes'             => $post_type_labels,
158
159
			// search options.
160
			'defaultSort'           => get_option( $prefix . 'default_sort', 'relevance' ),
161
			'excludedPostTypes'     => $excluded_post_types,
162
163
			// widget info.
164
			'hasOverlayWidgets'     => count( $overlay_widget_ids ) > 0,
165
			'widgets'               => array_values( $widgets ),
166
			'widgetsOutsideOverlay' => array_values( $widgets_outside_overlay ),
167
		);
168
169
		/**
170
		 * Customize Instant Search Options.
171
		 *
172
		 * @module search
173
		 *
174
		 * @since 7.7.0
175
		 *
176
		 * @param array $options Array of parameters used in Instant Search queries.
177
		 */
178
		$options = apply_filters( 'jetpack_instant_search_options', $options );
179
180
		// Use wp_add_inline_script instead of wp_localize_script, see https://core.trac.wordpress.org/ticket/25280.
181
		wp_add_inline_script( 'jetpack-instant-search', 'var JetpackInstantSearchOptions=JSON.parse(decodeURIComponent("' . rawurlencode( wp_json_encode( $options ) ) . '"));' );
182
	}
183
184
	/**
185
	 * Registers a widget sidebar for Instant Search.
186
	 */
187
	public function register_jetpack_instant_sidebar() {
188
		$args = array(
189
			'name'          => __( 'Jetpack Search Sidebar', 'jetpack' ),
190
			'id'            => 'jetpack-instant-search-sidebar',
191
			'description'   => __( 'Customize the sidebar inside the Jetpack Search overlay', 'jetpack' ),
192
			'class'         => '',
193
			'before_widget' => '<div id="%1$s" class="widget %2$s">',
194
			'after_widget'  => '</div>',
195
			'before_title'  => '<h2 class="widgettitle">',
196
			'after_title'   => '</h2>',
197
		);
198
		register_sidebar( $args );
199
	}
200
201
	/**
202
	 * Prints Instant Search sidebar.
203
	 */
204
	public function print_instant_search_sidebar() {
205
		?>
206
		<div class="jetpack-instant-search__widget-area" style="display: none">
207
			<?php if ( is_active_sidebar( 'jetpack-instant-search-sidebar' ) ) { ?>
208
				<?php dynamic_sidebar( 'jetpack-instant-search-sidebar' ); ?>
209
			<?php } ?>
210
		</div>
211
		<?php
212
	}
213
214
	/**
215
	 * Loads scripts for Tracks analytics library
216
	 */
217
	public function load_and_initialize_tracks() {
218
		wp_enqueue_script( 'jp-tracks', '//stats.wp.com/w.js', array(), gmdate( 'YW' ), true );
219
	}
220
221
	/**
222
	 * Bypass the normal Search query since we will run it with instant search.
223
	 *
224
	 * @since 8.3.0
225
	 *
226
	 * @param array    $posts Current array of posts (still pre-query).
227
	 * @param WP_Query $query The WP_Query being filtered.
228
	 *
229
	 * @return array Array of matching posts.
230
	 */
231
	public function filter__posts_pre_query( $posts, $query ) {
232
		if ( ! $this->should_handle_query( $query ) ) {
233
			// Intentionally not adding the 'jetpack_search_abort' action since this should fire for every request except for search.
234
			return $posts;
235
		}
236
237
		/**
238
		 * Bypass the main query and return dummy data
239
		 *  WP Core doesn't call the set_found_posts and its filters when filtering
240
		 *  posts_pre_query like we do, so need to do these manually.
241
		 */
242
		$query->found_posts   = 1;
243
		$query->max_num_pages = 1;
244
245
		return array();
246
	}
247
248
	/**
249
	 * Run the aggregations API query for any filtering
250
	 *
251
	 * @since 8.3.0
252
	 */
253
	public function action__parse_query() {
254
		if ( ! empty( $this->search_result ) ) {
255
			return;
256
		}
257
258
		if ( is_admin() ) {
259
			return;
260
		}
261
262
		if ( empty( $this->aggregations ) ) {
263
			return;
264
		}
265
266
		jetpack_require_lib( 'jetpack-wpes-query-builder/jetpack-wpes-query-builder' );
267
268
		$builder = new Jetpack_WPES_Query_Builder();
269
		$this->add_aggregations_to_es_query_builder( $this->aggregations, $builder );
270
		$this->search_result = $this->instant_api(
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->instant_api(array...ze' => 0, 'from' => 0)) of type object is incompatible with the declared type array of property $search_result.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
271
			array(
272
				'aggregations' => $builder->build_aggregation(),
273
				'size'         => 0,
274
				'from'         => 0,
275
			)
276
		);
277
	}
278
279
	/**
280
	 * Run an instant search on the WordPress.com public API.
281
	 *
282
	 * @since 8.3.0
283
	 *
284
	 * @param array $args Args conforming to the WP.com v1.3/sites/<blog_id>/search endpoint.
285
	 *
286
	 * @return object|WP_Error The response from the public API, or a WP_Error.
287
	 */
288
	public function instant_api( array $args ) {
289
		global $wp_version;
290
		$start_time = microtime( true );
291
292
		// Cache locally to avoid remote request slowing the page.
293
		$transient_name = 'jetpack_instant_search_cache_' . md5( wp_json_encode( $args ) );
294
		$cache          = get_transient( $transient_name );
295
		if ( false !== $cache ) {
296
			return $cache;
297
		}
298
299
		$service_url = add_query_arg(
300
			$args,
301
			sprintf(
302
				'https://public-api.wordpress.com/rest/v1.3/sites/%d/search',
303
				$this->jetpack_blog_id
304
			)
305
		);
306
307
		$request_args = array(
308
			'timeout'    => 10,
309
			'user-agent' => "WordPress/{$wp_version} | Jetpack/" . constant( 'JETPACK__VERSION' ),
310
		);
311
312
		$request  = wp_remote_get( esc_url_raw( $service_url ), $request_args );
313
		$end_time = microtime( true );
314
315
		if ( is_wp_error( $request ) ) {
316
			return $request;
317
		}
318
319
		$response_code = wp_remote_retrieve_response_code( $request );
320
		$response      = json_decode( wp_remote_retrieve_body( $request ), true );
321
322 View Code Duplication
		if ( ! $response_code || $response_code < 200 || $response_code >= 300 ) {
323
			/**
324
			 * Fires after a search query request has failed
325
			 *
326
			 * @module search
327
			 *
328
			 * @since  5.6.0
329
			 *
330
			 * @param array Array containing the response code and response from the failed search query
331
			 */
332
			do_action(
333
				'failed_jetpack_search_query',
334
				array(
335
					'response_code' => $response_code,
336
					'json'          => $response,
337
				)
338
			);
339
340
			return new WP_Error( 'invalid_search_api_response', 'Invalid response from API - ' . $response_code );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'invalid_search_api_response'.

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...
341
		}
342
343
		$took = is_array( $response ) && ! empty( $response['took'] )
344
			? $response['took']
345
			: null;
346
347
		$query = array(
348
			'args'          => $args,
349
			'response'      => $response,
350
			'response_code' => $response_code,
351
			'elapsed_time'  => ( $end_time - $start_time ) * 1000, // Convert from float seconds to ms.
352
			'es_time'       => $took,
353
			'url'           => $service_url,
354
		);
355
356
		/**
357
		 * Fires after a search request has been performed.
358
		 *
359
		 * Includes the following info in the $query parameter:
360
		 *
361
		 * array args Array of Elasticsearch arguments for the search
362
		 * array response Raw API response, JSON decoded
363
		 * int response_code HTTP response code of the request
364
		 * float elapsed_time Roundtrip time of the search request, in milliseconds
365
		 * float es_time Amount of time Elasticsearch spent running the request, in milliseconds
366
		 * string url API url that was queried
367
		 *
368
		 * @module search
369
		 *
370
		 * @since  5.0.0
371
		 * @since  5.8.0 This action now fires on all queries instead of just successful queries.
372
		 *
373
		 * @param array $query Array of information about the query performed
374
		 */
375
		do_action( 'did_jetpack_search_query', $query );
376
377
		// Update local cache.
378
		set_transient( $transient_name, $response, 1 * HOUR_IN_SECONDS );
379
380
		return $response;
381
	}
382
383
	/**
384
	 * Get the raw Aggregation results from the Elasticsearch response.
385
	 *
386
	 * @since  8.4.0
387
	 *
388
	 * @return array Array of Aggregations performed on the search.
389
	 */
390
	public function get_search_aggregations_results() {
391
		if ( empty( $this->search_result ) || is_wp_error( $this->search_result ) || ! isset( $this->search_result['aggregations'] ) ) {
392
			return array();
393
		}
394
395
		return $this->search_result['aggregations'];
396
	}
397
398
	/**
399
	 * Automatically configure necessary settings for instant search
400
	 *
401
	 * @since  8.3.0
402
	 */
403
	public function auto_config_search() {
404
		if ( ! current_user_can( 'edit_theme_options' ) ) {
405
			return;
406
		}
407
408
		// Set default result format to "expanded".
409
		update_option( Jetpack_Search_Options::OPTION_PREFIX . 'result_format', 'expanded' );
410
411
		$this->auto_config_excluded_post_types();
412
		$this->auto_config_overlay_sidebar_widgets();
413
	}
414
415
	/**
416
	 * Automatically copy configured search widgets into the overlay sidebar
417
	 *
418
	 * @since  8.8.0
419
	 */
420
	public function auto_config_overlay_sidebar_widgets() {
421
		global $wp_registered_sidebars;
422
		$sidebars = get_option( 'sidebars_widgets', array() );
423
		$slug     = Jetpack_Search_Helpers::FILTER_WIDGET_BASE;
424
425
		if ( isset( $sidebars['jetpack-instant-search-sidebar'] ) ) {
426
			foreach ( (array) $sidebars['jetpack-instant-search-sidebar'] as $widget_id ) {
427
				if ( 0 === strpos( $widget_id, $slug ) ) {
428
					// Already configured.
429
					return;
430
				}
431
			}
432
		}
433
434
		$has_sidebar           = isset( $wp_registered_sidebars['sidebar-1'] );
435
		$sidebar_id            = false;
436
		$sidebar_searchbox_idx = false;
437
		if ( $has_sidebar ) {
438
			if ( empty( $sidebars['sidebar-1'] ) ) {
439
				// Adding to an empty sidebar is generally a bad idea.
440
				$has_sidebar = false;
441
			}
442
			foreach ( (array) $sidebars['sidebar-1'] as $idx => $widget_id ) {
443
				if ( 0 === strpos( $widget_id, 'search-' ) ) {
444
					$sidebar_searchbox_idx = $idx;
445
				}
446
				if ( 0 === strpos( $widget_id, $slug ) ) {
447
					$sidebar_id = (int) str_replace( Jetpack_Search_Helpers::FILTER_WIDGET_BASE . '-', '', $widget_id );
448
					break;
449
				}
450
			}
451
		}
452
453
		$next_id         = 1;
454
		$widget_opt_name = Jetpack_Search_Helpers::get_widget_option_name();
455
		$widget_options  = get_option( $widget_opt_name, array() );
456
		foreach ( $widget_options as $id => $w ) {
457
			if ( $id >= $next_id ) {
458
				$next_id = $id + 1;
459
			}
460
		}
461
462
		// Copy sidebar settings to overlay.
463
		if ( ( false !== $sidebar_id ) && isset( $widget_options[ $sidebar_id ] ) ) {
464
			$widget_options[ $next_id ] = $widget_options[ $sidebar_id ];
465
			update_option( $widget_opt_name, $widget_options );
466
467
			if ( ! isset( $sidebars['jetpack-instant-search-sidebar'] ) ) {
468
				$sidebars['jetpack-instant-search-sidebar'] = array();
469
			}
470
			array_unshift( $sidebars['jetpack-instant-search-sidebar'], Jetpack_Search_Helpers::build_widget_id( $next_id ) );
471
			update_option( 'sidebars_widgets', $sidebars );
472
473
			return;
474
		}
475
476
		// Configure overlay and sidebar (if it exists).
477
		$preconfig_opts = $this->get_preconfig_widget_options();
478
		if ( ! isset( $sidebars['jetpack-instant-search-sidebar'] ) ) {
479
			$sidebars['jetpack-instant-search-sidebar'] = array();
480
		}
481
		if ( $has_sidebar ) {
482
			$widget_options[ $next_id ] = $preconfig_opts;
483
			if ( false !== $sidebar_searchbox_idx ) {
484
				// Replace Core search box.
485
				$sidebars['sidebar-1'][ $sidebar_searchbox_idx ] = Jetpack_Search_Helpers::build_widget_id( $next_id );
486
			} else {
487
				// Add to top.
488
				array_unshift( $sidebars['sidebar-1'], Jetpack_Search_Helpers::build_widget_id( $next_id ) );
489
			}
490
			$next_id++;
491
		}
492
		$widget_options[ $next_id ] = $preconfig_opts;
493
		array_unshift( $sidebars['jetpack-instant-search-sidebar'], Jetpack_Search_Helpers::build_widget_id( $next_id ) );
494
495
		update_option( $widget_opt_name, $widget_options );
496
		update_option( 'sidebars_widgets', $sidebars );
497
	}
498
499
	/**
500
	 * Autoconfig search by adding filter widgets
501
	 *
502
	 * @since  8.4.0
503
	 *
504
	 * @return array Array of config settings for search widget.
505
	 */
506
	protected function get_preconfig_widget_options() {
507
		$settings = array(
508
			'title'   => '',
509
			'filters' => array(),
510
		);
511
512
		$post_types = get_post_types(
513
			array(
514
				'public'   => true,
515
				'_builtin' => false,
516
			)
517
		);
518
519
		if ( ! empty( $post_types ) ) {
520
			$settings['filters'][] = array(
521
				array(
522
					'name'  => '',
523
					'type'  => 'post_type',
524
					'count' => 5,
525
				),
526
			);
527
		}
528
529
		$taxonomies = get_taxonomies(
530
			array(
531
				'public'   => true,
532
				'_builtin' => false,
533
			)
534
		);
535
536
		foreach ( $taxonomies as $t ) {
537
			$settings['filters'][] = array(
538
				'name'     => '',
539
				'type'     => 'taxonomy',
540
				'taxonomy' => $t,
541
				'count'    => 5,
542
			);
543
		}
544
545
		$settings['filters'][] = array(
546
			'name'     => '',
547
			'type'     => 'taxonomy',
548
			'taxonomy' => 'category',
549
			'count'    => 5,
550
		);
551
		$settings['filters'][] = array(
552
			'name'     => '',
553
			'type'     => 'taxonomy',
554
			'taxonomy' => 'post_tag',
555
			'count'    => 5,
556
		);
557
		$settings['filters'][] = array(
558
			'name'     => '',
559
			'type'     => 'date_histogram',
560
			'count'    => 5,
561
			'field'    => 'post_date',
562
			'interval' => 'year',
563
		);
564
		return $settings;
565
	}
566
	/**
567
	 * Automatically configure post types to exclude from one of the search widgets
568
	 *
569
	 * @since  8.8.0
570
	 */
571
	public function auto_config_excluded_post_types() {
572
		$post_types         = get_post_types(
573
			array(
574
				'exclude_from_search' => false,
575
				'public'              => true,
576
			)
577
		);
578
		$enabled_post_types = array();
579
		$widget_options     = get_option( Jetpack_Search_Helpers::get_widget_option_name(), array() );
580
581
		// Prior to Jetpack 8.8, post types were enabled via Jetpack Search widgets rather than disabled via the Customizer.
582
		// To continue supporting post types set up in the old way, we iterate through each Jetpack Search
583
		// widget configuration and append each enabled post type to $enabled_post_types.
584
		foreach ( $widget_options as $widget_option ) {
585
			if ( isset( $widget_option['post_types'] ) && is_array( $widget_option['post_types'] ) ) {
586
				foreach ( $widget_option['post_types'] as $enabled_post_type ) {
587
					$enabled_post_types[ $enabled_post_type ] = $enabled_post_type;
588
				}
589
			}
590
		}
591
592
		if ( ! empty( $enabled_post_types ) ) {
593
			$post_types_to_disable = array_diff( $post_types, $enabled_post_types );
594
			update_option( Jetpack_Search_Options::OPTION_PREFIX . 'excluded_post_types', join( ',', $post_types_to_disable ) );
595
		}
596
	}
597
}
598