PluginProbe
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More / 2.6.1
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More v2.6.1
trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.10 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 47 releases
← All changes | classes/RuleEngine/Rules.php +138 -47 2.0.122.6.1 View file →
@@ -10,8 +10,10 @@
10 10 defined( 'ABSPATH' ) || exit;
11 11
12 12 use ContentControl\Models\RuleEngine\Rule;
13 13
14 +use function ContentControl\plugin;
15 +
14 16 /**
15 17 * Rules registry
16 18 */
17 19 class Rules {
@@ -67,8 +69,13 @@
67 69 public function register_rule( $rule ) {
68 70 if ( $this->is_rule_valid( $rule ) ) {
69 71 $rule = wp_parse_args( $rule, $this->get_rule_defaults() );
70 72
73 + /**
74 + * Rule index.
75 + *
76 + * @var string $index
77 + */
71 78 $index = $rule['name'];
72 79 /**
73 80 * In the case multiple conditions are registered with the same
74 81 * identifier, we append an integer. This do/while quickly increases
@@ -144,9 +151,15 @@
144 151 *
145 152 * @return array<string,string> List of verbs with translatable text.
146 153 */
147 154 public function get_verbs() {
148 - return [
155 + static $verbs;
156 +
157 + if ( isset( $verbs ) ) {
158 + return $verbs;
159 + }
160 +
161 + $verbs = [
149 162 'are' => __( 'Are', 'content-control' ),
150 163 'arenot' => __( 'Are Not', 'content-control' ),
151 164 'is' => __( 'Is', 'content-control' ),
152 165 'isnot' => __( 'Is Not', 'content-control' ),
@@ -161,11 +174,36 @@
161 174 'wasnot' => __( 'Was Not', 'content-control' ),
162 175 'were' => __( 'Were', 'content-control' ),
163 176 'werenot' => __( 'Were Not', 'content-control' ),
164 177 ];
178 +
179 + return $verbs;
165 180 }
166 181
167 182 /**
183 + * Get a list of common text strings.
184 + *
185 + * @return array<string,string>
186 + */
187 + protected function get_common_text_strings() {
188 + static $text_strings;
189 +
190 + if ( ! isset( $text_strings ) ) {
191 + $text_strings = [
192 + 'User' => __( 'User', 'content-control' ),
193 + 'Role(s)' => __( 'Role(s)', 'content-control' ),
194 + 'Content' => __( 'Content', 'content-control' ),
195 + /* translators: %s: Post type plural name */
196 + 'Select %s' => __( 'Select %s', 'content-control' ),
197 + /* translators: %s: Post type singular name */
198 + 'A Selected %s' => __( 'A Selected %s', 'content-control' ),
199 + ];
200 + }
201 +
202 + return $text_strings;
203 + }
204 +
205 + /**
168 206 * Get a list of built in rules.
169 207 *
170 208 * @return void
171 209 */
@@ -205,15 +243,16 @@
205 243 *
206 244 * @return array<string,array<string,mixed>>
207 245 */
208 246 protected function get_user_rules() {
209 - $verbs = $this->get_verbs();
247 + $verbs = $this->get_verbs();
248 + $strings = $this->get_common_text_strings();
210 249 return [
211 250 'user_is_logged_in' => [
212 251 'name' => 'user_is_logged_in',
213 252 'label' => __( 'Logged In', 'content-control' ),
214 253 'context' => [ 'user' ],
215 - 'category' => __( 'User', 'content-control' ),
254 + 'category' => $strings['User'],
216 255 'format' => '{category} {verb} {label}',
217 256 'verbs' => [ $verbs['is'], $verbs['isnot'] ],
218 257 'callback' => '\is_user_logged_in',
219 258 ],
@@ -218,16 +257,16 @@
218 257 'callback' => '\is_user_logged_in',
219 258 ],
220 259 'user_has_role' => [
221 260 'name' => 'user_has_role',
222 - 'label' => __( 'Role(s)', 'content-control' ),
261 + 'label' => $strings['Role(s)'],
223 262 'context' => [ 'user' ],
224 - 'category' => __( 'User', 'content-control' ),
263 + 'category' => $strings['User'],
225 264 'format' => '{category} {verb} {label}',
226 265 'verbs' => [ $verbs['has'], $verbs['doesnothave'] ],
227 266 'fields' => [
228 267 'roles' => [
229 - 'label' => __( 'Role(s)', 'content-control' ),
268 + 'label' => $strings['Role(s)'],
230 269 'type' => 'tokenselect',
231 270 'multiple' => true,
232 271 'options' => wp_roles()->get_names(),
233 272 ],
@@ -242,16 +281,17 @@
242 281 *
243 282 * @return array<string,array<string,mixed>>
244 283 */
245 284 protected function get_general_content_rules() {
246 - $rules = [];
247 - $verbs = $this->get_verbs();
285 + $rules = [];
286 + $verbs = $this->get_verbs();
287 + $strings = $this->get_common_text_strings();
248 288
249 289 $rules['entire_site'] = [
250 290 'name' => 'entire_site',
251 291 'label' => __( 'Entire Site (Any Page, Post, or Archive)', 'content-control' ),
252 292 'context' => [ 'content' ],
253 - 'category' => __( 'Content', 'content-control' ),
293 + 'category' => $strings['Content'],
254 294 'format' => '{category} {verb} {label}',
255 295 'verbs' => [ $verbs['is'], $verbs['isnot'] ],
256 296 'callback' => '__return_true',
257 297 ];
@@ -259,9 +299,9 @@
259 299 $rules['content_is_front_page'] = [
260 300 'name' => 'content_is_front_page',
261 301 'label' => __( 'The Home Page', 'content-control' ),
262 302 'context' => [ 'content' ],
263 - 'category' => __( 'Content', 'content-control' ),
303 + 'category' => $strings['Content'],
264 304 'format' => '{category} {verb} {label}',
265 305 'verbs' => [ $verbs['is'], $verbs['isnot'] ],
266 306 'callback' => '\ContentControl\Rules\content_is_home_page',
267 307 ];
@@ -269,9 +309,9 @@
269 309 $rules['content_is_blog_index'] = [
270 310 'name' => 'content_is_blog_index',
271 311 'label' => __( 'The Blog Index', 'content-control' ),
272 312 'context' => [ 'content', 'posttype:post' ],
273 - 'category' => __( 'Content', 'content-control' ),
313 + 'category' => $strings['Content'],
274 314 'format' => '{category} {verb} {label}',
275 315 'verbs' => [ $verbs['is'], $verbs['isnot'] ],
276 316 'callback' => '\ContentControl\Rules\content_is_blog_index',
277 317 ];
@@ -279,9 +319,9 @@
279 319 $rules['content_is_search_results'] = [
280 320 'name' => 'content_is_search_results',
281 321 'label' => __( 'A Search Result Page', 'content-control' ),
282 322 'context' => [ 'content', 'search' ],
283 - 'category' => __( 'Content', 'content-control' ),
323 + 'category' => $strings['Content'],
284 324 'format' => '{category} {verb} {label}',
285 325 'verbs' => [ $verbs['is'], $verbs['isnot'] ],
286 326 'callback' => '\is_search',
287 327 ];
@@ -289,9 +329,9 @@
289 329 $rules['content_is_404_page'] = [
290 330 'name' => 'content_is_404_page',
291 331 'label' => __( 'A 404 Error Page', 'content-control' ),
292 332 'context' => [ 'content', '404' ],
293 - 'category' => __( 'Content', 'content-control' ),
333 + 'category' => $strings['Content'],
294 334 'format' => '{category} {verb} {label}',
295 335 'verbs' => [ $verbs['is'], $verbs['isnot'] ],
296 336 'callback' => '\is_404',
297 337 ];
@@ -304,12 +344,18 @@
304 344 *
305 345 * @return array<string,array<string,mixed>>
306 346 */
307 347 protected function get_post_type_rules() {
308 - $verbs = $this->get_verbs();
348 + $verbs = $this->get_verbs();
349 + $strings = $this->get_common_text_strings();
309 350
351 + // Skip post types that are not public.
352 + $should_skip_private_pt = ! plugin()->get_option( 'includePrivatePostTypes', false );
353 +
354 + $args = $should_skip_private_pt ? [ 'public' => true ] : [];
355 +
310 356 $rules = [];
311 - $post_types = get_post_types( [ 'public' => true ], 'objects' );
357 + $post_types = get_post_types( $args, 'objects' );
312 358
313 359 foreach ( $post_types as $post_type ) {
314 360 $type_rules = [];
315 361 $name = $post_type->name;
@@ -332,13 +378,13 @@
332 378
333 379 $type_rules[ "content_is_selected_{$name}" ] = [
334 380 'name' => "content_is_selected_{$name}",
335 381 /* translators: %s: Post type singular name */
336 - 'label' => sprintf( __( 'A Selected %s', 'content-control' ), $post_type->labels->singular_name ),
382 + 'label' => sprintf( $strings['A Selected %s'], $post_type->labels->singular_name ),
337 383 'fields' => [
338 384 'selected' => [
339 385 /* translators: %s: Post type plurals name */
340 - 'placeholder' => sprintf( __( 'Select %s.', 'content-control' ), strtolower( $post_type->labels->name ) ),
386 + 'placeholder' => sprintf( $strings['Select %s'], strtolower( $post_type->labels->name ) ),
341 387 'type' => 'postselect',
342 388 'post_type' => $name,
343 389 'multiple' => true,
344 390 ],
@@ -366,10 +412,10 @@
366 412 /* translators: %s: Post type plural name */
367 413 'label' => sprintf( __( 'A Child of Selected %s', 'content-control' ), $post_type->labels->name ),
368 414 'fields' => [
369 415 'selected' => [
370 - /* translators: %s: Post type plural name */
371 - 'placeholder' => sprintf( __( 'Select %s.', 'content-control' ), strtolower( $post_type->labels->name ) ),
416 +
417 + 'placeholder' => sprintf( $strings['Select %s'], strtolower( $post_type->labels->name ) ),
372 418 'type' => 'postselect',
373 419 'post_type' => $name,
374 420 'multiple' => true,
375 421 ],
@@ -383,9 +429,9 @@
383 429 'label' => sprintf( __( 'An Ancestor of Selected %s', 'content-control' ), $post_type->labels->name ),
384 430 'fields' => [
385 431 'selected' => [
386 432 /* translators: %s: Post type plural name */
387 - 'placeholder' => sprintf( __( 'Select %s.', 'content-control' ), strtolower( $post_type->labels->name ) ),
433 + 'placeholder' => sprintf( $strings['Select %s'], strtolower( $post_type->labels->name ) ),
388 434 'type' => 'postselect',
389 435 'post_type' => $name,
390 436 'multiple' => true,
391 437 ],
@@ -393,30 +439,32 @@
393 439 'callback' => '\ContentControl\Rules\content_is_ancestor_of_post',
394 440 ];
395 441 }
396 442
397 - $templates = wp_get_theme()->get_page_templates();
443 + if ( 'page' === $name ) {
444 + $templates = is_admin() ? wp_get_theme()->get_page_templates() : [];
398 445
399 - if ( 'page' === $name && ! empty( $templates ) ) {
400 - $type_rules[ "content_is_{$name}_with_template" ] = [
401 - 'name' => "content_is_{$name}_with_template",
402 - /* translators: %s: Post type singular name */
403 - 'label' => sprintf( __( 'A %s With Template', 'content-control' ), $post_type->labels->singular_name ),
404 - 'fields' => [
405 - 'selected' => [
406 - 'type' => 'tokenselect',
407 - 'multiple' => true,
408 - 'options' => array_merge( [ 'default' => __( 'Default', 'content-control' ) ], $templates ),
446 + if ( ! empty( $templates ) ) {
447 + $type_rules[ "content_is_{$name}_with_template" ] = [
448 + 'name' => "content_is_{$name}_with_template",
449 + /* translators: %s: Post type singular name */
450 + 'label' => sprintf( __( 'A %s With Template', 'content-control' ), $post_type->labels->singular_name ),
451 + 'fields' => [
452 + 'selected' => [
453 + 'type' => 'tokenselect',
454 + 'multiple' => true,
455 + 'options' => array_merge( [ 'default' => __( 'Default', 'content-control' ) ], $templates ),
456 + ],
409 457 ],
410 - ],
411 - 'callback' => '\ContentControl\Rules\content_is_post_with_template',
412 - ];
458 + 'callback' => '\ContentControl\Rules\content_is_post_with_template',
459 + ];
460 + }
413 461 }
414 462
415 463 foreach ( $type_rules as $rule ) {
416 464 // Merge defaults.
417 465 $type_rules[ $rule['name'] ] = wp_parse_args( $rule, [
418 - 'category' => __( 'Content', 'content-control' ),
466 + 'category' => $strings['Content'],
419 467 'context' => [ 'content', "posttype:{$name}" ],
420 468 'format' => '{category} {verb} {label}',
421 469 'verbs' => [ $verbs['is'], $verbs['isnot'] ],
422 470 'fields' => [],
@@ -425,8 +473,18 @@
425 473 ],
426 474 ] );
427 475 }
428 476
477 + /**
478 + * Allow filtering post type rules.
479 + *
480 + * @param array<string,array<string,mixed>> $type_rules Post type rules.
481 + * @param string $name Post type name.
482 + *
483 + * @return array<string,array<string,mixed>>
484 + */
485 + $type_rules = apply_filters( 'content_control/rule_engine/post_type_rules', $type_rules, $name, $post_type );
486 +
429 487 // Merge type rules & type tax rules.
430 488 $rules = array_merge( $rules, $type_rules, $this->get_post_type_tax_rules( $name ) );
431 489 }
432 490
@@ -440,9 +498,10 @@
440 498 *
441 499 * @return array<string,array<string,mixed>>
442 500 */
443 501 protected function get_post_type_tax_rules( $name ) {
444 - $verbs = $this->get_verbs();
502 + $verbs = $this->get_verbs();
503 + $strings = $this->get_common_text_strings();
445 504
446 505 $post_type = get_post_type_object( $name );
447 506 /**
448 507 * Taxnomies array.
@@ -448,12 +507,19 @@
448 507 * Taxnomies array.
449 508 *
450 509 * @var \WP_Taxonomy[]
451 510 */
452 - $taxonomies = get_object_taxonomies( $name, 'object' );
511 + $taxonomies = get_object_taxonomies( $name, 'objects' );
453 512 $rules = [];
454 513
514 + // Skip taxonomies that are not public.
515 + $should_skip_private_tax = ! plugin()->get_option( 'includePrivateTaxonomies', false );
516 +
455 517 foreach ( $taxonomies as $tax_name => $taxonomy ) {
518 + if ( $should_skip_private_tax && ! $taxonomy->public ) {
519 + continue;
520 + }
521 +
456 522 $rules[ "content_is_{$name}_with_{$tax_name}" ] = [
457 523 'name' => "content_is_{$name}_with_{$tax_name}",
458 524 'label' => sprintf(
459 525 /* translators: %1$s: Post type singular name, %2$s: Taxonomy singular name */
@@ -461,9 +527,9 @@
461 527 $post_type->labels->singular_name,
462 528 $taxonomy->labels->singular_name
463 529 ),
464 530 'context' => [ 'content', "posttype:{$name}", "taxonomy:{$tax_name}" ],
465 - 'category' => __( 'Content', 'content-control' ),
531 + 'category' => $strings['Content'],
466 532 'format' => '{category} {verb} {label}',
467 533 'verbs' => [ $verbs['is'], $verbs['isnot'] ],
468 534 'fields' => [
469 535 'selected' => [
@@ -468,9 +534,9 @@
468 534 'fields' => [
469 535 'selected' => [
470 536 'placeholder' => sprintf(
471 537 /* translators: %s: Taxonomy singular name */
472 - _x( 'Select %s.', 'condition: post type plural label ie. Select categories', 'content-control' ),
538 + $strings['Select %s'],
473 539 strtolower( $taxonomy->labels->name )
474 540 ),
475 541 'type' => 'taxonomyselect',
476 542 'taxonomy' => $tax_name,
@@ -484,8 +550,18 @@
484 550 'callback' => '\ContentControl\Rules\content_is_post_with_tax_term',
485 551 ];
486 552 }
487 553
554 + /**
555 + * Allow filtering post type taxonomy rules.
556 + *
557 + * @param array<string,array<string,mixed>> $rules Post type taxonomy rules.
558 + * @param string $name Post type name.
559 + *
560 + * @return array<string,array<string,mixed>>
561 + */
562 + $rules = apply_filters( 'content_control/rule_engine/post_type_tax_rules', $rules, $name );
563 +
488 564 return $rules;
489 565 }
490 566
491 567 /**
@@ -493,15 +569,21 @@
493 569 *
494 570 * @return array<string,array<string,mixed>>
495 571 */
496 572 protected function get_taxonomy_rules() {
573 + // Skip taxonomies that are not public.
574 + $should_skip_private_tax = ! plugin()->get_option( 'includePrivateTaxonomies', false );
575 +
576 + $args = $should_skip_private_tax ? [ 'public' => true ] : [];
577 +
497 578 $rules = [];
498 - $taxonomies = get_taxonomies( [ 'public' => true ], 'objects' );
579 + $taxonomies = get_taxonomies( $args, 'objects' );
499 580 $verbs = $this->get_verbs();
581 + $strings = $this->get_common_text_strings();
500 582
501 583 foreach ( $taxonomies as $tax_name => $taxonomy ) {
502 584 $tax_defaults = [
503 - 'category' => __( 'Content', 'content-control' ),
585 + 'category' => $strings['Content'],
504 586 'context' => [ 'content', "taxonomy:{$tax_name}" ],
505 587 'format' => '{category} {verb} {label}',
506 588 'verbs' => [ $verbs['is'], $verbs['isnot'] ],
507 589 'fields' => [],
@@ -519,13 +601,12 @@
519 601
520 602 $rules[ "content_is_selected_tax_{$tax_name}" ] = wp_parse_args( [
521 603 'name' => "content_is_selected_tax_{$tax_name}",
522 604 /* translators: %s: Taxonomy plural name */
523 - 'label' => sprintf( _x( 'A Selected %s', 'condition: taxonomy plural label ie. A Selected Category', 'content-control' ), $taxonomy->labels->singular_name ),
605 + 'label' => sprintf( $strings['A Selected %s'], $taxonomy->labels->singular_name ),
524 606 'fields' => [
525 607 'selected' => [
526 - /* translators: %s: Taxonomy plural name */
527 - 'placeholder' => sprintf( _x( 'Select %s.', 'condition: taxonomy plural label ie. Select Categories', 'content-control' ), strtolower( $taxonomy->labels->name ) ),
608 + 'placeholder' => sprintf( $strings['Select %s'], strtolower( $taxonomy->labels->name ) ),
528 609 'type' => 'taxonomyselect',
529 610 'taxonomy' => $tax_name,
530 611 'multiple' => true,
531 612 ],
@@ -556,14 +637,22 @@
556 637 *
557 638 * @return array<string,mixed> Array of rule default values.
558 639 */
559 640 public function get_rule_defaults() {
560 - $verbs = $this->get_verbs();
561 - return [
641 + static $rule_defaults;
642 +
643 + if ( isset( $rule_defaults ) ) {
644 + return $rule_defaults;
645 + }
646 +
647 + $verbs = $this->get_verbs();
648 + $strings = $this->get_common_text_strings();
649 +
650 + $rule_defaults = [
562 651 'name' => '',
563 652 'label' => '',
564 653 'context' => [],
565 - 'category' => __( 'Content', 'content-control' ),
654 + 'category' => $strings['Content'],
566 655 'format' => '{category} {verb} {label}',
567 656 'verbs' => [ $verbs['is'], $verbs['isnot'] ],
568 657 'fields' => [],
569 658 'callback' => null,
@@ -568,8 +657,10 @@
568 657 'fields' => [],
569 658 'callback' => null,
570 659 'frontend' => false,
571 660 ];
661 +
662 + return $rule_defaults;
572 663 }
573 664
574 665 /**
575 666 * Register & remap deprecated conditions to rules.