PluginProbe
Instantio — Side Cart & One-Page Checkout for WooCommerce / trunk
Instantio — Side Cart & One-Page Checkout for WooCommerce vtrunk
3.3.34 trunk 1.0 1.1 1.1.1 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 2.0.0 2.1.0 2.1.2 2.1.3 2.2.0 2.2.1 2.2.2 2.2.3 2.3.1 2.3.2 All 122 releases
instantio / includes / controller / App.php

App.php in Instantio — Side Cart & One-Page Checkout for WooCommerce trunk, at includes/controller/App.php

880 lines 32.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Themefic\Instantio\Controller;
3
4 defined( 'ABSPATH' ) || exit;
5
6 class App {
7
8 public $layout = 1;
9 public $layouts_slug = "/layouts/layout.php";
10 public $layout_class = "";
11
12
13
14
15 public function __construct() {
16
17 $this->ins_layout_set_data();
18
19 add_action( 'wp_body_open', array( $this, 'ins_layout_three' ), 10 );
20
21 // add_filter( 'woocommerce_add_to_cart_fragments', array($this, 'instantio_cart_count_fragments'), 50, 1 );
22
23 // Ajax Cart reload After Product Add to Cart
24 add_action( 'wp_ajax_nopriv_instantio_ajax_cart_reload', array( $this, 'instantio_ajax_cart_reload' ), 20 );
25 add_action( 'wp_ajax_instantio_ajax_cart_reload', array( $this, 'instantio_ajax_cart_reload' ), 20 );
26
27 // Single Product Page Ajax Add to Cart
28 add_action( 'wp_ajax_nopriv_instantio_ajax_cart_single', array( $this, 'instantio_ajax_cart_single' ), 20 );
29 add_action( 'wp_ajax_instantio_ajax_cart_single', array( $this, 'instantio_ajax_cart_single' ), 20 );
30
31 // Ajax Cart Remove To cart
32 add_action( 'wp_ajax_nopriv_instantio_ajax_cart_item_remove', array( $this, 'instantio_ajax_cart_item_remove' ), 20 );
33 add_action( 'wp_ajax_instantio_ajax_cart_item_remove', array( $this, 'instantio_ajax_cart_item_remove' ), 20 );
34
35 // Ajax Cart Remove To cart
36 add_action( 'wp_ajax_nopriv_instantio_ajax_empty_cart', array( $this, 'instantio_ajax_empty_cart' ), 20 );
37 add_action( 'wp_ajax_instantio_ajax_empty_cart', array( $this, 'instantio_ajax_empty_cart' ), 20 );
38
39 // Ajax Update Cart
40 add_action( 'wp_ajax_nopriv_instantio_ajax_update_cart', array( $this, 'instantio_ajax_update_cart' ) );
41 add_action( 'wp_ajax_instantio_ajax_update_cart', array( $this, 'instantio_ajax_update_cart' ) );
42
43 // Ajax Remove Coupon
44 add_action( 'wp_ajax_nopriv_instantio_ajax_remove_coupon', array( $this, 'instantio_ajax_remove_coupon' ) );
45 add_action( 'wp_ajax_instantio_ajax_remove_coupon', array( $this, 'instantio_ajax_remove_coupon' ) );
46
47
48 // Ins Cart Toggle
49 add_action( 'instantio_cart_toggle', array( $this, 'instantio_cart_toggle' ), 11 );
50
51 // Ins Cart Toggle
52 add_action( 'instantio_cart_header', array( $this, 'ins_cart_modern_header' ), 10 );
53
54 // Ins Cart Buttons
55 add_action( 'instantio_cart_buttons', array( $this, 'instantio_cart_buttons' ), 11 );
56
57 // Ins Cart Toggle
58 add_action( 'instantio_cart_content', array( $this, 'instantio_cart_content_modern' ), 10, 2 );
59 add_action( 'instantio_cart_content_single', array( $this, 'ins_modern_cart_only' ), 10, 2 );
60
61 add_shortcode( 'instantio-cart-icon', [ $this, 'instantio_carticon_function' ] );
62
63 }
64
65
66 public function ins_options_init() {
67 // Retained for backward compatibility. Options are initialized elsewhere.
68 }
69
70 // Instantio Layout Set Data
71 public function ins_layout_set_data() {
72 $ins_layout = ! empty( instantio_get_option( 'ins-layout-options' ) ) ? instantio_get_option( 'ins-layout-options' ) : '1';
73
74 require_once INSTANTIO_INC_PATH . "/controller/icon-svg.php";
75
76 if ( $ins_layout == 1 ) {
77 $this->layout = $ins_layout;
78 $this->layout_class = '';
79 $this->layouts_slug = "/layouts/layout-1.php";
80 } elseif ( $ins_layout == 2 ) {
81 $this->layout = $ins_layout;
82 $this->layout_class = 'slide ';
83 $this->layouts_slug = "/layouts/layout-2.php";
84
85 } elseif ( $ins_layout == 3 ) {
86 $this->layout = $ins_layout;
87 $this->layout_class = 'popup ';
88 $this->layouts_slug = "/layouts/layout-3.php";
89 }
90 }
91
92 // ShortCode for instantio mini cart icon
93 public function instantio_carticon_function() {
94
95 // Option
96 $mini_cart_option = ! empty( instantio_get_option( 'ins-mini-cart' )['ins-mini-cart-option'] ) ? instantio_get_option( 'ins-mini-cart' )['ins-mini-cart-option'] : '0';
97
98 if ( $mini_cart_option != 1 ) {
99 return;
100 }
101
102 // icons
103 $cart_icon = ! empty( instantio_get_option( 'ins-toggle-tab' )['cart-icon'] ) ? instantio_get_option( 'ins-toggle-tab' )['cart-icon'] : 'shopping-bag';
104 $wi_icon_choice = ! empty( instantio_get_option( 'ins-toggle-tab' )['wi-icon-choice'] ) ? instantio_get_option( 'ins-toggle-tab' )['wi-icon-choice'] : 'icon';
105 $wi_icon_choice_uploder = ! empty( instantio_get_option( 'ins-toggle-tab' )['wi-icon-choice-uploder'] ) ? instantio_get_option( 'ins-toggle-tab' )['wi-icon-choice-uploder'] : '';
106
107 if ( $cart_icon == 'shopping-bag' ) {
108 $toggle_icon = apply_filters( 'instantio_get_svg_icon_pro', instantio_svg_icon( $cart_icon ) );
109 } else {
110 $toggle_icon = '<i class="' . esc_attr( $cart_icon ) . '"></i>';
111 }
112 if ( $wi_icon_choice == 'image' && $wi_icon_choice_uploder != '' ) {
113 $toggle_icon = '<img src="' . esc_url( $wi_icon_choice_uploder ) . '" alt="' . esc_attr__( 'Cart icon', 'instantio' ) . '">';
114 }
115
116 // class for toggle
117 if ( $this->layout == 2 ) {
118 $togglebtnClass = 'sidecart';
119 } elseif ( $this->layout == 3 ) {
120 $togglebtnClass = 'popupcart';
121 }
122
123 if ( $this->layout == 1 || $this->layout == '' ) {
124 $output = '<a id="mini_cart" class="ins-click-to-show" aria-label="' . esc_attr__( 'Go to checkout', 'instantio' ) . '" href="' . esc_url( wc_get_checkout_url() ) . '">';
125 $output .= $toggle_icon;
126 $output .= '</a>';
127 return $output;
128 } else {
129 $output = '<button type="button" id="mini_cart" class="ins-click-to-show ' . esc_attr( $togglebtnClass ) . '" aria-label="' . esc_attr__( 'Open cart', 'instantio' ) . '" aria-controls="instantio-cart-panel" aria-expanded="false">';
130 $output .= $toggle_icon;
131 $output .= '</button>';
132 return $output;
133 }
134
135 }
136
137
138 // Ins Cart Header
139 public function ins_cart_modern_header() {
140
141 $ins_single_layout = ! empty( instantio_get_option( 'ins-layout-step' ) ) ? instantio_get_option( 'ins-layout-step' ) : false;
142
143
144 ob_start();
145 ?>
146 <div class="header-wrap">
147 <div class="ins-checkout-header">
148 <span class="ins-checkout-header-icon">
149 <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
150 <g clip-path="url(#clip0_139_572)">
151 <path
152 d="M8.5489 9.0962L5.00006 5.54846L6.54851 4.00002L10.0962 7.54885H26.7757C26.9462 7.54884 27.1145 7.5887 27.2669 7.66525C27.4193 7.7418 27.5517 7.85292 27.6536 7.98974C27.7554 8.12657 27.8239 8.2853 27.8535 8.45328C27.8831 8.62126 27.873 8.79384 27.824 8.95723L25.1977 17.7117C25.1301 17.9372 24.9916 18.1349 24.8028 18.2755C24.6139 18.416 24.3848 18.4919 24.1493 18.4919H10.7375V20.6805H22.7749V22.8692H9.64321C9.35298 22.8692 9.07464 22.7539 8.86941 22.5486C8.66419 22.3434 8.5489 22.0651 8.5489 21.7748V9.0962ZM10.7375 9.73747V16.3033H23.3352L25.3049 9.73747H10.7375ZM10.1904 27.2464C9.75502 27.2464 9.3375 27.0734 9.02967 26.7656C8.72184 26.4578 8.5489 26.0403 8.5489 25.6049C8.5489 25.1696 8.72184 24.7521 9.02967 24.4442C9.3375 24.1364 9.75502 23.9635 10.1904 23.9635C10.6257 23.9635 11.0432 24.1364 11.351 24.4442C11.6589 24.7521 11.8318 25.1696 11.8318 25.6049C11.8318 26.0403 11.6589 26.4578 11.351 26.7656C11.0432 27.0734 10.6257 27.2464 10.1904 27.2464ZM23.322 27.2464C22.8867 27.2464 22.4692 27.0734 22.1614 26.7656C21.8535 26.4578 21.6806 26.0403 21.6806 25.6049C21.6806 25.1696 21.8535 24.7521 22.1614 24.4442C22.4692 24.1364 22.8867 23.9635 23.322 23.9635C23.7574 23.9635 24.1749 24.1364 24.4827 24.4442C24.7906 24.7521 24.9635 25.1696 24.9635 25.6049C24.9635 26.0403 24.7906 26.4578 24.4827 26.7656C24.1749 27.0734 23.7574 27.2464 23.322 27.2464Z"
153 fill="#494E5C" />
154 </g>
155 <defs>
156 <clipPath id="clip0_139_572">
157 <rect width="32" height="32" rx="4" fill="white" />
158 </clipPath>
159 </defs>
160 </svg>
161 </span>
162 <span class="ins-checkout-header-title">
163 <?php esc_html_e( 'Your cart ', 'instantio' ) ?>
164 </span>
165 <button type="button" class="ins-checkout-close" aria-label="<?php esc_attr_e( 'Close cart', 'instantio' ); ?>">
166 <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
167 <g clip-path="url(#clip0_139_578)">
168 <path
169 d="M16 14.1147L22.6 7.51467L24.4853 9.4L17.8853 16L24.4853 22.6L22.6 24.4853L16 17.8853L9.4 24.4853L7.51466 22.6L14.1147 16L7.51466 9.4L9.4 7.51467L16 14.1147Z"
170 fill="#494E5C" />
171 </g>
172 <defs>
173 <clipPath id="clip0_139_578">
174 <rect width="32" height="32" rx="4" fill="white" />
175 </clipPath>
176 </defs>
177 </svg>
178 </button>
179 </div>
180 <?php
181 if ( $ins_single_layout == false ) {
182 do_action( 'instantio_template_steps' );
183 }
184 // do_action('instantio_template_steps');
185 ?>
186 </div>
187 <?php
188 // The buffer contains only the static local template above and registered action output.
189 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
190 echo ob_get_clean();
191 }
192
193 // Ins Toggle button
194 public function instantio_cart_toggle() {
195 ob_start();
196 $ins_toggler = instantio_get_option( 'ins-toggler' );
197
198 $cart_icon = ! empty( instantio_get_option( 'ins-toggle-tab' )['cart-icon'] ) ? instantio_get_option( 'ins-toggle-tab' )['cart-icon'] : 'shopping-bag';
199 $wi_icon_choice = ! empty( instantio_get_option( 'ins-toggle-tab' )['wi-icon-choice'] ) ? instantio_get_option( 'ins-toggle-tab' )['wi-icon-choice'] : 'icon';
200 $wi_icon_choice_uploder = ! empty( instantio_get_option( 'ins-toggle-tab' )['wi-icon-choice-uploder'] ) ? instantio_get_option( 'ins-toggle-tab' )['wi-icon-choice-uploder'] : '';
201
202 if ( $cart_icon == 'shopping-bag' ) {
203
204 $toggle_icon = apply_filters( 'instantio_get_svg_icon_pro', instantio_svg_icon( $cart_icon ) );
205 } else {
206 $toggle_icon = '<i class="' . esc_attr( $cart_icon ) . '"></i>';
207 }
208 if ( $wi_icon_choice == 'image' && $wi_icon_choice_uploder != '' ) {
209 $toggle_icon = '<img src="' . esc_url( $wi_icon_choice_uploder ) . '" alt="' . esc_attr__( 'Cart icon', 'instantio' ) . '">';
210 }
211
212 if ( $this->layout == 2 ) {
213 $togglebtnClass = 'sidecart';
214 } elseif ( $this->layout == 3 ) {
215 $togglebtnClass = 'popupcart';
216 }
217 $icon_style = ! empty( instantio_get_option( 'ins-toggle-tab' )['cart-icon-style'] ) ? instantio_get_option( 'ins-toggle-tab' )['cart-icon-style'] : 'cart-style-1';
218 $dedicated_mobile = ! empty( instantio_get_option( 'dedicated_mobile' ) ) ? instantio_get_option( 'dedicated_mobile' ) : false;
219 $mobile_cart_panel = ! empty( instantio_get_option( 'mobile-cart-panel' ) ) ? instantio_get_option( 'mobile-cart-panel' ) : false;
220 $dedicated_mobile_panel_class = $dedicated_mobile == true && $mobile_cart_panel == true ? ' ins-dedicated-mobile-card-panel' : '';
221
222 $offMain_cart = ! empty( instantio_get_option( 'ins-mini-cart' )['ins-sidecart-icon'] ) ? instantio_get_option( 'ins-mini-cart' )['ins-sidecart-icon'] : '0';
223
224 if ( $offMain_cart == 1 ) {
225 $hiddenClass = 'hidden';
226 } else {
227 $hiddenClass = '';
228 }
229
230 // Setting
231 if ( $this->layout == 1 || $this->layout == '' ) {
232 $ins_toggler = 'tog-1';
233 ?>
234 <a aria-label="<?php esc_attr_e( 'Go to checkout', 'instantio' ); ?>" class="ins-toggle-btn <?php echo esc_attr( $ins_toggler ) ?>
235 <?php echo esc_attr( $dedicated_mobile_panel_class ) ?>
236 <?php echo esc_attr( $icon_style ) ?>
237 <?php echo esc_attr( $hiddenClass ) ?> " href="<?php echo esc_url( wc_get_checkout_url() ); ?>">
238 <span class="ins-cart-icon">
239 <?php // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Sanitized local SVG or escaped icon/image markup. ?>
240 <?php echo $toggle_icon; ?>
241 </span>
242
243 <?php // echo instantio_get_option( 'ins-toggle-tab' )['ins-cart-emty-hide']; ?>
244 <span class="ins-items-count"><span id="ins_cart_totals" class="ins_cart_total">
245 <?php echo absint( WC()->cart->get_cart_contents_count() ); ?>
246 </span></span>
247 </a>
248 <?php
249 } else {
250 ?>
251 <button type="button"
252 class="ins-click-to-show ins-toggle-btn <?php echo esc_attr( $hiddenClass ) ?>
253 <?php echo esc_attr( $togglebtnClass ) ?> <?php echo esc_attr( $dedicated_mobile_panel_class ) ?> <?php echo esc_attr( $icon_style ) ?> <?php echo esc_attr( $ins_toggler ) ?>"
254 aria-label="<?php esc_attr_e( 'Open cart', 'instantio' ); ?>" aria-controls="instantio-cart-panel" aria-expanded="false">
255 <span class="ins-cart-icon">
256 <?php // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Sanitized local SVG or escaped icon/image markup. ?>
257 <?php echo $toggle_icon; ?>
258 </span>
259
260 <span class="ins-items-count">
261 <span id="ins_cart_totals" class="ins_cart_total">
262 <?php echo absint( WC()->cart->get_cart_contents_count() ); ?>
263 </span>
264 </span>
265 </button>
266 <?php
267 }
268
269 // The buffer contains only the template above; all dynamic attributes are escaped.
270 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
271 echo ob_get_clean();
272 }
273
274
275 // Ins Cart Buttons
276 public function instantio_cart_buttons() {
277 ob_start();
278
279 // Cart Button
280 $on_cart_btn = isset( instantio_get_option( 'cart-btn' )['on-cart-btn'] ) ? instantio_get_option( 'cart-btn' )['on-cart-btn'] : false;
281 $cart_button_text = isset( instantio_get_option( 'cart-btn' )['cart_button_text'] ) ? instantio_get_option( 'cart-btn' )['cart_button_text'] : '';
282 $cart_button_url = isset( instantio_get_option( 'cart-btn' )['cart_button_url'] ) ? instantio_get_option( 'cart-btn' )['cart_button_url'] : '';
283
284 $cart_button_text = ! empty( $cart_button_text ) && $on_cart_btn == true ? wp_strip_all_tags( $cart_button_text ) : __( 'View Cart', 'instantio' );
285 $cart_button_url = ! empty( $cart_button_url ) && $on_cart_btn == true ? $cart_button_url : wc_get_cart_url();
286
287 // Cart Button Link
288 $cart_button = '<a href="' . esc_url( $cart_button_url ) . '" class="view-cart active">' . esc_html( $cart_button_text ) . '</a>';
289
290 // instantio_get_option( 'auto-tog-panel' )
291 // Checkout Button
292 $on_checkout_btn = isset( instantio_get_option( 'checkout-btn' )['on-checkout-btn'] ) ? instantio_get_option( 'checkout-btn' )['on-checkout-btn'] : false;
293
294 $checkout_button_text = isset( instantio_get_option( 'checkout-btn' )['checkout_button_text'] ) ? instantio_get_option( 'checkout-btn' )['checkout_button_text'] : '';
295 $checkout_button_url = isset( instantio_get_option( 'checkout-btn' )['checkout_button_url'] ) ? instantio_get_option( 'checkout-btn' )['checkout_button_url'] : '';
296
297 $checkout_button_text = ! empty( $checkout_button_text ) && $on_checkout_btn == true ? wp_strip_all_tags( $checkout_button_text ) : __( 'Checkout Now', 'instantio' );
298 $checkout_button_url = ! empty( $checkout_button_url ) && $on_checkout_btn == true ? $checkout_button_url : wc_get_checkout_url();
299
300 // Checkout button Link
301 $checkout_button = '<a href="' . esc_url( $checkout_button_url ) . '" class="checkout">' . esc_html( $checkout_button_text ) . '</a>';
302
303
304 ?>
305 <div class="ins-cart-btns">
306 <?php echo wp_kses_post( $cart_button ); ?>
307 <?php echo wp_kses_post( $checkout_button ); ?>
308 </div>
309 <?php
310
311 $html = ob_get_clean();
312 echo wp_kses_post( apply_filters( 'instantio_cart_buttons_pro', $html ) );
313 }
314
315
316 // Ins Cart Content Modern
317 public function instantio_cart_content_modern( $display ) {
318 ob_start();
319 ?>
320 <div class="ins-content <?php echo esc_attr( $display ) ?>">
321 <div class="ins-cart-inner step-1 ins-cart-step active">
322 <?php require_once apply_filters( 'instantio_cart_template', INSTANTIO_INC_PATH . '/templates/cart-modern.php' ); ?>
323 </div>
324 <?php do_action( 'instantio_template_step_content' ); ?>
325 </div>
326 <?php
327 // The buffer contains a local cart template and registered extension action output.
328 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
329 echo ob_get_clean();
330 }
331
332 // Ins Only Modern Cart Content
333 public function ins_modern_cart_only( $display ) {
334 ob_start();
335 ?>
336 <div class="ins-content <?php echo esc_attr( $display ) ?>">
337 <div class="ins-cart-inner step-1 ins-cart-step active">
338 <?php require_once apply_filters( 'instantio_cart_template', INSTANTIO_INC_PATH . '/templates/ins_single_step_cart.php' ); ?>
339 </div>
340 </div>
341 <?php
342 // The buffer contains a local cart template whose dynamic attributes are escaped.
343 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
344 echo ob_get_clean();
345 }
346
347 // Ajax Cart reload After Product Add to Cart
348 public function instantio_ajax_cart_reload( $include_fragments = false ) {
349 if ( wp_doing_ajax() && ! $include_fragments ) {
350 check_ajax_referer( 'instantio_ajax_nonce', 'nonce' );
351 }
352 ob_start();
353 // require_once apply_filters( 'instantio_layout_slug', INSTANTIO_INC_PATH . $this->layouts_slug );
354
355 // checked is single step
356 $ins_single_layout = ! empty( instantio_get_option( 'ins-layout-step' ) ) ? instantio_get_option( 'ins-layout-step' ) : false;
357
358 if ( $ins_single_layout ) {
359 require_once INSTANTIO_TEMPLATES_PATH . '/ins_single_step_cart.php';
360 } else {
361 require_once INSTANTIO_TEMPLATES_PATH . '/cart-modern.php';
362 }
363 // require_once INSTANTIO_INC_PATH . $this->layouts_slug;
364 $data = ob_get_clean();
365
366 // Override the checkout template
367 if ( ! is_user_logged_in() ) {
368 // Display for non-logged-in users
369 ob_start();
370 add_action( 'woocommerce_checkout_shipping', array( WC()->checkout(), 'checkout_form_shipping' ) );
371 do_action( 'woocommerce_checkout_shipping' );
372 $ins_shipping_additional = ob_get_clean();
373 } else {
374 // Use the default WooCommerce action for logged-in users
375 ob_start();
376 do_action( 'woocommerce_checkout_shipping' );
377 $ins_shipping_additional = ob_get_clean();
378 }
379
380 $hide_empty = 'hide';
381 $display = 'ins-show';
382 if ( WC()->cart->is_empty() ) :
383 $hide_empty = 'ins-show';
384 $display = 'hide';
385 endif;
386
387 $ins_cart_total = WC()->cart->get_cart_contents_count();
388 $fragments = array();
389
390 if ( $include_fragments ) {
391 WC()->cart->maybe_set_cart_cookies();
392 ob_start();
393 woocommerce_mini_cart();
394 $mini_cart = ob_get_clean();
395 $fragments = apply_filters(
396 'woocommerce_add_to_cart_fragments',
397 array(
398 'div.widget_shopping_cart_content' => '<div class="widget_shopping_cart_content">' . $mini_cart . '</div>',
399 )
400 );
401 }
402 // need to check this again
403 // $ins_checkout_load = apply_filters('instantio_template_step_content');
404
405 $response = array(
406 // 'fragments' => apply_filters( 'instantio_cart_count_fragments', array() ),
407 'cart_hash' => apply_filters( 'woocommerce_add_to_cart_hash', WC()->cart->get_cart_for_session() ? md5( json_encode( WC()->cart->get_cart_for_session() ) ) : '', WC()->cart->get_cart_for_session() ),
408 'data' => $data,
409 'cart_total' => WC()->cart->get_cart_total(),
410 'hide_empty' => $hide_empty,
411 'display' => $display,
412 'ins_cart_count' => $ins_cart_total,
413 'ins_shipping_additional' => $ins_shipping_additional,
414 'fragments' => $fragments,
415 // 'ins_checkout_load' => $ins_checkout_load,
416 );
417
418 wp_send_json_success( $response );
419
420 wp_die();
421 }
422
423 public function instantio_ajax_cart_single() {
424
425 if ( ! isset( $_POST['nonce'] ) ||
426 ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'instantio_ajax_nonce' ) ) {
427 wp_send_json( [ 'error' => true ] );
428 }
429
430 if ( ! isset( $_POST['product_id'] ) ) {
431 wp_send_json( [ 'error' => true ] );
432 }
433
434 $product_id = apply_filters( 'woocommerce_add_to_cart_product_id', absint( wp_unslash( $_POST['product_id'] ) ) );
435 $variation_id = isset( $_POST['variation_id'] ) ? absint( wp_unslash( $_POST['variation_id'] ) ) : 0;
436 $quantity_request = isset( $_POST['quantity'] )
437 ? map_deep( wp_unslash( $_POST['quantity'] ), 'sanitize_text_field' )
438 : null;
439 $product = wc_get_product( $product_id );
440
441 if ( ! $product || get_post_status( $product_id ) !== 'publish' ) {
442 wp_send_json( [ 'error' => true ] );
443 }
444
445 $product_status = get_post_status( $product_id );
446
447 // GROUPED PRODUCT HANDLING
448 if ( $product->is_type( 'grouped' ) ) {
449
450 $added = false;
451
452 if ( ! empty( $quantity_request ) && is_array( $quantity_request ) ) {
453
454 foreach ( $quantity_request as $child_id => $qty ) {
455
456 $child_id = absint( $child_id );
457 $qty = wc_stock_amount( $qty );
458
459 if ( $qty <= 0 ) {
460 continue;
461 }
462
463 $passed_validation = apply_filters(
464 'woocommerce_add_to_cart_validation',
465 true,
466 $child_id,
467 $qty
468 );
469
470 if ( $passed_validation && get_post_status( $child_id ) === 'publish' ) {
471
472 $cart_item_key = WC()->cart->add_to_cart( $child_id, $qty );
473
474 if ( $cart_item_key ) {
475 $added = true;
476 do_action( 'woocommerce_ajax_added_to_cart', $child_id );
477 }
478 }
479 }
480 }
481
482 if ( $added ) {
483
484 if ( get_option( 'woocommerce_cart_redirect_after_add' ) === 'yes' ) {
485 wc_add_to_cart_message( array( $product_id => 1 ), true );
486 }
487
488 $this->instantio_ajax_cart_reload( true );
489 }
490
491 wp_send_json( [
492 'error' => true,
493 'product_url' => apply_filters(
494 'woocommerce_cart_redirect_after_error',
495 get_permalink( $product_id ),
496 $product_id
497 )
498 ] );
499 }
500
501 // EASY PRODUCT BUNDLE (Manual Add Like Grouped)
502 if ( $product->get_type() === 'easy_product_bundle' ) {
503
504 $added = false;
505 $main_qty = ! empty( $quantity_request ) ? wc_stock_amount( $quantity_request ) : 1;
506
507 if ( ! empty( $_POST['asnp_wepb_items'] ) ) {
508
509 $items = json_decode( sanitize_text_field( wp_unslash( $_POST['asnp_wepb_items'] ) ), true );
510
511 if ( is_array( $items ) ) {
512
513 foreach ( $items as $item ) {
514
515 $child_id = isset( $item['id'] ) ? absint( $item['id'] ) : 0;
516 $child_qty = isset( $item['qty'] ) ? wc_stock_amount( $item['qty'] ) : 0;
517 $attributes = isset( $item['attributes'] ) ? (array) $item['attributes'] : [];
518
519 if ( $child_id <= 0 || $child_qty <= 0 ) {
520 continue;
521 }
522
523 $child_product = wc_get_product( $child_id );
524
525 if ( ! $child_product || get_post_status( $child_id ) !== 'publish' ) {
526 continue;
527 }
528
529 $total_qty = $child_qty * $main_qty;
530
531 $variation_id = 0;
532 $variation_data = [];
533
534 /*
535 |--------------------------------------------------------------------------
536 | Handle Variable Products
537 |--------------------------------------------------------------------------
538 */
539 if ( $child_product->is_type( 'variable' ) && ! empty( $attributes ) ) {
540
541 $variation_data = [];
542
543 foreach ( $attributes as $attr_key => $attr_value ) {
544
545 // Convert to proper WooCommerce format
546 $taxonomy = wc_attribute_taxonomy_name( $attr_key );
547
548 if ( taxonomy_exists( $taxonomy ) ) {
549 $variation_data[ 'attribute_' . $taxonomy ] = sanitize_title( $attr_value );
550 } else {
551 $variation_data[ 'attribute_' . sanitize_title( $attr_key ) ] = sanitize_title( $attr_value );
552 }
553 }
554
555 // Find matching variation
556 $data_store = \WC_Data_Store::load( 'product' );
557 $variation_id = $data_store->find_matching_product_variation(
558 $child_product,
559 $variation_data
560 );
561 }
562
563 $price = $child_product->get_price();
564
565 $cart_item_data = [
566 'custom_bundle_price' => $price,
567 ];
568
569 $cart_item_key = WC()->cart->add_to_cart(
570 $child_id,
571 $total_qty,
572 $variation_id,
573 $variation_data,
574 $cart_item_data
575 );
576
577 if ( $cart_item_key ) {
578 $added = true;
579 do_action( 'woocommerce_ajax_added_to_cart', $child_id );
580 }
581 }
582 }
583 }
584
585 if ( $added ) {
586
587 if ( get_option( 'woocommerce_cart_redirect_after_add' ) === 'yes' ) {
588 wc_add_to_cart_message( array( $product_id => $main_qty ), true );
589 }
590
591 $this->instantio_ajax_cart_reload( true );
592 }
593
594 wp_send_json( [
595 'error' => true,
596 'product_url' => get_permalink( $product_id )
597 ] );
598 }
599
600 // SIMPLE / VARIABLE PRODUCTS
601 $quantity = empty( $quantity_request ) ? 1 : wc_stock_amount( $quantity_request );
602
603 $passed_validation = apply_filters(
604 'woocommerce_add_to_cart_validation',
605 true,
606 $product_id,
607 $quantity,
608 $variation_id
609 );
610
611 if (
612 $passed_validation &&
613 $product_status === 'publish' &&
614 WC()->cart->add_to_cart( $product_id, $quantity, $variation_id )
615 ) {
616
617 do_action( 'woocommerce_ajax_added_to_cart', $product_id );
618
619 if ( get_option( 'woocommerce_cart_redirect_after_add' ) === 'yes' ) {
620 wc_add_to_cart_message( array( $product_id => $quantity ), true );
621 }
622
623 $this->instantio_ajax_cart_reload( true );
624 }
625
626 wp_send_json( [
627 'error' => true,
628 'product_url' => apply_filters(
629 'woocommerce_cart_redirect_after_error',
630 get_permalink( $product_id ),
631 $product_id
632 )
633 ] );
634 }
635
636 // Ajax Cart Remove To cart
637 public function instantio_ajax_cart_item_remove() {
638 check_ajax_referer( 'instantio_ajax_nonce', 'nonce' );
639
640 $product_id = isset( $_POST['product_id'] ) ? absint( wp_unslash( $_POST['product_id'] ) ) : 0;
641 $variation_id = isset( $_POST['variation_id'] ) ? absint( wp_unslash( $_POST['variation_id'] ) ) : 0;
642
643 $cart = WC()->cart->get_cart();
644
645 foreach ( $cart as $cart_item_key => $cart_item ) {
646 if ( $cart_item['product_id'] == $product_id && $cart_item['variation_id'] == $variation_id ) {
647
648 // Remove product in the cart using cart_item_key.
649 WC()->cart->remove_cart_item( $cart_item_key );
650 }
651 }
652 WC()->cart->calculate_totals();
653 WC()->cart->maybe_set_cart_cookies();
654
655 return $this->instantio_ajax_cart_reload();
656
657
658 }
659
660 // Ajax Update Cart
661 public function instantio_ajax_update_cart() {
662 check_ajax_referer( 'instantio_ajax_nonce', 'nonce' );
663
664 $cart_item_keys = isset( $_POST['cart_item_keys'] ) && is_array( $_POST['cart_item_keys'] )
665 ? array_map( 'sanitize_text_field', wp_unslash( $_POST['cart_item_keys'] ) )
666 : array();
667 $quantities = isset( $_POST['quantities'] ) && is_array( $_POST['quantities'] )
668 ? array_map( 'wc_stock_amount', array_map( 'sanitize_text_field', wp_unslash( $_POST['quantities'] ) ) )
669 : array();
670 $coupon_code = isset( $_POST['coupon_code'] ) ? sanitize_text_field( wp_unslash( $_POST['coupon_code'] ) ) : '';
671 $cart_updated = false;
672
673 // if cart_item_keys not empty then start the loop
674 if ( ! empty( $cart_item_keys ) ) {
675 for ( $i = 0; $i < count( $cart_item_keys ); $i++ ) {
676 if ( ! isset( $quantities[ $i ] ) ) {
677 continue;
678 }
679 WC()->cart->set_quantity( $cart_item_keys[ $i ], $quantities[ $i ], false );
680 if ( $quantities[ $i ] == 0 ) {
681 WC()->cart->remove_cart_item( $cart_item_keys[ $i ] );
682 continue;
683 }
684 }
685 }
686
687 if ( ! empty( $coupon_code ) ) {
688 WC()->cart->add_discount( sanitize_text_field( $coupon_code ) );
689 }
690
691 WC()->cart->calculate_totals();
692 WC()->cart->maybe_set_cart_cookies();
693 $hide_empty = 'hide';
694 $display = 'ins-show';
695 if ( WC()->cart->is_empty() ) :
696 $hide_empty = 'ins-show';
697 $display = 'hide';
698 endif;
699
700 ob_start();
701 // require_once apply_filters( 'instantio_layout_slug', INSTANTIO_INC_PATH . $this->layouts_slug );
702 $this->instantio_ajax_cart_reload();
703 $cart_data = ob_get_clean();
704
705 // Override the checkout template
706 if ( ! is_user_logged_in() ) {
707 // Display for non-logged-in users
708 ob_start();
709 add_action( 'woocommerce_checkout_shipping', array( WC()->checkout(), 'checkout_form_shipping' ) );
710 do_action( 'woocommerce_checkout_shipping' );
711 $ins_shipping_additional = ob_get_clean();
712 } else {
713 // Use the default WooCommerce action for logged-in users
714 ob_start();
715 do_action( 'woocommerce_checkout_shipping' );
716 $ins_shipping_additional = ob_get_clean();
717 }
718
719 $data = array(
720 'cart_data' => $cart_data,
721 'hide_empty' => $hide_empty,
722 'display' => $display,
723 'cart_hash' => apply_filters( 'woocommerce_add_to_cart_hash', WC()->cart->get_cart_for_session() ? md5( json_encode( WC()->cart->get_cart_for_session() ) ) : '', WC()->cart->get_cart_for_session() ),
724 'ins_shipping_additional' => $ins_shipping_additional,
725 );
726
727 wp_send_json( $data );
728 wp_die();
729
730 }
731
732 // Ajax Cart Empty To cart
733 public function instantio_ajax_empty_cart() {
734 check_ajax_referer( 'instantio_ajax_nonce', 'nonce' );
735
736 WC()->cart->empty_cart();
737 WC()->cart->calculate_totals();
738 WC()->cart->maybe_set_cart_cookies();
739
740 ob_start();
741
742 // require_once apply_filters( 'instantio_layout_slug', INSTANTIO_INC_PATH . $this->layouts_slug );
743 $this->instantio_ajax_cart_reload();
744 $cart_data = ob_get_clean();
745
746 $data = array(
747 'cart_data' => $cart_data,
748 'cart_hash' => apply_filters( 'woocommerce_add_to_cart_hash', WC()->cart->get_cart_for_session() ? md5( json_encode( WC()->cart->get_cart_for_session() ) ) : '', WC()->cart->get_cart_for_session() )
749 );
750
751 wp_send_json( $data );
752 wp_die();
753
754 }
755
756 // Ajax Remove Coupon
757 public function instantio_ajax_remove_coupon() {
758 check_ajax_referer( 'instantio_ajax_nonce', 'nonce' );
759
760 $coupon_code = isset( $_POST['coupon'] ) ? wc_format_coupon_code( sanitize_text_field( wp_unslash( $_POST['coupon'] ) ) ) : '';
761 WC()->cart->remove_coupon( $coupon_code );
762
763 WC()->cart->calculate_totals();
764 WC()->cart->maybe_set_cart_cookies();
765
766 ob_start();
767
768 require_once apply_filters( 'instantio_layout_slug', INSTANTIO_INC_PATH . $this->layouts_slug );
769 $cart_data = ob_get_clean();
770
771 $data = array(
772 'cart_data' => $cart_data,
773 'cart_hash' => apply_filters( 'woocommerce_add_to_cart_hash', WC()->cart->get_cart_for_session() ? md5( json_encode( WC()->cart->get_cart_for_session() ) ) : '', WC()->cart->get_cart_for_session() )
774 );
775
776 wp_send_json( $data );
777 wp_die();
778
779 }
780
781
782
783 public function ins_layout_three() {
784
785 // Return if WooCommerce not active
786 if ( ! class_exists( 'WooCommerce' ) ) {
787 return;
788 }
789
790 // Do not render Instantio on WooCommerce checkout pages or endpoints.
791 if ( is_checkout() ) {
792 return;
793 }
794
795 // Return if cart page
796 if ( is_cart() ) {
797 return;
798 }
799
800 // checked is page seleted or not
801 $ins_page_selected = instantio_get_option( 'ins-page-selected' ); // Retrieve the option value
802
803 if ( ! empty( $ins_page_selected ) && is_array( $ins_page_selected ) ) {
804 // The option value is an array, so you can proceed with array operations
805 $pages = array_values( $ins_page_selected );
806 } else {
807 // Handle the case where the option value is not an array (e.g., set a default value)
808 $pages = array( 'cart', 'checkout' );
809 }
810
811 // Return is particular page seleted
812 if ( class_exists( 'woocommerce' ) ) {
813 if ( is_page( $pages ) ) {
814 return;
815 }
816 }
817
818 $toggle_position = isset( instantio_get_option( 'ins-toggle-tab' )['toggle-position'] ) ? instantio_get_option( 'ins-toggle-tab' )['toggle-position'] : 'right-bottom';
819
820 // checked is single step
821 $ins_single_layout = ! empty( instantio_get_option( 'ins-layout-step' ) ) ? instantio_get_option( 'ins-layout-step' ) : false;
822
823 if ( ! empty( $toggle_position ) ) {
824 $toggle_position = explode( '-', $toggle_position );
825 $toggle_position_horizontal = $toggle_position[0];
826 $toggle_position_vertical = $toggle_position[1];
827 } else {
828 $toggle_position_horizontal = 'right';
829 $toggle_position_vertical = 'bottom';
830 }
831 $toggle_panel_position = isset( instantio_get_option( 'ins-toggle-panel-tab' )['toggle-panel-position'] ) ? 'panel-' . instantio_get_option( 'ins-toggle-panel-tab' )['toggle-panel-position'] : 'panel-right';
832 $this->layout_class .= ! empty( $toggle_position_horizontal ) ? 'ins-hori-' . $toggle_position_horizontal . ' ' : 'ins-hori-right ';
833 $this->layout_class .= ! empty( $toggle_panel_position ) ? $toggle_panel_position . ' ' : 'panel-right ';
834 $this->layout_class .= ! empty( $toggle_position_vertical ) ? 'ins-var-cart-' . $toggle_position_vertical . ' ' : 'ins-var-cart-bottom ';
835 $this->layout_class .= ! empty( instantio_get_option( 'ins-layout-mode' ) ) ? 'ins-layout-' . instantio_get_option( 'ins-layout-mode' ) . ' ' : '';
836 $this->layout_class .= ! empty( instantio_get_option( 'ins-layout-animation' ) ) ? instantio_get_option( 'ins-layout-animation' ) . ' ' : '';
837 $this->layout_class .= $ins_single_layout == true ? 'ins-single-layout-step ' : '';
838
839 $instantio_layout_class = apply_filters( 'instantio_layout_class', $this->layout_class );
840
841
842 // Dedicated mobile Version hook for
843 do_action( 'instantio_dedicated_mobile_version' );
844
845 ob_start();
846
847 if ( $this->layout == 1 || $this->layout == 3 ) :
848 ?>
849 <div class="ins-fixed-toogle <?php echo esc_attr( $this->layout_class ) ?>">
850 <?php do_action( 'instantio_cart_toggle' ); ?>
851 </div>
852 <?php
853 endif;
854
855 if ( $this->layout == 2 || $this->layout == 3 ) :
856 ?>
857 <div class="ins-checkout-popup ins-checkout-modern <?php echo esc_attr( $instantio_layout_class ) ?>">
858 <div class="ins-checkout-overlay"></div>
859 <div id="instantio-cart-panel" role="dialog" aria-modal="true" aria-label="<?php esc_attr_e( 'Shopping cart', 'instantio' ); ?>" tabindex="-1" class="ins-checkout-layout ins-checkout-layout-3 <?php echo esc_attr( $instantio_layout_class ) ?>">
860 <?php
861 require_once apply_filters( 'instantio_layout_slug', INSTANTIO_INC_PATH . $this->layouts_slug );
862 ?>
863 </div>
864 </div>
865 <?php
866 endif;
867 ?>
868 </div>
869 <?php
870 $output = ob_get_clean();
871 // The buffer contains local layout templates; each template owns contextual escaping.
872 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
873 echo $output;
874 }
875
876 }
877
878
879 ?>
880