1: <?php
2:
3: 4: 5: 6:
7: class Papi_Conditional_Rules {
8:
9: 10: 11:
12: public function __construct() {
13: $this->setup_filters();
14: }
15:
16: 17: 18: 19: 20: 21: 22:
23: private function convert_bool( $str ) {
24: if ( ! is_string( $str ) ) {
25: return $str;
26: }
27:
28: switch ( $str ) {
29: case 'false':
30: return false;
31: case 'true':
32: return true;
33: default:
34: return $str;
35: }
36: }
37:
38: 39: 40: 41: 42: 43: 44: 45:
46: private function convert_prop( $value, Papi_Core_Conditional_Rule $rule ) {
47: $post_id = papi_get_post_id();
48: $page_type = papi_get_page_type_by_post_id( $post_id );
49:
50: if ( ! papi_is_empty( $value ) && $page_type instanceof Papi_Page_Type !== false ) {
51: $property = $page_type->get_property( $rule->slug );
52:
53: if ( papi_is_property( $property ) ) {
54: $prop_value = $property->format_value(
55: $value,
56: $property->slug,
57: $post_id
58: );
59:
60: $prop_value = papi_filter_format_value(
61: $property->type,
62: $prop_value,
63: $property->slug,
64: $post_id
65: );
66:
67: $prop_value = $this->get_deep_value(
68: $rule->slug,
69: $prop_value
70: );
71:
72: if ( gettype( $prop_value ) === gettype( $rule->value ) ) {
73: return $prop_value;
74: }
75: }
76:
77: return $value;
78: }
79:
80: return $value;
81: }
82:
83: 84: 85: 86: 87: 88: 89:
90: private function convert_number( $str ) {
91: if ( is_numeric( $str ) && ! is_string( $str ) || ! is_numeric( $str ) ) {
92: return $str;
93: }
94:
95: if ( $str == (int) $str ) {
96: return (int) $str;
97: } else {
98: return (float) $str;
99: }
100: }
101:
102: 103: 104: 105: 106: 107: 108:
109: private function get_converted_value( Papi_Core_Conditional_Rule $rule ) {
110: $value = $this->get_value( $rule );
111:
112:
113: if ( is_numeric( $value ) && is_numeric( $rule->value ) ) {
114: return [
115: $this->convert_number( $value ),
116: $this->convert_number( $rule->value )
117: ];
118: }
119:
120:
121: $value = $this->convert_bool( $value );
122: $rule->value = $this->convert_bool( $rule->value );
123:
124:
125: return [
126: $this->convert_prop( $value, $rule ),
127: $rule->value
128: ];
129: }
130:
131: 132: 133: 134: 135: 136: 137: 138:
139: private function get_deep_value( $slug, $value ) {
140: $slugs = explode( '.', $slug );
141: array_shift( $slugs );
142: return papi_field_value( $slugs, $value, $value );
143: }
144:
145: 146: 147: 148: 149: 150: 151:
152: private function get_value( Papi_Core_Conditional_Rule $rule ) {
153: if ( papi_doing_ajax() ) {
154: $source = $rule->get_source();
155: $post_id = papi_get_post_id();
156: $page_type = papi_get_page_type_by_post_id( $post_id );
157:
158: if ( ! papi_is_empty( $source ) && $page_type instanceof Papi_Page_Type !== false ) {
159: if ( papi_is_property( $page_type->get_property( $rule->slug ) ) ) {
160: return $this->get_deep_value( $rule->slug, $source );
161: }
162: }
163: }
164:
165: if ( ! papi_is_empty( $rule->get_source() ) ) {
166: return $this->get_deep_value( $rule->slug, $rule->get_source() );
167: }
168:
169: $slug = $rule->get_field_slug();
170:
171: if ( papi_is_option_page() ) {
172: $value = papi_get_option( $slug );
173: } else {
174: $value = papi_get_field( $slug );
175: }
176:
177: return $this->get_deep_value( $slug, $value );
178: }
179:
180: 181: 182: 183: 184: 185: 186:
187: public function rule_equal( Papi_Core_Conditional_Rule $rule ) {
188: list( $value, $rule_value ) = $this->get_converted_value( $rule );
189: return $value === $rule_value;
190: }
191:
192: 193: 194: 195: 196: 197: 198:
199: public function rule_not_equal( Papi_Core_Conditional_Rule $rule ) {
200: list( $value, $rule_value ) = $this->get_converted_value( $rule );
201: return $value !== $rule_value;
202: }
203:
204: 205: 206: 207: 208: 209: 210:
211: public function rule_greater_then( Papi_Core_Conditional_Rule $rule ) {
212: $value = $this->get_value( $rule );
213:
214: if ( is_array( $value ) ) {
215: $value = count( $value );
216: }
217:
218: if ( ! is_numeric( $value ) || ! is_numeric( $rule->value ) ) {
219: return false;
220: }
221:
222: return $this->convert_number( $value ) >
223: $this->convert_number( $rule->value );
224: }
225:
226: 227: 228: 229: 230: 231: 232:
233: public function rule_greater_then_or_equal( Papi_Core_Conditional_Rule $rule ) {
234: $value = $this->get_value( $rule );
235:
236: if ( is_array( $value ) ) {
237: $value = count( $value );
238: }
239:
240: if ( ! is_numeric( $value ) || ! is_numeric( $rule->value ) ) {
241: return false;
242: }
243:
244: return $this->convert_number( $value ) >=
245: $this->convert_number( $rule->value );
246: }
247:
248: 249: 250: 251: 252: 253: 254:
255: public function rule_less_then( Papi_Core_Conditional_Rule $rule ) {
256: $value = $this->get_value( $rule );
257:
258: if ( is_array( $value ) ) {
259: $value = count( $value );
260: }
261:
262: if ( ! is_numeric( $value ) || ! is_numeric( $rule->value ) ) {
263: return false;
264: }
265:
266: return $this->convert_number( $value ) <
267: $this->convert_number( $rule->value );
268: }
269:
270: 271: 272: 273: 274: 275: 276:
277: public function rule_less_then_or_equal( Papi_Core_Conditional_Rule $rule ) {
278: $value = $this->get_value( $rule );
279:
280: if ( is_array( $value ) ) {
281: $value = count( $value );
282: }
283:
284: if ( ! is_numeric( $value ) || ! is_numeric( $rule->value ) ) {
285: return false;
286: }
287:
288: return $this->convert_number( $value ) <=
289: $this->convert_number( $rule->value );
290: }
291:
292: 293: 294: 295: 296: 297: 298:
299: public function rule_in( Papi_Core_Conditional_Rule $rule ) {
300: list( $value, $rule_value ) = $this->get_converted_value( $rule );
301:
302: if ( ! is_array( $rule_value ) ) {
303: return false;
304: }
305:
306: return in_array( $value, $rule_value );
307: }
308:
309: 310: 311: 312: 313: 314: 315:
316: public function rule_not_in( Papi_Core_Conditional_Rule $rule ) {
317: list( $value, $rule_value ) = $this->get_converted_value( $rule );
318:
319: if ( ! is_array( $rule_value ) ) {
320: return false;
321: }
322:
323: return ! in_array( $value, $rule_value );
324: }
325:
326: 327: 328: 329: 330: 331: 332:
333: public function rule_like( Papi_Core_Conditional_Rule $rule ) {
334: $value = $this->get_value( $rule );
335:
336: if ( ! is_string( $value ) ) {
337: $value = papi_convert_to_string( $value );
338: }
339:
340: if ( papi_is_empty( $value ) ) {
341: return false;
342: }
343:
344: return strpos(
345: strtolower( $value ),
346: strtolower( $rule->value )
347: ) !== false;
348: }
349:
350: 351: 352: 353: 354: 355: 356:
357: private function get_between_values( Papi_Core_Conditional_Rule $rule ) {
358: $value = $this->get_value( $rule );
359:
360: if ( ! is_array( $rule->value ) ) {
361: return [$rule, false];
362: }
363:
364: foreach ( $rule->value as $index => $v ) {
365: $v = $this->convert_number( $v );
366:
367: if ( is_numeric( $v ) ) {
368: $rule->value[$index] = $v;
369: } else {
370: unset( $rule->value[$index] );
371: }
372: }
373:
374: if ( ! is_numeric( $value ) || count( $rule->value ) !== 2 ) {
375: return [$rule, false];
376: }
377:
378: return [$rule, $this->convert_number( $value )];
379: }
380:
381: 382: 383: 384: 385: 386: 387:
388: public function rule_between( Papi_Core_Conditional_Rule $rule ) {
389: list( $rule, $value ) = $this->get_between_values( $rule );
390:
391: if ( $value === false ) {
392: return false;
393: }
394:
395: return $rule->value[0] <= $value && $value <= $rule->value[1];
396: }
397:
398: 399: 400: 401: 402: 403: 404:
405: public function rule_not_between( Papi_Core_Conditional_Rule $rule ) {
406: list( $rule, $value ) = $this->get_between_values( $rule );
407:
408: if ( $value === false ) {
409: return false;
410: }
411:
412: return ! ( $rule->value[0] <= $value && $value <= $rule->value[1] );
413: }
414:
415: 416: 417: 418: 419: 420: 421:
422: public function rule_exists( Papi_Core_Conditional_Rule $rule ) {
423: return ! in_array( $this->get_value( $rule ), [null, []] );
424: }
425:
426: 427: 428: 429: 430: 431: 432:
433: public function rule_not_exists( Papi_Core_Conditional_Rule $rule ) {
434: return in_array( $this->get_value( $rule ), [null, []] );
435: }
436:
437: 438: 439: 440: 441: 442: 443:
444: public function rule_empty( Papi_Core_Conditional_Rule $rule ) {
445: return papi_is_empty( $this->get_value( $rule ) );
446: }
447:
448: 449: 450: 451: 452: 453: 454:
455: public function rule_not_empty( Papi_Core_Conditional_Rule $rule ) {
456: return ! papi_is_empty( $this->get_value( $rule ) );
457: }
458:
459: 460: 461:
462: public function setup_filters() {
463: add_filter( 'papi/conditional/rule/=', [$this, 'rule_equal'] );
464: add_filter( 'papi/conditional/rule/!=', [$this, 'rule_not_equal'] );
465: add_filter( 'papi/conditional/rule/>', [$this, 'rule_greater_then'] );
466: add_filter( 'papi/conditional/rule/>=', [$this, 'rule_greater_then_or_equal'] );
467: add_filter( 'papi/conditional/rule/<', [$this, 'rule_less_then'] );
468: add_filter( 'papi/conditional/rule/<=', [$this, 'rule_less_then_or_equal'] );
469: add_filter( 'papi/conditional/rule/IN', [$this, 'rule_in'] );
470: add_filter( 'papi/conditional/rule/NOT IN', [$this, 'rule_not_in'] );
471: add_filter( 'papi/conditional/rule/LIKE', [$this, 'rule_like'] );
472: add_filter( 'papi/conditional/rule/BETWEEN', [$this, 'rule_between'] );
473: add_filter( 'papi/conditional/rule/NOT BETWEEN', [$this, 'rule_not_between'] );
474: add_filter( 'papi/conditional/rule/EXISTS', [$this, 'rule_exists'] );
475: add_filter( 'papi/conditional/rule/NOT EXISTS', [$this, 'rule_not_exists'] );
476: add_filter( 'papi/conditional/rule/EMPTY', [$this, 'rule_empty'] );
477: add_filter( 'papi/conditional/rule/NOT EMPTY', [$this, 'rule_not_empty'] );
478: }
479: }
480:
481: new Papi_Conditional_Rules();
482: