PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 3.3.0
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v3.3.0
3.3.0 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.1 trunk 1.0.4 1.1.0 1.1.0.1 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 All 162 releases
← All changes | classes/class-cartflows-utils.php +476 -57 1.1.12 → 3.3.0 View file →
@@ -21,13 +21,21 @@
21 21 */
22 22 private static $instance;
23 23
24 24 /**
25 + * Member Variable
26 + *
27 + * @var checkout_products
28 + */
29 + public $checkout_products = array();
30 +
31 +
32 + /**
25 33 * Initiator
26 34 */
27 35 public static function get_instance() {
28 36 if ( ! isset( self::$instance ) ) {
29 - self::$instance = new self;
37 + self::$instance = new self();
30 38 }
31 39 return self::$instance;
32 40 }
33 41
@@ -33,9 +41,9 @@
33 41
34 42 /**
35 43 * Constructor
36 44 */
37 - function __construct() {
45 + public function __construct() {
38 46 }
39 47
40 48 /**
41 49 * Get current post type
@@ -42,12 +50,14 @@
42 50 *
43 51 * @param string $post_type post type.
44 52 * @return string
45 53 */
46 - function current_post_type( $post_type = '' ) {
54 + public function current_post_type( $post_type = '' ) {
47 55
48 - if ( '' === $post_type ) {
49 - $post_type = get_post_type();
56 + global $post;
57 +
58 + if ( '' === $post_type && is_object( $post ) ) {
59 + $post_type = $post->post_type;
50 60 }
51 61
52 62 return $post_type;
53 63 }
@@ -57,9 +67,9 @@
57 67 *
58 68 * @param string $post_type post type.
59 69 * @return bool
60 70 */
61 - function is_step_post_type( $post_type = '' ) {
71 + public function is_step_post_type( $post_type = '' ) {
62 72
63 73 if ( $this->get_step_post_type() === $this->current_post_type( $post_type ) ) {
64 74
65 75 return true;
@@ -73,9 +83,9 @@
73 83 *
74 84 * @param string $post_type post type.
75 85 * @return bool
76 86 */
77 - function is_flow_post_type( $post_type = '' ) {
87 + public function is_flow_post_type( $post_type = '' ) {
78 88
79 89 if ( $this->get_flow_post_type() === $this->current_post_type( $post_type ) ) {
80 90
81 91 return true;
@@ -88,9 +98,9 @@
88 98 * Get post type of step.
89 99 *
90 100 * @return string
91 101 */
92 - function get_step_post_type() {
102 + public function get_step_post_type() {
93 103
94 104 return CARTFLOWS_STEP_POST_TYPE;
95 105 }
96 106
@@ -98,9 +108,9 @@
98 108 * Get post type of flow.
99 109 *
100 110 * @return string
101 111 */
102 - function get_flow_post_type() {
112 + public function get_flow_post_type() {
103 113
104 114 return CARTFLOWS_FLOW_POST_TYPE;
105 115 }
106 116
@@ -108,13 +118,19 @@
108 118 * Get flow id
109 119 *
110 120 * @return int
111 121 */
112 - function get_flow_id() {
122 + public function get_flow_id() {
113 123
114 124 global $post;
115 125
116 - return get_post_meta( $post->ID, 'wcf-flow-id', true );
126 + $post_meta = false;
127 +
128 + if ( $post ) {
129 + $post_meta = get_post_meta( $post->ID, 'wcf-flow-id', true );
130 + }
131 +
132 + return $post_meta;
117 133 }
118 134
119 135 /**
120 136 * Get flow id by step
@@ -121,9 +137,9 @@
121 137 *
122 138 * @param int $step_id step ID.
123 139 * @return int
124 140 */
125 - function get_flow_id_from_step_id( $step_id ) {
141 + public function get_flow_id_from_step_id( $step_id ) {
126 142
127 143 return get_post_meta( $step_id, 'wcf-flow-id', true );
128 144 }
129 145
@@ -132,9 +148,9 @@
132 148 *
133 149 * @param int $flow_id flow ID.
134 150 * @return int
135 151 */
136 - function get_flow_steps( $flow_id ) {
152 + public function get_flow_steps( $flow_id ) {
137 153
138 154 $steps = get_post_meta( $flow_id, 'wcf-steps', true );
139 155
140 156 if ( is_array( $steps ) && ! empty( $steps ) ) {
@@ -149,9 +165,9 @@
149 165 *
150 166 * @param int $step_id step ID.
151 167 * @return int
152 168 */
153 - function get_step_type( $step_id ) {
169 + public function get_step_type( $step_id ) {
154 170
155 171 return get_post_meta( $step_id, 'wcf-step-type', true );
156 172 }
157 173
@@ -161,61 +177,116 @@
161 177 * @param int $flow_id flow ID.
162 178 * @param int $step_id step ID.
163 179 * @return bool
164 180 */
165 - function get_next_step_id( $flow_id, $step_id ) {
181 + public function get_next_step_id( $flow_id, $step_id ) {
166 182
167 - $steps = $this->get_flow_steps( $flow_id );
168 - $step_id = intval( $step_id );
183 + $wcf_step_obj = wcf_get_step( $step_id );
184 + $next_step_id = $wcf_step_obj->get_direct_next_step_id();
169 185
170 - if ( ! $steps ) {
171 - return false;
186 + return $next_step_id;
187 + }
188 +
189 + /**
190 + * Get next id for step
191 + *
192 + * @param object $order order object.
193 + * @return int
194 + */
195 + public function get_flow_id_from_order( $order ) {
196 +
197 + if ( ! is_object( $order ) ) {
198 + $order = wc_get_order( $order );
172 199 }
173 200
174 - foreach ( $steps as $i => $step ) {
201 + $flow_id = is_object( $order ) ? $order->get_meta( '_wcf_flow_id' ) : 0;
175 202
176 - if ( intval( $step['id'] ) === $step_id ) {
203 + return intval( $flow_id );
204 + }
177 205
178 - $next_i = $i + 1;
206 + /**
207 + * Get checkout id for order
208 + *
209 + * @param object $order order object.
210 + * @return int
211 + */
212 + public function get_checkout_id_from_order( $order ) {
179 213
180 - if ( isset( $steps[ $next_i ] ) ) {
214 + if ( ! is_object( $order ) ) {
215 + $order = wc_get_order( $order );
216 + }
181 217
182 - $navigation = $steps[ $next_i ];
218 + $checkout_id = is_object( $order ) ? $order->get_meta( '_wcf_checkout_id' ) : 0;
183 219
184 - return intval( $navigation['id'] );
185 - }
220 + return intval( $checkout_id );
221 + }
186 222
187 - break;
188 - }
223 + /**
224 + * We are using this function mostly in ajax on checkout page
225 + *
226 + * @return mixed
227 + */
228 + public function get_checkout_id_from_post_data() {
229 +
230 + $checkout_id = false;
231 +
232 + //phpcs:disable WordPress.Security.NonceVerification
233 +
234 + if ( isset( $_POST['_wcf_checkout_id'] ) ) {
235 +
236 + $checkout_id = intval( $_POST['_wcf_checkout_id'] );
237 +
238 + } elseif ( isset( $_GET['wcf_checkout_id'] ) ) {
239 +
240 + $checkout_id = intval( $_GET['wcf_checkout_id'] );
241 +
189 242 }
243 + //phpcs:enable WordPress.Security.NonceVerification
190 244
191 - return false;
245 + return $checkout_id;
192 246 }
193 247
194 248 /**
195 - * Get next id for step
249 + * We are using this function mostly in ajax on checkout page
196 250 *
197 - * @param int $order_id order ID.
198 - * @return int
251 + * @return bool
199 252 */
200 - function get_flow_id_from_order( $order_id ) {
253 + public function get_flow_id_from_post_data() {
201 254
202 - $flow_id = get_post_meta( $order_id, '_wcf_flow_id', true );
255 + $flow_id = false;
203 256
204 - return intval( $flow_id );
257 + //phpcs:disable WordPress.Security.NonceVerification
258 +
259 + if ( isset( $_POST['_wcf_flow_id'] ) ) {
260 +
261 + $flow_id = intval( $_POST['_wcf_flow_id'] );
262 +
263 + } elseif ( isset( $_GET['wcf_checkout_id'] ) ) {
264 +
265 + $flow_id = wcf()->utils->get_flow_id_from_step_id( intval( $_GET['wcf_checkout_id'] ) );
266 +
267 + }
268 +
269 + //phpcs:enable WordPress.Security.NonceVerification
270 +
271 + return $flow_id;
205 272 }
206 273
207 274 /**
208 - * Get checkout id for order
275 + * Get optin id for order
209 276 *
210 - * @param int $order_id order ID.
277 + * @param object $order order object.
211 278 * @return int
212 279 */
213 - function get_checkout_id_from_order( $order_id ) {
280 + public function get_optin_id_from_order( $order ) {
214 281
215 - $checkout_id = get_post_meta( $order_id, '_wcf_checkout_id', true );
282 + if ( ! is_object( $order ) ) {
283 + $order = wc_get_order( $order );
284 + }
216 285
217 - return intval( $checkout_id );
286 + $optin_id = $order ? $order->get_meta( '_wcf_optin_id' ) : 0;
287 +
288 + return intval( $optin_id );
218 289 }
219 290
220 291 /**
221 292 * We are using this function mostly in ajax on checkout page
@@ -221,32 +292,34 @@
221 292 * We are using this function mostly in ajax on checkout page
222 293 *
223 294 * @return bool
224 295 */
225 - function get_checkout_id_from_post_data() {
296 + public function get_optin_id_from_post_data() {
226 297
227 - if ( isset( $_POST['_wcf_checkout_id'] ) ) {
298 + if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
228 299
229 - $checkout_id = filter_var( $_POST['_wcf_checkout_id'], FILTER_SANITIZE_NUMBER_INT );
300 + $optin_id = intval( $_POST['_wcf_optin_id'] ); //phpcs:ignore WordPress.Security.NonceVerification.Missing
230 301
231 - return intval( $checkout_id );
302 + return $optin_id;
232 303 }
233 304
234 305 return false;
235 306 }
236 307
308 +
237 309 /**
238 - * We are using this function mostly in ajax on checkout page
310 + * Check for checkout page
239 311 *
312 + * @param int $step_id step ID.
240 313 * @return bool
241 314 */
242 - function get_flow_id_from_post_data() {
315 + public function check_is_checkout_page( $step_id ) {
243 316
244 - if ( isset( $_POST['_wcf_flow_id'] ) ) {
317 + $step_type = $this->get_step_type( $step_id );
245 318
246 - $flow_id = filter_var( $_POST['_wcf_flow_id'], FILTER_SANITIZE_NUMBER_INT );
319 + if ( 'checkout' === $step_type ) {
247 320
248 - return intval( $flow_id );
321 + return true;
249 322 }
250 323
251 324 return false;
252 325 }
@@ -256,9 +329,9 @@
256 329 *
257 330 * @param int $step_id step ID.
258 331 * @return bool
259 332 */
260 - function check_is_thankyou_page( $step_id ) {
333 + public function check_is_thankyou_page( $step_id ) {
261 334
262 335 $step_type = $this->get_step_type( $step_id );
263 336
264 337 if ( 'thankyou' === $step_type ) {
@@ -274,9 +347,9 @@
274 347 *
275 348 * @param int $step_id step ID.
276 349 * @return bool
277 350 */
278 - function check_is_offer_page( $step_id ) {
351 + public function check_is_offer_page( $step_id ) {
279 352
280 353 $step_type = $this->get_step_type( $step_id );
281 354
282 355 if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
@@ -287,18 +360,67 @@
287 360 return false;
288 361 }
289 362
290 363 /**
364 + * Check if a step is disabled.
365 + *
366 + * @since 2.1.20
367 + * @param int $step_id step ID.
368 + * @return bool
369 + */
370 + public function is_step_disabled( $step_id ) {
371 +
372 + if ( empty( $step_id ) ) {
373 + return false;
374 + }
375 +
376 + $is_disabled = get_post_meta( $step_id, 'wcf-disable-step', true );
377 +
378 + // Step is enabled by default, so if disabled step meta is set to 'yes', the step is disabled.
379 + return ( 'yes' === $is_disabled );
380 + }
381 +
382 + /**
383 + * Check if loaded page requires woo.
384 + *
385 + * @return bool
386 + */
387 + public function check_is_woo_required_page() {
388 +
389 + global $post;
390 + $step_id = $post->ID;
391 + $woo_not_required_type = array( 'landing' );
392 + $step_type = $this->get_step_type( $step_id );
393 + return ( ! in_array( $step_type, $woo_not_required_type, true ) );
394 + }
395 +
396 + /**
291 397 * Define constant for cache
292 398 *
293 399 * @return void
294 400 */
295 - function do_not_cache() {
401 + public function do_not_cache() {
296 402
297 - wc_maybe_define_constant( 'DONOTCACHEPAGE', true );
298 - wc_maybe_define_constant( 'DONOTCACHEOBJECT', true );
299 - wc_maybe_define_constant( 'DONOTCACHEDB', true );
403 + global $post;
300 404
405 + if ( ! apply_filters( 'cartflows_do_not_cache_step', true, $post->ID ) ) {
406 + return;
407 + }
408 +
409 + $this->get_cache_headers();
410 + }
411 +
412 + /**
413 + * Function to get/set the do not cache page constants.
414 + *
415 + * @return void
416 + */
417 + public function get_cache_headers() {
418 +
419 + wcf_maybe_define_constant( 'DONOTCACHEPAGE', true );
420 + wcf_maybe_define_constant( 'DONOTCACHEOBJECT', true );
421 + wcf_maybe_define_constant( 'DONOTCACHEDB', true );
422 +
301 423 nocache_headers();
302 424 }
303 425
304 426 /**
@@ -306,9 +428,9 @@
306 428 *
307 429 * @param array $args query args.
308 430 * @return string
309 431 */
310 - function get_linking_url( $args = array() ) {
432 + public function get_linking_url( $args = array() ) {
311 433
312 434 $url = get_home_url();
313 435
314 436 $url = add_query_arg( $args, $url );
@@ -314,8 +436,305 @@
314 436 $url = add_query_arg( $args, $url );
315 437
316 438 return $url;
317 439 }
440 +
441 + /**
442 + * Get assets urls
443 + *
444 + * @return array
445 + * @since 1.1.6
446 + */
447 + public function get_assets_path() {
448 +
449 + $rtl = '';
450 +
451 + if ( is_rtl() ) {
452 + $rtl = '-rtl';
453 + }
454 +
455 + $file_prefix = '';
456 + $dir_name = '';
457 +
458 + $is_min = apply_filters( 'cartflows_load_min_assets', false );
459 +
460 + if ( $is_min ) {
461 + $file_prefix = '.min';
462 + $dir_name = 'min-';
463 + }
464 +
465 + $js_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'js/';
466 + $css_gen_path = CARTFLOWS_URL . 'assets/' . $dir_name . 'css/';
467 +
468 + return array(
469 + 'css' => $css_gen_path,
470 + 'js' => $js_gen_path,
471 + 'file_prefix' => $file_prefix,
472 + 'rtl' => $rtl,
473 + );
474 + }
475 +
476 + /**
477 + * Get assets css url
478 + *
479 + * @param string $file file name.
480 + * @return string
481 + * @since 1.1.6
482 + */
483 + public function get_css_url( $file ) {
484 +
485 + $assets_vars = wcf()->assets_vars;
486 +
487 + $url = $assets_vars['css'] . $file . $assets_vars['rtl'] . $assets_vars['file_prefix'] . '.css';
488 +
489 + return $url;
490 + }
491 +
492 + /**
493 + * Get assets js url
494 + *
495 + * @param string $file file name.
496 + * @return string
497 + * @since 1.1.6
498 + */
499 + public function get_js_url( $file ) {
500 +
501 + $assets_vars = wcf()->assets_vars;
502 +
503 + $url = $assets_vars['js'] . $file . $assets_vars['file_prefix'] . '.js';
504 +
505 + return $url;
506 + }
507 +
508 + /**
509 + * Get unique id.
510 + *
511 + * @param int $length Length.
512 + *
513 + * @return string|false
514 + */
515 + public function get_unique_id( $length = 8 ) {
516 +
517 + return substr( wp_generate_password( $length * 2, false ), 0, $length );
518 + }
519 +
520 + /**
521 + * Get selected checkout products and data
522 + *
523 + * @param int $checkout_id Checkout id..
524 + * @param array $saved_products Saved product.
525 + *
526 + * @return array
527 + */
528 + public function get_selected_checkout_products( $checkout_id = '', $saved_products = array() ) {
529 +
530 + if ( empty( $checkout_id ) ) {
531 +
532 + global $post;
533 +
534 + $checkout_id = $post->ID;
535 + }
536 +
537 + if ( ! isset( $this->checkout_products[ $checkout_id ] ) ) {
538 +
539 + if ( ! empty( $saved_products ) ) {
540 +
541 + $products = $saved_products;
542 + } else {
543 +
544 + $products = wcf()->options->get_checkout_meta_value( $checkout_id, 'wcf-checkout-products' );
545 + }
546 +
547 + $default_add_to_cart = true;
548 +
549 + if ( is_array( $products ) ) {
550 +
551 + foreach ( $products as $in => $data ) {
552 +
553 + $default_data = array(
554 + 'quantity' => 1,
555 + 'discount_type' => '',
556 + 'discount_value' => '',
557 + 'unique_id' => $this->get_unique_id(),
558 + 'add_to_cart' => $default_add_to_cart,
559 + );
560 +
561 + $products[ $in ] = wp_parse_args( $products[ $in ], $default_data );
562 + }
563 + }
564 +
565 + $products = apply_filters( 'cartflows_selected_checkout_products', $products, $checkout_id );
566 +
567 + // This is frontend. Ignoring nonce rule.
568 + if ( isset( $_GET['wcf-default'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
569 + $products = $this->update_the_add_to_cart_param( $products );
570 + }
571 +
572 + $this->checkout_products[ $checkout_id ] = $products;
573 + }
574 +
575 + return $this->checkout_products[ $checkout_id ];
576 + }
577 +
578 + /**
579 + * Update product add to cart option.
580 + *
581 + * @param array $products product data.
582 + */
583 + public function update_the_add_to_cart_param( $products ) {
584 +
585 + $default_sequence = isset( $_GET['wcf-default'] ) ? sanitize_text_field( wp_unslash( $_GET['wcf-default'] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended
586 + $default_ids = array_map( 'intval', explode( ',', $default_sequence ) );
587 +
588 + if ( is_array( $products ) ) {
589 +
590 + foreach ( $products as $in => $data ) {
591 +
592 + $default_add_to_cart = 'no';
593 + $sequence = $in + 1;
594 +
595 + if ( in_array( $sequence, $default_ids, true ) ) {
596 + $default_add_to_cart = 'yes';
597 +
598 + }
599 +
600 + $products[ $in ]['add_to_cart'] = $default_add_to_cart;
601 + }
602 + }
603 +
604 + return $products;
605 + }
606 +
607 + /**
608 + * Get selected checkout products and data
609 + *
610 + * @param int $checkout_id Checkout id..
611 + * @param array $products_data Saved product.
612 + *
613 + * @return array
614 + */
615 + public function set_selcted_checkout_products( $checkout_id = '', $products_data = array() ) {
616 +
617 + if ( empty( $checkout_id ) ) {
618 +
619 + global $post;
620 +
621 + $checkout_id = $post->ID;
622 + }
623 +
624 + if ( isset( $this->checkout_products[ $checkout_id ] ) ) {
625 +
626 + $products = $this->checkout_products[ $checkout_id ];
627 + } else {
628 + $products = $this->get_selected_checkout_products( $checkout_id );
629 + }
630 +
631 + if ( is_array( $products ) && ! empty( $products_data ) ) {
632 +
633 + foreach ( $products as $in => $data ) {
634 +
635 + if ( isset( $products_data[ $in ] ) ) {
636 + $products[ $in ] = wp_parse_args( $products_data[ $in ], $products[ $in ] );
637 + }
638 + }
639 + }
640 +
641 + $this->checkout_products[ $checkout_id ] = $products;
642 +
643 + return $this->checkout_products[ $checkout_id ];
644 + }
645 +
646 + /**
647 + * Clear Installed Page Builder Cache
648 + */
649 + public function clear_cache() {
650 +
651 + // Clear 'Elementor' file cache.
652 + if ( class_exists( '\Elementor\Plugin' ) ) {
653 + Elementor\Plugin::$instance->files_manager->clear_cache();
654 + }
655 + }
656 +
657 + /**
658 + * Append the query strings present in the URL to pass it to the next step URL.
659 + * This will carry-forward the passed query strings to the next step URL.
660 + *
661 + * @param array $original_query_strings Default query strings of CartFlows.
662 + * @return array $original_query_strings Modified query strings.
663 + */
664 + public function may_be_append_query_string( $original_query_strings ) {
665 +
666 + // Return if the feature is not enabled. Default is disabled.
667 + if ( ! apply_filters( 'cartflows_enable_append_query_string', false ) ) {
668 + return $original_query_strings;
669 + }
670 +
671 + // Check if HTTP_REFERER is set and fetch its query strings.
672 + if ( empty( $_SERVER['HTTP_REFERER'] ) ) {
673 + return $original_query_strings;
674 + }
675 +
676 + // Get the current page URL and parse it to explode the URL in different URL components.
677 + $url_params_components = wp_parse_url( esc_url_raw( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) );
678 +
679 + // Process only if the URL components is not empty and query i:e query strings are not empty.
680 + if ( is_array( $url_params_components ) && ! empty( $url_params_components['query'] ) ) {
681 +
682 + $forwarded_params = $url_params_components['query'];
683 +
684 + // Convert the string query from string to array format.
685 + parse_str( $forwarded_params, $parsed_query_string );
686 +
687 + // Remove the already present wcf-key and wcf-order params from the URl and append the rest of.
688 + if ( $parsed_query_string['wcf-key'] && $parsed_query_string['wcf-order'] ) {
689 + unset( $parsed_query_string['wcf-key'] );
690 + unset( $parsed_query_string['wcf-order'] );
691 + }
692 +
693 + // Merge the new and already existing query strings.
694 + $original_query_strings = array_merge( $original_query_strings, $parsed_query_string );
695 + }
696 +
697 + // Return the query strings.
698 + return apply_filters( 'cartflows_may_be_append_query_strings_args', $original_query_strings );
699 + }
700 +
701 + /**
702 + * Checks if the WooCommerce cart is empty.
703 + *
704 + * This function checks if the WooCommerce cart is empty and if the session has not expired.
705 + * It returns true if the cart is empty and the session is valid, otherwise it returns false.
706 + *
707 + * @return bool True if the cart is empty and the session is valid, otherwise false.
708 + */
709 + public function is_woo_cart_empty() {
710 +
711 + $wc = function_exists( 'WC' ) ? WC() : null;
712 + $cart = ( $wc && $wc->cart instanceof WC_Cart ) ? $wc->cart : null;
713 + $cart_is_empty = ! $cart || $cart->is_empty();
714 +
715 + return $cart_is_empty
716 + && ! is_customize_preview()
717 + && apply_filters( 'woocommerce_checkout_update_order_review_expired', true );
718 + }
719 +
720 + /**
721 + * Checks if WooCommerce HPOS (High-Performance Order Storage) is enabled.
722 + *
723 + * @since 2.2.2
724 + *
725 + * @return bool True if HPOS is enabled, false otherwise.
726 + */
727 + public function is_hpos_enabled() {
728 +
729 + if (
730 + class_exists( '\Automattic\WooCommerce\Utilities\OrderUtil' )
731 + && method_exists( '\Automattic\WooCommerce\Utilities\OrderUtil', 'custom_orders_table_usage_is_enabled' )
732 + ) {
733 + return \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled();
734 + }
735 + return false;
736 + }
318 737 }
319 738
320 739 /**
321 740 * Get a specific property of an array without needing to check if that property exists.
@@ -327,9 +746,9 @@
327 746 * @param string $default Optional. Value that should be returned if the property is not set or empty. Defaults to null.
328 747 *
329 748 * @return null|string|mixed The value
330 749 */
331 -function wcf_get_prop( $array, $prop, $default = null ) {
750 +function wcf_get_prop( $array, $prop, $default = null ) { // phpcs:ignore Universal.Files.SeparateFunctionsFromOO.Mixed
332 751
333 752 if ( ! is_array( $array ) && ! ( is_object( $array ) && $array instanceof ArrayAccess ) ) {
334 753 return $default;
335 754 }