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 +763 -344 1.1.13 → 3.3.0 View file →
@@ -1,344 +1,763 @@
1 -<?php
2 -/**
3 - * Utils.
4 - *
5 - * @package CARTFLOWS
6 - */
7 -
8 -if ( ! defined( 'ABSPATH' ) ) {
9 - exit; // Exit if accessed directly.
10 -}
11 -
12 -/**
13 - * Class Cartflows_Utils.
14 - */
15 -class Cartflows_Utils {
16 -
17 - /**
18 - * Member Variable
19 - *
20 - * @var instance
21 - */
22 - private static $instance;
23 -
24 - /**
25 - * Initiator
26 - */
27 - public static function get_instance() {
28 - if ( ! isset( self::$instance ) ) {
29 - self::$instance = new self;
30 - }
31 - return self::$instance;
32 - }
33 -
34 - /**
35 - * Constructor
36 - */
37 - function __construct() {
38 - }
39 -
40 - /**
41 - * Get current post type
42 - *
43 - * @param string $post_type post type.
44 - * @return string
45 - */
46 - function current_post_type( $post_type = '' ) {
47 -
48 - if ( '' === $post_type ) {
49 - $post_type = get_post_type();
50 - }
51 -
52 - return $post_type;
53 - }
54 -
55 - /**
56 - * Check if post type is of step.
57 - *
58 - * @param string $post_type post type.
59 - * @return bool
60 - */
61 - function is_step_post_type( $post_type = '' ) {
62 -
63 - if ( $this->get_step_post_type() === $this->current_post_type( $post_type ) ) {
64 -
65 - return true;
66 - }
67 -
68 - return false;
69 - }
70 -
71 - /**
72 - * Check if post type is of flow.
73 - *
74 - * @param string $post_type post type.
75 - * @return bool
76 - */
77 - function is_flow_post_type( $post_type = '' ) {
78 -
79 - if ( $this->get_flow_post_type() === $this->current_post_type( $post_type ) ) {
80 -
81 - return true;
82 - }
83 -
84 - return false;
85 - }
86 -
87 - /**
88 - * Get post type of step.
89 - *
90 - * @return string
91 - */
92 - function get_step_post_type() {
93 -
94 - return CARTFLOWS_STEP_POST_TYPE;
95 - }
96 -
97 - /**
98 - * Get post type of flow.
99 - *
100 - * @return string
101 - */
102 - function get_flow_post_type() {
103 -
104 - return CARTFLOWS_FLOW_POST_TYPE;
105 - }
106 -
107 - /**
108 - * Get flow id
109 - *
110 - * @return int
111 - */
112 - function get_flow_id() {
113 -
114 - global $post;
115 -
116 - return get_post_meta( $post->ID, 'wcf-flow-id', true );
117 - }
118 -
119 - /**
120 - * Get flow id by step
121 - *
122 - * @param int $step_id step ID.
123 - * @return int
124 - */
125 - function get_flow_id_from_step_id( $step_id ) {
126 -
127 - return get_post_meta( $step_id, 'wcf-flow-id', true );
128 - }
129 -
130 - /**
131 - * Get flow steps by id
132 - *
133 - * @param int $flow_id flow ID.
134 - * @return int
135 - */
136 - function get_flow_steps( $flow_id ) {
137 -
138 - $steps = get_post_meta( $flow_id, 'wcf-steps', true );
139 -
140 - if ( is_array( $steps ) && ! empty( $steps ) ) {
141 - return $steps;
142 - }
143 -
144 - return false;
145 - }
146 -
147 - /**
148 - * Get template type of step
149 - *
150 - * @param int $step_id step ID.
151 - * @return int
152 - */
153 - function get_step_type( $step_id ) {
154 -
155 - return get_post_meta( $step_id, 'wcf-step-type', true );
156 - }
157 -
158 - /**
159 - * Get next id for step
160 - *
161 - * @param int $flow_id flow ID.
162 - * @param int $step_id step ID.
163 - * @return bool
164 - */
165 - function get_next_step_id( $flow_id, $step_id ) {
166 -
167 - $steps = $this->get_flow_steps( $flow_id );
168 - $step_id = intval( $step_id );
169 -
170 - if ( ! $steps ) {
171 - return false;
172 - }
173 -
174 - foreach ( $steps as $i => $step ) {
175 -
176 - if ( intval( $step['id'] ) === $step_id ) {
177 -
178 - $next_i = $i + 1;
179 -
180 - if ( isset( $steps[ $next_i ] ) ) {
181 -
182 - $navigation = $steps[ $next_i ];
183 -
184 - return intval( $navigation['id'] );
185 - }
186 -
187 - break;
188 - }
189 - }
190 -
191 - return false;
192 - }
193 -
194 - /**
195 - * Get next id for step
196 - *
197 - * @param int $order_id order ID.
198 - * @return int
199 - */
200 - function get_flow_id_from_order( $order_id ) {
201 -
202 - $flow_id = get_post_meta( $order_id, '_wcf_flow_id', true );
203 -
204 - return intval( $flow_id );
205 - }
206 -
207 - /**
208 - * Get checkout id for order
209 - *
210 - * @param int $order_id order ID.
211 - * @return int
212 - */
213 - function get_checkout_id_from_order( $order_id ) {
214 -
215 - $checkout_id = get_post_meta( $order_id, '_wcf_checkout_id', true );
216 -
217 - return intval( $checkout_id );
218 - }
219 -
220 - /**
221 - * We are using this function mostly in ajax on checkout page
222 - *
223 - * @return bool
224 - */
225 - function get_checkout_id_from_post_data() {
226 -
227 - if ( isset( $_POST['_wcf_checkout_id'] ) ) {
228 -
229 - $checkout_id = filter_var( $_POST['_wcf_checkout_id'], FILTER_SANITIZE_NUMBER_INT );
230 -
231 - return intval( $checkout_id );
232 - }
233 -
234 - return false;
235 - }
236 -
237 - /**
238 - * We are using this function mostly in ajax on checkout page
239 - *
240 - * @return bool
241 - */
242 - function get_flow_id_from_post_data() {
243 -
244 - if ( isset( $_POST['_wcf_flow_id'] ) ) {
245 -
246 - $flow_id = filter_var( $_POST['_wcf_flow_id'], FILTER_SANITIZE_NUMBER_INT );
247 -
248 - return intval( $flow_id );
249 - }
250 -
251 - return false;
252 - }
253 -
254 - /**
255 - * Check for thank you page
256 - *
257 - * @param int $step_id step ID.
258 - * @return bool
259 - */
260 - function check_is_thankyou_page( $step_id ) {
261 -
262 - $step_type = $this->get_step_type( $step_id );
263 -
264 - if ( 'thankyou' === $step_type ) {
265 -
266 - return true;
267 - }
268 -
269 - return false;
270 - }
271 -
272 - /**
273 - * Check for offer page
274 - *
275 - * @param int $step_id step ID.
276 - * @return bool
277 - */
278 - function check_is_offer_page( $step_id ) {
279 -
280 - $step_type = $this->get_step_type( $step_id );
281 -
282 - if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
283 -
284 - return true;
285 - }
286 -
287 - return false;
288 - }
289 -
290 - /**
291 - * Define constant for cache
292 - *
293 - * @return void
294 - */
295 - function do_not_cache() {
296 -
297 - wc_maybe_define_constant( 'DONOTCACHEPAGE', true );
298 - wc_maybe_define_constant( 'DONOTCACHEOBJECT', true );
299 - wc_maybe_define_constant( 'DONOTCACHEDB', true );
300 -
301 - nocache_headers();
302 - }
303 -
304 - /**
305 - * Get linking url
306 - *
307 - * @param array $args query args.
308 - * @return string
309 - */
310 - function get_linking_url( $args = array() ) {
311 -
312 - $url = get_home_url();
313 -
314 - $url = add_query_arg( $args, $url );
315 -
316 - return $url;
317 - }
318 -}
319 -
320 -/**
321 - * Get a specific property of an array without needing to check if that property exists.
322 - *
323 - * Provide a default value if you want to return a specific value if the property is not set.
324 - *
325 - * @param array $array Array from which the property's value should be retrieved.
326 - * @param string $prop Name of the property to be retrieved.
327 - * @param string $default Optional. Value that should be returned if the property is not set or empty. Defaults to null.
328 - *
329 - * @return null|string|mixed The value
330 - */
331 -function wcf_get_prop( $array, $prop, $default = null ) {
332 -
333 - if ( ! is_array( $array ) && ! ( is_object( $array ) && $array instanceof ArrayAccess ) ) {
334 - return $default;
335 - }
336 -
337 - if ( isset( $array[ $prop ] ) ) {
338 - $value = $array[ $prop ];
339 - } else {
340 - $value = '';
341 - }
342 -
343 - return empty( $value ) && null !== $default ? $default : $value;
344 -}
1 +<?php
2 +/**
3 + * Utils.
4 + *
5 + * @package CARTFLOWS
6 + */
7 +
8 +if ( ! defined( 'ABSPATH' ) ) {
9 + exit; // Exit if accessed directly.
10 +}
11 +
12 +/**
13 + * Class Cartflows_Utils.
14 + */
15 +class Cartflows_Utils {
16 +
17 + /**
18 + * Member Variable
19 + *
20 + * @var instance
21 + */
22 + private static $instance;
23 +
24 + /**
25 + * Member Variable
26 + *
27 + * @var checkout_products
28 + */
29 + public $checkout_products = array();
30 +
31 +
32 + /**
33 + * Initiator
34 + */
35 + public static function get_instance() {
36 + if ( ! isset( self::$instance ) ) {
37 + self::$instance = new self();
38 + }
39 + return self::$instance;
40 + }
41 +
42 + /**
43 + * Constructor
44 + */
45 + public function __construct() {
46 + }
47 +
48 + /**
49 + * Get current post type
50 + *
51 + * @param string $post_type post type.
52 + * @return string
53 + */
54 + public function current_post_type( $post_type = '' ) {
55 +
56 + global $post;
57 +
58 + if ( '' === $post_type && is_object( $post ) ) {
59 + $post_type = $post->post_type;
60 + }
61 +
62 + return $post_type;
63 + }
64 +
65 + /**
66 + * Check if post type is of step.
67 + *
68 + * @param string $post_type post type.
69 + * @return bool
70 + */
71 + public function is_step_post_type( $post_type = '' ) {
72 +
73 + if ( $this->get_step_post_type() === $this->current_post_type( $post_type ) ) {
74 +
75 + return true;
76 + }
77 +
78 + return false;
79 + }
80 +
81 + /**
82 + * Check if post type is of flow.
83 + *
84 + * @param string $post_type post type.
85 + * @return bool
86 + */
87 + public function is_flow_post_type( $post_type = '' ) {
88 +
89 + if ( $this->get_flow_post_type() === $this->current_post_type( $post_type ) ) {
90 +
91 + return true;
92 + }
93 +
94 + return false;
95 + }
96 +
97 + /**
98 + * Get post type of step.
99 + *
100 + * @return string
101 + */
102 + public function get_step_post_type() {
103 +
104 + return CARTFLOWS_STEP_POST_TYPE;
105 + }
106 +
107 + /**
108 + * Get post type of flow.
109 + *
110 + * @return string
111 + */
112 + public function get_flow_post_type() {
113 +
114 + return CARTFLOWS_FLOW_POST_TYPE;
115 + }
116 +
117 + /**
118 + * Get flow id
119 + *
120 + * @return int
121 + */
122 + public function get_flow_id() {
123 +
124 + global $post;
125 +
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;
133 + }
134 +
135 + /**
136 + * Get flow id by step
137 + *
138 + * @param int $step_id step ID.
139 + * @return int
140 + */
141 + public function get_flow_id_from_step_id( $step_id ) {
142 +
143 + return get_post_meta( $step_id, 'wcf-flow-id', true );
144 + }
145 +
146 + /**
147 + * Get flow steps by id
148 + *
149 + * @param int $flow_id flow ID.
150 + * @return int
151 + */
152 + public function get_flow_steps( $flow_id ) {
153 +
154 + $steps = get_post_meta( $flow_id, 'wcf-steps', true );
155 +
156 + if ( is_array( $steps ) && ! empty( $steps ) ) {
157 + return $steps;
158 + }
159 +
160 + return false;
161 + }
162 +
163 + /**
164 + * Get template type of step
165 + *
166 + * @param int $step_id step ID.
167 + * @return int
168 + */
169 + public function get_step_type( $step_id ) {
170 +
171 + return get_post_meta( $step_id, 'wcf-step-type', true );
172 + }
173 +
174 + /**
175 + * Get next id for step
176 + *
177 + * @param int $flow_id flow ID.
178 + * @param int $step_id step ID.
179 + * @return bool
180 + */
181 + public function get_next_step_id( $flow_id, $step_id ) {
182 +
183 + $wcf_step_obj = wcf_get_step( $step_id );
184 + $next_step_id = $wcf_step_obj->get_direct_next_step_id();
185 +
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 );
199 + }
200 +
201 + $flow_id = is_object( $order ) ? $order->get_meta( '_wcf_flow_id' ) : 0;
202 +
203 + return intval( $flow_id );
204 + }
205 +
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 ) {
213 +
214 + if ( ! is_object( $order ) ) {
215 + $order = wc_get_order( $order );
216 + }
217 +
218 + $checkout_id = is_object( $order ) ? $order->get_meta( '_wcf_checkout_id' ) : 0;
219 +
220 + return intval( $checkout_id );
221 + }
222 +
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 +
242 + }
243 + //phpcs:enable WordPress.Security.NonceVerification
244 +
245 + return $checkout_id;
246 + }
247 +
248 + /**
249 + * We are using this function mostly in ajax on checkout page
250 + *
251 + * @return bool
252 + */
253 + public function get_flow_id_from_post_data() {
254 +
255 + $flow_id = false;
256 +
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;
272 + }
273 +
274 + /**
275 + * Get optin id for order
276 + *
277 + * @param object $order order object.
278 + * @return int
279 + */
280 + public function get_optin_id_from_order( $order ) {
281 +
282 + if ( ! is_object( $order ) ) {
283 + $order = wc_get_order( $order );
284 + }
285 +
286 + $optin_id = $order ? $order->get_meta( '_wcf_optin_id' ) : 0;
287 +
288 + return intval( $optin_id );
289 + }
290 +
291 + /**
292 + * We are using this function mostly in ajax on checkout page
293 + *
294 + * @return bool
295 + */
296 + public function get_optin_id_from_post_data() {
297 +
298 + if ( isset( $_POST['_wcf_optin_id'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing
299 +
300 + $optin_id = intval( $_POST['_wcf_optin_id'] ); //phpcs:ignore WordPress.Security.NonceVerification.Missing
301 +
302 + return $optin_id;
303 + }
304 +
305 + return false;
306 + }
307 +
308 +
309 + /**
310 + * Check for checkout page
311 + *
312 + * @param int $step_id step ID.
313 + * @return bool
314 + */
315 + public function check_is_checkout_page( $step_id ) {
316 +
317 + $step_type = $this->get_step_type( $step_id );
318 +
319 + if ( 'checkout' === $step_type ) {
320 +
321 + return true;
322 + }
323 +
324 + return false;
325 + }
326 +
327 + /**
328 + * Check for thank you page
329 + *
330 + * @param int $step_id step ID.
331 + * @return bool
332 + */
333 + public function check_is_thankyou_page( $step_id ) {
334 +
335 + $step_type = $this->get_step_type( $step_id );
336 +
337 + if ( 'thankyou' === $step_type ) {
338 +
339 + return true;
340 + }
341 +
342 + return false;
343 + }
344 +
345 + /**
346 + * Check for offer page
347 + *
348 + * @param int $step_id step ID.
349 + * @return bool
350 + */
351 + public function check_is_offer_page( $step_id ) {
352 +
353 + $step_type = $this->get_step_type( $step_id );
354 +
355 + if ( 'upsell' === $step_type || 'downsell' === $step_type ) {
356 +
357 + return true;
358 + }
359 +
360 + return false;
361 + }
362 +
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 + /**
397 + * Define constant for cache
398 + *
399 + * @return void
400 + */
401 + public function do_not_cache() {
402 +
403 + global $post;
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 +
423 + nocache_headers();
424 + }
425 +
426 + /**
427 + * Get linking url
428 + *
429 + * @param array $args query args.
430 + * @return string
431 + */
432 + public function get_linking_url( $args = array() ) {
433 +
434 + $url = get_home_url();
435 +
436 + $url = add_query_arg( $args, $url );
437 +
438 + return $url;
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 + }
737 +}
738 +
739 +/**
740 + * Get a specific property of an array without needing to check if that property exists.
741 + *
742 + * Provide a default value if you want to return a specific value if the property is not set.
743 + *
744 + * @param array $array Array from which the property's value should be retrieved.
745 + * @param string $prop Name of the property to be retrieved.
746 + * @param string $default Optional. Value that should be returned if the property is not set or empty. Defaults to null.
747 + *
748 + * @return null|string|mixed The value
749 + */
750 +function wcf_get_prop( $array, $prop, $default = null ) { // phpcs:ignore Universal.Files.SeparateFunctionsFromOO.Mixed
751 +
752 + if ( ! is_array( $array ) && ! ( is_object( $array ) && $array instanceof ArrayAccess ) ) {
753 + return $default;
754 + }
755 +
756 + if ( isset( $array[ $prop ] ) ) {
757 + $value = $array[ $prop ];
758 + } else {
759 + $value = '';
760 + }
761 +
762 + return empty( $value ) && null !== $default ? $default : $value;
763 +}