PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 1.2.1
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v1.2.1
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 1.8.1 All 42 releases
sellkit / includes / funnel / steps / checkout.php

checkout.php in SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster 1.2.1, at includes/funnel/steps/checkout.php

271 lines 6.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Sellkit\Funnel\Steps;
4
5 use Sellkit\Funnel\Analytics\Data_Updater;
6 use Sellkit_Funnel;
7
8 defined( 'ABSPATH' ) || die();
9
10 /**
11 * Class Sellkit_Checkout.
12 *
13 * @since 1.1.0
14 */
15 class Checkout {
16
17 /**
18 * Funnel instance.
19 *
20 * @var Sellkit_Funnel Funnel object.
21 * @since 1.1.0
22 */
23 public $funnel;
24
25 /**
26 * Checkout constructor.
27 *
28 * @since 1.1.0
29 */
30 public function __construct() {
31 $this->update_funnel_data();
32
33 if ( empty( $this->funnel->funnel_id ) ) {
34 return;
35 }
36
37 add_action( 'woocommerce_checkout_create_order', [ $this, 'save_order_custom_meta_data' ], 10 );
38 add_action( 'woocommerce_after_order_notes', [ $this, 'custom_checkout_hidden_fields' ], 10 );
39 add_action( 'wc_ajax_update_order_review', [ $this, 'do_actions' ] );
40 }
41
42 /**
43 * Adding items to the checkout page.
44 *
45 * @since 1.1.0
46 * @SuppressWarnings(PHPMD.NPathComplexity)
47 * @SuppressWarnings(PHPMD.CyclomaticComplexity)
48 */
49 public function do_actions() {
50 // These variables should be used in checkout builder widget.
51 $funnel_data = $this->funnel->current_step_data;
52 $optimization_data = ! empty( $funnel_data['data']['optimization'] ) ? $funnel_data['data']['optimization'] : '';
53 $redirect_url = ! empty( $optimization_data['closed_checkout_redirect_url'] ) ? $optimization_data['closed_checkout_redirect_url'] : site_url();
54
55 add_action( 'template_redirect', function () use ( $funnel_data ) {
56 $product_settings = ! empty( $funnel_data['data']['products']['settings'] ) ? $funnel_data['data']['products']['settings'] : '';
57 $bump_data = ! empty( $funnel_data['bump'] ) ? $funnel_data['bump'] : '';
58
59 if ( ! empty( $product_settings ) ) {
60 set_query_var( 'funnel_product_settings', $product_settings );
61 }
62
63 if ( ! empty( $bump_data ) ) {
64 $bump_data = $this->get_valid_bumps( $bump_data );
65
66 set_query_var( 'bump_data', $bump_data );
67 }
68 } );
69
70 if (
71 ! empty( $optimization_data['expiration_date'] ) &&
72 ! empty( $optimization_data['expire_checkout_coupons_switch'] ) &&
73 time() > $optimization_data['expiration_date'] &&
74 'on' === $optimization_data['expire_checkout_coupons_switch']
75 ) {
76 wp_redirect( $redirect_url ); // phpcs:ignore
77 exit;
78 }
79
80 if ( empty( $funnel_data ) ) {
81 return;
82 }
83
84 if (
85 empty( $funnel_data['data']['products']['list'] ) ||
86 ! is_array( $funnel_data['data']['products']['list'] )
87 ) {
88 return;
89 }
90
91 $funnel_products = $funnel_data['data']['products']['list'];
92
93 $action = sellkit_htmlspecialchars( INPUT_GET, 'wc-ajax' );
94
95 if ( 'update_order_review' !== $action && 'checkout' !== $action ) {
96 wc()->cart->empty_cart();
97
98 foreach ( $funnel_products as $product_id => $product ) {
99 $quantity = ! empty( $product['quantity'] ) ? $product['quantity'] : 1;
100
101 wc()->cart->add_to_cart( $product_id, $quantity );
102 }
103 }
104
105 foreach ( wc()->cart->get_cart() as $cart_item ) {
106 $price = $cart_item['data']->get_regular_price();
107 $product_id = $cart_item['product_id'];
108
109 if ( empty( $funnel_products[ $product_id ] ) && empty( $funnel_products[ $cart_item['variation_id'] ] ) ) {
110 continue;
111 }
112
113 $discount_info = ! empty( $funnel_products[ $cart_item['variation_id'] ] ) ? $funnel_products[ $cart_item['variation_id'] ] : $funnel_products[ $product_id ];
114 $discount_value = $this->calculate_discount( $price, $discount_info['discount'], $discount_info['discountType'] );
115
116 $cart_item['data']->set_price( floatval( $price ) - ( floatval( $discount_value ) ) );
117 }
118
119 if ( empty( $optimization_data ) ) {
120 return;
121 }
122
123 if ( $this->apply_coupon_validation( $optimization_data ) ) {
124 foreach ( $optimization_data['auto_apply_coupons'] as $auto_apply_coupon ) {
125 wc()->cart->add_discount( get_the_title( $auto_apply_coupon['value'] ) );
126 }
127
128 wc_clear_notices();
129 }
130 }
131
132 /**
133 * Saving the funnel data to the order.
134 *
135 * @since 1.1.0
136 * @param object $order Order object.
137 */
138 public function save_order_custom_meta_data( $order ) {
139 if ( empty( $this->funnel->next_step_data ) ) {
140 return;
141 }
142
143 $analytics_updater = new Data_Updater();
144
145 $analytics_updater->set_funnel_id( $this->funnel->funnel_id );
146 $analytics_updater->add_new_order_log( $order );
147
148 $order->update_meta_data( 'sellkit_funnel_next_step_data', $this->funnel->next_step_data );
149 }
150
151 /**
152 * Adding page id field to the inputs.
153 *
154 * @since 1.1.0
155 */
156 public function custom_checkout_hidden_fields() {
157 woocommerce_form_field( 'sellkit_current_page_id', [
158 'type' => 'hidden',
159 'class' => [ 'hidden form-row-wide' ],
160 ], get_the_ID() );
161 }
162
163 /**
164 * Check If a coupon should be applied.
165 *
166 * @since 1.1.0
167 * @param array $optimization_data Optimization data.
168 */
169 public function apply_coupon_validation( $optimization_data ) {
170 if (
171 empty( $optimization_data['auto_apply_coupons_switch'] ) ||
172 'on' !== $optimization_data['auto_apply_coupons_switch']
173 ) {
174 return false;
175 }
176
177 if (
178 empty( $optimization_data['auto_apply_coupons'] ) ||
179 ! is_array( $optimization_data['auto_apply_coupons'] )
180 ) {
181 return false;
182 }
183
184 return true;
185 }
186
187 /**
188 * Calculate total discount.
189 *
190 * @since 1.1.0
191 * @param string $total Total.
192 * @param string $value Value.
193 * @param string $type Type.
194 * @return false|float|int|mixed
195 */
196 public function calculate_discount( $total, $value, $type ) {
197 if ( 'fixed' === $type ) {
198 return $value;
199 }
200
201 if ( 'percentage' === $type ) {
202 return ( floatval( $total ) * floatval( $value ) ) / 100;
203 }
204
205 return 0;
206 }
207
208 /**
209 * Gets extracted post data.
210 *
211 * @since 1.1.0
212 * @param string $post_data Post data.
213 */
214 private function get_current_page_id_by_post_data( $post_data ) {
215 $vars = explode( '&', $post_data );
216 $extracted_data = [];
217
218 foreach ( $vars as $value ) {
219 $result = explode( '=', urldecode( $value ) );
220 $extracted_data[ $result[0] ] = $result[1];
221 }
222
223 if ( empty( $extracted_data['sellkit_current_page_id'] ) ) {
224 return null;
225 }
226
227 return $extracted_data['sellkit_current_page_id'];
228 }
229
230 /**
231 * Checks all bumps and return data.
232 *
233 * @since 1.1.0
234 * @param array $bump_data Bump data.
235 */
236 public function get_valid_bumps( $bump_data ) {
237 $valid_bumps = [];
238
239 foreach ( $bump_data as $bump ) {
240 $conditions = ! empty( $bump['data']['conditions'] ) ? $bump['data']['conditions'] : '';
241
242 if ( ! empty( $conditions ) && empty( sellkit_conditions_validation( $conditions ) ) ) {
243 continue;
244 }
245
246 $valid_bumps[] = $bump;
247 }
248
249 return $valid_bumps;
250 }
251
252 /**
253 * Updates funnel data.
254 *
255 * @since 1.1.0
256 */
257 public function update_funnel_data() {
258 $action = sellkit_htmlspecialchars( INPUT_GET, 'wc-ajax' );
259
260 if ( 'update_order_review' === $action ) {
261 $post_data = sellkit_htmlspecialchars( INPUT_POST, 'post_data' );
262
263 $this->funnel = new Sellkit_Funnel( $this->get_current_page_id_by_post_data( $post_data ) );
264
265 return;
266 }
267
268 $this->funnel = Sellkit_Funnel::get_instance();
269 }
270 }
271