PluginProbe
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster / 1.6.5
SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster v1.6.5
2.7.0 2.6.0 trunk 1.1.0 1.1.4 1.2.1 1.2.2 1.2.3 1.2.5 1.2.9 1.3.1 1.3.2 1.5.0 1.5.1 1.5.4 1.5.7 1.5.8 1.5.9 1.6.2 1.6.5 1.6.8 1.7.2 1.7.4 1.7.5 1.7.9 All 43 releases
sellkit / includes / elementor / modules / checkout / classes / helper.php

helper.php in SellKit – Funnel builder and checkout optimizer for WooCommerce to sell more, faster 1.6.5, at includes/elementor/modules/checkout/classes/helper.php

721 lines 22.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Sellkit\Elementor\Modules\Checkout\Classes;
4
5 defined( 'ABSPATH' ) || exit;
6
7 use Elementor\Plugin as Elementor;
8
9 /**
10 * Helper class.
11 *
12 * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
13 * @SuppressWarnings(PHPMD.NPathComplexity)
14 * @since 1.1.0
15 */
16 class Helper {
17
18 /**
19 * Instance of this class.
20 *
21 * @since NEXT
22 * @access public
23 * @var Checkout
24 */
25 public static $instance;
26
27 /**
28 * Provides access to a single instance of a module using the singleton pattern.
29 *
30 * @since NEXT
31 * @return object
32 */
33 public static function instance() {
34 if ( null === self::$instance ) {
35 self::$instance = new self();
36 }
37
38 return self::$instance;
39 }
40
41 /**
42 * Default sellkit checkout widget billing fields.
43 *
44 * @return array
45 * @since 1.1.0
46 */
47 public function billing_fields() {
48 return [
49 'billing_first_name' => esc_html__( 'Billing First Name', 'sellkit' ),
50 'billing_last_name' => esc_html__( 'Billing Last Name', 'sellkit' ),
51 'billing_company' => esc_html__( 'Billing Company', 'sellkit' ),
52 'billing_address_1' => esc_html__( 'Billing Address 1', 'sellkit' ),
53 'billing_address_2' => esc_html__( 'Billing Address 2', 'sellkit' ),
54 'billing_city' => esc_html__( 'Billing City', 'sellkit' ),
55 'billing_postcode' => esc_html__( 'Billing Postal Code', 'sellkit' ),
56 'billing_country' => esc_html__( 'Billing Country', 'sellkit' ),
57 'billing_state' => esc_html__( 'Billing State', 'sellkit' ),
58 'billing_email' => esc_html__( 'Billing State', 'sellkit' ),
59 'billing_phone' => esc_html__( 'Billing Phone', 'sellkit' ),
60 ];
61 }
62
63 /**
64 * Default sellkit checkout widget shipping fields.
65 *
66 * @return array
67 * @since 1.1.0
68 */
69 public function shipping_fields() {
70 return [
71 'shipping_first_name' => esc_html__( 'shipping First Name', 'sellkit' ),
72 'shipping_last_name' => esc_html__( 'shipping Last Name', 'sellkit' ),
73 'shipping_address_1' => esc_html__( 'shipping Address 1', 'sellkit' ),
74 'shipping_address_2' => esc_html__( 'shipping Address 2', 'sellkit' ),
75 'shipping_city' => esc_html__( 'shipping City', 'sellkit' ),
76 'shipping_postcode' => esc_html__( 'shipping Postal Code', 'sellkit' ),
77 'shipping_country' => esc_html__( 'shipping Country', 'sellkit' ),
78 'shipping_state' => esc_html__( 'shipping State', 'sellkit' ),
79 ];
80 }
81
82 /**
83 * Gets user defined fields and return array of slug.
84 *
85 * @param array $user_defined_fields widget fields.
86 * @param string $type billing/shipping field.
87 * @return array
88 * @since 1.1.0
89 */
90 public function get_user_defined_fields_slug( $user_defined_fields, $type ) {
91 $fields = [];
92
93 foreach ( $user_defined_fields as $field ) {
94 $fields[] = $field[ $type ];
95 }
96
97 return $fields;
98 }
99
100 /**
101 * Assign user defined values to each field.
102 *
103 * @param array $default_fields : default woocommerce fields.
104 * @param array $widget_fields : fields get added by user from widget option.
105 * @param string $type : shipping / billing.
106 * @param array $settings : whole widget settings.
107 * @return array
108 * @since 1.1.0
109 * @SuppressWarnings(PHPMD.NPathComplexity)
110 */
111 public function assign_settings_per_field( $default_fields, $widget_fields, $type, $settings ) {
112 // Assign user properties.
113 foreach ( $widget_fields as $key => $field ) {
114 $field_slug = $field[ $type . '_list_field' ];
115 $is_custom = false;
116
117 // IF field is a custom field we replace key with id. So it will be unique.
118 // !important: user has to define id for each field using custom id field.
119 if ( 'custom_role' === $field_slug ) {
120 // Create billing_bla_bla & shipping_bla_bla for custom field.
121 $field_slug = $type . '_' . $field['_id'];
122
123 if ( ! empty( $field[ $type . '_custom_id' ] ) ) {
124 $field_slug = $type . '_' . $field[ $type . '_custom_id' ];
125 }
126
127 $is_custom = true;
128 }
129
130 $default_fields[ $field_slug ]['label'] = $field[ $type . '_list_placeholder' ];
131 $default_fields[ $field_slug ]['class'] = explode( ' ', $field[ $type . '_list_class' ] ); // phpcs:ignore
132 $default_fields[ $field_slug ]['class'][] = $field[ $type . '_width' ];
133 $default_fields[ $field_slug ]['class'][] = 'sellkit-widget-checkout-fields';
134 $default_fields[ $field_slug ]['class'][] = 'sellkit-checkout-fields-validation-' . $field[ $type . '_list_validation' ];
135 $default_fields[ $field_slug ]['required'] = ( 'yes' === $field[ $type . '_list_required' ] ) ? true : false;
136 $default_fields[ $field_slug ]['clear'] = ( 'yes' === $field[ $type . '_list_clear' ] ) ? true : false;
137 $default_fields[ $field_slug ]['priority'] = ( $key + 1 ) * 10;
138 // Widget defined fields are local. third party plugins's fields are not.
139 $default_fields[ $field_slug ]['local'] = true;
140
141 // Append postal code autocomplete class.
142 if (
143 array_key_exists( 'state_lookup_by_postcode', $settings )
144 && 'yes' === $settings['state_lookup_by_postcode']
145 && ( 'billing_postcode' === $field_slug || 'shipping_postcode' === $field_slug )
146 ) {
147 $default_fields[ $field_slug ]['class'][] = 'post_code_autocomplete';
148 }
149
150 // IF not custom field, go next.
151 if ( false === $is_custom ) {
152 continue;
153 }
154
155 $default_fields = $this->custom_field_setup( $field, $type, $field_slug, $default_fields );
156 }
157
158 foreach ( $default_fields as $key => $details ) {
159 if ( ! array_key_exists( 'local', $details ) || false === $details['local'] ) {
160 $default_fields[ $key ]['priority'] = 500;
161 }
162 }
163
164 return $default_fields;
165 }
166
167 /**
168 * Setup custom field options and assign required things to custom fields.
169 * also helps to reduce assign_settings_per_field method complexity.
170 *
171 * @param array $field html string of checkout fields.
172 * @param string $type type of checkout fields.
173 * @param string $field_slug unique sluf per field.
174 * @param array $default_fields default checkout fields.
175 * @return array
176 * @since 1.1.0
177 */
178 private function custom_field_setup( $field, $type, $field_slug, $default_fields ) {
179 $tag = $field[ $type . '_custom_type' ];
180
181 // Set default options.
182 $default_fields[ $field_slug ]['class'][] = ( $field[ $type . '_width' ] ) ? $field[ $type . '_width' ] : 'w-100';
183 $default_fields[ $field_slug ]['type'] = ( $field[ $type . '_custom_type' ] ) ? $field[ $type . '_custom_type' ] : 'text';
184 $default_fields[ $field_slug ]['default'] = $field[ $type . '_custom_value' ];
185
186 // Convert select to multiselect.
187 if ( 'multiselect' === $tag ) {
188 $default_fields[ $field_slug ]['type'] = 'multiselect';
189 }
190
191 // Assign one extra class to style radio group wrapper.
192 if ( 'radio' === $tag ) {
193 $default_fields[ $field_slug ]['type'] = 'radio';
194 $default_fields[ $field_slug ]['class'][] = 'radio-group-wrapper';
195 $default_fields[ $field_slug ]['mode'] = $field[ $type . '_radio_field_mode' ];
196 }
197
198 // Check if checkbox must be checked on default.
199 if ( 'checkbox' === $tag ) {
200 $default_fields[ $field_slug ]['checked'] = $field[ $type . '_checkbox_custom_value' ];
201 }
202
203 // Assign options.
204 $tags = [ 'select', 'multiselect', 'radio' ];
205 if ( in_array( $tag, $tags, true ) ) {
206 $options = $this->convert_value_to_array( $field[ $type . '_custom_options' ] );
207
208 $default_fields[ $field_slug ]['options'] = $options;
209 }
210
211 return $default_fields;
212 }
213
214 /**
215 * Gets widget options string and convert it to array to be used for select / radio and etc.
216 *
217 * @param string $value string of options.
218 * @return array
219 * @since 1.1.0
220 */
221 private function convert_value_to_array( $value ) {
222 $array = [];
223 $values = preg_split( '/\r\n|\r|\n/', $value );
224
225 foreach ( $values as $option ) {
226 $split = explode( ':', $option );
227 $array[ $split[0] ] = $split[1];
228 }
229
230 return $array;
231 }
232
233 /**
234 * Is used to validate user defined custom fields after pressing place order button at checkout page.
235 * Validate both custom shipping and billing fields at once if exists.
236 *
237 * @uses sellkit_Core\Raven\Modules\Checkout\Classes\Global_Hooks::validate_user_defined_fields
238 * @param array $shipping_fields custom shipping fields.
239 * @param array $billing_fields custom billing fields.
240 * @return void
241 * @since 1.1.0
242 */
243 public function validate_user_defined_fields( $shipping_fields, $billing_fields ) {
244 foreach ( $shipping_fields as $data ) {
245 // Escape all if cart does not need shipping information.
246 if ( ! WC()->cart->needs_shipping() ) {
247 continue;
248 }
249
250 $final_name = isset( $data['shipping_list_field'] ) ? $data['shipping_list_field'] : '';
251
252 if ( 'custom_role' === $final_name ) {
253 $final_name = 'shipping_' . $data['_id'];
254
255 if ( ! empty( $data['shipping_custom_id'] ) ) {
256 $id = $data['shipping_custom_id'];
257 $final_name = "shipping_$id";
258 }
259 }
260
261 // Get $name variable from label or placeholder and/or id to be used in validate error.
262 $label = $this->create_name_for_errors( $data, __( 'Shipping', 'sellkit' ), 'shipping', $final_name );
263
264 // Field value.
265 $value = filter_input( INPUT_POST, $final_name, FILTER_DEFAULT );
266
267 // #1. Required validation.
268 $is_required = ( ! empty( $data['shipping_list_required'] ) && 'yes' === $data['shipping_list_required'] ) ? true : false;
269
270 if ( true === $is_required && ( ! array_key_exists( $final_name, $_POST ) || empty( $value ) ) ) { // phpcs:ignore
271 /* translators: %s field_name. */
272 wc_add_notice( sprintf( __( '%s is a required field.', 'sellkit' ), '<strong>' . $label . '</strong>' ), 'error' );
273 }
274
275 // #2. Phone validation.
276 $this->phone_validation( $data, $final_name, 'shipping', $label );
277
278 // #3. Postcode validation.
279 $this->postcode_validation( $data, $final_name, 'shipping', $label );
280 }
281
282 foreach ( $billing_fields as $data ) {
283 $final_name = $data['billing_list_field'];
284
285 if ( 'custom_role' !== $final_name ) {
286 continue;
287 }
288
289 $final_name = 'billing_' . $data['_id'];
290
291 if ( ! empty( $data['billing_custom_id'] ) ) {
292 $id = $data['billing_custom_id'];
293 $final_name = "billing_$id";
294 }
295
296 // Get $name variable from label or placeholder and/or id to be used in validate error.
297 $label = $this->create_name_for_errors( $data, __( 'Billing', 'sellkit' ), 'billing', $final_name );
298
299 // Field value.
300 $value = filter_input( INPUT_POST, $final_name, FILTER_DEFAULT );
301
302 // #1. Required validation.
303 $is_required = ( ! empty( $data['billing_list_required'] ) && 'yes' === $data['billing_list_required'] ) ? true : false;
304
305 if ( true === $is_required && empty( $value ) ) { // phpcs:ignore
306 /* translators: %s field_name. */
307 wc_add_notice( sprintf( __( '%s is a required field.', 'sellkit' ), '<strong>' . $label . '</strong>' ), 'error' );
308 }
309
310 // #2. phone validation.
311 $this->phone_validation( $data, $final_name, 'billing', $label );
312
313 // #3. Postcode validation.
314 $this->postcode_validation( $data, $final_name, 'billing', $label );
315 }
316
317 // Validate main checkout email.
318 $email = filter_input( INPUT_POST, 'billing_email', FILTER_SANITIZE_EMAIL );
319 $valid = filter_var( $email, FILTER_VALIDATE_EMAIL );
320
321 if ( ! $email ) {
322 /* translators: %s field_name. */
323 wc_add_notice( sprintf( __( '%s is a required field.', 'sellkit' ), '<strong>' . __( 'Email address', 'sellkit' ) . '</strong>' ), 'error' );
324 return;
325 }
326
327 if ( ! $valid ) {
328 /* translators: %s field_name. */
329 wc_add_notice( sprintf( __( '%s is not a valid email.', 'sellkit' ), '<strong>' . __( 'Email address', 'sellkit' ) . '</strong>' ), 'error' );
330 }
331 }
332
333 /**
334 * Create name for each field to be used in errors text.
335 *
336 * @param array $data field data.
337 * @param string $display_type shipping / billing with text-domain.
338 * @param string $type shipping / billing.
339 * @param string $final_name field key.
340 * @return string
341 * @since 1.1.0
342 */
343 private function create_name_for_errors( $data, $display_type, $type, $final_name ) {
344 $name = $data[ $type . '_list_placeholder' ];
345
346 if ( empty( $data[ $type . '_list_placeholder' ] ) ) {
347 $name = $data[ $type . '_list_label' ];
348 }
349
350 $label = $display_type . ' ' . $name;
351
352 if ( empty( $name ) ) {
353 $label = $final_name;
354 }
355
356 return $label;
357 }
358
359 /**
360 * Validate phone number using woocommerce way.
361 *
362 * @see woocommerce/includes/class-wc-validation.php
363 * @param array $data widget field data.
364 * @param string $final_name key of field in checkout form.
365 * @param string $type shipping/billing.
366 * @param string $label field label for error.
367 * @return boolean
368 * @since 1.1.0
369 */
370 private function phone_validation( $data, $final_name, $type, $label ) {
371 if ( ! array_key_exists( $type . '_list_validation', $data ) || 'phone' !== $data[ $type . '_list_validation' ] ) {
372 return true;
373 }
374
375 $phone = filter_input( INPUT_POST, $final_name, FILTER_DEFAULT );
376 $valid = \WC_Validation::is_phone( $phone );
377
378 if ( ! $valid ) {
379 /* translators: %s field_name. */
380 wc_add_notice( sprintf( __( '%s is not a valid phone.', 'sellkit' ), '<strong>' . $label . '</strong>' ), 'error' );
381 }
382 }
383
384 /**
385 * Validate postcode using woocommerce way.
386 *
387 * @param array $data field data.
388 * @param string $final_name field key in checkout form.
389 * @param string $type shipping / billing.
390 * @param string $label field label to be used in error text.
391 * @return void
392 * @since 1.1.0
393 */
394 private function postcode_validation( $data, $final_name, $type, $label ) {
395 if ( ! array_key_exists( $type . '_list_validation', $data ) || 'postcode' !== $data[ $type . '_list_validation' ] ) {
396 return;
397 }
398
399 $postcode = filter_input( INPUT_POST, $final_name, FILTER_DEFAULT );
400 $country = filter_input( INPUT_POST, $type . '_country' );
401 $postcode = wc_format_postcode( $postcode, $country );
402 $valid = \WC_Validation::is_postcode( $postcode, $country );
403
404 if ( ! $valid ) {
405 /* translators: %s field_name. */
406 wc_add_notice( sprintf( __( '%s is not a valid postcode.', 'sellkit' ), '<strong>' . $label . '</strong>' ), 'error' );
407 }
408 }
409
410 /**
411 * Is used to save user defined custom fields in database for the current order id.
412 * save both billing and shipping custom fields at once if exists.
413 *
414 * @uses sellkit_Core\Raven\Modules\Checkout\Classes\Global_Hooks::save_user_defined_fields
415 * @param array $shipping_fields custom shipping fields.
416 * @param array $billing_fields custom billing fields.
417 * @param int $order_id order id.
418 * @return void
419 * @since 1.1.0
420 */
421 public function save_user_defined_fields( $shipping_fields, $billing_fields, $order_id ) {
422 // We store saved fields in this array and save keys as a meta for this order, to use it later.
423 $saved_fields = [];
424
425 foreach ( $shipping_fields as $field ) {
426 if ( empty( $field['shipping_custom_id'] ) ) {
427 continue;
428 }
429
430 $item = $this->prepare_custom_fields_to_save( $field, 'shipping' );
431 $final_name = $item['key_name'];
432
433 // Field value.
434 $value = sellkit_htmlspecialchars( INPUT_POST, $final_name );
435 if ( 'multiselect' === $field['shipping_custom_type'] ) {
436 $value = filter_input( INPUT_POST, $final_name, FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
437 }
438
439 // Some user defined field might be not required ( & empty ). so again we check if field is has value save it.
440 if ( ! empty( $value ) ) { // phpcs:ignore
441 update_post_meta( $order_id, $final_name, sanitize_text_field( $value ) ); // phpcs:ignore
442 array_push( $saved_fields, $item );
443 }
444 }
445
446 foreach ( $billing_fields as $field ) {
447 if ( empty( $field['billing_custom_id'] ) ) {
448 continue;
449 }
450
451 $item = $this->prepare_custom_fields_to_save( $field, 'billing' );
452 $final_name = $item['key_name'];
453
454 // Field value.
455 $value = sellkit_htmlspecialchars( INPUT_POST, $final_name );
456 if ( 'multiselect' === $field['billing_custom_type'] ) {
457 $value = filter_input( INPUT_POST, $final_name, FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
458 }
459
460 // Some user defined field might be not required ( & empty ). so again we check if field has value save it.
461 if ( ! empty( $value ) ) { // phpcs:ignore
462 update_post_meta( $order_id, $final_name, sanitize_text_field( $value ) ); // phpcs:ignore
463 array_push( $saved_fields, $item );
464 }
465 }
466
467 // Save id of those custom fields that are validate and has value as an meta for order to be used later.
468 if ( count( $saved_fields ) > 0 ) {
469 update_post_meta( $order_id, 'sellkit_checkout_widget_custom_field_of_order', $saved_fields );
470 }
471 }
472
473 /**
474 * The way to save custom fields names as array for order as meta to be used later.
475 *
476 * @param array $data sent data from checkout.
477 * @param string $type shippin/billing.
478 * @return array
479 * @since 1.1.0
480 */
481 private function prepare_custom_fields_to_save( $data, $type ) {
482 $id = $data[ $type . '_custom_id' ];
483 $final_name = $type . '_' . $id;
484 $item = [
485 'show_in_thank_you' => ( 'yes' === $data[ $type . '_show_in_thankyou' ] ) ? 'yes' : 'no',
486 'show_in_email' => ( 'yes' === $data[ $type . '_show_in_order_mail' ] ) ? 'yes' : 'no',
487 'key_name' => $final_name,
488 ];
489
490 return $item;
491 }
492
493 /**
494 * Convert required fields to optional based on widget options.
495 * will be called after clicking place order button.
496 *
497 * @uses sellkit_Core\Raven\Modules\Checkout\Classes\Global_Hooks::validate_user_defined_fields
498 * @param array $widget_shipping_fields user defined fields in widget.
499 * @param array $widget_billing_fields user defined fields in widget.
500 * @return void
501 * @since 1.1.0
502 */
503 public function make_sure_to_convert_required_field_to_optional( $widget_shipping_fields, $widget_billing_fields ) {
504 add_filter( 'woocommerce_checkout_fields', function( $default_fields ) use ( $widget_shipping_fields, $widget_billing_fields ) {
505 // Make phone field optional at beginning.
506 $default_fields['billing']['billing_phone']['required'] = false;
507 unset( $default_fields['billing']['billing_email'] );
508
509 // Make it optional.
510 foreach ( $widget_billing_fields as $data ) {
511 $slug = $data['billing_list_field'];
512 $is_required = false;
513
514 if ( 'custom_role' === $slug ) {
515 continue;
516 }
517
518 if ( ! empty( $data['billing_list_required'] ) && 'yes' === $data['billing_list_required'] ) {
519 $is_required = true;
520 }
521
522 $default_fields['billing'][ $slug ]['required'] = $is_required;
523 }
524
525 foreach ( $widget_shipping_fields as $data ) {
526 $slug = isset( $data['shipping_list_field'] ) ? $data['shipping_list_field'] : '';
527 $is_required = false;
528
529 if ( 'custom_role' === $slug ) {
530 continue;
531 }
532
533 if ( ! empty( $data['shipping_list_required'] ) && 'yes' === $data['shipping_list_required'] ) {
534 $is_required = true;
535 }
536
537 $default_fields['shipping'][ $slug ]['required'] = $is_required;
538 }
539
540 return $default_fields;
541 } );
542 }
543
544 /**
545 * Retrieve required widget settings of current checkout widget.
546 *
547 * @param int $post_id page id.
548 * @param string $form_id form id.
549 * @return array
550 * @since 1.1.0
551 */
552 public function retrieve_checkout_widget_settings( $post_id, $form_id ) {
553 $form_meta = Elementor::$instance->documents->get( $post_id )->get_elements_data();
554 $form = self::find_element_recursive( $form_meta, $form_id );
555
556 if ( ! is_array( $form ) || ! array_key_exists( 'settings', $form ) ) {
557 return [];
558 }
559
560 $settings = $form['settings'];
561
562 return $settings;
563 }
564
565 /**
566 * Find elementor element.
567 * Code block copied from sellkit-core directly.
568 *
569 * @param array $elements elements of elementor.
570 * @param string $form_id elementor form id.
571 * @return array
572 * @since 1.1.0
573 */
574 public static function find_element_recursive( $elements, $form_id ) {
575 foreach ( $elements as $element ) {
576 if ( $form_id === $element['id'] ) {
577 return $element;
578 }
579
580 if ( ! empty( $element['elements'] ) ) {
581 $element = self::find_element_recursive( $element['elements'], $form_id );
582
583 if ( $element ) {
584 return $element;
585 }
586 }
587 }
588
589 return false;
590 }
591
592 /**
593 * Hide checkout order product quantity input and show raw quantity.
594 *
595 * @param string $input_html default quantity input.
596 * @param int $quantity product quantity in cart.
597 * @since 1.1.0
598 * @return void
599 *
600 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
601 */
602 public function checkout_order_hidden_quantity( $input_html, $quantity ) {
603 echo sprintf(
604 /** Translators: %s: product quantity */
605 '<strong class="product-quantity"> <i class="fa fa-times" aria-hidden="true"></i>%s</strong>',
606 esc_html( $quantity )
607 );
608 }
609
610 /**
611 * Calculate item discount.
612 *
613 * @param int $id product id.
614 * @param string $type discount type.
615 * @param int $value discount value.
616 * @return int|boolean
617 * @since 1.2.8
618 */
619 public static function calculate_discount( $id, $type, $value ) {
620 if ( false === $type && false === $value ) {
621 return false;
622 }
623
624 $product = wc_get_product( $id );
625 $regular = $product->get_regular_price();
626 $sale = $product->get_sale_price();
627 $price = false;
628
629 if ( strpos( $type, 'sale' ) !== false ) {
630 $discount = ( 'fixed-sale' === $type ) ? floatval( $value ) : ( floatval( $sale ) * floatval( $value ) ) / 100;
631 $discount = floatval( $sale ) - $discount;
632
633 return ( $discount > 0 ) ? $discount : 0;
634 }
635
636 if ( strpos( $type, 'sale' ) === false ) {
637 $discount = ( 'fixed' === $type ) ? floatval( $value ) : ( floatval( $regular ) * floatval( $value ) ) / 100;
638 $discount = floatval( $regular ) - $discount;
639
640 return ( $discount > 0 ) ? $discount : 0;
641 }
642
643 return $price;
644 }
645
646 /**
647 * Add extra js in editor mode.
648 *
649 * @since 1.1.0
650 * @return void
651 */
652 public function editor_mode_extra_js() {
653 ?>
654 <script>
655 jQuery( document ).on( 'mousemove', function() {
656 $( '.sellkit-coupon-toggle' ).off( 'click' ).on( 'click', function() {
657 let direction = 'row';
658 const status = $( '.sellkit-custom-coupon-form' ).css( 'display' );
659 let displayValue = '';
660
661 if ( $( window ).width() < 600 ) {
662 direction = 'column';
663 }
664
665 if ( 'none' === status ) {
666 displayValue = 'inline-flex';
667 } else {
668 displayValue = 'none';
669 }
670
671 $( '.sellkit-custom-coupon-form' ).css( {
672 display: displayValue,
673 flexDirection: direction,
674 } );
675 } );
676 } );
677 </script>
678 <?php
679 }
680
681 /**
682 * Assigning checkout ajax default shipping fields after ajax is sent.
683 *
684 * @param array $post post request.
685 * @param array $clear checkout form data.
686 * @return array
687 * @since 1.2.8
688 */
689 public function assigning_default_ajax_shipping_fields( $post, $clear ) {
690 if ( array_key_exists( 'billing_state', $clear ) ) {
691 $post['state'] = $clear['billing_state'];
692 }
693
694 if ( array_key_exists( 'shipping_country', $clear ) ) {
695 $post['s_country'] = $clear['shipping_country'];
696 }
697
698 if ( array_key_exists( 'shipping_state', $clear ) ) {
699 $post['s_state'] = $clear['shipping_state'];
700 }
701
702 if ( array_key_exists( 'shipping_postcode', $clear ) ) {
703 $post['s_postcode'] = $clear['shipping_postcode'];
704 }
705
706 if ( array_key_exists( 'shipping_city', $clear ) ) {
707 $post['s_city'] = $clear['shipping_city'];
708 }
709
710 if ( array_key_exists( 'shipping_address_1', $clear ) ) {
711 $post['s_address'] = $clear['shipping_address_1'];
712 }
713
714 if ( array_key_exists( 'shipping_address_2', $clear ) ) {
715 $post['s_address_2'] = $clear['shipping_address_2'];
716 }
717
718 return $post;
719 }
720 }
721