PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / 1.10.1
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant v1.10.1
2.3.2 2.3.1 2.3.0 2.2.8 2.2.7 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.11.1 1.11.2 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.9.10 1.9.11 All 60 releases
merchant / inc / helpers.php

helpers.php in Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant 1.10.1, at inc/helpers.php

768 lines 19.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Helper functions.
5 *
6 * @package Merchant
7 */
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit; // Exit if accessed directly
11 }
12
13 /**
14 * Allowed tags general.
15 * Should be used to escape complex outputs like entire features html.
16 *
17 * @param array $extra
18 * @param bool $include_post_tags Whether to include post kses allowed tags or not. Default true.
19 *
20 * @return array $allowed_tags
21 */
22 if ( ! function_exists( 'merchant_kses_allowed_tags' ) ) {
23 function merchant_kses_allowed_tags( $extra = array(), $include_post_tags = true ) {
24 // Default
25 $allowed_tags = array_merge(
26 array(
27 // Meta
28 'meta' => array(
29 'name' => true,
30 'content' => true,
31 ),
32
33 // SVG Support
34 'svg' => array(
35 'class' => true,
36 'xmlns' => true,
37 'width' => true,
38 'height' => true,
39 'viewbox' => true,
40 'aria-hidden' => true,
41 'role' => true,
42 'focusable' => true,
43 'fill' => true,
44 'stroke' => true,
45 'stroke-linecap' => true,
46 'stroke-linejoin' => true,
47 'stroke-width' => true,
48 ),
49 'g' => array(
50 'id' => true,
51 'class' => true,
52 'clip-path' => true,
53 'style' => true,
54 'transform' => true,
55 ),
56 'path' => array(
57 'fill' => true,
58 'fill-rule' => true,
59 'd' => true,
60 'transform' => true,
61 'stroke' => true,
62 'stroke-width' => true,
63 'stroke-linejoin' => true,
64 'clip-rule' => true,
65 ),
66 'polyline' => array(
67 'points' => true,
68 'fill' => true,
69 'fill-rule' => true,
70 'd' => true,
71 'transform' => true,
72 'stroke' => true,
73 'stroke-width' => true,
74 'stroke-linejoin' => true,
75 ),
76 'polygon' => array(
77 'fill' => true,
78 'fill-rule' => true,
79 'points' => true,
80 'transform' => true,
81 'focusable' => true,
82 'stroke' => true,
83 'stroke-width' => true,
84 ),
85 'rect' => array(
86 'x' => true,
87 'y' => true,
88 'rx' => true,
89 'width' => true,
90 'height' => true,
91 'transform' => true,
92 'fill' => true,
93 'stroke' => true,
94 'stroke-width' => true,
95 ),
96 'circle' => array(
97 'cx' => true,
98 'cy' => true,
99 'r' => true,
100 'width' => true,
101 'height' => true,
102 'transform' => true,
103 'fill' => true,
104 'stroke' => true,
105 'stroke-width' => true,
106 'stroke-linecap' => true,
107 'stroke-linejoin' => true,
108 ),
109 'line' => array(
110 'x1' => true,
111 'y1' => true,
112 'x2' => true,
113 'y2' => true,
114 'width' => true,
115 'height' => true,
116 'transform' => true,
117 'fill' => true,
118 'stroke' => true,
119 'stroke-width' => true,
120 'stroke-linecap' => true,
121 'stroke-linejoin' => true,
122 ),
123 'clipPath' => array(
124 'id' => true,
125 'class' => true,
126 'style' => true,
127 ),
128 'defs' => array(
129 'id' => true,
130 ),
131 'progress' => array(
132 'id' => true,
133 'class' => true,
134 'value' => true,
135 'max' => true,
136 ),
137 ),
138 $include_post_tags ? wp_kses_allowed_html( 'post' ) : array()
139 );
140
141 // Include schema markup tags
142 if ( in_array( 'schema_markup', $extra, true ) || in_array( 'all', $extra, true ) ) {
143 $tags = array( 'meta', 'nav', 'ul', 'li', 'a', 'span' );
144
145 foreach ( $tags as $tag ) {
146 if ( isset( $allowed_tags[ $tag ] ) ) {
147 $allowed_tags[ $tag ]['itemprop'] = true;
148 $allowed_tags[ $tag ]['itemscope'] = true;
149 $allowed_tags[ $tag ]['itemtype'] = true;
150 } else {
151 $allowed_tags[ $tag ] = array(
152 'itemprop' => true,
153 'itemscope' => true,
154 'itemtype' => true,
155 );
156 }
157 }
158 }
159
160 // Include iframe tags
161 if ( in_array( 'iframe', $extra, true ) || in_array( 'all', $extra, true ) ) {
162 $allowed_tags['iframe'] = array(
163 'src' => true,
164 'height' => true,
165 'width' => true,
166 'frameborder' => true,
167 'allowfullscreen' => true,
168 );
169 }
170
171 if ( in_array( 'wc_email', $extra, true ) || in_array( 'all', $extra, true ) ) {
172 $allowed_tags['body'] = array(
173 'class' => true,
174 'style' => true,
175 'leftmargin' => true,
176 'marginwidth' => true,
177 'topmargin' => true,
178 'marginheight' => true,
179 'offset' => true,
180 );
181
182 $allowed_tags['html'] = array(
183 'lang' => true,
184 );
185
186 $allowed_tags['style'] = array(
187 'type' => true,
188 );
189 $allowed_tags['head'] = array();
190 $allowed_tags['meta']['http-equiv'] = true;
191 }
192
193 // Include nonce tags
194 if ( in_array( 'nonce', $extra, true ) || in_array( 'all', $extra, true ) ) {
195 $allowed_tags['input'] = array(
196 'type' => true,
197 'id' => true,
198 'name' => true,
199 'value' => true,
200 'data-name' => true,
201 );
202 }
203
204 // Include bdi tag
205 if ( in_array( 'bdi', $extra, true ) || in_array( 'all', $extra, true ) ) {
206 $allowed_tags['bdi'] = array(
207 'class' => true,
208 'id' => true,
209 'style' => true,
210 );
211 }
212
213 // Include select2
214 if ( in_array( 'select2', $extra, true ) || in_array( 'all', $extra, true ) ) {
215 $allowed_tags['select'] = array(
216 'name' => true,
217 'class' => true,
218 'id' => true,
219 'style' => true,
220 'data-name' => true,
221 'data-source' => true,
222 'multiple' => true,
223 );
224
225 $allowed_tags['option'] = array(
226 'value' => true,
227 'selected' => true,
228 );
229
230 $allowed_tags['optgroup'] = array(
231 'label' => true,
232 );
233 }
234
235 // Include dd, dt tags
236 if ( in_array( 'dd', $extra, true ) || in_array( 'all', $extra, true ) ) {
237 $allowed_tags['dd'] = array(
238 'class' => true,
239 'id' => true,
240 'style' => true,
241 );
242
243 $allowed_tags['dt'] = array(
244 'class' => true,
245 'id' => true,
246 'style' => true,
247 );
248 }
249
250 // Include forms tags.
251 if ( in_array( 'forms', $extra, true ) || in_array( 'all', $extra, true ) ) {
252 $tags = array( 'form', 'input', 'select', 'option', 'textarea', 'a' );
253
254 foreach ( $tags as $tag ) {
255 $allowed_tags[ $tag ] = array(
256 'id' => true,
257 'class' => true,
258 'style' => true,
259 'name' => true,
260 'href' => true,
261 'target' => true,
262 'value' => true,
263 'type' => true,
264 'placeholder' => true,
265 'data' => '*',
266 'data-source' => true,
267 'data-product_id' => true,
268 'data-product_variations' => true,
269 'data-attribute_name' => true,
270 'data-show_option_none' => true,
271 'data-name' => true,
272 'data-allowed-types' => true,
273 'step' => true,
274 'min' => true,
275 'max' => true,
276 'selected' => true,
277 'checked' => true,
278 'onchange' => true,
279 'autocomplete' => true,
280 'required' => true,
281 'action' => true,
282 'method' => true,
283 'enctype' => true,
284 'size' => true,
285 'role' => true,
286 'inputmode' => true,
287 'aria-label' => true,
288 'multiple' => true,
289 );
290
291 if ( $tag === 'a' ) {
292 $allowed_tags[ $tag ]['href'] = true;
293 $allowed_tags[ $tag ]['title'] = true;
294 $allowed_tags[ $tag ]['target'] = true;
295 }
296 }
297 }
298
299 /**
300 * Filters the allowed tags.
301 *
302 * @since 1.2.5
303 */
304 return apply_filters( 'merchant_kses_allowed_tags', $allowed_tags );
305 }
306 }
307
308 /**
309 * Allowed tags for scripts.
310 *
311 * @return array $allowed_tags
312 */
313 if ( ! function_exists( 'merchant_kses_allowed_tags_for_code_snippets' ) ) {
314 function merchant_kses_allowed_tags_for_code_snippets() {
315 return array(
316 'script' => array(
317 'type' => true,
318 ),
319 );
320 }
321 }
322
323 /**
324 * Check if WooCommerce checkout page is being rendered by block.
325 * Since WooCommerce 8.3.0 the checkout page is rendered by block.
326 *
327 * @return bool
328 */
329 if ( ! function_exists( 'merchant_is_checkout_block_layout' ) ) {
330 function merchant_is_checkout_block_layout() {
331 $checkout_page = wc_get_page_id( 'checkout' );
332
333 if ( empty( $checkout_page ) ) {
334 return false;
335 }
336
337 if ( function_exists( 'has_blocks' ) && has_blocks( $checkout_page ) ) {
338 $post = get_post( $checkout_page );
339 $blocks = parse_blocks( $post->post_content );
340
341 foreach ( $blocks as $block ) {
342 if ( 'woocommerce/checkout' === $block['blockName'] ) {
343 return true;
344 }
345 }
346 }
347
348 return false;
349 }
350 }
351
352 /**
353 * Check if WooCommerce cart page is being rendered by block.
354 * Since WooCommerce 8.3.0 the cart page is rendered by block.
355 *
356 * @return bool
357 */
358 if ( ! function_exists( 'merchant_is_cart_block_layout' ) ) {
359 function merchant_is_cart_block_layout() {
360 $cart_page = wc_get_page_id( 'cart' );
361
362 if ( empty( $cart_page ) ) {
363 return false;
364 }
365
366 if ( function_exists( 'has_blocks' ) && has_blocks( $cart_page ) ) {
367 $post = get_post( $cart_page );
368 $blocks = parse_blocks( $post->post_content );
369
370 foreach ( $blocks as $block ) {
371 if ( 'woocommerce/cart' === $block['blockName'] ) {
372 return true;
373 }
374 }
375 }
376
377 return false;
378 }
379 }
380
381 /**
382 * Get the product categories.
383 */
384 if ( ! function_exists( 'merchant_get_product_categories' ) ) {
385 function merchant_get_product_categories() {
386 $args = array(
387 'taxonomy' => 'product_cat',
388 'hide_empty' => false,
389 );
390
391 $categories = get_terms( $args );
392
393 $categories_tree = array();
394 $indexed_categories = array();
395
396 if ( ! empty( $categories ) && ! is_wp_error( $categories ) ) {
397 foreach ( $categories as $category ) {
398 $indexed_categories[ $category->term_id ] = array(
399 'id' => $category->term_id,
400 'slug' => $category->slug,
401 'name' => $category->name,
402 'parent' => $category->parent,
403 'children' => array(),
404 );
405 }
406
407 foreach ( $indexed_categories as &$cat ) {
408 if ( (int) $cat['parent'] === 0 ) {
409 $categories_tree[] = &$cat;
410 } else {
411 $indexed_categories[ $cat['parent'] ]['children'][] = &$cat;
412 }
413 }
414 }
415
416 return $categories_tree;
417 }
418 }
419
420 /**
421 * Get the product tags.
422 */
423 if ( ! function_exists( 'merchant_get_product_tags' ) ) {
424 function merchant_get_product_tags() {
425 $product_tags = get_terms( array(
426 'taxonomy' => 'product_tag',
427 'hide_empty' => false,
428 ) );
429
430 $tag_names = array();
431
432 if ( ! empty( $product_tags ) && ! is_wp_error( $product_tags ) ) {
433 foreach ( $product_tags as $tag ) {
434 $tag_names[ $tag->slug ] = $tag->name;
435 }
436 }
437
438 return $tag_names;
439 }
440 }
441
442 /**
443 * Convert array to css.
444 */
445 if ( ! function_exists( 'merchant_array_to_css' ) ) {
446 function merchant_array_to_css( $css_array ) {
447 $css = '';
448 if ( empty( $css_array ) ) {
449 return $css;
450 }
451 foreach ( $css_array as $key => $value ) {
452 $css .= $key . ':' . $value . ';';
453 }
454
455 return $css;
456 }
457 }
458
459 /**
460 * Get the share link data structure.
461 *
462 * @return array
463 */
464 if ( ! function_exists( 'merchant_get_share_link_data' ) ) {
465 function merchant_get_share_link_data() {
466 return array(
467 'facebook' => array(
468 'url' => 'https://www.facebook.com/sharer.php?u={{url}}',
469 'title' => __( 'Facebook', 'merchant' ),
470 ),
471 'twitter' => array(
472 'url' => 'https://twitter.com/intent/tweet?url={{url}}&text={{title}}',
473 'title' => __( 'X', 'merchant' ),
474 ),
475 'linkedin' => array(
476 'url' => 'https://www.linkedin.com/sharing/share-offsite/?url={{url}}',
477 'title' => __( 'LinkedIn', 'merchant' ),
478 ),
479 'reddit' => array(
480 'url' => 'https://reddit.com/submit?url={{url}}&title={{title}}',
481 'title' => __( 'Reddit', 'merchant' ),
482 ),
483 'whatsapp' => array(
484 'url' => 'https://api.whatsapp.com/send/?text={{url}}',
485 'title' => __( 'WhatsApp', 'merchant' ),
486 ),
487 'pinterest' => array(
488 'url' => 'http://pinterest.com/pin/create/link/?url={{url}}',
489 'title' => __( 'Pinterest', 'merchant' ),
490 ),
491 'telegram' => array(
492 'url' => 'https://t.me/share/url?url={{url}}&text={{title}}',
493 'title' => __( 'Telegram', 'merchant' ),
494 ),
495 'weibo' => array(
496 'url' => 'http://service.weibo.com/share/share.php?url={{url}}&appkey=&title={{title}}&pic=&ralateUid=',
497 'title' => __( 'Weibo', 'merchant' ),
498 ),
499 'vk' => array(
500 'url' => 'http://vk.com/share.php?url={{url}}&title={{title}}&comment={text}',
501 'title' => __( 'VK', 'merchant' ),
502 ),
503 'ok' => array(
504 'url' => 'https://connect.ok.ru/dk?st.cmd=WidgetSharePreview&st.shareUrl={{url}}',
505 'title' => __( 'OK', 'merchant' ),
506 ),
507 'xing' => array(
508 'url' => 'https://www.xing.com/spi/shares/new?url={{url}}',
509 'title' => __( 'Xing', 'merchant' ),
510 ),
511 'mail' => array(
512 'url' => 'mailto:?subject={{title}}&body={{url}}',
513 'title' => __( 'Mail', 'merchant' ),
514 ),
515 );
516 }
517 }
518
519 /**
520 * Get the share link url.
521 *
522 * @param string $social_network
523 *
524 * @return string
525 */
526 if ( ! function_exists( 'merchant_get_share_link_url' ) ) {
527 function merchant_get_share_link_url( $social_network, $url_to_share, $title_to_share = '' ) {
528 $share_link_data = merchant_get_share_link_data();
529
530 if ( ! isset( $share_link_data[ $social_network ] ) ) {
531 return '';
532 }
533
534 $share_link_url = str_replace(
535 array( '{{url}}', '{{title}}' ),
536 array( $url_to_share, $title_to_share ),
537 $share_link_data[ $social_network ]['url']
538 );
539
540 return $share_link_url;
541 }
542 }
543
544 /**
545 * Get the share link title.
546 *
547 * @param string $social_network
548 *
549 * @return string
550 */
551 if ( ! function_exists( 'merchant_get_share_link_title' ) ) {
552 function merchant_get_share_link_title( $social_network ) {
553 $share_link_data = merchant_get_share_link_data();
554
555 return isset( $share_link_data[ $social_network ] ) ? $share_link_data[ $social_network ]['title'] : '';
556 }
557 }
558
559 if ( ! function_exists( 'merchant_timezone' ) ) {
560 /**
561 * Get the WP timezone.
562 *
563 * @return string
564 */
565 function merchant_timezone() {
566 /**
567 * Filter the storewide sale timezone.
568 *
569 * @param string $timezone
570 *
571 * @since 1.9.9
572 */
573 return apply_filters(
574 'merchant_storewide_sale_timezone',
575 wp_timezone_string()
576 );
577 }
578 }
579
580 if ( ! function_exists( 'merchant_get_current_timestamp' ) ) {
581 /**
582 * Get the current timestamp.
583 *
584 * @return int|string
585 */
586 function merchant_get_current_timestamp() {
587 $timezone = new DateTimeZone( merchant_timezone() );
588
589 // Get the timestamp
590 return ( new DateTime( 'now', $timezone ) )->getTimestamp();
591 }
592 }
593
594 if ( ! function_exists( 'merchant_convert_date_to_timestamp' ) ) {
595 /**
596 * Convert date to timestamp.
597 *
598 * @param string $date The date to convert
599 * @param string $format The format of the date
600 *
601 * @return int The timestamp
602 */
603 function merchant_convert_date_to_timestamp( $date, $format = 'm-d-Y h:i A' ) {
604 $timezone = new DateTimeZone( merchant_timezone() );
605 $date_object = DateTime::createFromFormat( $format, $date, $timezone ); // Create DateTime object with specified format and timezone
606 if ( false === $date_object ) {
607 return 0;
608 }
609
610 return $date_object->getTimestamp(); // Output the timestamp
611 }
612 }
613
614 /**
615 * Parses a list of product IDs
616 * @return array
617 */
618 if ( ! function_exists( 'merchant_parse_product_ids' ) ) {
619 function merchant_parse_product_ids( $product_ids ) {
620 $parsed_ids = $product_ids ?? array();
621
622 // Convert to array if it's not already an array
623 $parsed_ids = ! is_array( $parsed_ids ) ? explode( ',', $parsed_ids ) : $parsed_ids;
624
625 // Convert all elements to integers
626 $parsed_ids = array_map( 'intval', $parsed_ids );
627
628 return $parsed_ids;
629 }
630 }
631
632 /**
633 * Check if the user condition is passed.
634 *
635 * @param $args
636 *
637 * @return bool
638 */
639 if ( ! function_exists( 'merchant_is_user_condition_passed' ) ) {
640 function merchant_is_user_condition_passed( $args = array() ) {
641 $passed = false;
642
643 $is_logged_in = is_user_logged_in();
644 $current_user = $is_logged_in ? wp_get_current_user() : null;
645
646 $condition = $args['user_condition'] ?? 'all';
647
648 switch ( $condition ) {
649 case 'all':
650 case '':
651 $passed = true;
652 break;
653
654 case 'logged-in':
655 if ( $is_logged_in ) {
656 $passed = true;
657 }
658 break;
659
660 case 'roles':
661 $roles = $args['user_condition_roles'] ?? array();
662 $role = $current_user->roles[0] ?? '';
663
664 if ( in_array( $role, $roles, true ) ) {
665 $passed = true;
666 }
667 break;
668
669 case 'customers':
670 $customers_id = $args['user_condition_users'] ?? array();
671 $customers_id = array_map( 'intval', $customers_id );
672 $customer_id = (int) ( $current_user->ID ?? 0 );
673
674 if ( in_array( $customer_id, $customers_id, true ) ) {
675 $passed = true;
676 }
677 break;
678 }
679
680 return $passed;
681 }
682 }
683
684 /**
685 * Check if a product is excluded based on given arguments.
686 *
687 * @param $product_id
688 * @param $args
689 *
690 * @return bool
691 */
692 if ( ! function_exists( 'merchant_is_product_excluded' ) ) {
693 function merchant_is_product_excluded( $product_id, $args = array() ) {
694 $display_rule = $args['rules_to_display'] ?? $args['display_rules'] ?? $args['rules_to_apply'] ?? 'products';
695
696 $rules = array(
697 'all',
698 'all_products',
699 'categories',
700 'by_category',
701 'tags',
702 'by_tags',
703 'featured_products',
704 'products_on_sale',
705 'new_products',
706 'out_of_stock',
707 'pre-order',
708 );
709
710 // Exclude products
711 if ( in_array( $display_rule, $rules, true ) ) {
712 $excluded_product_ids = $args['excluded_products'] ?? array();
713 $excluded_product_ids = merchant_parse_product_ids( $excluded_product_ids );
714
715 if ( in_array( (int) $product_id, $excluded_product_ids, true ) ) {
716 return true;
717 }
718 }
719
720 // Exclude categories
721 if ( in_array( $display_rule, array( 'all', 'all_products' ), true ) ) {
722 $excluded_categories_slugs = $args['excluded_categories'] ?? array();
723
724 $product = wc_get_product( $product_id );
725 $_product_id = $product && $product->is_type( 'variation' ) ? $product->get_parent_id() : $product_id;
726
727 if ( ! empty( $excluded_categories_slugs ) && has_term( $excluded_categories_slugs, 'product_cat', $_product_id ) ) {
728 return true;
729 }
730 }
731
732 // Exclude tags
733 if ( in_array( $display_rule, array( 'all', 'all_products' ), true ) ) {
734 $excluded_tags_slugs = $args['excluded_tags'] ?? array();
735
736 $product = wc_get_product( $product_id );
737 $_product_id = $product && $product->is_type( 'variation' ) ? $product->get_parent_id() : $product_id;
738
739 if ( ! empty( $excluded_tags_slugs ) && has_term( $excluded_tags_slugs, 'product_tag', $_product_id ) ) {
740 return true;
741 }
742 }
743
744 return false;
745 }
746 }
747
748
749 /**
750 * Get the label of the first active payment gateway in WooCommerce.
751 *
752 * @return string|null The label of the first active payment gateway, or null if none are found.
753 */
754 if ( ! function_exists( 'merchant_get_first_active_payment_gateway_label' ) ) {
755 function merchant_get_first_active_payment_gateway_label() {
756 // Get the available payment gateways
757 $available_gateways = WC()->payment_gateways->get_available_payment_gateways();
758
759 // Check if there are any active gateways
760 if ( ! empty( $available_gateways ) ) {
761 // Get the first active gateway
762 return reset( $available_gateways )->get_title();
763 }
764
765 // Return null if no active gateways are found
766 return null;
767 }
768 }