Completed
Push — fix/visibility-condition-issue... ( eee6fd...a71c15 )
by
unknown
11:07
created

widget_conditions_has_children()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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