PluginProbe
Customify / 2.3.3
Customify v2.3.3
2.10.9 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.7.1 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.6.0 1.6.0.1 1.6.5 1.7.0 1.7.1 All 77 releases
customify / includes / admin-notifications-manager / class-notification-conditions.php

class-notification-conditions.php in Customify 2.3.3, at includes/admin-notifications-manager/class-notification-conditions.php

732 lines 20.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 *
5 * A class to handle the conditions of notifications.
6 *
7 * These conditions are in the format provided by jQuery QueryBuilder.
8 */
9 class Pixcloud_Notification_Conditions {
10
11 protected static $group_relations = array(
12 'AND', 'OR',
13 );
14
15 protected static $active_theme_details = null;
16
17 /**
18 * Process a notification's conditions.
19 *
20 * @param array $conditions
21 *
22 * @return bool|mixed
23 */
24 public static function process( $conditions ) {
25 // First check if the conditions are valid.
26 // On invalid conditions we return true.
27 if ( empty( $conditions['valid'] ) ) {
28 return apply_filters( 'pixcloud_notification_conditions_result', true, $conditions );
29 }
30
31 // Process the group. Any top level conditions are expected to be a group, not an individual rule.
32 $result = self::process_group( $conditions );
33
34 return apply_filters( 'pixcloud_notification_conditions_result', $result, $conditions );
35 }
36
37 /**
38 * Process and evaluate a notification condition group.
39 *
40 * @param array $group_conditions
41 *
42 * @return bool
43 */
44 public static function process_group( $group_conditions ) {
45 // By default we will use the AND relation among group rules or subgroups.
46 $group_relation = 'AND';
47 if ( ! empty( $group_conditions['condition'] ) && in_array( $group_conditions['condition'], self::$group_relations ) ) {
48 $group_relation = $group_conditions['condition'];
49 }
50
51 if ( empty( $group_conditions['rules'] ) || ! is_array( $group_conditions['rules'] ) ) {
52 return true;
53 }
54
55 switch ( $group_relation ) {
56 case 'AND':
57 // By default we assure that the conditions evaluate to true.
58 $result = true;
59 break;
60 case 'OR':
61 // By default we assure that the conditions evaluate to false.
62 $result = false;
63 break;
64 default:
65 $result = false;
66 break;
67 }
68
69 $stop = false;
70 foreach ( $group_conditions['rules'] as $rule ) {
71 // Determine if it is a simple rule or a subgroup.
72 if ( ! empty( $rule['rules'] ) ) {
73 $result = self::process_group( $rule );
74 } else {
75 $result = self::process_rule( $rule );
76 }
77
78 // Now evaluate the rule result according to the group relation.
79 switch ( $group_relation ) {
80 case 'AND':
81 if ( false === $result ) {
82 // Stop the evaluation.
83 $stop = true;
84 }
85 break;
86 case 'OR':
87 if ( true === $result ) {
88 // Stop the evaluation.
89 $stop = true;
90 }
91 break;
92 default:
93 // We should not reach here but just in case.
94 $stop = true;
95 break;
96 }
97
98 // Stop the rules processing if this is the case.
99 if ( true === $stop ) {
100 break;
101 }
102 }
103
104 return apply_filters( 'pixcloud_notification_conditions_group_result', $result, $group_conditions['rules'], $group_relation, $group_conditions );
105 }
106
107 /**
108 * Process and evaluate a notification condition rule.
109 *
110 * @param array $rule
111 *
112 * @return bool
113 */
114 public static function process_rule( $rule ) {
115 $result = true;
116
117 // First validate the rule, just in case. On anything invalid we will return true.
118 if ( empty( $rule['id'] ) ) {
119 return $result;
120 }
121 if ( empty( $rule['operator'] ) ) {
122 return $result;
123 }
124
125 if ( ! isset( $rule['value'] ) ) {
126 $rule['value'] = null;
127 }
128
129 // Now determine the field value (the dynamic part of the rule).
130 if ( ! method_exists( __CLASS__, 'get_' . $rule['id'] ) ) {
131 return $result;
132 }
133 $field_value = call_user_func( array( __CLASS__, 'get_' . $rule['id'] ), $rule );
134 // Make sure that we work with the provided field type, regardless if it is a single value or a list.
135 $field_value = self::convert_value_to_type( $field_value, $rule['type'] );
136 $rule['value'] = self::convert_value_to_type( $rule['value'], $rule['type'] );
137
138 // Before we evaluate the expression, we need to account for the special expressions (e.g. function_exists, class_exists).
139 switch ( $rule['id'] ) {
140 case 'function_exists':
141 // We apply function_exists to each value.
142 if ( is_array( $rule['value'] ) ) {
143 $rule['value'] = array_map( 'function_exists', $rule['value'] );
144 } else {
145 $rule['value'] = function_exists( $rule['value'] );
146 }
147
148 // Make sure that the field value is true.
149 $field_value = true;
150 break;
151 case 'class_exists':
152 // We apply function_exists to each value.
153 if ( is_array( $rule['value'] ) ) {
154 $rule['value'] = array_map( 'class_exists', $rule['value'] );
155 } else {
156 $rule['value'] = class_exists( $rule['value'] );
157 }
158
159 // Make sure that the field value is true.
160 $field_value = true;
161 break;
162 default:
163 break;
164 }
165
166 // Now evaluate the expression.
167 require_once 'class-notification-logicalexpression.php';
168 $result = Pixcloud_Notification_LogicalExpression::evaluate( $field_value, $rule['operator'], $rule['value'] );
169
170 return apply_filters( 'pixcloud_notification_conditions_rule_result', $result, $field_value, $rule['operator'], $rule['value'], $rule );
171 }
172
173 public static function evaluate_expression( $left, $operator, $right, $rule ) {
174
175 }
176
177 /* ========================
178 * THE FIELD VALUES GETTERS
179 */
180
181 public static function get_style_manager_is_supported( $rule = null ) {
182 if ( class_exists( 'Customify_Style_Manager' ) && Customify_Style_Manager::instance()->is_supported() ) {
183 return true;
184 }
185
186 return false;
187 }
188
189 public static function get_style_manager_user_provided_feedback( $rule = null ) {
190 if ( class_exists( 'Customify_Style_Manager' ) && Customify_Style_Manager::instance()->user_provided_feedback() ) {
191 return true;
192 }
193
194 return false;
195 }
196
197 public static function get_style_manager_user_provided_feedback_days_ago( $rule = null ) {
198 $user_provided_feedback = get_option( 'style_manager_user_feedback_provided' );
199 if ( empty( $user_provided_feedback ) ) {
200 return false;
201 }
202
203 return round( ( time() - $user_provided_feedback ) / DAY_IN_SECONDS );
204 }
205
206 public static function get_current_color_palette_hashid( $rule = null ) {
207 if ( class_exists('Customify_Color_Palettes') ) {
208 return Customify_Color_Palettes::instance()->get_current_palette();
209 }
210
211 return '';
212 }
213
214 public static function get_current_color_palette_label( $rule = null ) {
215 if ( class_exists('Customify_Color_Palettes') ) {
216 $color_palette_hashid = self::get_current_color_palette_hashid( $rule );
217 $color_palettes = Customify_Color_Palettes::instance()->get_palettes();
218 if ( ! empty( $color_palettes[ $color_palette_hashid ] ) ) {
219 return $color_palettes[ $color_palette_hashid ]['label'];
220 }
221 }
222
223 return '';
224 }
225
226 public static function get_current_color_palette_is_custom( $rule = null ) {
227 if ( class_exists('Customify_Color_Palettes') ) {
228 return Customify_Color_Palettes::instance()->is_using_custom_palette();
229 }
230
231 return false;
232 }
233
234 public static function get_current_color_palette_is_variation_in_use( $rule = null ) {
235 if ( class_exists('Customify_Color_Palettes') ) {
236 return Customify_Color_Palettes::instance()->get_current_palette_variation();
237 }
238
239 return false;
240 }
241
242 public static function get_active_theme_slug( $rule = null ) {
243 $theme_details = self::get_active_theme_details();
244
245 if ( ! empty( $theme_details['slug'] ) ) {
246 return $theme_details['slug'];
247 }
248
249 return '';
250 }
251
252 public static function get_active_theme_hashid( $rule = null ) {
253 $theme_details = self::get_active_theme_details();
254
255 if ( ! empty( $theme_details['hashid'] ) ) {
256 return $theme_details['hashid'];
257 }
258
259 return '';
260 }
261
262 public static function get_active_theme_name( $rule = null ) {
263 $theme_details = self::get_active_theme_details();
264
265 if ( ! empty( $theme_details['name'] ) ) {
266 return $theme_details['name'];
267 }
268
269 return '';
270 }
271
272 public static function get_active_theme_author( $rule = null ) {
273 $theme_details = self::get_active_theme_details();
274
275 if ( ! empty( $theme_details['author'] ) ) {
276 return $theme_details['author'];
277 }
278
279 return '';
280 }
281
282 public static function get_active_theme_has_wupdates_valid_code( $rule = null ) {
283 $theme_details = self::get_active_theme_details();
284
285 if ( ! empty( $theme_details['wupdates_code_unchanged'] ) ) {
286 return true;
287 }
288
289 return false;
290 }
291
292 public static function get_active_theme_has_pixelgrade_license( $rule = null ) {
293 $theme_details = self::get_active_theme_details();
294
295 if ( ! empty( $theme_details['license_hash'] ) ) {
296 return true;
297 }
298
299 return false;
300 }
301
302 public static function get_active_theme_pixelgrade_license_status( $rule = null ) {
303 $theme_details = self::get_active_theme_details();
304
305 if ( ! empty( $theme_details['license_status'] ) ) {
306 return $theme_details['license_status'];
307 }
308
309 return '';
310 }
311
312 public static function get_active_theme_version( $rule = null ) {
313 $theme_details = self::get_active_theme_details();
314
315 if ( ! empty( $theme_details['version'] ) ) {
316 return $theme_details['version'];
317 }
318
319 return '0.0.1';
320 }
321
322 public static function get_customify_version( $rule = null ) {
323 if ( function_exists( 'PixCustomifyPlugin' ) ) {
324 return PixCustomifyPlugin()->get_version();
325 }
326
327 return false;
328 }
329
330 public static function get_style_manager_version( $rule = null ) {
331 if ( function_exists( 'StyleManager_Plugin' ) ) {
332 return StyleManager_Plugin()->get_version();
333 }
334
335 return false;
336 }
337
338 public static function get_wp_version( $rule = null ) {
339 return get_bloginfo( 'version' );
340 }
341
342 public static function get_php_version( $rule = null ) {
343 if ( function_exists( 'phpversion' ) ) {
344 return phpversion();
345 }
346
347 return false;
348 }
349
350 public static function get_current_user_role( $rule = null ) {
351 $current_user = wp_get_current_user();
352
353 if ( ! empty( $current_user ) && ! is_wp_error( $current_user ) ) {
354 return $current_user->roles;
355 }
356
357 return false;
358 }
359
360 public static function get_current_user_capabilities( $rule = null ) {
361 $current_user = wp_get_current_user();
362
363 if ( ! empty( $current_user ) && ! is_wp_error( $current_user ) ) {
364 return $current_user->allcaps;
365 }
366
367 return false;
368 }
369
370 public static function get_site_is_public( $rule = null ) {
371 // Local/development url parts to match for
372 $devsite_needles = array(
373 'localhost',
374 ':8888',
375 '.local',
376 '.dev',
377 ':8082',
378 'staging.',
379 '.invalid',
380 '.test',
381 '.example',
382 );
383
384 if ( self::string_contains_any( get_bloginfo( 'url'), $devsite_needles ) ) {
385 return false;
386 }
387
388 return true;
389 }
390
391 public static function get_site_url( $rule = null ) {
392 return get_bloginfo( 'url');
393 }
394
395 public static function get_site_is_multisite( $rule = null ) {
396 return is_multisite();
397 }
398
399 public static function get_site_number_of_posts( $rule = null ) {
400 // Make sure it is an array.
401 $post_count = json_decode( json_encode( wp_count_posts( 'post' ) ), true );
402 return ! empty( $post_count['publish'] ) ? $post_count['publish'] : 0;
403 }
404
405 public static function get_site_number_of_pages( $rule = null ) {
406 // Make sure it is an array.
407 $post_count = json_decode( json_encode( wp_count_posts( 'page' ) ), true );
408 return ! empty( $post_count['publish'] ) ? $post_count['publish'] : 0;
409 }
410
411 public static function get_current_date( $rule = null ) {
412 return date('Y/m/d');
413 }
414
415 // This is special.
416 public static function get_class_exists( $rule = null ) {
417 return true;
418 }
419
420 // This is special.
421 public static function get_function_exists( $rule = null ) {
422 return true;
423 }
424
425 public static function get_wp_debug_active( $rule = null ) {
426 return defined( 'WP_DEBUG') && true === WP_DEBUG;
427 }
428
429 public static function get_pixelgrade_dev_mode_active( $rule = null ) {
430 return defined( 'PIXELGRADE_CARE__DEV_MODE') && true === PIXELGRADE_CARE__DEV_MODE;
431 }
432
433 public static function get_customify_dev_force_defaults_active( $rule = null ) {
434 return defined( 'CUSTOMIFY_DEV_FORCE_DEFAULTS') && true === CUSTOMIFY_DEV_FORCE_DEFAULTS;
435 }
436
437 public static function get_sm_dev_customizer_force_defaults_active( $rule = null ) {
438 return defined( 'SM_DEV_CUSTOMIZER_FORCE_DEFAULTS') && true === SM_DEV_CUSTOMIZER_FORCE_DEFAULTS;
439 }
440
441 /* =======
442 * HELPERS
443 */
444
445 /**
446 * @param $value
447 * @param $type
448 *
449 * @return false|float|int|string
450 */
451 public static function convert_value_to_type( $value, $type ) {
452 if ( null === $value ) {
453 return $value;
454 }
455
456 // Make sure we are not dealing with stdClass.
457 if ( $value instanceof stdClass ) {
458 $value = json_decode( json_encode( $value ), true );
459 }
460
461 if ( ! empty( $type ) ) {
462 switch ( $type ) {
463 case 'integer':
464 if ( is_array( $value ) ) {
465 $value = array_map( 'intval', $value );
466 } else {
467 $value = intval( $value );
468 }
469 break;
470 case 'string':
471 if ( is_array( $value ) ) {
472 $value = array_map( 'strval', $value );
473 } else {
474 $value = strval( $value );
475 }
476 break;
477 case 'double':
478 if ( is_array( $value ) ) {
479 $value = array_map( 'doubleval', $value );
480 } else {
481 $value = doubleval( $value );
482 }
483 break;
484 case 'date':
485 if ( is_array( $value ) ) {
486 $value = array_map( 'strtotime', $value );
487 $value = array_map( array( __CLASS__, 'dateval' ), $value );
488 } else {
489 $value = self::dateval( strtotime( $value ) );
490 }
491 break;
492 case 'time':
493 if ( is_array( $value ) ) {
494 $value = array_map( 'strtotime', $value );
495 $value = array_map( array( __CLASS__, 'timeval' ), $value );
496 } else {
497 $value = self::timeval( strtotime( $value ) );
498 }
499 break;
500 case 'datetime':
501 if ( is_array( $value ) ) {
502 $value = array_map( 'strtotime', $value );
503 $value = array_map( array( __CLASS__, 'datetimeval' ), $value );
504 } else {
505 $value = self::datetimeval( strtotime( $value ) );
506 }
507 break;
508 case 'boolean':
509 if ( is_array( $value ) ) {
510 $value = array_map( 'boolval', $value );
511 } else {
512 $value = boolval( $value );
513 }
514 break;
515 default:
516 break;
517 }
518 }
519
520 return $value;
521 }
522
523 protected static function dateval( $timestamp ) {
524 return date('Y/m/d', $timestamp );
525 }
526
527 protected static function timeval( $timestamp ) {
528 return date('H:i:s', $timestamp );
529 }
530
531 protected static function datetimeval( $timestamp ) {
532 return date('Y/m/d H:i:s', $timestamp );
533 }
534
535 /**
536 * Grab all the details about the current active theme.
537 *
538 * @return array
539 */
540 public static function get_active_theme_details() {
541 if ( self::$active_theme_details !== null ) {
542 return self::$active_theme_details;
543 }
544
545 $theme_details = array();
546
547 // Gather Pixelgrade and WUpdates theme details.
548 $theme_details['is_pixelgrade_theme'] = self::is_pixelgrade_theme();
549 $theme_details['hashid'] = self::get_wupdates_theme_hashid();
550 $theme_details['wupdates_code_unchanged'] = self::is_wupdates_code_unchanged();
551 $theme_details['license_hash'] = get_theme_mod( 'pixcare_license_hash', false );
552 $theme_details['license_status'] = get_theme_mod( 'pixcare_license_status', false );
553
554 // Gather the rest of the theme details.
555 /** @var WP_Theme $theme */
556 $theme = wp_get_theme();
557 $parent = $theme->parent();
558 if ( is_child_theme() && ! empty( $parent ) ) {
559 $theme = $parent;
560 }
561
562 // The theme name should be the one from the wupdates array.
563 $wupdates_theme_name = self::get_original_theme_name();
564 if ( ! empty( $wupdates_theme_name ) ) {
565 $theme_details['name'] = $wupdates_theme_name;
566 }
567 // If for some reason we couldn't get the theme name from the WUpdates code, use the standard theme name.
568 if ( empty( $theme_details['name'] ) ) {
569 $theme_details['name'] = $theme->get( 'Name' );
570 }
571
572 // The theme slug should be the one from the wupdates array
573 $wupdates_theme_slug = self::get_original_theme_slug();
574 if ( ! empty( $wupdates_theme_slug ) ) {
575 $theme_details['slug'] = $wupdates_theme_slug;
576 }
577 // If for some reason we couldn't get the theme slug from the WUpdates code, use the standard theme slug.
578 if ( empty( $theme_details['slug'] ) ) {
579 $theme_details['slug'] = basename( get_template_directory() );
580 }
581
582 $theme_details['uri'] = $theme->get( 'ThemeURI' );
583 $theme_details['desc'] = $theme->get( 'Description' );
584 $theme_details['author'] = $theme->get( 'Author' );
585 $theme_details['version'] = $theme->get( 'Version' );
586
587 $theme_details['is_child'] = is_child_theme();
588 $theme_details['template'] = $theme->get_template();
589
590 self::$active_theme_details = $theme_details;
591
592 return $theme_details;
593 }
594
595 /**
596 * Determine if the current theme is one of ours.
597 *
598 * @return bool
599 */
600 public static function is_pixelgrade_theme() {
601 // Get the id of the current theme
602 $wupdates_ids = apply_filters( 'wupdates_gather_ids', array() );
603 $slug = basename( get_template_directory() );
604 // If we have the WUpdates information tied to the current theme slug, then we are good
605 if ( isset( $wupdates_ids[ $slug ] ) ) {
606 return true;
607 }
608
609 // Next we will test for the author in the theme header
610 $theme = wp_get_theme();
611 $theme_author = $theme->get( 'Author' );
612 if ( ! empty( $theme_author ) && strtolower( $theme_author ) == 'pixelgrade' ) {
613 return true;
614 }
615
616 return false;
617 }
618
619 /**
620 * Checks if the wupdates_gather_ids code has been tempered with.
621 *
622 * @return bool
623 */
624 public static function is_wupdates_code_unchanged() {
625 // Get the id of the current theme
626 $wupdates_ids = apply_filters( 'wupdates_gather_ids', array() );
627 $slug = basename( get_template_directory() );
628 // If the user hasn't got any pixelgrade themes - return true. They don't need this filter
629 if ( ! self::has_pixelgrade_theme() ) {
630 return true;
631 }
632
633 // Check if the wupdates_ids array is missing either of this properties
634 if ( ! isset( $wupdates_ids[ $slug ] ) || ! isset( $wupdates_ids[ $slug ]['name'] ) || ! isset( $wupdates_ids[ $slug ]['slug'] ) || ! isset( $wupdates_ids[ $slug ]['id'] ) || ! isset( $wupdates_ids[ $slug ]['type'] ) || ! isset( $wupdates_ids[ $slug ]['digest'] ) ) {
635 return false;
636 }
637 // Create the md5 hash from the properties of wupdates_ids and compare it to the digest from that array
638 $md5 = md5( 'name-' . $wupdates_ids[ $slug ]['name'] . ';slug-' . $wupdates_ids[ $slug ]['slug'] . ';id-' . $wupdates_ids[ $slug ]['id'] . ';type-' . $wupdates_ids[ $slug ]['type'] );
639 // the md5 hash should be the same one as the digest hash
640 if ( $md5 !== $wupdates_ids[ $slug ]['digest'] ) {
641 return false;
642 }
643 return true;
644 }
645
646 /**
647 * Determine if there are any Pixelgrade themes currently installed.
648 *
649 * @return bool
650 */
651 public static function has_pixelgrade_theme() {
652 $themes = wp_get_themes();
653 // Loop through the themes.
654 // If we find a theme from pixelgrade return true.
655 /** @var WP_Theme $theme */
656 foreach ( $themes as $theme ) {
657 $theme_author = $theme->get( 'Author' );
658
659 if ( ! empty( $theme_author ) && strtolower( $theme_author ) == 'pixelgrade' ) {
660 return true;
661 }
662 }
663
664 // No themes from pixelgrade found, return false.
665 return false;
666 }
667
668 /**
669 * Get the current theme original name from the WUpdates code.
670 *
671 * @return string
672 */
673 public static function get_original_theme_name() {
674 // Get the id of the current theme
675 $wupdates_ids = apply_filters( 'wupdates_gather_ids', array() );
676 $slug = basename( get_template_directory() );
677 if ( ! isset( $wupdates_ids[ $slug ] ) || ! isset( $wupdates_ids[ $slug ]['name'] ) ) {
678 return ucfirst( $slug );
679 }
680 return $wupdates_ids[ $slug ]['name'];
681 }
682
683 /**
684 * Get the current theme original slug from the WUpdates code.
685 *
686 * @return string
687 */
688 public static function get_original_theme_slug() {
689 // Get the id of the current theme
690 $wupdates_ids = apply_filters( 'wupdates_gather_ids', array() );
691 $slug = basename( get_template_directory() );
692 if ( ! isset( $wupdates_ids[ $slug ] ) || ! isset( $wupdates_ids[ $slug ]['slug'] ) ) {
693 return $slug;
694 }
695
696 return sanitize_title( $wupdates_ids[ $slug ]['slug'] );
697 }
698
699 /**
700 * Get the current theme hashid from the WUpdates code.
701 *
702 * @return string
703 */
704 public static function get_wupdates_theme_hashid() {
705 // Get the id of the current theme
706 $wupdates_ids = apply_filters( 'wupdates_gather_ids', array() );
707 $slug = basename( get_template_directory() );
708 if ( ! isset( $wupdates_ids[ $slug ] ) || ! isset( $wupdates_ids[ $slug ]['id'] ) ) {
709 return false;
710 }
711
712 return $wupdates_ids[ $slug ]['id'];
713 }
714
715 /**
716 * Check if the $haystack contains any of the needles.
717 *
718 * @param string $haystack
719 * @param array $needles
720 *
721 * @return bool
722 */
723 public static function string_contains_any( $haystack, $needles ) {
724 foreach ( $needles as $needle ) {
725 if ( false !== strpos( $haystack, $needle ) ) {
726 return true;
727 }
728 }
729
730 return false;
731 }
732 }