Completed
Push — branch-4.7-built ( d133c7...cb9558 )
by
unknown
64:35 queued 55:53
created

Jetpack_Widget_Conditions::widget_admin_setup()   F

Complexity

Conditions 13
Paths 2304

Size

Total Lines 133
Code Lines 78

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 78
nc 2304
nop 0
dl 0
loc 133
rs 2
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
4
/**
5
 * Hide or show widgets conditionally.
6
 */
7
8
class Jetpack_Widget_Conditions {
9
	static $passed_template_redirect = false;
0 ignored issues
show
Coding Style introduced by
The visibility should be declared for property $passed_template_redirect.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
10
11
	public static function init() {
12
		if ( is_admin() ) {
13
			add_action( 'sidebar_admin_setup', array( __CLASS__, 'widget_admin_setup' ) );
14
			add_filter( 'widget_update_callback', array( __CLASS__, 'widget_update' ), 10, 3 );
15
			add_action( 'in_widget_form', array( __CLASS__, 'widget_conditions_admin' ), 10, 3 );
16
		} else if ( ! in_array( $GLOBALS['pagenow'], array( 'wp-login.php', 'wp-register.php' ) ) ) {
17
			add_filter( 'widget_display_callback', array( __CLASS__, 'filter_widget' ) );
18
			add_filter( 'sidebars_widgets', array( __CLASS__, 'sidebars_widgets' ) );
19
			add_action( 'template_redirect', array( __CLASS__, 'template_redirect' ) );
20
		}
21
	}
22
23
	public static function widget_admin_setup() {
24
		if( is_rtl() ) {
25
			wp_enqueue_style( 'widget-conditions', plugins_url( 'widget-conditions/rtl/widget-conditions-rtl.css', __FILE__ ) );
26
		} else {
27
			wp_enqueue_style( 'widget-conditions', plugins_url( 'widget-conditions/widget-conditions.css', __FILE__ ) );
28
		}
29
		wp_enqueue_style( 'widget-conditions', plugins_url( 'widget-conditions/widget-conditions.css', __FILE__ ) );
30
		wp_enqueue_script( 'widget-conditions', plugins_url( 'widget-conditions/widget-conditions.js', __FILE__ ), array( 'jquery', 'jquery-ui-core' ), 20140721, true );
31
32
		// Set up a single copy of all of the data that Widget Visibility needs.
33
		// This allows all widget conditions to reuse the same data, keeping page size down
34
		// and eliminating the AJAX calls we used to have to use to fetch the minor rule options.
35
		$widget_conditions_data = array();
36
37
		$widget_conditions_data['category'] = array();
38
		$widget_conditions_data['category'][] = array( '', __( 'All category pages', 'jetpack' ) );
39
40
		$categories = get_categories( array( 'number' => 1000, 'orderby' => 'count', 'order' => 'DESC' ) );
41
		usort( $categories, array( __CLASS__, 'strcasecmp_name' ) );
42
43
		foreach ( $categories as $category ) {
44
			$widget_conditions_data['category'][] = array( (string) $category->term_id, $category->name );
45
		}
46
47
		$widget_conditions_data['loggedin'] = array();
48
		$widget_conditions_data['loggedin'][] = array( 'loggedin', __( 'Logged In', 'jetpack' ) );
49
		$widget_conditions_data['loggedin'][] = array( 'loggedout', __( 'Logged Out', 'jetpack' ) );
50
51
		$widget_conditions_data['author'] = array();
52
		$widget_conditions_data['author'][] = array( '', __( 'All author pages', 'jetpack' ) );
53
54
		$authors = get_users( array( 'orderby' => 'name', 'exclude_admin' => true ) );
55
56
		foreach ( $authors as $author ) {
57
			$widget_conditions_data['author'][] = array( (string) $author->ID, $author->display_name );
58
		}
59
60
		$widget_conditions_data['role'] = array();
61
62
		global $wp_roles;
63
64
		foreach ( $wp_roles->roles as $role_key => $role ) {
65
			$widget_conditions_data['role'][] = array( (string) $role_key, $role['name'] );
66
		}
67
68
		$widget_conditions_data['tag'] = array();
69
		$widget_conditions_data['tag'][] = array( '', __( 'All tag pages', 'jetpack' ) );
70
71
		$tags = get_tags( array( 'number' => 1000, 'orderby' => 'count', 'order' => 'DESC' ) );
72
		usort( $tags, array( __CLASS__, 'strcasecmp_name' ) );
73
74
		foreach ( $tags as $tag ) {
75
			$widget_conditions_data['tag'][] = array( (string) $tag->term_id, $tag->name );
76
		}
77
78
		$widget_conditions_data['date'] = array();
79
		$widget_conditions_data['date'][] = array( '', __( 'All date archives', 'jetpack' ) );
80
		$widget_conditions_data['date'][] = array( 'day', __( 'Daily archives', 'jetpack' ) );
81
		$widget_conditions_data['date'][] = array( 'month', __( 'Monthly archives', 'jetpack' ) );
82
		$widget_conditions_data['date'][] = array( 'year', __( 'Yearly archives', 'jetpack' ) );
83
84
		$widget_conditions_data['page'] = array();
85
		$widget_conditions_data['page'][] = array( 'front', __( 'Front page', 'jetpack' ) );
86
		$widget_conditions_data['page'][] = array( 'posts', __( 'Posts page', 'jetpack' ) );
87
		$widget_conditions_data['page'][] = array( 'archive', __( 'Archive page', 'jetpack' ) );
88
		$widget_conditions_data['page'][] = array( '404', __( '404 error page', 'jetpack' ) );
89
		$widget_conditions_data['page'][] = array( 'search', __( 'Search results', 'jetpack' ) );
90
91
		$post_types = get_post_types( array( 'public' => true ), 'objects' );
92
93
		$widget_conditions_post_types = array();
94
		$widget_conditions_post_type_archives = array();
95
96
		foreach ( $post_types as $post_type ) {
97
			$widget_conditions_post_types[] = array( 'post_type-' . $post_type->name, $post_type->labels->singular_name );
98
			$widget_conditions_post_type_archives[] = array( 'post_type_archive-' . $post_type->name, $post_type->labels->name );
99
		}
100
101
		$widget_conditions_data['page'][] = array( __( 'Post type:', 'jetpack' ), $widget_conditions_post_types );
102
103
		$widget_conditions_data['page'][] = array( __( 'Post type Archives:', 'jetpack' ), $widget_conditions_post_type_archives );
104
105
		$pages_dropdown = preg_replace( '/<\/?select[^>]*?>/i', '', wp_dropdown_pages( array( 'echo' => false ) ) );
106
107
		preg_match_all( '/value=.([0-9]+).[^>]*>([^<]+)</', $pages_dropdown, $page_ids_and_titles, PREG_SET_ORDER );
108
109
		$static_pages = array();
110
111
		foreach ( $page_ids_and_titles as $page_id_and_title ) {
0 ignored issues
show
Bug introduced by
The expression $page_ids_and_titles of type null|array<integer,array<integer,string>> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
112
			$static_pages[] = array( (string) $page_id_and_title[1], $page_id_and_title[2] );
113
		}
114
115
		$widget_conditions_data['page'][] = array( __( 'Static page:', 'jetpack' ), $static_pages );
116
117
		$widget_conditions_data['taxonomy'] = array();
118
		$widget_conditions_data['taxonomy'][] = array( '', __( 'All taxonomy pages', 'jetpack' ) );
119
120
		$taxonomies = get_taxonomies( array( '_builtin' => false ), 'objects' );
121
		usort( $taxonomies, array( __CLASS__, 'strcasecmp_name' ) );
122
123
		foreach ( $taxonomies as $taxonomy ) {
124
			$taxonomy_terms = get_terms( array( $taxonomy->name ), array( 'number' => 250, 'hide_empty' => false ) );
125
126
			$widget_conditions_terms = array();
127
			$widget_conditions_terms[] = array( $taxonomy->name, __( 'All pages', 'jetpack' ) );
128
129
			foreach ( $taxonomy_terms as $term ) {
130
				$widget_conditions_terms[] = array( $taxonomy->name . '_tax_' . $term->term_id, $term->name );
131
			}
132
133
			$widget_conditions_data['taxonomy'][] = array( $taxonomy->labels->name . ':', $widget_conditions_terms );
134
		}
135
136
		wp_localize_script( 'widget-conditions', 'widget_conditions_data', $widget_conditions_data );
137
138
		// Save a list of the IDs of all pages that have children for dynamically showing the "Include children" checkbox.
139
		$all_pages = get_pages();
140
		$all_parents = array();
141
142
		foreach ( $all_pages as $page ) {
143
			if ( $page->post_parent ) {
144
				$all_parents[ (string) $page->post_parent ] = true;
145
			}
146
		}
147
148
		$front_page_id = get_option( 'page_on_front' );
149
150
		if ( isset( $all_parents[ $front_page_id ] ) ) {
151
			$all_parents[ 'front' ] = true;
152
		}
153
154
		wp_localize_script( 'widget-conditions', 'widget_conditions_parent_pages', $all_parents );
155
	}
156
157
	/**
158
	 * Add the widget conditions to each widget in the admin.
159
	 *
160
	 * @param $widget unused.
161
	 * @param $return unused.
162
	 * @param array $instance The widget settings.
163
	 */
164
	public static function widget_conditions_admin( $widget, $return, $instance ) {
165
		$conditions = array();
166
167
		if ( isset( $instance['conditions'] ) )
168
			$conditions = $instance['conditions'];
169
170
		if ( ! isset( $conditions['action'] ) )
171
			$conditions['action'] = 'show';
172
173
		if ( empty( $conditions['rules'] ) )
174
			$conditions['rules'][] = array( 'major' => '', 'minor' => '', 'has_children' => '' );
175
176
		if ( empty( $conditions['match_all'] ) ) {
177
			$conditions['match_all'] = false;
178
		}
179
180
		?>
181
		<div
182
			class="
183
				widget-conditional
184
				<?php
185
					if (
186
						empty( $_POST['widget-conditions-visible'] )
187
						|| $_POST['widget-conditions-visible'] == '0'
188
					) {
189
						?>widget-conditional-hide<?php
190
					}
191
				?>
192
				<?php
193
					if ( ! empty( $conditions['match_all'] ) && $conditions['match_all'] ) {
194
						?>intersection<?php
195
					} else {
196
						?>conjunction<?php
197
					}
198
				?>
199
			">
200
			<input type="hidden" name="widget-conditions-visible" value="<?php if ( isset( $_POST['widget-conditions-visible'] ) ) { echo esc_attr( $_POST['widget-conditions-visible'] ); } else { ?>0<?php } ?>" />
201
			<?php if ( ! isset( $_POST['widget-conditions-visible'] ) ) { ?><a href="#" class="button display-options"><?php _e( 'Visibility', 'jetpack' ); ?></a><?php } ?>
202
			<div class="widget-conditional-inner">
203
				<div class="condition-top">
204
					<?php printf( _x( '%s if:', 'placeholder: dropdown menu to select widget visibility; hide if or show if', 'jetpack' ), '<select name="conditions[action]"><option value="show" ' . selected( $conditions['action'], 'show', false ) . '>' . esc_html_x( 'Show', 'Used in the "%s if:" translation for the widget visibility dropdown', 'jetpack' ) . '</option><option value="hide" ' . selected( $conditions['action'], 'hide', false ) . '>' . esc_html_x( 'Hide', 'Used in the "%s if:" translation for the widget visibility dropdown', 'jetpack' ) . '</option></select>' ); ?>
205
				</div><!-- .condition-top -->
206
207
				<div class="conditions">
208
					<?php
209
210
					foreach ( $conditions['rules'] as $rule_index => $rule ) {
211
						$rule = wp_parse_args( $rule, array( 'major' => '', 'minor' => '', 'has_children' => '' ) );
212
						?>
213
						<div class="condition" data-rule-major="<?php echo esc_attr( $rule['major'] ); ?>" data-rule-minor="<?php echo esc_attr( $rule['minor'] ); ?>" data-rule-has-children="<?php echo esc_attr( $rule['has_children'] ); ?>">
214
							<div class="selection alignleft">
215
								<select class="conditions-rule-major" name="conditions[rules_major][]">
216
									<option value="" <?php selected( "", $rule['major'] ); ?>><?php echo esc_html_x( '-- Select --', 'Used as the default option in a dropdown list', 'jetpack' ); ?></option>
217
									<option value="category" <?php selected( "category", $rule['major'] ); ?>><?php esc_html_e( 'Category', 'jetpack' ); ?></option>
218
									<option value="author" <?php selected( "author", $rule['major'] ); ?>><?php echo esc_html_x( 'Author', 'Noun, as in: "The author of this post is..."', 'jetpack' ); ?></option>
219
220
									<?php if( ! ( defined( 'IS_WPCOM' ) && IS_WPCOM ) ) { // this doesn't work on .com because of caching ?>
221
										<option value="loggedin" <?php selected( "loggedin", $rule['major'] ); ?>><?php echo esc_html_x( 'User', 'Noun', 'jetpack' ); ?></option>
222
										<option value="role" <?php selected( "role", $rule['major'] ); ?>><?php echo esc_html_x( 'Role', 'Noun, as in: "The user role of that can access this widget is..."', 'jetpack' ); ?></option>
223
									<?php } ?>
224
225
									<option value="tag" <?php selected( "tag", $rule['major'] ); ?>><?php echo esc_html_x( 'Tag', 'Noun, as in: "This post has one tag."', 'jetpack' ); ?></option>
226
									<option value="date" <?php selected( "date", $rule['major'] ); ?>><?php echo esc_html_x( 'Date', 'Noun, as in: "This page is a date archive."', 'jetpack' ); ?></option>
227
									<option value="page" <?php selected( "page", $rule['major'] ); ?>><?php echo esc_html_x( 'Page', 'Example: The user is looking at a page, not a post.', 'jetpack' ); ?></option>
228
									<?php if ( get_taxonomies( array( '_builtin' => false ) ) ) : ?>
229
										<option value="taxonomy" <?php selected( "taxonomy", $rule['major'] ); ?>><?php echo esc_html_x( 'Taxonomy', 'Noun, as in: "This post has one taxonomy."', 'jetpack' ); ?></option>
230
									<?php endif; ?>
231
								</select>
232
233
								<?php _ex( 'is', 'Widget Visibility: {Rule Major [Page]} is {Rule Minor [Search results]}', 'jetpack' ); ?>
234
235
								<select class="conditions-rule-minor" name="conditions[rules_minor][]" <?php if ( ! $rule['major'] ) { ?> disabled="disabled"<?php } ?>>
236
									<?php /* Include the currently selected value so that if the widget is saved without
237
									         expanding the Visibility section, we don't lose the minor part of the rule.
238
									         If it is opened, this list is cleared out and populated with all the values. */ ?>
239
									<option value="<?php echo esc_attr( $rule['minor'] ); ?>" selected="selected"></option>
240
								</select>
241
242
								<span class="conditions-rule-has-children" <?php if ( ! $rule['has_children'] ) { ?> style="display: none;"<?php } ?>>
243
									<label>
244
										<input type="checkbox" name="conditions[page_children][<?php echo $rule_index; ?>]" value="has" <?php checked( $rule['has_children'], true ); ?> />
245
										<?php echo esc_html_x( "Include children", 'Checkbox on Widget Visibility if children of the selected page should be included in the visibility rule.', 'jetpack' ); ?>
246
									</label>
247
								</span>
248
							</div>
249
250
							<div class="condition-control">
251
								<span class="condition-conjunction">
252
									<?php echo esc_html_x( 'or', 'Shown between widget visibility conditions.', 'jetpack' ); ?>
253
								</span>
254
								<span class="condition-intersection">
255
									<?php echo esc_html_x( 'and', 'Shown between widget visibility conditions.', 'jetpack' ); ?>
256
								</span>
257
								<div class="actions alignright">
258
									<a href="#" class="delete-condition dashicons dashicons-no"><?php esc_html_e( 'Delete', 'jetpack' ); ?></a><a href="#" class="add-condition dashicons dashicons-plus"><?php esc_html_e( 'Add', 'jetpack' ); ?></a>
259
								</div>
260
							</div>
261
262
						</div><!-- .condition -->
263
						<?php
264
					}
265
266
					?>
267
				</div><!-- .conditions -->
268
				<div class="conditions">
269
					<div class="condition-top">
270
						<label>
271
							<input
272
								type="checkbox"
273
								name="conditions[match_all]"
274
								value="1"
275
								class="conditions-match-all"
276
								<?php checked( $conditions['match_all'], '1' ); ?> />
277
							<?php esc_html_e( 'Match all conditions', 'jetpack' ); ?>
278
						</label>
279
					</div><!-- .condition-top -->
280
				</div><!-- .conditions -->
281
			</div><!-- .widget-conditional-inner -->
282
		</div><!-- .widget-conditional -->
283
		<?php
284
	}
285
286
	/**
287
	 * On an AJAX update of the widget settings, process the display conditions.
288
	 *
289
	 * @param array $new_instance New settings for this instance as input by the user.
290
	 * @param array $old_instance Old settings for this instance.
291
	 * @return array Modified settings.
292
	 */
293
	public static function widget_update( $instance, $new_instance, $old_instance ) {
294
		if ( empty( $_POST['conditions'] ) ) {
295
			return $instance;
296
		}
297
298
		$conditions = array();
299
		$conditions['action'] = $_POST['conditions']['action'];
300
		$conditions['match_all'] = ( isset( $_POST['conditions']['match_all'] ) ? '1' : '0' );
301
		$conditions['rules'] = array();
302
303
		foreach ( $_POST['conditions']['rules_major'] as $index => $major_rule ) {
304
			if ( ! $major_rule )
305
				continue;
306
307
			$conditions['rules'][] = array(
308
				'major' => $major_rule,
309
				'minor' => isset( $_POST['conditions']['rules_minor'][$index] ) ? $_POST['conditions']['rules_minor'][$index] : '',
310
				'has_children' => isset( $_POST['conditions']['page_children'][$index] ) ? true : false,
311
			);
312
		}
313
314
		if ( ! empty( $conditions['rules'] ) )
315
			$instance['conditions'] = $conditions;
316
		else
317
			unset( $instance['conditions'] );
318
319
		if (
320
				( isset( $instance['conditions'] ) && ! isset( $old_instance['conditions'] ) )
321
				||
322
				(
323
					isset( $instance['conditions'], $old_instance['conditions'] )
324
					&&
325
					serialize( $instance['conditions'] ) != serialize( $old_instance['conditions'] )
326
				)
327
			) {
328
329
			/**
330
			 * Fires after the widget visibility conditions are saved.
331
			 *
332
			 * @module widget-visibility
333
			 *
334
			 * @since 2.4.0
335
			 */
336
			do_action( 'widget_conditions_save' );
337
		}
338
		else if ( ! isset( $instance['conditions'] ) && isset( $old_instance['conditions'] ) ) {
339
340
			/**
341
			 * Fires after the widget visibility conditions are deleted.
342
			 *
343
			 * @module widget-visibility
344
			 *
345
			 * @since 2.4.0
346
			 */
347
			do_action( 'widget_conditions_delete' );
348
		}
349
350
		return $instance;
351
	}
352
353
	/**
354
	 * Filter the list of widgets for a sidebar so that active sidebars work as expected.
355
	 *
356
	 * @param array $widget_areas An array of widget areas and their widgets.
357
	 * @return array The modified $widget_area array.
358
	 */
359
	public static function sidebars_widgets( $widget_areas ) {
360
		$settings = array();
361
362
		foreach ( $widget_areas as $widget_area => $widgets ) {
363
			if ( empty( $widgets ) )
364
				continue;
365
366
			if ( ! is_array( $widgets ) )
367
				continue;
368
369
			if ( 'wp_inactive_widgets' == $widget_area )
370
				continue;
371
372
			foreach ( $widgets as $position => $widget_id ) {
373
				// Find the conditions for this widget.
374
				if ( preg_match( '/^(.+?)-(\d+)$/', $widget_id, $matches ) ) {
375
					$id_base = $matches[1];
376
					$widget_number = intval( $matches[2] );
377
				}
378
				else {
379
					$id_base = $widget_id;
380
					$widget_number = null;
381
				}
382
383
				if ( ! isset( $settings[$id_base] ) ) {
384
					$settings[$id_base] = get_option( 'widget_' . $id_base );
385
				}
386
387
				// New multi widget (WP_Widget)
388
				if ( ! is_null( $widget_number ) ) {
389
					if ( isset( $settings[$id_base][$widget_number] ) && false === self::filter_widget( $settings[$id_base][$widget_number] ) ) {
390
						unset( $widget_areas[$widget_area][$position] );
391
					}
392
				}
393
394
				// Old single widget
395
				else if ( ! empty( $settings[ $id_base ] ) && false === self::filter_widget( $settings[$id_base] ) ) {
396
					unset( $widget_areas[$widget_area][$position] );
397
				}
398
			}
399
		}
400
401
		return $widget_areas;
402
	}
403
404
	public static function template_redirect() {
405
		self::$passed_template_redirect = true;
406
	}
407
408
	/**
409
	 * Generates a condition key based on the rule array
410
	 *
411
	 * @param array $rule
412
	 * @return string key used to retrieve the condition.
413
	 */
414
	static function generate_condition_key( $rule ) {
415
		if ( isset( $rule['has_children'] ) ) {
416
			return $rule['major'] . ":" . $rule['minor'] . ":" . $rule['has_children'];
417
		}
418
		return $rule['major'] . ":" . $rule['minor'];
419
	}
420
421
	/**
422
	 * Determine whether the widget should be displayed based on conditions set by the user.
423
	 *
424
	 * @param array $instance The widget settings.
425
	 * @return array Settings to display or bool false to hide.
426
	 */
427
	public static function filter_widget( $instance ) {
428
		global $wp_query;
429
430
		if ( empty( $instance['conditions'] ) || empty( $instance['conditions']['rules'] ) )
431
			return $instance;
432
433
		// Store the results of all in-page condition lookups so that multiple widgets with
434
		// the same visibility conditions don't result in duplicate DB queries.
435
		static $condition_result_cache = array();
436
437
		$condition_result = false;
438
439
		foreach ( $instance['conditions']['rules'] as $rule ) {
440
			$condition_result = false;
441
			$condition_key = self::generate_condition_key( $rule );
442
443
			if ( isset( $condition_result_cache[ $condition_key ] ) ) {
444
				$condition_result = $condition_result_cache[ $condition_key ];
445
			}
446
			else {
447
				switch ( $rule['major'] ) {
448
					case 'date':
449
						switch ( $rule['minor'] ) {
450
							case '':
451
								$condition_result = is_date();
452
							break;
453
							case 'month':
454
								$condition_result = is_month();
455
							break;
456
							case 'day':
457
								$condition_result = is_day();
458
							break;
459
							case 'year':
460
								$condition_result = is_year();
461
							break;
462
						}
463
					break;
464
					case 'page':
465
						// Previously hardcoded post type options.
466
						if ( 'post' == $rule['minor'] )
467
							$rule['minor'] = 'post_type-post';
468
						else if ( ! $rule['minor'] )
469
							$rule['minor'] = 'post_type-page';
470
471
						switch ( $rule['minor'] ) {
472
							case '404':
473
								$condition_result = is_404();
474
							break;
475
							case 'search':
476
								$condition_result = is_search();
477
							break;
478
							case 'archive':
479
								$condition_result = is_archive();
480
							break;
481
							case 'posts':
482
								$condition_result = $wp_query->is_posts_page;
483
							break;
484
							case 'home':
485
								$condition_result = is_home();
486
							break;
487
							case 'front':
488
								if ( current_theme_supports( 'infinite-scroll' ) )
489
									$condition_result = is_front_page();
490
								else {
491
									$condition_result = is_front_page() && !is_paged();
492
								}
493
							break;
494
							default:
495
								if ( substr( $rule['minor'], 0, 10 ) == 'post_type-' ) {
496
									$condition_result = is_singular( substr( $rule['minor'], 10 ) );
497 View Code Duplication
								} elseif ( substr( $rule['minor'], 0, 18 ) == 'post_type_archive-' ) {
498
									$condition_result = is_post_type_archive( substr( $rule['minor'], 18 ) );
499
								} elseif ( $rule['minor'] == get_option( 'page_for_posts' ) ) {
500
									// If $rule['minor'] is a page ID which is also the posts page
501
									$condition_result = $wp_query->is_posts_page;
502
								} else {
503
									// $rule['minor'] is a page ID
504
									$condition_result = is_page() && ( $rule['minor'] == get_the_ID() );
505
506
									// Check if $rule['minor'] is parent of page ID
507
									if ( ! $condition_result && isset( $rule['has_children'] ) && $rule['has_children'] )
508
										$condition_result = wp_get_post_parent_id( get_the_ID() ) == $rule['minor'];
509
								}
510
							break;
511
						}
512
					break;
513 View Code Duplication
					case 'tag':
514
						// All tag pages.
515
						if( ! $rule['minor'] ) {
516
							if ( is_tag() ) {
517
								$condition_result = true;
518
							} else if ( is_singular() ) {
519
								if( in_array( 'post_tag', get_post_taxonomies() ) ) {
520
									$condition_result = true;
521
								}
522
							}
523
							break;
524
						}
525
526
						// All pages with the specified tag term.
527
						if ( is_tag( $rule['minor'] ) ) {
528
							$condition_result = true;
529
						}
530
						else if ( is_singular() && has_term( $rule['minor'], 'post_tag' ) ) {
531
							$condition_result = true;
532
						}
533
					break;
534 View Code Duplication
					case 'category':
535
						// All category pages.
536
						if( ! $rule['minor'] ) {
537
							if ( is_category() ) {
538
								$condition_result = true;
539
							}
540
							else if ( is_singular() ) {
541
								if( in_array( 'category', get_post_taxonomies() ) ) {
542
									$condition_result = true;
543
								}
544
							}
545
							break;
546
						}
547
548
						// All pages with the specified category term.
549
						if ( is_category( $rule['minor'] ) ) {
550
							$condition_result = true;
551
						}
552
						else if ( is_singular() && has_term( $rule['minor'], 'category' ) ) {
553
							$condition_result = true;
554
						}
555
					break;
556
					case 'loggedin':
557
						$condition_result = is_user_logged_in();
558
						if ( 'loggedin' !== $rule['minor'] ) {
559
							$condition_result = ! $condition_result;
560
						}
561
					break;
562
					case 'author':
563
						$post = get_post();
564
						if ( ! $rule['minor'] && is_author() )
565
							$condition_result = true;
566
						else if ( $rule['minor'] && is_author( $rule['minor'] ) )
567
							$condition_result = true;
568
						else if ( is_singular() && $rule['minor'] && $rule['minor'] == $post->post_author )
569
							$condition_result = true;
570
					break;
571
					case 'role':
572
						if( is_user_logged_in() ) {
573
							$current_user = wp_get_current_user();
574
575
							$user_roles = $current_user->roles;
576
577
							if( in_array( $rule['minor'], $user_roles ) ) {
578
								$condition_result = true;
579
							} else {
580
								$condition_result = false;
581
							}
582
583
						} else {
584
							$condition_result = false;
585
						}
586
					break;
587
					case 'post_type':
588
						if ( substr( $rule['minor'], 0, 10 ) == 'post_type-' ) {
589
							$condition_result = is_singular( substr( $rule['minor'], 10 ) );
590 View Code Duplication
						} elseif ( substr( $rule['minor'], 0, 18 ) == 'post_type_archive-' ) {
591
							$condition_result = is_post_type_archive( substr( $rule['minor'], 18 ) );
592
						}
593
					break;
594
					case 'taxonomy':
595
						// All taxonomy pages.
596
						if( ! $rule['minor'] ) {
597
							if ( is_archive() ) {
598
								if ( is_tag() || is_category() || is_tax() ) {
599
									$condition_result = true;
600
								}
601
							}
602
							else if ( is_singular() ) {
603
								$post_taxonomies = get_post_taxonomies();
604
								$condition_result = ! empty( $post_taxonomies );
605
							}
606
							break;
607
						}
608
609
						// Specified taxonomy page.
610
						$term = explode( '_tax_', $rule['minor'] ); // $term[0] = taxonomy name; $term[1] = term id
611
						if ( isset( $term[0] ) && isset( $term[1] ) ) {
612
							$term[1] = self::maybe_get_split_term( $term[1], $term[0] );
613
						}
614
615
						// All pages of the specified taxonomy.
616
						if ( ! isset( $term[1] ) || ! $term[1] ) {
617
							if ( is_tax( $term[0] ) ) {
618
								$condition_result = true;
619
							}
620
							else if ( is_singular() ) {
621
								if( in_array( $term[0], get_post_taxonomies() ) ) {
622
									$condition_result = true;
623
								}
624
							}
625
							break;
626
						}
627
628
						// All pages with the specified taxonomy term.
629
						if ( is_tax( $term[0], $term[1] ) ) {
630
							$condition_result = true;
631
						}
632
						else if ( is_singular() && has_term( $term[1], $term[0] ) ) {
633
							$condition_result = true;
634
						}
635
					break;
636
				}
637
638
				if ( $condition_result || self::$passed_template_redirect ) {
639
					// Some of the conditions will return false when checked before the template_redirect
640
					// action has been called, like is_page(). Only store positive lookup results, which
641
					// won't be false positives, before template_redirect, and everything after.
642
					$condition_result_cache[ $condition_key ] = $condition_result;
643
				}
644
			}
645
646
			if (
647
				isset( $instance['conditions']['match_all'] )
648
				&& $instance['conditions']['match_all'] == '1'
649
				&& ! $condition_result
650
			) {
651
652
				// In case the match_all flag was set we quit on first failed condition
653
				break;
654
			} elseif (
655
				(
656
					empty( $instance['conditions']['match_all'] )
657
					|| $instance['conditions']['match_all'] !== '1'
658
				)
659
				&& $condition_result
660
			) {
661
662
				// Only quit on first condition if the match_all flag was not set
663
				break;
664
			}
665
		}
666
667
		if (
668
			(
669
				'show' == $instance['conditions']['action']
670
				&& ! $condition_result
671
			) || (
672
				'hide' == $instance['conditions']['action']
673
				&& $condition_result
674
			)
675
		) {
676
			return false;
677
		}
678
679
		return $instance;
680
	}
681
682
	public static function strcasecmp_name( $a, $b ) {
683
		return strcasecmp( $a->name, $b->name );
684
	}
685
686
	public static function maybe_get_split_term( $old_term_id = '', $taxonomy = '' ) {
687
		$term_id = $old_term_id;
688
689
		if ( 'tag' == $taxonomy ) {
690
			$taxonomy = 'post_tag';
691
		}
692
693
		if ( function_exists( 'wp_get_split_term' ) && $new_term_id = wp_get_split_term( $old_term_id, $taxonomy ) ) {
694
			$term_id = $new_term_id;
695
		}
696
697
		return $term_id;
698
	}
699
700
	/**
701
	 * Upgrade routine to go through all widgets and move the Post Type
702
	 * setting to its newer location.
703
	 *
704
	 * @since 4.7.1
705
	 *
706
	 */
707
	static function migrate_post_type_rules() {
708
		global $wp_registered_widgets;
709
710
		$sidebars_widgets = get_option( 'sidebars_widgets' );
711
712
		// Going through all sidebars and through inactive and orphaned widgets
713
		foreach ( $sidebars_widgets as $s => $sidebar ) {
714
			if ( ! is_array( $sidebar ) ) {
715
				continue;
716
			}
717
718
			foreach ( $sidebar as $w => $widget ) {
719
				// $widget is the id of the widget
720
				if ( empty( $wp_registered_widgets[ $widget ] ) ) {
721
					continue;
722
				}
723
724
				$opts = $wp_registered_widgets[ $widget ];
725
				$instances = get_option( $opts['callback'][0]->option_name );
726
727
				// Going through each instance of the widget
728
				foreach( $instances as $number => $instance ) {
729
					if (
730
						! is_array( $instance ) ||
731
						empty( $instance['conditions'] ) ||
732
						empty( $instance['conditions']['rules'] )
733
					) {
734
						continue;
735
					}
736
737
					// Going through all visibility rules
738
					foreach( $instance['conditions']['rules'] as $index => $rule ) {
739
740
						// We only need Post Type rules
741
						if ( 'post_type' !== $rule['major'] ) {
742
							continue;
743
						}
744
745
						$rule_type = false;
746
747
						// Post type or type archive rule
748
						if ( 0 === strpos( $rule['minor'], 'post_type_archive' ) ) {
749
							$rule_type = 'post_type_archive';
750
						} else if ( 0 === strpos( $rule['minor'], 'post_type' ) ) {
751
							$rule_type = 'post_type';
752
						}
753
754
						if ( $rule_type ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $rule_type of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
755
							$post_type = substr( $rule['minor'], strlen( $rule_type ) + 1 );
756
							$rule['minor'] = $rule_type . '-' . $post_type;
757
							$rule['major'] = 'page';
758
759
							$instances[ $number ]['conditions']['rules'][ $index ] = $rule;
760
						}
761
					}
762
				}
763
764
				update_option( $opts['callback'][0]->option_name, $instances );
765
			}
766
		}
767
	}
768
769
}
770
771
add_action( 'init', array( 'Jetpack_Widget_Conditions', 'init' ) );
772