PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 1.3.1
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v1.3.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.3.1, at includes/funnel/steps/checkout.php

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