PluginProbe
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell / 2.8.16
WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell v2.8.16
3.13.3 3.13.2 3.13.1 3.13.0 3.12.13 3.12.12 3.12.11 3.12.10 3.12.9 3.12.8 3.12.7 3.12.6 3.12.5 3.12.4 3.12.3 3.12.1 3.12.2 3.12.0 3.11.1 3.11.0 3.10.9 3.10.8 3.10.7 3.10.6 2.8.16 All 261 releases
wpfunnels / public / modules / checkout / class-wpfnl-checkout.php

class-wpfnl-checkout.php in WPFunnels – Funnel Builder for WooCommerce with Checkout & One Click Upsell 2.8.16, at public/modules/checkout/class-wpfnl-checkout.php

1,315 lines 43.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Checkout module
4 *
5 * @package
6 * @since 2.7.9
7 */
8
9 namespace WPFunnels\Modules\Frontend\Checkout;
10
11 use Error;
12 use WC_Session_Handler;
13 use WPFunnels\Data_Store\Wpfnl_Steps_Store_Data;
14 use WPFunnels\Frontend\Module\Wpfnl_Frontend_Module;
15 use WPFunnels\Frontend\Wpfnl_Public;
16 use WPFunnels\Meta\Wpfnl_Default_Meta;
17 use WPFunnels\Wpfnl;
18 use WPFunnels\Wpfnl_functions;
19 use WPFunnels\lms\helper\Wpfnl_lms_learndash_functions;
20 use WPFunnels\Modules\Frontend\Checkout\Variable\Wpfnl_Variable_Product;
21 use WPFunnels\Modules\Frontend\Checkout\Single\Wpfnl_Single_Product;
22 use function cli\err;
23 use Wpfnl_Public_Type_Factory;
24 use WPFunnels\Conditions\Wpfnl_Condition_Checker;
25 use WPFunnels\Discount\WpfnlDiscount;
26 use WPFunnels\Modules\Frontend\CheckoutHelper\CheckoutHelper;
27
28 class Module extends Wpfnl_Frontend_Module
29 {
30 public $funnel_id;
31
32 public $step_id;
33
34 // const CHECKOUT = "";
35
36 public function __construct()
37 {
38
39 /* set checkout flag */
40 add_filter('woocommerce_is_checkout', [$this, 'checkout_flag'], 9999);
41 add_action('woocommerce_checkout_update_order_meta', [$this, 'save_checkout_fields'], 10, 2);
42
43 /* initialize cart data */
44 add_action('wp', [ $this, 'initialize_cart_data' ] );
45
46 add_action('wp', [$this, 'init_wc_actions']);
47 /* register checkout shortcode */
48 add_shortcode('wpfunnels_checkout', array($this, 'render_checkout_shortcode'));
49 add_action('wp_ajax_wpfnl_next_button_ajax', [$this, 'wpfnl_next_button_ajax']);
50 add_action('wp_ajax_nopriv_wpfnl_next_button_ajax', [$this, 'wpfnl_next_button_ajax']);
51
52 add_action( 'wp_ajax_wpfnl_order_bump_ajax', [$this, 'wpfnl_order_bump_ajax']);
53 add_action( 'wp_ajax_nopriv_wpfnl_order_bump_ajax', [$this, 'wpfnl_order_bump_ajax']);
54
55 add_action( 'wp_ajax_wpfnl_get_course_details', [$this, 'wpfnl_get_course_details']);
56 add_action( 'wp_ajax_nopriv_wpfnl_get_course_details', [$this, 'wpfnl_get_course_details']);
57
58 add_action( 'wp_ajax_wpfnl_update_variation', [$this, 'wpfnl_update_variation']);
59 add_action( 'wp_ajax_nopriv_wpfnl_update_variation', [$this, 'wpfnl_update_variation']);
60
61 add_action( 'woocommerce_before_calculate_totals', [$this, 'custom_price_to_cart_item'], 9999);
62 add_action( 'woocommerce_before_checkout_form', [$this, 'apply_auto_coupon'], 9999);
63
64 add_action( 'wp_ajax_nopriv_wpfnl_checkout_cart', [$this, 'wpfnl_checkout_cart']);
65 add_filter('woocommerce_cart_product_out_of_stock_message', [$this,'wpfnl_out_of_stock_message_in_checkout'], 10, 2);
66
67 add_action( 'wpfunnels/before_checkout_form', array($this, 'before_checkout_form_actions') );
68
69 add_action( 'woocommerce_after_order_notes', array( $this, 'wpfnl_set_checkout_id' ), 999 );
70 add_action( 'woocommerce_login_form_end', array( $this, 'wpfnl_set_checkout_id' ), 999 );
71 add_filter( 'woocommerce_login_redirect', [$this,'wpfnl_redirect_after_login'], 10, 2 );
72 add_action( 'woocommerce_cart_calculate_fees', [$this,'wpfnl_checkout_discount'], 10);
73 add_action('woocommerce_cart_totals_get_fees_from_cart_taxes', [$this, 'exclude_cart_fees_taxes'], 10 ,3);
74 add_action( 'wpfunnels/after_optin_submit', array( $this, 'get_optin_data_checkout' ), 10, 4 );
75 add_filter( 'woocommerce_checkout_fields', array($this, 'set_option_data_in_checkout_filed'),10 );
76 // add_filter( 'woocommerce_subscriptions_display_recurring_fee_totals', array($this, 'remove_discount_from_recurring_totals'),10, 2 );
77
78 // add_filter( 'woocommerce_subscriptions_display_recurring_subscription_totals', array($this, 'remove_discount_from_recurring_totals'),10, 2 );
79
80
81 }
82
83
84 /**
85 * Set checkout flag to true if this is checkout step type
86 *
87 * @param $is_checkout
88 *
89 * @return bool
90 *
91 * @since 1.0.0
92 */
93 public function checkout_flag($is_checkout)
94 {
95 if (Wpfnl_functions::check_if_this_is_step_type('checkout')) {
96 $is_checkout = true;
97 }
98 return $is_checkout;
99 }
100
101
102 /**
103 * Init WooCommerce related actions
104 */
105 public function init_wc_actions() {
106 add_action( 'woocommerce_after_order_notes', [$this, 'checkout_shortcode_metas']);
107 $this->display_coupon_field();
108 $this->enable_checkout_hook();
109 }
110
111
112 /**
113 * Enable checkout hook
114 */
115 private function enable_checkout_hook(){
116
117 if ( Wpfnl_functions::check_if_this_is_step_type('checkout') ) {
118
119 if( is_plugin_active( 'woocommerce-german-market/WooCommerce-German-Market.php' )){
120 add_action( 'woocommerce_checkout_order_review','woocommerce_checkout_payment' );
121 }
122 }
123 }
124
125
126 /**
127 * Save checkout metas
128 *
129 * @param $order_id
130 * @param $posted
131 *
132 * @since 1.0.0
133 */
134 public function save_checkout_fields( $order_id, $posted )
135 {
136 // Instantiate the CheckoutModuleHelper
137 $helper = new CheckoutHelper();
138
139 if (isset($_POST['_wpfunnels_checkout_id'])) {
140 $helper->update_checkout_id_post_meta($order_id, sanitize_text_field( $_POST['_wpfunnels_checkout_id'] ) );
141 if (isset($_POST['_wpfunnels_funnel_id'])) {
142 $funnel_id = $helper->update_order_meta_for_funnel($order_id, sanitize_text_field($_POST['_wpfunnels_funnel_id']));
143 }
144 if (isset($_POST['_wpfunnels_order_unique_identifier'])) {
145 $helper->update_unique_identifier_post_meta($order_id, sanitize_text_field($_POST['_wpfunnels_order_unique_identifier']));
146 }
147 $order_bump_products = get_post_meta( $_POST['_wpfunnels_checkout_id'], 'order-bump-settings' , true );
148 $helper->update_order_bump_product( $order_bump_products, $order_id );
149 }
150
151 if (isset($funnel_id)) {
152 $order = Wpfnl_functions::is_wc_active() ? wc_get_order($order_id) : null;
153 $funnel_id = $helper->update_order_meta_for_funnel($order_id, sanitize_text_field( $_POST['_wpfunnels_funnel_id']) );
154
155 if( $funnel_id ){
156 $discount_instance = new WpfnlDiscount();
157 $discount = $discount_instance->get_discount_settings( $_POST['_wpfunnels_checkout_id'] );
158 $main_products = $helper->get_main_products( $_POST['_wpfunnels_checkout_id'], $funnel_id );
159
160 $variable_product_check = $helper->variable_product_check( $order->get_items(), $main_products, false );
161 $main_products = isset( $variable_product_check['main_products'] ) ? $variable_product_check['main_products'] : $main_products;
162
163 $is_main_product_in_cart = isset( $variable_product_check['is_main_product_in_cart'] ) ? $variable_product_check['is_main_product_in_cart'] : false;
164 $total = Wpfnl_functions::calculate_main_product_total( $main_products , WC()->cart->cart_contents, $_POST['_wpfunnels_checkout_id'] );
165 $response = $helper->apply_discount_and_update_total( $order, $total, $discount, $is_main_product_in_cart );
166 }
167 $user_id = $order->get_user_id();
168 $orders[sanitize_text_field($_POST['_wpfunnels_checkout_id'])] = $order_id;
169 WC()->session->set('wpfnl_orders_'.$user_id.'_'.$funnel_id, $orders);
170
171 $session_handler = new WC_Session_Handler();
172 WC()->session->set('wpfnl_order_owner', $session_handler->generate_customer_id());
173
174 /**
175 * Fires after a funnel order is placed.
176 *
177 * @since 1.0.0
178 *
179 * @param int $order_id The ID of the order.
180 * @param string $funnel_id The ID of the funnel.
181 * @param string $_POST['_wpfunnels_checkout_id'] The checkout ID associated with the order.
182 */
183 do_action( 'wpfunnels/funnel_order_placed', $order_id, $funnel_id, $_POST['_wpfunnels_checkout_id'] );
184 }
185 }
186
187
188 /**
189 * Automatically add products to funnel checkout
190 *
191 * @throws \Exception
192 *
193 * @since 1.0.0
194 */
195 public function initialize_cart_data() {
196 global $post;
197
198 if(
199 is_admin()
200 || isset( $_GET[ 'removed_item' ] )
201 || wp_doing_ajax()
202 || !$post
203 ) {
204 return;
205 }
206
207 $checkout_id = $post->ID;
208
209 // Returns if the post id is not funnel checkout type.
210 if(
211 !Wpfnl_functions::check_if_this_is_step_type_by_id( $checkout_id, 'checkout' )
212 || !Wpfnl_functions::check_if_this_is_step_type( 'checkout' )
213 || Wpfnl_functions::is_orderbump_clicked_from_post_data()
214 || Wpfnl_functions::is_variation_selected_from_post_data()
215 ) {
216 return;
217 }
218
219 $funnel_id = get_post_meta( $checkout_id, '_funnel_id', true );
220
221 // Returns in case of invalid funnel id or if the funnel id is `lms` type.
222 if( !$funnel_id || 'lms' === get_post_meta( $funnel_id, '_wpfnl_funnel_type', true ) ) {
223 return;
224 }
225
226 $this->render_express_checkout( $checkout_id );
227
228 /**
229 * Filter hook to modify funnel products
230 *
231 * @param array $product_array Products selected for funnel checkout.
232 * @param string|int $funnel_id Funnel ID.
233 * @param string|int $checkout_id Checkout ID.
234 *
235 * @since 2.7.11
236 */
237 $product_array = apply_filters(
238 'wpfunnels/funnel_products',
239 get_post_meta( $checkout_id, '_wpfnl_checkout_products', true ),
240 $funnel_id,
241 $checkout_id
242 );
243
244 \WC()->cart->empty_cart();
245
246 if( !is_array( $product_array ) || empty( $product_array[ 0 ][ 'id' ] ) ) {
247 wc_clear_notices();
248 wc_add_notice( __( 'No product is added to the funnel. Please add product from checkout step settings.', 'wpfnl' ), 'error' );
249 return;
250 }
251 $price_type = $this->get_product_price_type( $funnel_id, $checkout_id );
252
253 if( $product_array && is_array( $product_array )) {
254 foreach( $product_array as $product ) {
255 if( isset( $product[ "id" ] ) && isset( $product[ "quantity" ] ) ) {
256 $product_id = !empty($product['variation_id']) ? $product[ "variation_id" ] : $product[ "id" ];
257 $quantity = $product[ "quantity" ];
258 $_product = $product_id ? wc_get_product( $product_id ) : null;
259
260 if( $_product instanceof \WC_Product ) {
261 //check if product type is variable or not from $_product object.
262
263 if( 'variable' === $_product->get_type() ) {
264 $this->add_default_variation( $product_id, $_product, $quantity, $price_type );
265 continue;
266 }
267
268 $product_type = $_product->get_type();
269
270 if( 'variation' === $product_type || 'subscription_variation' === $product_type ) {
271 $is_perfect_variation = Wpfnl_functions::is_perfect_variations( $product_id );
272 $type = empty($is_perfect_variation['status']) ? 'single-variation' : 'variation';
273 $this->add_variaiton_product_in_cart( $product_id, $quantity, $price_type, $type, [], null );
274 continue;
275 }
276
277 if( $price_type == 'original' || $price_type == 'sale' ){
278 $custom_data = [
279 'custom_price' => get_post_meta($product_id, '_price', true) ? get_post_meta($product_id, '_price', true) : get_post_meta($product_id, '_regular_price', true),
280 'product_type' => $product_type
281 ];
282 }else{
283 $custom_data = [
284 'custom_price' => get_post_meta($product_id, '_regular_price', true) ? get_post_meta($product_id, '_regular_price', true) : get_post_meta($product_id, '_price', true),
285 'product_type' => $product_type
286 ];
287
288 }
289
290 WC()->cart->add_to_cart( $product_id, $quantity, '' , array(), $custom_data );
291 }
292 }
293 }
294 }
295 //Add coupons for funnel checkout.
296 $this->add_coupons( $checkout_id );
297
298 /**
299 * After initialize funnels checkout
300 *
301 * This hook will trigger in checkout page
302 *
303 * @param init $funnel_id Funnel ID
304 *
305 * @since 2.7.19
306 */
307 do_action( 'wpfunnels/after_init_checkout', $funnel_id );
308 }
309
310
311 /**
312 * Checks if a variation is incomplete based on its attributes.
313 *
314 * @param int $variation_id The ID of the variation.
315 * @param \WC_Product $parent_product (Optional) The parent product object. If not provided, it will be retrieved based on the variation ID.
316 *
317 * @return bool True if the variation is incomplete, false otherwise.
318 */
319 private function is_variation_incomplete( $variation_id, $parent_product = null ) {
320 if( !$parent_product ) {
321 $parent_product = wc_get_product( $variation_id );
322 }
323
324 $var_product = wc_get_product( $variation_id );
325 $attributes = $parent_product->get_attributes();
326 $var_attributes = $var_product->get_attributes();
327
328 return sizeof( $attributes ) !== sizeof( array_filter( $var_attributes ) );
329 }
330
331
332 /**
333 * Adds coupons to the funnel checkout
334 *
335 * @param int|string $checkout_id Funnel checkout ID.
336 *
337 * @since 2.7.11
338 */
339 private function add_coupons( $checkout_id ) {
340 $coupon = get_post_meta( $checkout_id, '_wpfnl_checkout_discount', true );
341 if( is_array( $coupon ) && !empty( $coupon ) ) {
342 $coupon = reset( $coupon );
343 }
344 WC()->session->set( 'order_bump_accepted', 'no' );
345
346 if( !empty( $coupon ) ) {
347 WC()->cart->add_discount( $coupon );
348 }
349 }
350
351 /**
352 * Renders express funnel checkout
353 *
354 * @param int|string $checkout_id Funnel checkout ID.
355 *
356 * @since 2.7.11
357 */
358 private function render_express_checkout( $checkout_id ) {
359 // Only for express checkout
360 if( \WPFunnels\Wpfnl_functions::is_wpfnl_pro_activated() && Wpfnl_functions::maybe_express_checkout( $checkout_id ) ) {
361 remove_action( 'woocommerce_checkout_order_review', 'woocommerce_order_review' );
362 add_filter( 'woocommerce_update_order_review_fragments', [ $this, 'wpfnl_express_checkout_shipping_table_update' ], 10, 1 );
363 }
364 }
365
366 /**
367 * Get the first id of available product variations by parent id
368 *
369 * @param int|string $parent_id Parent product id.
370 *
371 * @return int|string|null
372 * @since 2.7.11
373 */
374 private function get_first_variation_id( $parent_id ) {
375 $product_id = get_posts( [
376 'post_parent' => $parent_id,
377 'fields' => 'ids',
378 'post_type' => 'product_variation',
379 'post_status' => [ 'private', 'publish' ],
380 'numberposts' => 1,
381 'orderby' => 'menu_order',
382 'order' => 'asc'
383 ] );
384 return !empty( $product_id[ 0 ] ) ? $product_id[ 0 ] : null;
385 }
386 /**
387 * Add default variation to funnel checkout
388 *
389 * @param string|int $product_id Variable parent ID.
390 * @param \WC_Product $product Variable parent product.
391 * @param string|int $quantity Product quantity.
392 *
393 * @return void
394 * @since 2.7.11
395 * @throws \Exception
396 */
397 private function add_default_variation( $product_id, \WC_Product $product, $quantity, $price_type ) {
398 $attributes = $product->get_attributes();
399 $variation_id = null;
400 $default_variation = $product->get_default_attributes();
401 $formatted_variation = [];
402
403 if( sizeof( $attributes ) === sizeof( $default_variation ) ) {
404 $formatted_variation = $this->get_formatted_variation( $default_variation );
405 if( !empty( $formatted_variation ) ) {
406 $variation_id = ( new \WC_Product_Data_Store_CPT() )->find_matching_product_variation(
407 $product,
408 $formatted_variation
409 );
410 }
411 }
412 else {
413 $variation_id = $this->get_first_variation_id( $product_id );
414 }
415
416 if( $variation_id ) {
417 $this->add_variaiton_product_in_cart( $variation_id, $quantity, $price_type, 'variable', $formatted_variation, $product);
418 }
419 }
420
421 /**
422 * Adds a variation product to the cart.
423 *
424 * @param int $variation_id The ID of the variation.
425 * @param int $quantity The quantity of the product to add to the cart.
426 * @param array $formatted_variation The formatted variation array with attribute keys and values.
427 * @param \WC_Product $parent_product (Optional) The parent product object. If not provided, it will be retrieved based on the variation ID.
428 *
429 * @return void
430 * @since 2.7.11
431 */
432 private function add_variaiton_product_in_cart( $variation_id, $quantity, $price_type, $product_type, $formatted_variation = [], $parent_product = null ) {
433 if( !$quantity || !$variation_id ) {
434 return;
435 }
436
437 $parent_id = wc_get_product( $variation_id )->get_parent_id();
438 if( !$parent_product ) {
439 $parent_product = wc_get_product( $parent_id );
440 }
441
442 if( empty( $formatted_variation ) ) {
443 $is_var_incomplete = $this->is_variation_incomplete( $variation_id, $parent_product );
444 $formatted_variation = $is_var_incomplete ? $this->get_complete_variation_format( $variation_id, $parent_product ) : $formatted_variation;
445 }
446 $custom_data = [];
447 if( $price_type == 'original' || $price_type == 'sale' ){
448 $custom_data = [
449 'custom_price' => get_post_meta($variation_id, '_price', true) ? get_post_meta($variation_id, '_price', true) : get_post_meta($variation_id, '_regular_price', true),
450 'product_type' => $product_type
451 ];
452 }else{
453 $custom_data = [
454 'custom_price' => get_post_meta($variation_id, '_regular_price', true) ? get_post_meta($variation_id, '_regular_price', true) : get_post_meta($variation_id, '_price', true),
455 'product_type' => $product_type
456 ];
457
458 }
459 WC()->cart->add_to_cart( $parent_id, $quantity, $variation_id, $formatted_variation, $custom_data );
460 }
461
462
463
464 /**
465 * Formats the variation attributes into a formatted variation array.
466 *
467 * @param array $var_attributes The variation attributes.
468 *
469 * @return array The formatted variation array with attribute keys and values.
470 * @since 2.7.11
471 */
472 private function get_formatted_variation( array $var_attributes ) {
473 $formatted_variation = [];
474
475 foreach( $var_attributes as $key => $value ) {
476 $formatted_variation[ "attribute_{$key}" ] = $value;
477 }
478 return $formatted_variation;
479 }
480
481 /**
482 * Retrieves the complete variation format for a given variation ID and parent product.
483 *
484 * @param int $variation_id The variation ID.
485 * @param \WC_Product $parent_product (Optional) The parent product object. If not provided, it will be retrieved based on the variation ID.
486 *
487 * @return array The formatted variation array with attribute keys and values.
488 * @since 2.7.11
489 */
490 private function get_complete_variation_format( $variation_id, $parent_product = null ) {
491 if( !$variation_id ) {
492 return [];
493 }
494 if( !$parent_product ) {
495 $parent_product = wc_get_product( $variation_id );
496 }
497 $var_product = wc_get_product( $variation_id );
498 $var_attributes = $var_product instanceof \WC_Product ? $var_product->get_attributes() : [];
499 $formatted_variation = [];
500
501 foreach( $var_attributes as $key => $value ) {
502 $value = $value ?: strtolower( $this->get_first_attribute_value( $key, $parent_product ) );
503 $formatted_variation[ "attribute_{$key}" ] = $value;
504 }
505 return $formatted_variation;
506 }
507
508 /**
509 * Retrieves the first value of a specified attribute from a WooCommerce product.
510 *
511 * @param string $key The attribute key.
512 * @param \WC_Product $product The WooCommerce product object.
513 *
514 * @return string The first attribute value, or an empty string if not found.
515 * @since 2.7.11
516 */
517 private function get_first_attribute_value( $key, \WC_Product $product ) {
518 $attribute = $product->get_attribute( $key );
519 if( strpos( $attribute, '|' ) ) {
520 $attribute = explode( '|', $attribute );
521 }
522 else {
523 $attribute = explode( ',', $attribute );
524 }
525 return !empty( $attribute[ 0 ] ) ? trim( $attribute[ 0 ] ) : '';
526 }
527
528 /*============*/
529
530 /**
531 * Update shiiping markup for express checkout
532 *
533 * @since 2.4.18
534 */
535 public function wpfnl_express_checkout_shipping_table_update( $fragments ) {
536 ob_start();
537 require WPFNL_DIR.'/woocommerce/templates/checkout/review-order.php';
538 $woocommerce_shipping_methods = ob_get_clean();
539 $fragments['.woocommerce-checkout-review-order-table'] = $woocommerce_shipping_methods;
540 return $fragments;
541 }
542
543 /**
544 * Render content for wpfunnels_checkout shortcode
545 *
546 * @param $atts
547 *
548 * @return string
549 *
550 * @since 2.0.3
551 */
552 public function render_checkout_shortcode($atts)
553 {
554 $atts = shortcode_atts(
555 array(
556 'id' => 0,
557 ),
558 $atts
559 );
560 $checkout_id = intval($atts['id']);
561 if (is_admin()) {
562 if (0 === $checkout_id && isset($_POST['id'])) {
563 $checkout_id = intval($_POST['id']);
564 }
565 }
566
567 if (empty($checkout_id)) {
568 global $post;
569 if(is_object($post)) {
570 $checkout_id = intval($post->ID);
571 }
572 }
573 if(!$checkout_id) {
574 return '';
575 }
576 $checkout_layout = Wpfnl::get_instance()->meta->get_checkout_meta_value($checkout_id, 'wpfnl_checkout_layout', 'wpfnl-col-2');
577
578 $floating_label = Wpfnl::get_instance()->meta->get_checkout_meta_value($checkout_id, 'wpfnl_floating_label', '');
579
580 $output = '';
581 ob_start();
582
583 do_action('wpfunnels/before_gb_checkout_form', $checkout_id);
584
585 $template_file = WPFNL_DIR . "public/modules/checkout/templates/checkout-template.php";
586 include $template_file;
587
588 do_action('wpfunnels/after_checkout_form', $checkout_id);
589
590 $output .= ob_get_clean();
591 return $output;
592
593 }
594
595
596 public function custom_price_to_cart_item($cart_object)
597 {
598 if (wp_doing_ajax() && !WC()->session->__isset('reload_checkout')) {
599 foreach ($cart_object->cart_contents as $key => $value) {
600 if (isset($value['custom_price'])) {
601 $custom_price = floatval($value['custom_price']);
602 $value['data']->set_price($custom_price);
603 }
604 }
605 }
606 }
607
608 /**
609 * Auto apply coupon on funnel checkout
610 *
611 * @param object $cart_object
612 *
613 * @since 2.7.9
614 * @return void
615 */
616 public function apply_auto_coupon($cart_object)
617 {
618 global $post;
619 if( !$post ){
620 return false;
621 }
622 $checkout_id = '';
623 if ( wp_doing_ajax() || isset( $_GET['wc-ajax'] ) ) {
624 $checkout_id = Wpfnl_functions::get_checkout_id_from_post($_POST);
625 } else {
626 $checkout_id = $post->ID;
627 }
628 if( $checkout_id ){
629 $coupon = Wpfnl_functions::get_applied_coupon( $checkout_id );
630 if( $coupon ){
631 if ( WC()->cart->has_discount( $coupon ) ) return;
632 WC()->cart->apply_coupon( $coupon );
633 wc_print_notices();
634 }
635 }
636
637 }
638
639 public function render_order_bump_popup()
640 {
641 $step_id = get_the_ID();
642 $order_bump = get_post_meta($step_id, 'order-bump', true);
643 $order_bump_settings = get_post_meta($step_id, 'order-bump-settings', true);
644 require_once WPFNL_DIR . 'public/modules/checkout/templates-style/order-bump-template-style3.php';
645 }
646
647
648
649 /**
650 * Insert helper hidden ids
651 *
652 * @since 1.0.0
653 */
654 public function checkout_shortcode_metas()
655 {
656 if (Wpfnl_functions::check_if_this_is_step_type('checkout')) {
657 global $post;
658 $this->step_id = $post->ID;
659 $step = new Wpfnl_Steps_Store_Data();
660 $step->read($this->step_id);
661 $this->funnel_id = $step->get_funnel_id();
662 echo '<input type="hidden" class="input-hidden _wpfunnels_funnel_id" name="_wpfunnels_funnel_id" value="' . intval($this->funnel_id) . '">';
663 echo '<input type="hidden" class="input-hidden _wpfunnels_checkout_id" name="_wpfunnels_checkout_id" value="' . intval($post->ID) . '">';
664 echo '<input type="hidden" class="input-hidden _wpfunnels_order_unique_identifier" name="_wpfunnels_order_unique_identifier" value="' . uniqid() . '">';
665 }
666 }
667
668
669 /**
670 * Next step button ajax
671 *
672 * @since 1.0.0
673 */
674 public function wpfnl_next_button_ajax()
675 {
676 $step_id = sanitize_text_field($_POST['step_id']);
677 $funnel_id = get_post_meta($step_id, '_funnel_id', true);
678 $next_step = Wpfnl_functions::get_next_step($funnel_id, $step_id);
679
680 $url = isset($_POST['url']) ? $_POST['url'] : '';
681 $parts = parse_url($url);
682 $query = [];
683 if( isset($parts['query']) ){
684 parse_str($parts['query'], $query);
685 }
686
687 if (!empty($next_step['step_type']) && 'conditional' == $next_step['step_type']) {
688 $next_step = $this->match_conditional_step($next_step, $funnel_id, $step_id );
689 }
690
691 $next_step = apply_filters( 'wpfunnels/next_step_data', $next_step );
692
693 if ( $next_step ) {
694
695 $custom_url = Wpfnl_functions::custom_url_for_thankyou_page( $next_step['step_id'] );
696 if( $custom_url ){
697 $response = $custom_url;
698 }else{
699 $redirect_url = add_query_arg( $this->prepare_query_param($query), get_the_permalink($next_step['step_id']));
700 if ($redirect_url) {
701 $response = $redirect_url;
702 } else {
703 $response = 'error';
704 }
705 }
706
707 do_action( 'wpfunnels/trigger_cta', $step_id, $funnel_id );
708 wp_send_json($response);
709 }
710 return false;
711 }
712
713
714 /**
715 * Prepare query param for redirect url
716 *
717 * @param String $name
718 * @param Array $query
719 *
720 * @return Array
721 * @since 2.5.9
722 */
723 private function prepare_query_param( $query ){
724 $query_param = [];
725 if( isset( $query['optin'], $query['uname'] ) ){
726 $query_param['optin'] = $query['optin'];
727 $query_param['uname'] = $query['uname'];
728 }
729
730 if( isset($query['wpfnl-order'], $query['wpfnl-key']) ){
731 $query_param['wpfnl-order'] = $query['wpfnl-order'];
732 $query_param['wpfnl-key'] = $query['wpfnl-key'];
733 }
734 return $query_param;
735 }
736
737
738
739 /**
740 * Match ption submit condition
741 *
742 * @param Array $next_step
743 * @param Number $funnel_id
744 *
745 * @return Array $next_step
746 * @since 2.5.7
747 */
748 private function match_conditional_step($next_step, $funnel_id, $step_id )
749 {
750 $condition = Wpfnl_Condition_Checker::getInstance();
751 $condition_identifier = strval($next_step['step_id']);
752 $data['cta'] = 'yes';
753 $condition_matched = $condition->check_condition($funnel_id, $data, $condition_identifier);
754 $next_node = Wpfnl_functions::get_next_step($funnel_id, $condition_identifier, $condition_matched);
755 $next_node = apply_filters('wpfunnels/next_step_data', $next_node);
756 return $next_node;
757 }
758
759
760
761 /**
762 * Calculate Discount.
763 *
764 * @since 1.1.5
765 */
766 public function calculate_custom_price($discount_type, $discount_value, $product_price)
767 {
768 $custom_price = $product_price;
769
770 if (!empty($discount_type)) {
771 if ('discount-percentage' === $discount_type) {
772 if ( $discount_value > 0 && $discount_value <= 100) {
773 $custom_price = $product_price - (($product_price * $discount_value) / 100);
774 }else{
775 $custom_price = $product_price;
776 }
777 } elseif ('discount-price' === $discount_type) {
778 if ($discount_value > 0 && $product_price >= $discount_value ) {
779 $custom_price = $product_price - $discount_value;
780 }else{
781 $custom_price = $product_price;
782 }
783 }
784 }
785
786 return number_format($custom_price, 2);
787 }
788
789 public function wpfnl_update_variation(){
790
791 $variations = $_POST['variations'];
792 $product_id = $_POST['variations'][0]['product_id'];
793 $variation_id = $_POST['variations'][0]['variation_id'];
794 $quantity = $_POST['variations'][0]['quantity'];
795
796 $_product = wc_get_product($variation_id);
797 if( $_product ){
798 $attribute = $_product->get_attributes();
799 foreach ( $attribute as $key => $value) {
800 if( $value ){
801 $formatted_variation['attribute_'.$key] = $value;
802 }else{
803 foreach( $variations as $variation ){
804 if( $variation['attr'] == $key ){
805 $formatted_variation['attribute_'.$key] = $variation['value'];
806 }
807 }
808 }
809 }
810 }
811
812
813 $variation_id = (new \WC_Product_Data_Store_CPT())->find_matching_product_variation(
814 new \WC_Product($product_id),
815 $formatted_variation
816 );
817
818 foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
819 if( !isset($cart_item['product_type'])|| (isset($cart_item['product_type']) && 'single-variation' === $cart_item['product_type']) ){
820 if ($cart_item['product_id'] == $product_id) {
821 WC()->cart->remove_cart_item($cart_item_key);
822 }
823 }
824 }
825 $cart_item_data = [
826 'custom_price' => get_post_meta($variation_id, '_price', true) ? get_post_meta($variation_id, '_price', true) : get_post_meta($variation_id, '_regular_price', true),
827 'product_type' => 'single-variation'
828 ];
829
830 WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $formatted_variation, $cart_item_data);
831 }
832
833
834
835
836
837 /**
838 * Order Bump Ajax Initialized
839 * When you click on add order bump button it will add the product to cart and click again to recover cart
840 *
841 * @since 1.1.
842 */
843 public function wpfnl_get_course_details()
844 {
845 $course_id = filter_input(INPUT_POST, 'course_id', FILTER_VALIDATE_INT);
846 $course_meta = Wpfnl_lms_learndash_functions::get_course_details_by_id($course_id);
847 // ld_update_course_access( 1, $course_id, false );
848 $data = [
849 'status' => 'success',
850 'course' => $course_meta,
851 ];
852
853 wp_send_json( $data );
854
855 }
856
857
858 /**
859 * Order Bump Ajax Initialized
860 * When you click on add order bump button it will add the product to cart and click again to recover cart
861 *
862 * @since 1.1.
863 */
864 public function wpfnl_order_bump_ajax() {
865 $step_id = filter_input( INPUT_POST, 'step_id', FILTER_VALIDATE_INT );
866 $product_id = filter_input( INPUT_POST, 'product', FILTER_VALIDATE_INT );
867 $checker = filter_input( INPUT_POST, 'checker', FILTER_SANITIZE_SPECIAL_CHARS );
868 $quantity = filter_input( INPUT_POST, 'quantity', FILTER_SANITIZE_SPECIAL_CHARS );
869 $key = filter_input( INPUT_POST, 'key', FILTER_SANITIZE_SPECIAL_CHARS );
870 $is_lms = filter_input( INPUT_POST, 'is_lms', FILTER_SANITIZE_SPECIAL_CHARS );
871 $user_id = filter_input( INPUT_POST, 'user_id', FILTER_SANITIZE_SPECIAL_CHARS );
872 $funnel_id = Wpfnl_functions::get_funnel_id_from_step( $step_id );
873 $type = get_post_meta( $funnel_id, '_wpfnl_funnel_type', true );
874 $type = !$type ? 'wc' : $type;
875 $class_object = Wpfnl_Public_Type_Factory::build( $type );
876 if( $class_object ) {
877 $data = $class_object->wpfnl_order_bump_trigger( $step_id, $product_id, $quantity, $key, $user_id, $funnel_id, $checker );
878 if( $type === 'lms' ) {
879 wp_send_json( $data );
880 }
881 elseif( $type === 'wc' ) {
882 add_filter( 'woocommerce_locate_template', [ new Wpfnl_Public(), 'wpfunnels_woocommerce_locate_template' ], 20, 3 );
883 wp_send_json( Wpfnl_functions::get_wc_fragments( $data ) );
884 }
885 }
886 }
887
888
889 /**
890 * Get replaceable orderbump products
891 */
892 private function get_replaceable_ob_products( $ob_settings ){
893
894
895 $replaceable_ob = [];
896 foreach( $ob_settings as $key=>$settings ){
897 if( $settings['isReplace'] === 'yes' ){
898 $replaceable_ob[] = [
899 'id' => $settings['product'],
900 'quantity' => $settings['quantity'],
901 ];
902 }
903 }
904
905 return $replaceable_ob;
906
907 }
908
909
910 /**
911 * Get calculable price
912 *
913 * @param \WC_Product $product
914 * @param $discount_apply
915 *
916 * @return string
917 *
918 * @since 2.0.5
919 */
920 private function get_product_price( \WC_Product $product, $discount_apply = 'regular' ) {
921 $price = $product->get_regular_price();
922 // if( is_plugin_active( 'woocommerce-subscriptions/woocommerce-subscriptions.php' ) ){
923 // $signUpFee = \WC_Subscriptions_Product::get_sign_up_fee( $product );
924 // $price = $price + $signUpFee;
925 // }
926 return $discount_apply === 'sale' && $product->get_sale_price() ? $product->get_sale_price() : $price;
927 }
928
929
930 /**
931 * Add checkout products to cart
932 *
933 * @param $checkout_id
934 *
935 * @throws \Exception
936 */
937 private function add_checkout_products($checkout_id)
938 {
939 $checkout_products = get_post_meta( $checkout_id, '_wpfnl_checkout_products', true );
940 foreach ($checkout_products as $product) {
941 $_product_id = $product['id'];
942 $_qty = $product['quantity'];
943 WC()->cart->add_to_cart($_product_id, $_qty);
944 }
945 }
946
947 /**
948 * Add last updated checkout products to cart
949 *
950 * @param $updated_cart
951 *
952 * @throws \Exception
953 */
954 private function update_checkout_with_last_updated_cart($updated_cart){
955 foreach ($updated_cart as $cart) {
956 WC()->cart->add_to_cart( $cart['product_id'], $cart['quantity'], $cart['variation_id'], $cart['variation'], $cart['line_total']);
957 }
958 }
959
960
961 public function wpfnl_checkout_cart()
962 {
963 $values = [];
964 parse_str(sanitize_text_field($_POST['post_data']), $values);
965 $cart = $values['cart'];
966 foreach ($cart as $cart_key => $cart_value) {
967 WC()->cart->set_quantity($cart_key, $cart_value['qty'], false);
968 WC()->cart->calculate_totals();
969 woocommerce_cart_totals();
970 }
971 wp_die();
972 }
973
974
975 /**
976 * Order Bump Templates
977 *
978 * @param $settings
979 *
980 * @since 1.0.0
981 */
982 public function render_order_bump_template($settings)
983 {
984 if (!empty($settings['selectedStyle'])) {
985 require_once WPFNL_DIR . 'public/modules/checkout/templates-style/order-bump-template-' . $settings['selectedStyle'] . '.php';
986 }
987 }
988
989
990 /**
991 * Display coupon field or not
992 *
993 * @since 2.0.5
994 */
995 public function display_coupon_field() {
996 if ( Wpfnl_functions::check_if_this_is_step_type('checkout') ) {
997 global $post;
998 $checkout_id = $post->ID;
999 $show_coupon = Wpfnl::get_instance()->meta->get_checkout_meta_value( $checkout_id, '_wpfnl_checkout_coupon' );
1000 if( 'no' === $show_coupon ) {
1001 remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_form' );
1002 }
1003 }
1004 }
1005
1006 /**
1007 * Out of Stock message in checkout page
1008 *
1009 * @param $message
1010 * @param $product_data
1011 *
1012 * @return string
1013 */
1014
1015 public function wpfnl_out_of_stock_message_in_checkout( $message, $product_data ){
1016 $message = __( 'Sorry, the following product(s) that you are willing to purchase is out of stock at the moment.', 'wpfnl' );
1017 $image = wp_get_attachment_image_src( get_post_thumbnail_id( $product_data->get_id() ), array( 100, 100) );
1018 $message .= '<div class="wpfnl-checkout-stock-message"><img src="'.$image[0].'"><h4>'.$product_data->get_title().' </h4></div>';
1019 return $message;
1020 }
1021
1022
1023 /**
1024 * Remove Astra theme checkout shipping hook
1025 */
1026 public function remove_astra_theme_checkout_shipping_hook(){
1027 return true;
1028 }
1029
1030
1031 /**
1032 * Update quantity from checkout page
1033 *
1034 * @param $quantity, $cart_item, $cart_item_key
1035 */
1036 public function wpfnl_checkout_cart_item_quantity( $quantity, $cart_item, $cart_item_key ) {
1037
1038 $step_id = 0;
1039 $isQuantity = 'no';
1040
1041 if( wp_doing_ajax() ) {
1042 $step_id = isset($_POST['step_id']) ? $_POST['step_id'] : 0;
1043 } else {
1044 $step_id = get_the_ID();
1045 }
1046
1047
1048 $isQuantity = get_post_meta($step_id, '_wpfnl_quantity_support',true);
1049 $order_bump_product = get_post_meta($step_id,'order-bump-settings',true);
1050
1051 if($isQuantity === 'yes'){
1052 if(isset($order_bump_product['product']) && isset($order_bump_product['isEnabled'])){
1053
1054 if( ($order_bump_product['product'] == $cart_item["product_id"]) && $order_bump_product['isEnabled'] == 'yes' ){
1055 return $quantity;
1056 }
1057 $variations = json_encode($cart_item['variation']);
1058 $product_id = $cart_item["product_id"];
1059 $quantity = $cart_item["quantity"];
1060 $variation_id = $cart_item["variation_id"];
1061 $quantity = "× <input type='number' min='1' value='".$quantity."' class='wpfnl-quantity-setect' data-product-id='".$product_id."' data-variation='".$variations."' data-variation-id='".$variation_id."'/>";
1062 }
1063 }
1064 return $quantity;
1065
1066 }
1067
1068
1069 public function before_checkout_form_actions( $checkout_id ) {
1070
1071 if( Wpfnl_functions::is_wc_active() ){
1072
1073 remove_all_actions( 'woocommerce_checkout_billing' );
1074 remove_all_actions( 'woocommerce_checkout_shipping' );
1075
1076 add_action( 'woocommerce_checkout_billing', array( WC()->checkout, 'checkout_form_billing' ) );
1077 add_action( 'woocommerce_checkout_shipping', array( WC()->checkout, 'checkout_form_shipping' ) );
1078 }
1079
1080 }
1081
1082
1083 /**
1084 * Set checkout ID hidden field in checkout page.
1085 *
1086 * @param array $checkout
1087 *
1088 * @return void
1089 */
1090 public function wpfnl_set_checkout_id( $checkout ) {
1091 global $post;
1092 $checkout_id = 0;
1093 if ( Wpfnl_functions::is_funnel_checkout_page() ) {
1094 if( isset($post->ID) ){
1095 $checkout_id = $post->ID;
1096 }else{
1097 $checkout_id = isset($_POST['step_id']) ? $_POST['step_id'] : '';
1098 }
1099
1100 }
1101 if( $checkout_id ){
1102 echo '<input type="hidden" class="input-hidden _wpfunnels_checkout_id" name="_wpfunnels_checkout_id" value="' . intval( $checkout_id ) . '">';
1103 }
1104 }
1105
1106
1107 /**
1108 * Redirect funnel checkout after login in checkout page
1109 *
1110 * @param $redirect_url
1111 * @param $user
1112 *
1113 * @return false|string
1114 */
1115 public function wpfnl_redirect_after_login( $redirect_url, $user ) {
1116
1117 if (isset($_POST['_wpfunnels_checkout_id'])) {
1118 $funnel_checkout_id = $_POST['_wpfunnels_checkout_id'];
1119 $redirect_url = get_the_permalink($funnel_checkout_id);
1120 }
1121 return $redirect_url;
1122
1123 }
1124
1125
1126 /**
1127 * Get Custom Woocommerce template
1128 *
1129 * @param $template
1130 * @param $template_name
1131 * @param $template_path
1132 *
1133 * @return mixed|string
1134 */
1135
1136 public static function wpfunnels_woocommerce_locate_template($template, $template_name, $template_path)
1137 {
1138 global $woocommerce;
1139 $_template = $template;
1140 $plugin_path = WPFNL_DIR . '/woocommerce/templates/';
1141
1142 if (file_exists($plugin_path . $template_name)) {
1143 $template = $plugin_path . $template_name;
1144 }
1145
1146 if ( ! $template ) {
1147 $template = $_template;
1148 }
1149
1150 return $template;
1151 }
1152
1153
1154 /**
1155 * Discount on checkout
1156 *
1157 * @param $cart_object
1158 */
1159 public function wpfnl_checkout_discount( $cart_object ){
1160 if ( is_admin() && !wp_doing_ajax() ){
1161 return;
1162 }
1163 $step_id = '';
1164
1165 $step_id = Wpfnl_functions::get_checkout_id_from_post( $_POST );
1166
1167 if( !$step_id ){
1168 $step_id = isset($_POST['step_id']) ? $_POST['step_id'] : '';
1169 }
1170 if( $step_id ) {
1171 $funnel_id = Wpfnl_functions::get_funnel_id_from_step( $step_id );
1172 if( $funnel_id ){
1173 $discount_instance = new WpfnlDiscount();
1174 $discount = $discount_instance->get_discount_settings( $step_id );
1175 $main_products = get_post_meta($step_id, '_wpfnl_checkout_products', true );
1176 $is_gbf = get_post_meta( $funnel_id, 'is_global_funnel', true);
1177 if( 'yes' === $is_gbf ){
1178 $main_products = WC()->session->get('wpfunnels_global_funnel_product');
1179 }
1180
1181 $is_main_product_in_cart = false;
1182 foreach( $cart_object->cart_contents as $content ){
1183 $product_id = !empty($content['variation_id']) ? $content['variation_id'] : $content['product_id'];
1184 if( !empty($main_products) && is_array($main_products) ){
1185 $key = array_search($product_id, array_column($main_products, 'id'));
1186 foreach( $main_products as $key=>$main_product ){
1187 if( isset($main_product['id']) ){
1188 $product_obj = wc_get_product( $product_id );
1189 if( $product_obj ){
1190 $_product_id = 'variation' === $product_obj->get_type() ? $product_obj->get_parent_id() : $product_obj->get_id();
1191 $main_product_obj = wc_get_product( $main_product['id'] );
1192 $main_product_id = 'variation' === $main_product_obj->get_type() ? $main_product_obj->get_parent_id() : $main_product_obj->get_id();
1193 if( (int)$main_product_id === $_product_id){
1194 $is_main_product_in_cart = true;
1195 $main_products[$key]['id'] = $product_id;
1196 break;
1197 }
1198 }
1199 }
1200
1201 }
1202 }
1203 if( $is_main_product_in_cart ){
1204 break;
1205 }
1206 }
1207
1208 $total = Wpfnl_functions::calculate_main_product_total( $main_products , $cart_object->cart_contents, $step_id );
1209
1210 if( is_array($discount) && $is_main_product_in_cart ){
1211 if( !isset($discount['discountOptions']) || (isset($discount['discountOptions']) && $discount['discountOptions'] !== 'original') ){
1212
1213 $discount_amount = $discount_instance->get_discount_amount( $discount['discountOptions'], $discount['mutedDiscountValue'], $total );
1214 $discount_amount = filter_var($discount_amount, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);
1215 $discount_amount = '-'.$discount_amount;
1216 $cart_object->add_fee( __('Discount','wpfnl'), $discount_amount, false);
1217 }
1218 }
1219 }
1220 }
1221 }
1222
1223 /**
1224 * Exclude tax from fee
1225 *
1226 * @param Array
1227 * @param String
1228 * @param Obj
1229 *
1230 * @return mix
1231 */
1232 public function exclude_cart_fees_taxes($taxes, $fee, $cart)
1233 {
1234 return [];
1235 if (wc_tax_enabled()) {
1236 if ( wc_prices_include_tax() ) {
1237 return [];
1238 }
1239 }
1240 return $taxes;
1241 }
1242
1243 /**
1244 * Get price type
1245 */
1246 public function get_product_price_type( $funnel_id, $step_id ){
1247
1248 $is_gbf = get_post_meta( $funnel_id, 'is_global_funnel', true );
1249 if( $is_gbf == 'no' || !$is_gbf ){
1250 $discount_instance = new WpfnlDiscount();
1251 $discount = $discount_instance->get_discount_settings( $step_id );
1252 if( is_array($discount) ){
1253 if( $discount['discountOptions'] !== 'original' ){
1254 if( $discount['discountapplyto'] == '' || $discount['discountapplyto'] == 'regular' ){
1255 return 'regular';
1256 }else{
1257 return 'sale';
1258 }
1259 }
1260 }
1261 }
1262 return 'original';
1263 }
1264
1265 /**
1266 * After optin form submition set cookie data
1267 * Use cookes data for checkout billings fields
1268 *
1269 * @param $step_id
1270 * @param $post_action
1271 * @param $action_type
1272 * @param $record
1273 */
1274
1275 public function get_optin_data_checkout($step_id, $post_action, $action_type, $record){
1276 if(isset($record->form_data['data_to_checkout']) && 'yes' == $record->form_data['data_to_checkout']){
1277 /**
1278 * Set Cookie Data
1279 */
1280 $cookie_name = 'wpfunnels_send_data_checkout';
1281 $cookie = isset( $_COOKIE[$cookie_name] ) ? json_decode( wp_unslash( $_COOKIE[$cookie_name] ), true ) : array();
1282 $cookie['after_optin_submit_send_for_checkout'] = ( isset($record->form_data['email']) && $record->form_data['email'] ) ? $record->form_data : false;
1283 ob_start();
1284 setcookie( $cookie_name, wp_json_encode( $cookie ), time() + 3600 * 6, '/', COOKIE_DOMAIN );
1285 ob_end_flush();
1286 }
1287 }
1288
1289 /**
1290 * Get Optin cookes data in checkout fields
1291 *
1292 * @param $fields
1293 *
1294 * @return array
1295 */
1296 public function set_option_data_in_checkout_filed($fields)
1297 {
1298
1299 $cookie_name = 'wpfunnels_send_data_checkout';
1300 $cookie = isset( $_COOKIE[$cookie_name] ) ? json_decode( wp_unslash( $_COOKIE[$cookie_name] ), true ) : array();
1301 if(!empty($cookie)){
1302 if(isset($cookie['after_optin_submit_send_for_checkout'])){
1303 $first_name = isset($cookie['after_optin_submit_send_for_checkout']['first_name']) ? $cookie['after_optin_submit_send_for_checkout']['first_name'] : '';
1304 $last_name = isset($cookie['after_optin_submit_send_for_checkout']['last_name']) ? $cookie['after_optin_submit_send_for_checkout']['last_name'] : '';
1305 $phone = isset($cookie['after_optin_submit_send_for_checkout']['phone']) ? $cookie['after_optin_submit_send_for_checkout']['phone'] : '';
1306 $email = isset($cookie['after_optin_submit_send_for_checkout']['email']) ? $cookie['after_optin_submit_send_for_checkout']['email'] : '';
1307 $fields['billing']['billing_first_name']['default'] = $first_name ;
1308 $fields['billing']['billing_last_name']['default'] = $last_name ;
1309 $fields['billing']['billing_phone']['default'] = $phone ;
1310 $fields['billing']['billing_email']['default'] = $email ;
1311 }
1312 }
1313 return $fields;
1314 }
1315 }