Completed
Push — add/comments/moderation-email-... ( de3dc7...f0fd59 )
by
unknown
09:51
created

Jetpack_Search_Helpers::get_widgets_from_option()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 2
nop 0
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
class Jetpack_Search_Helpers {
4
	const FILTER_WIDGET_BASE = 'jetpack-search-filters';
5
6
	static function get_search_url() {
7
		$query_args = $_GET;
8
9
		// Handle the case where a permastruct is being used, such as /search/{$query}
10
		if ( ! isset( $query_args['s'] ) ) {
11
			$query_args['s'] = get_search_query();
12
		}
13
14
		if ( isset( $query_args['paged'] ) ) {
15
			unset( $query_args['paged'] );
16
		}
17
18
		$query = http_build_query( $query_args );
19
		return home_url( "?{$query}" );
20
	}
21
22
	static function add_query_arg( $key, $value = false ) {
23
		if ( is_array( $key ) ) {
24
			return add_query_arg( $key, self::get_search_url() );
25
		}
26
27
		return add_query_arg( $key, $value, self::get_search_url() );
28
	}
29
30
	static function remove_query_arg( $key ) {
31
		return remove_query_arg( $key, self::get_search_url() );
32
	}
33
34
	static function get_widget_option_name() {
35
		return sprintf( 'widget_%s', self::FILTER_WIDGET_BASE );
36
	}
37
38
	static function get_widgets_from_option() {
39
		$widget_options = get_option( self::get_widget_option_name(), array() );
40
41
		// We don't need this
42
		if ( ! empty( $widget_options ) && isset( $widget_options['_multiwidget'] ) ) {
43
			unset( $widget_options['_multiwidget'] );
44
		}
45
46
		return $widget_options;
47
	}
48
49
	static function build_widget_id( $number ) {
50
		return sprintf( '%s-%d', self::FILTER_WIDGET_BASE, $number );
51
	}
52
53
	static function is_active_widget( $widget_id ) {
54
		return (bool) is_active_widget( false, $widget_id, self::FILTER_WIDGET_BASE );
55
	}
56
57
	static function get_filters_from_widgets() {
58
		$filters = array();
59
60
		$widget_options = self::get_widgets_from_option();
61
		if ( empty( $widget_options ) ) {
62
			return $filters;
63
		}
64
65
		foreach ( (array) $widget_options as $number => $settings ) {
66
			$widget_id = self::build_widget_id( $number );
67
			if ( ! self::is_active_widget( $widget_id ) || empty( $settings['filters'] ) ) {
68
				continue;
69
			}
70
71
			if ( empty( $settings['use_filters'] ) ) {
72
				continue;
73
			}
74
75
			foreach ( (array) $settings['filters'] as $widget_filter ) {
76
				$widget_filter['widget_id'] = $widget_id;
77
				$key = sprintf( '%s_%d', $widget_filter['type'], count( $filters ) );
78
				$filters[ $key ] = $widget_filter;
79
			}
80
		}
81
82
		return $filters;
83
	}
84
85
	/**
86
	 * Whether we should rerun a search in the customizer preview or not.
87
	 *
88
	 * @since 5.8.0
89
	 *
90
	 * @return bool
91
	 */
92
	static function should_rerun_search_in_customizer_preview() {
93
		// Only update when in a customizer preview and data is being posted.
94
		// Check for $_POST removes an extra update when the customizer loads.
95
		//
96
		// Note: We use $GLOBALS['wp_customize'] here instead of is_customize_preview() to support unit tests.
97
		if ( ! isset( $GLOBALS['wp_customize'] ) || ! $GLOBALS['wp_customize']->is_preview() || empty( $_POST ) ) {
98
			return false;
99
		}
100
101
		return true;
102
	}
103
104
	/**
105
	 * Since PHP's built-in array_diff() works by comparing the values that are in array 1 to the other arrays,
106
	 * if there are less values in array 1, it's possible to get an empty diff where one might be expected.
107
	 *
108
	 * @since 5.8.0
109
	 *
110
	 * @param array $array_1
111
	 * @param array $array_2
112
	 *
113
	 * @return array
114
	 */
115
	static function array_diff( $array_1, $array_2 ) {
116
		// If the array counts are the same, then the order doesn't matter. If the count of
117
		// $array_1 is higher than $array_2, that's also fine. If the count of $array_2 is higher,
118
		// we need to swap the array order though.
119
		if ( count( $array_1 ) != count( $array_2 ) && count( $array_2 ) > count( $array_1 ) ) {
120
			$temp = $array_1;
121
			$array_1 = $array_2;
122
			$array_2 = $temp;
123
		}
124
125
		// Disregard keys
126
		return array_values( array_diff( $array_1, $array_2 ) );
127
	}
128
129
	/**
130
	 * Given the widget instance, will return true when selected post types differ from searchable post types.
131
	 *
132
	 * @since 5.8.0
133
	 *
134
	 * @param array $instance
135
	 * @return bool
136
	 */
137
	static function post_types_differ_searchable( $instance ) {
138
		if ( empty( $instance['post_types'] ) ) {
139
			return false;
140
		}
141
142
		$searchable_post_types = get_post_types( array( 'exclude_from_search' => false ) );
143
		$diff_of_searchable = self::array_diff( $searchable_post_types, (array) $instance['post_types'] );
144
145
		return ! empty( $diff_of_searchable );
146
	}
147
148
	/**
149
	 * Given the widget instance, will return true when selected post types differ from the post type filters
150
	 * applied to the search.
151
	 *
152
	 * @since 5.8.0
153
	 *
154
	 * @param array $instance
155
	 * @return bool
156
	 */
157
	static function post_types_differ_query( $instance ) {
158
		if ( empty( $instance['post_types'] ) ) {
159
			return false;
160
		}
161
162
		if ( empty( $_GET['post_type'] ) ) {
163
			$post_types_from_query = array();
164
		} else if ( is_array( $_GET['post_type'] ) ) {
165
			$post_types_from_query = $_GET['post_type'];
166
		} else {
167
			$post_types_from_query = (array) explode( ',',  $_GET['post_type'] );
168
		}
169
170
		$post_types_from_query = array_map( 'trim', $post_types_from_query );
171
172
		$diff_query = self::array_diff( (array) $instance['post_types'], $post_types_from_query );
173
		return ! empty( $diff_query );
174
	}
175
176
	static function get_widget_tracks_value( $old_value, $new_value ) {
177
		$old_value = (array) $old_value;
178
		if ( isset( $old_value['_multiwidget'] ) ) {
179
			unset( $old_value['_multiwidget'] );
180
		}
181
182
		$new_value = (array) $new_value;
183
		if ( isset( $new_value['_multiwidget'] ) ) {
184
			unset( $new_value['_multiwidget'] );
185
		}
186
187
		$action = '';
0 ignored issues
show
Unused Code introduced by
$action 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...
188
		$old_keys = array_keys( $old_value );
189
		$new_keys = array_keys( $new_value );
190
191
		if ( count( $new_keys ) > count( $old_keys ) ) { // This is the case for a widget being added
192
			$diff = self::array_diff( $new_keys, $old_keys );
193
			$action = 'widget_added';
194
			$widget = empty( $diff ) || ! isset( $new_value[ $diff[0] ] )
195
				? false
196
				: $new_value[ $diff[0] ];
197
		} else if ( count( $old_keys ) > count( $new_keys ) ) { // This is the case for a widget being deleted
198
			$diff = self::array_diff( $old_keys, $new_keys );
199
			$action = 'widget_deleted';
200
			$widget = empty( $diff ) || ! isset( $old_value[ $diff[0] ] )
201
				? false
202
				: $old_value[ $diff[0] ];
203
		} else {
204
			$action = 'widget_updated';
205
			$widget = false;
206
207
			// This is a bit crazy. Since there can be multiple widgets stored in a single option,
208
			// we need to diff the old and new values to figure out which widget was updated.
209
			foreach ( $new_value as $key => $new_instance ) {
210
				if ( ! isset( $old_value[ $key ] ) ) {
211
					continue;
212
				}
213
				$old_instance = $old_value[ $key ];
214
215
				// First, let's test the keys of each instance
216
				$diff = self::array_diff( array_keys( $new_instance ), array_keys( $old_instance ) );
217
				if ( ! empty( $diff ) ) {
218
					$widget = $new_instance;
219
					break;
220
				}
221
222
				// Next, lets's loop over each value and compare it
223
				foreach ( $new_instance as $k => $v ) {
224
					if ( is_scalar( $v ) && (string) $v !== (string) $old_instance[ $k ] ) {
225
						$widget = $new_instance;
226
						break;
227
					}
228
229
					if ( 'filters' == $k ) {
230
						if ( count( $new_instance['filters'] ) != count( $old_instance['filters'] ) ) {
231
							$widget = $new_instance;
232
							break;
233
						}
234
235
						foreach ( $v as $filter_key => $new_filter_value ) {
236
							$diff = self::array_diff( $new_filter_value, $old_instance[ 'filters' ][ $filter_key ] );
237
							if ( ! empty( $diff ) ) {
238
								$widget = $new_instance;
239
								break;
240
							}
241
						}
242
					}
243
				}
244
			}
245
		}
246
247
		if ( empty( $action ) || empty( $widget ) ) {
248
			return false;
249
		}
250
251
		return array(
252
			'action' => $action,
253
			'widget' => self::get_widget_properties_for_tracks( $widget ),
254
		);
255
	}
256
257
	static function get_widget_properties_for_tracks( $widget ) {
258
		$sanitized = array();
259
260
		foreach ( (array) $widget as $key => $value ) {
261
			if ( '_multiwidget' == $key ) {
262
				continue;
263
			}
264
			if ( is_scalar( $value ) ) {
265
				$key = str_replace( '-', '_', sanitize_key( $key ) );
266
				$key = "widget_{$key}";
267
				$sanitized[ $key ] = $value;
268
			}
269
		}
270
271
		$filters_properties = ! empty( $widget['filters'] )
272
			? self::get_filter_properties_for_tracks( $widget['filters'] )
273
			: array();
274
275
		return array_merge( $sanitized, $filters_properties );
276
	}
277
278
	static function get_filter_properties_for_tracks( $filters ) {
279
		if ( empty( $filters ) ) {
280
			return $filters;
281
		}
282
283
		$filters_properties = array(
284
			'widget_filter_count' => count( $filters ),
285
		);
286
287
		foreach ( $filters as $filter ) {
288
			if ( empty( $filter['type'] ) ) {
289
				continue;
290
			}
291
292
			$key = sprintf( 'widget_filter_type_%s', $filter['type'] );
293
			if ( isset( $filters_properties[ $key ] ) ) {
294
				$filters_properties[ $key ]++;
295
			} else {
296
				$filters_properties[ $key ] = 1;
297
			}
298
		}
299
300
		return $filters_properties;
301
	}
302
}
303