PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 2.7.0
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v2.7.0
2.7.0 2.6.0 trunk 1.1.0 1.1.4 1.2.1 1.2.2 1.2.3 1.2.5 1.2.9 1.3.1 1.3.2 1.5.0 1.5.1 1.5.4 1.5.7 1.5.8 1.5.9 1.6.2 1.6.5 1.6.8 1.7.2 1.7.4 1.7.5 1.7.9 All 43 releases
← All changes | includes/elementor/modules/checkout/classes/local-hooks.php +336 -34 1.5.92.7.0 View file →
@@ -5,8 +5,10 @@
5 5 defined( 'ABSPATH' ) || exit;
6 6
7 7 use Sellkit\Elementor\Modules\Checkout\Classes\{ Helper, Global_Hooks };
8 8 use Elementor\Plugin as Elementor;
9 +use Sellkit_Funnel;
10 +use Sellkit\Global_Checkout\Checkout;
9 11
10 12 /**
11 13 * Local hooks.
12 14 * Applies before widget.
@@ -14,12 +16,44 @@
14 16 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
15 17 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
16 18 * @SuppressWarnings(PHPMD.TooManyMethods)
17 19 * @SuppressWarnings(PHPMD.NPathComplexity)
20 + * @SuppressWarnings(PHPMD.CyclomaticComplexity)
18 21 * @since 1.1.0
19 22 */
20 23 class Local_Hooks {
21 24 /**
25 + * Checkout widget settings.
26 + *
27 + * @since 1.8.6
28 + * @var array
29 + */
30 + public $settings;
31 +
32 + /**
33 + * Checkout widget.
34 + *
35 + * @since 1.8.6
36 + * @var object
37 + */
38 + public $widget;
39 +
40 + /** Array of added products to cart.
41 + *
42 + * @since 1.7.9
43 + * @var array
44 + */
45 + public static $in_cart = [];
46 +
47 + /**
48 + * Checks if bumps applied.
49 + *
50 + * @since 1.8.1
51 + * @var bool
52 + */
53 + public static $is_bumps_applied = false;
54 +
55 + /**
22 56 * Create instance of class without construct.
23 57 *
24 58 * @since 1.1.0
25 59 * @return object
@@ -99,8 +133,17 @@
99 133 add_action( 'woocommerce_before_checkout_form', [ $this, 'order_bump' ] );
100 134
101 135 // Bundle products.
102 136 $this->bundled_products();
137 +
138 + // Trigger for upsell steps popup.
139 + add_action( 'sellkit_checkout_required_hidden_fields', [ $this, 'add_trigger_field_for_upsell_steps' ] );
140 +
141 + // Add upsell templates at the end of page.
142 + add_action( 'wp_footer', [ $this, 'sellkit_funnel_display_upsell_as_popup' ] );
143 +
144 + // Add order notes to checkout form to desired location.
145 + add_action( 'sellkit_checkout_after_term_and_condition', [ $this, 'order_notes' ] );
103 146 }
104 147
105 148 /**
106 149 * Opens a wrapper around widget checkout form.
@@ -303,9 +346,9 @@
303 346 $class = '\Sellkit\Elementor\Modules\Checkout\Fields\\' . ucfirst( $class );
304 347 $class = new $class();
305 348 $field = '';
306 349
307 - $class->final_html_structure( $field, $details, $key );
350 + $class->final_html_structure( $field, $details, $key, $checkout->get_value( $key ) );
308 351 }
309 352 }
310 353
311 354 /**
@@ -317,12 +360,13 @@
317 360 */
318 361 public function customize_billing_field( $default_fields ) {
319 362 $widget_billing_fields = $this->settings['billing_list'];
320 363 $widget_field_slug = Helper::instance()->get_user_defined_fields_slug( $widget_billing_fields, 'billing_list_field' );
364 + $core_billing_fields = array_keys( Helper::instance()->billing_fields() );
321 365
322 366 // Unset default fields.
323 367 foreach ( $default_fields as $key => $field ) {
324 - if ( ! in_array( $key, $widget_field_slug, true ) && 'billing_email' !== $field ) {
368 + if ( in_array( $key, $core_billing_fields, true ) && ! in_array( $key, $widget_field_slug, true ) && 'billing_email' !== $key ) {
325 369 unset( $default_fields[ $key ] );
326 370 }
327 371 }
328 372
@@ -391,9 +435,9 @@
391 435 $class = '\Sellkit\Elementor\Modules\Checkout\Fields\\' . ucfirst( $class );
392 436 $class = new $class();
393 437 $field = '';
394 438
395 - $field = $class->final_html_structure( $field, $details, $key );
439 + $field = $class->final_html_structure( $field, $details, $key, $checkout->get_value( $key ) );
396 440 }
397 441 }
398 442
399 443 /**
@@ -424,9 +468,9 @@
424 468 }
425 469 }
426 470
427 471 foreach ( $widget_shipping_fields as $data ) {
428 - $slug = $data['shipping_list_field'];
472 + $slug = isset( $data['shipping_list_field'] ) ? $data['shipping_list_field'] : '';
429 473
430 474 if ( 'yes' !== $data['shipping_list_required'] && array_key_exists( $slug, $default_fields['shipping'] ) ) {
431 475 $default_fields['shipping'][ $slug ]['required'] = false;
432 476 unset( $default_fields['shipping'][ $slug ]['required'] );
@@ -484,9 +528,9 @@
484 528 ?>
485 529 <section class="sellkit-checkout-widget-express-checkout sellkit-checkout-express-checkout-step-1">
486 530 <fieldset class="express-box sellkit-checkout-widget-divider">
487 531 <legend class="sellkit-express-checkout-legend heading">
488 - <?php echo __( 'Express Checkout', 'sellkit' ); ?>
532 + <?php echo esc_html__( 'Express Checkout', 'sellkit' ); ?>
489 533 </legend>
490 534 <div class="express-methods">
491 535 <?php do_action( 'sellkit-checkout-widget-express-methods' ); ?>
492 536 </div>
@@ -493,15 +537,15 @@
493 537 </fieldset>
494 538 </section>
495 539 <section class="sellkit-checkout-widget-express-checkout sellkit-checkout-express-checkout-step-2">
496 540 <fieldset id="sellkit-checkout-or-divider" class="divider-box sellkit-checkout-widget-divider">
497 - <legend class="heading"><?php echo __( 'OR', 'sellkit' ); ?></legend>
541 + <legend class="heading"><?php echo esc_html__( 'OR', 'sellkit' ); ?></legend>
498 542 </fieldset>
499 543 </section>
500 544 <?php
501 545 $express = ob_get_clean();
502 546 $express = apply_filters( 'sellkit-checkout-widget-express-checkout', $express );
503 - echo $express;
547 + echo wp_kses_post( $express );
504 548 }
505 549
506 550 /**
507 551 * Apply custom Messages.
@@ -521,9 +565,9 @@
521 565 add_action( 'sellkit_core/widgets/checkout/custom_message/create_website_account', function() {
522 566 $site = get_bloginfo( 'name' );
523 567 $text = $this->settings['create_website_account'];
524 568
525 - echo str_replace( '{{website}}', $site, $text );
569 + echo wp_kses_post( str_replace( '{{website}}', $site, $text ) );
526 570 } );
527 571
528 572 add_filter( 'sellkit_core/widgets/checkout/custom_message/secure_transaction_text', function() {
529 573 return $this->settings['secure_transaction_text'];
@@ -559,8 +603,23 @@
559 603 add_action( 'sellkit-checkout-widget-custom-coupon-form', function() use ( $settings ) {
560 604 Global_Hooks::instance()->coupon_form( $settings );
561 605 } );
562 606
607 + // Improve UI issue in the editor for the order summary input.
608 + add_filter( 'woocommerce_cart_item_class', function( $default ) use ( $settings, $posted_data ) {
609 + $default = str_replace( 'product-title-one-row', '', $default );
610 +
611 + if (
612 + ! array_key_exists( 'show_cart_edit', $settings ) ||
613 + array_key_exists( 'bundle-products-force', $posted_data ) ||
614 + empty( $settings['show_cart_edit'] )
615 + ) {
616 + $default .= ' product-title-one-row';
617 + }
618 +
619 + return $default;
620 + } );
621 +
563 622 return;
564 623 }
565 624
566 625 if ( wp_doing_ajax() ) {
@@ -582,9 +641,13 @@
582 641 } );
583 642
584 643 // Disable order item quantity input.
585 644 if ( array_key_exists( 'show_cart_edit', $settings ) || array_key_exists( 'bundle-products-force', $posted_data ) ) {
586 - add_action( 'sellkit-checkout-widget-disable-quantity', [ Helper::instance(), 'checkout_order_hidden_quantity' ], 10, 2 );
645 + add_filter( 'sellkit-checkout-widget-disable-quantity', [ Helper::instance(), 'checkout_order_hidden_quantity' ], 10, 2 );
646 +
647 + add_filter( 'woocommerce_cart_item_class', function( $default ) {
648 + return $default . ' product-title-one-row';
649 + } );
587 650 }
588 651
589 652 add_filter( 'woocommerce_shipping_package_name', function() {
590 653 return '<h4 id="shipping_header_title" class="shipping-method-header heading">' . esc_html__( 'Shipping Methods', 'sellkit' ) . '</h4>';
@@ -631,9 +694,9 @@
631 694 }, 10 );
632 695
633 696 // Disable order item quantity input.
634 697 if ( array_key_exists( 'show_cart_edit', $settings ) ) {
635 - add_action( 'sellkit-checkout-widget-disable-quantity', [ Helper::instance(), 'checkout_order_hidden_quantity' ], 10, 2 );
698 + add_filter( 'sellkit-checkout-widget-disable-quantity', [ Helper::instance(), 'checkout_order_hidden_quantity' ], 10, 2 );
636 699
637 700 add_filter( 'sellkit/includes/elementor/modules/checkout/quanity/class', function( $classes ) {
638 701 return $classes .= ' sellkit-checkout-widget-d-block';
639 702 } );
@@ -638,8 +701,14 @@
638 701 return $classes .= ' sellkit-checkout-widget-d-block';
639 702 } );
640 703 }
641 704
705 + if ( array_key_exists( 'show_cart_edit', $settings ) || array_key_exists( 'bundle-products-force', $posted_data ) ) {
706 + add_filter( 'woocommerce_cart_item_class', function( $default ) {
707 + return $default . ' product-title-one-row';
708 + } );
709 + }
710 +
642 711 add_filter( 'sellkit-checkout-place-order-btn-text', function( $place_order_btn ) {
643 712 if ( ! empty( $settings['place_order_btn_txt'] ) ) {
644 713 return $settings['place_order_btn_txt'];
645 714 }
@@ -699,14 +768,14 @@
699 768 }
700 769 ?>
701 770 <?php if ( array_key_exists( 'coupon_field_type', $settings ) && 'collapsible' === $settings['coupon_field_type'] ) : ?>
702 771 <span id="copoun_toggle" class="copoun_toggle sellkit-coupon-toggle sellkit-checkout-widget-links">
703 - <?php echo __( 'Have a coupon? Click here to enter your code', 'sellkit' ); ?>
772 + <?php echo esc_html__( 'Have a coupon? Click here to enter your code', 'sellkit' ); ?>
704 773 </span>
705 774 <?php $class .= ' sellkit-checkout-collapsible'; ?>
706 775 <?php Helper::instance()->editor_mode_extra_js(); ?>
707 776 <?php endif; ?>
708 - <div class="sellkit-custom-coupon-form <?php echo $class; ?>">
777 + <div class="sellkit-custom-coupon-form <?php echo esc_attr( $class ); ?>">
709 778 <p class="jx-form-row-first">
710 779 <input class="jx-coupon" type="text" placeholder="<?php esc_attr_e( 'Enter Promo code', 'sellkit' ); ?>" />
711 780 </p>
712 781
@@ -758,9 +827,9 @@
758 827 * @since 1.1.0
759 828 * return void
760 829 */
761 830 public static function bundle_product_action( $option ) {
762 - add_action( 'sellkit-checkout-widget-disable-quantity', [ Helper::instance(), 'checkout_order_hidden_quantity' ], 10, 2 );
831 + add_filter( 'sellkit-checkout-widget-disable-quantity', [ Helper::instance(), 'checkout_order_hidden_quantity' ], 10, 2 );
763 832
764 833 if ( 'force-products' === $option || Elementor::$instance->editor->is_edit_mode() ) {
765 834 return;
766 835 }
@@ -791,12 +860,25 @@
791 860 </thead>
792 861 <tbody>
793 862 <?php foreach ( $products as $cart_item_key => $cart_item ) : ?>
794 863 <?php
864 + if ( in_array( $cart_item_key, self::$in_cart, true ) ) {
865 + continue;
866 + }
867 +
795 868 $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
796 869 $default = $_product->get_id();
797 870 $default_q = $cart_item['quantity'];
798 871 $unique_id = 'bundle-unique-id-' . $default;
872 + $checked = '';
873 +
874 + if ( 'checkbox' === $fields_type ) {
875 + $checked = 'checked';
876 + }
877 +
878 + if ( 'radio' === $fields_type && array_key_last( $products ) === $cart_item_key ) {
879 + $checked = 'checked';
880 + }
799 881 ?>
800 882 <tr class="sellkit-checkout-bundled-products-item">
801 883 <td class="sellkit-checkout-bundled-title">
802 884 <input
@@ -804,12 +886,12 @@
804 886 value="<?php echo esc_attr( $_product->get_id() ); ?>"
805 887 name="sellkit-checkout-bundle-item"
806 888 class="sellkit-checkout-bundle-item"
807 889 id="<?php echo esc_attr( $unique_id ); ?>"
808 - <?php echo ( array_key_last( $products ) === $cart_item_key ) ? 'checked' : ''; ?>
890 + <?php echo esc_html( $checked ); ?>
809 891 >
810 892 <label for="<?php echo esc_attr( $unique_id ); ?>">
811 - <?php echo $_product->get_name(); ?>
893 + <?php echo esc_html( $_product->get_name() ); ?>
812 894 </label>
813 895 </td>
814 896 <td class="sellkit-checkout-bundled-quantity">
815 897 <input type="number" <?php echo esc_attr( $readonly ); ?> min="1" value="<?php echo esc_attr( $cart_item['quantity'] ); ?>" data-id="<?php echo esc_attr( $cart_item_key ); ?>" class="sellkit-checkout-single-bundle-item-quantity" >
@@ -814,9 +896,9 @@
814 896 <td class="sellkit-checkout-bundled-quantity">
815 897 <input type="number" <?php echo esc_attr( $readonly ); ?> min="1" value="<?php echo esc_attr( $cart_item['quantity'] ); ?>" data-id="<?php echo esc_attr( $cart_item_key ); ?>" class="sellkit-checkout-single-bundle-item-quantity" >
816 898 </td>
817 899 <td class="sellkit-checkout-bundled-price">
818 - <?php echo apply_filters( 'woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key ); ?>
900 + <?php echo wp_kses_post( apply_filters( 'woocommerce_cart_item_subtotal', WC()->cart->get_product_subtotal( $_product, $cart_item['quantity'] ), $cart_item, $cart_item_key ) ); ?>
819 901 </td>
820 902 <tr>
821 903 <?php if ( array_key_last( $products ) !== $cart_item_key ) : ?>
822 904 <tr>
@@ -833,24 +915,71 @@
833 915 <?php
834 916 $bundle_html = ob_get_clean();
835 917
836 918 add_action( 'sellkit-bundled-products-position', function() use ( $bundle_html ) {
837 - echo $bundle_html;
919 + $allowed_html = [
920 + 'section' => [
921 + 'class' => true,
922 + ],
923 + 'div' => [
924 + 'class' => true,
925 + ],
926 + 'span' => [
927 + 'class' => true,
928 + ],
929 + 'table' => [
930 + 'class' => true,
931 + ],
932 + 'thead' => [
933 + 'class' => true,
934 + ],
935 + 'tr' => [
936 + 'class' => true,
937 + ],
938 + 'th' => [
939 + 'class' => true,
940 + ],
941 + 'tbody' => [
942 + 'class' => true,
943 + ],
944 + 'td' => [
945 + 'class' => true,
946 + 'colspan' => true,
947 + ],
948 + 'input' => [
949 + 'type' => true,
950 + 'value' => true,
951 + 'name' => true,
952 + 'class' => true,
953 + 'id' => true,
954 + 'checked' => true,
955 + 'readonly' => true,
956 + 'min' => true,
957 + 'data-id' => true,
958 + ],
959 + 'label' => [
960 + 'for' => true,
961 + ],
962 + 'hr' => [],
963 + ];
964 +
965 + echo wp_kses( $bundle_html, $allowed_html );
838 966 } );
839 967
840 - if ( ! wp_doing_ajax() ) {
968 + if ( wp_doing_ajax() ) {
969 + return;
970 + }
971 +
972 + if ( 'radio' === $fields_type && null !== $default ) {
841 973 WC()->cart->empty_cart();
974 + WC()->cart->add_to_cart( $default, $default_q );
975 + }
842 976
843 - if ( null !== $default ) {
844 - WC()->cart->add_to_cart( $default, $default_q );
977 + if ( ! WC()->cart->needs_shipping() ) {
978 + wp_add_inline_script( 'sellkit-initialize-widgets', 'var sellkitCheckoutShipping = true', 'before' );
979 + }
845 980
846 - if ( ! WC()->cart->needs_shipping() ) {
847 - wp_add_inline_script( 'sellkit-initialize-widgets', 'var sellkitCheckoutShipping = true', 'before' );
848 - }
849 - }
850 -
851 - Global_Hooks::make_changes_after_cart_item_edit( get_the_id() );
852 - }
981 + Global_Hooks::make_changes_after_cart_item_edit( get_the_id() );
853 982 }
854 983
855 984 /**
856 985 * Trigger to activate order bumb or not for this checkout.
@@ -872,8 +1001,12 @@
872 1001 * @since 1.1.0
873 1002 * @return void
874 1003 */
875 1004 private static function order_bump_frontend_manager() {
1005 + if ( self::$is_bumps_applied ) {
1006 + return;
1007 + }
1008 +
876 1009 global $wp_query;
877 1010 $query = $wp_query->query_vars;
878 1011
879 1012 if ( ! array_key_exists( 'bump_data', $query ) ) {
@@ -893,8 +1026,10 @@
893 1026 add_action( $design['sellkit_funnels_bump_position'], function() use ( $design, $products ) {
894 1027 self::bump_html( $design, $products );
895 1028 }, 5 );
896 1029 }
1030 +
1031 + self::$is_bumps_applied = true;
897 1032 }
898 1033
899 1034 /**
900 1035 * Order bump html.
@@ -904,9 +1039,9 @@
904 1039 * @since 1.1.0
905 1040 * @return void
906 1041 */
907 1042 public static function bump_html( $design, $products ) {
908 - $list = $products['list'];
1043 + $list = empty( $products['list'] ) ? [] : $products['list'];
909 1044 $ids = [];
910 1045
911 1046 foreach ( $list as $id => $details ) {
912 1047 $ids[] = $id;
@@ -918,9 +1053,9 @@
918 1053 $ids_string = implode( '|', $ids );
919 1054 $product = wc_get_product( $ids_string );
920 1055 $qty = ( empty( $qty ) ) ? 1 : $qty;
921 1056
922 - if ( empty( $product ) || ! $product->get_id() ) {
1057 + if ( empty( $product ) || ! $product->get_id() || ! $product->is_in_stock() ) {
923 1058 return;
924 1059 }
925 1060
926 1061 $unique_id = 'bump-title-' . $ids_string;
@@ -931,8 +1066,10 @@
931 1066 'sellkit-checkout-after-order-summary' === current_action()
932 1067 ) {
933 1068 $class = 'sellkit-bump-review-order';
934 1069 }
1070 +
1071 + $checked = empty( WC()->cart->find_product_in_cart( WC()->cart->generate_cart_id( $product->get_id() ) ) ) ? false : true;
935 1072 ?>
936 1073 <div class="sellkit-checkout-step-bump-wrapper <?php echo esc_attr( $class ); ?>" >
937 1074 <div class="sellkit-checkout-bump-order-header">
938 1075 <div class="sellkit-bump-order-left-header">
@@ -943,8 +1080,9 @@
943 1080 class="sellkit-checkout-bump-order-products"
944 1081 data-qty="<?php echo esc_attr( $qty ); ?>"
945 1082 name="sellkit_bump_data_<?php echo esc_attr( $ids_string ); ?>"
946 1083 id="<?php echo esc_html( $unique_id ); ?>"
1084 + <?php echo ( true === $checked ) ? 'checked="true"' : ''; ?>
947 1085 >
948 1086 <label
949 1087 for="<?php echo esc_attr( $unique_id ); ?>"
950 1088 class="sellkit-checkout-order-bump-title"
@@ -965,18 +1103,18 @@
965 1103 <del aria-hidden="true">
966 1104 <span class="woocommerce-Price-amount amount">
967 1105 <bdi>
968 1106 <span class="woocommerce-Price-currencySymbol">
969 - <?php echo wc_price( $main_price ); ?>
1107 + <?php echo wp_kses_post( wc_price( $main_price ) ); ?>
970 1108 </span>
971 1109 </bdi>
972 1110 </span>
973 1111 </del>
974 - <bdi class="bump-price-bolded"><?php echo wc_price( $discounted_price ); ?></bdi>
1112 + <bdi class="bump-price-bolded"><?php echo wp_kses_post( wc_price( $discounted_price ) ); ?></bdi>
975 1113 <?php
976 1114 } else {
977 1115 ?>
978 - <bdi><?php echo wc_price( $main_price ); ?></bdi>
1116 + <bdi><?php echo wp_kses_post( wc_price( $main_price ) ); ?></bdi>
979 1117 <?php
980 1118 }
981 1119 ?>
982 1120 </span>
@@ -985,17 +1123,181 @@
985 1123 <div class="sellkit-checkout-bump-order-body" >
986 1124 <div class="sellkit-bump-order-left-body">
987 1125 <?php $image = wp_get_attachment_image_src( $product->get_image_id() ); ?>
988 1126 <?php if ( 'true' === $design['sellkit_funnels_bump_product_image'] && ! empty( $image[0] ) ) : ?>
989 - <img src="<?php echo esc_attr( $image[0] ); ?>" >
1127 + <img src="<?php echo esc_url( $image[0] ); ?>" >
990 1128 <?php endif; ?>
991 1129 </div>
992 1130 <div class="sellkit-bump-order-right-body">
993 1131 <div class="sellkit-bump-order-description">
994 - <?php echo $design['sellkit_content']; ?>
1132 + <?php echo wp_kses_post( $design['sellkit_content'] ); ?>
995 1133 </div>
996 1134 </div>
997 1135 </div>
998 1136 </div>
999 1137 <?php
1138 + }
1139 +
1140 + /**
1141 + * Checks if funnel includes upsell step.
1142 + *
1143 + * @param string $goal customize return value.
1144 + * @param int $ajax_id upsell id through ajax.
1145 + * @since 1.6.2
1146 + */
1147 + public static function is_funnel_includes_upsell( $goal = 'is_upsell', $ajax_id = null ) {
1148 + $id = get_queried_object_id();
1149 +
1150 + if ( wp_doing_ajax() ) {
1151 + $id = $ajax_id;
1152 + }
1153 +
1154 + $step_data = get_post_meta( $id, 'step_data', true );
1155 + $include_upsell = false;
1156 + $upsell_steps = [];
1157 + $upsell_ids = [];
1158 + $global_checkout_id = get_option( Checkout::SELLKIT_GLOBAL_CHECKOUT_OPTION, 0 );
1159 +
1160 + // We are in default WooCommerce checkout page.
1161 + if ( empty( $step_data ) && $global_checkout_id > 0 && 'publish' === get_post_status( $global_checkout_id ) ) {
1162 + $steps = get_post_meta( $global_checkout_id, 'nodes', true );
1163 + $checkout_id = 0;
1164 +
1165 + foreach ( $steps as $step ) {
1166 + $step['type'] = (array) $step['type'];
1167 +
1168 + if ( 'checkout' === $step['type']['key'] ) {
1169 + $checkout_id = $step['page_id'];
1170 + }
1171 + }
1172 +
1173 + $step_data = get_post_meta( $checkout_id, 'step_data', true );
1174 + }
1175 +
1176 + if ( empty( $step_data ) ) {
1177 + return $include_upsell;
1178 + }
1179 +
1180 + $funnel_id = intval( $step_data['funnel_id'] );
1181 + $funnel_data = get_post_meta( $funnel_id, 'nodes', true );
1182 +
1183 + if ( empty( $funnel_data ) ) {
1184 + return $include_upsell;
1185 + }
1186 +
1187 + $popups = [ 'downsell', 'upsell' ];
1188 +
1189 + foreach ( $funnel_data as $step ) {
1190 + if ( isset( $step['data'] ) && isset( $step['data']['products'] ) && isset( $step['data']['products']['list'] ) ) {
1191 + $product_id = array_keys( $step['data']['products']['list'] )[0] ?? 0;
1192 +
1193 + if ( $product_id ) {
1194 + $product = wc_get_product( $product_id );
1195 +
1196 + if ( $product && ! $product->is_in_stock() ) {
1197 + return $include_upsell;
1198 + }
1199 + }
1200 + }
1201 +
1202 + $step['type'] = (array) $step['type'];
1203 +
1204 + if ( in_array( $step['type']['key'], $popups, true ) ) {
1205 + $include_upsell = true;
1206 + $upsell_steps[] = $step;
1207 + $upsell_ids[] = $step['page_id'];
1208 + }
1209 + }
1210 +
1211 + if ( 'get_ids' === $goal ) {
1212 + return $upsell_ids;
1213 + }
1214 +
1215 + // Send data to the filter that keeps steps data to prepare popup.
1216 + add_filter( 'sellkit_upsell_steps_popup_information', function( $default ) use ( $upsell_steps ) {
1217 + if ( ! empty( $upsell_steps ) ) {
1218 + return $upsell_steps;
1219 + }
1220 +
1221 + return $default;
1222 + } );
1223 +
1224 + return $include_upsell;
1225 + }
1226 +
1227 + /**
1228 + * Add an extra hidden field to checkout form if funnel includes upsell step.
1229 + *
1230 + * @since 1.6.2
1231 + */
1232 + public function add_trigger_field_for_upsell_steps() {
1233 + $include_upsell = self::is_funnel_includes_upsell();
1234 +
1235 + if ( false === $include_upsell ) {
1236 + return;
1237 + }
1238 +
1239 + echo '<input type="hidden" id="sellkit_funnel_has_upsell" value="upsell" >';
1240 + echo '<input type="hidden" id="sellkit_funnel_popup_step_id" value="0" >';
1241 + }
1242 +
1243 + /**
1244 + * Display sellkit upsell steps as popup.
1245 + *
1246 + * @since 1.6.2
1247 + */
1248 + public function sellkit_funnel_display_upsell_as_popup() {
1249 + $upsell_data = apply_filters( 'sellkit_upsell_steps_popup_information', [] );
1250 + $i = 1;
1251 +
1252 + if ( empty( $upsell_data ) ) {
1253 + return;
1254 + }
1255 +
1256 + foreach ( $upsell_data as $data ) {
1257 + $id = 'sellkit_funnel_upsell_popup_' . $i;
1258 + $class = 'sellkit_funnel_upsell_popup sellkit_funnel_upsell_popup_' . apply_filters( 'wpml_object_id', $data['page_id'], 'sellkit_step', true ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WPML API.
1259 + ?>
1260 + <div class="<?php echo esc_attr( $class ); ?>" id="<?php echo esc_attr( $id ); ?>">
1261 + <?php echo wp_kses_post( Elementor::instance()->frontend->get_builder_content_for_display( apply_filters( 'wpml_object_id', $data['page_id'], 'sellkit_step', true ) ) ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WPML API. ?>
1262 + <input type="hidden" class="identify" value="<?php echo esc_attr( apply_filters( 'wpml_object_id', $data['page_id'], 'sellkit_step', true ) ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WPML API. ?>" >
1263 + </div>
1264 + <?php
1265 + $i++;
1266 + }
1267 + }
1268 +
1269 + /**
1270 + * Display checkout order notes field.
1271 + *
1272 + * @since 1.8.9
1273 + */
1274 + public function order_notes() {
1275 + // Get woocommerce order notes field.
1276 + $notes = WC()->checkout()->get_checkout_fields( 'order' );
1277 +
1278 + // print notes field.
1279 + foreach ( $notes as $key => $field ) {
1280 + ?>
1281 + <div class="sellkit-checkout-order-fields sellkit-widget-checkout-fields">
1282 + <?php
1283 + if ( 'order_comments' === $key ) {
1284 + ?>
1285 + <div class="sellkit-checkout-order-notes">
1286 + <div class="sellkit-order-note-field-wrapper">
1287 + <input id="sellkit-add-notes-to-order-box" type="checkbox">
1288 + <label for="sellkit-add-notes-to-order-box">
1289 + <?php echo esc_html__( 'Add a note to your order', 'sellkit' ); ?>
1290 + </label>
1291 + </div>
1292 + <?php
1293 + woocommerce_form_field( $key, $field, WC()->checkout()->get_value( $key ) );
1294 + ?>
1295 + </div>
1296 + <?php
1297 + }
1298 + ?>
1299 + </div>
1300 + <?php
1301 + }
1000 1302 }
1001 1303 }