PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.3.21
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.3.21
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
fluent-cart / app / Helpers / CartCheckoutHelper.php

CartCheckoutHelper.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.3.21, at app/Helpers/CartCheckoutHelper.php

941 lines 30.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCart\App\Helpers;
4
5 use FluentCart\Api\Resource\CustomerResource;
6 use FluentCart\Api\Resource\FrontendResource\CartResource;
7 use FluentCart\Api\Resource\FrontendResource\CustomerAddressResource;
8 use FluentCart\Api\Resource\ProductResource;
9 use FluentCart\Api\StoreSettings;
10 use FluentCart\App\App;
11 use FluentCart\App\Models\Cart;
12 use FluentCart\App\Models\Customer;
13 use FluentCart\App\Models\ProductVariation;
14 use FluentCart\App\Services\CheckoutService;
15 use FluentCart\App\Services\Localization\LocalizationManager;
16 use FluentCart\App\Services\OrderService;
17 use FluentCart\Framework\Database\Orm\Builder;
18 use FluentCart\Framework\Database\Orm\Model;
19 use FluentCart\Framework\Support\Arr;
20 use FluentCart\Framework\Support\ArrayableInterface;
21 use FluentCart\Framework\Support\Collection;
22
23 class CartCheckoutHelper implements ArrayableInterface
24 {
25 private $cart;
26
27 private ?array $utmData = [];
28
29 private ?array $checkoutData = [];
30
31 protected ?StoreSettings $storeSettings = null;
32
33 static $instance = false;
34
35 protected array $couponDiscountData = [];
36
37
38 public bool $disableCoupon = false;
39
40 public function __construct($disableCoupon = false)
41 {
42 $this->disableCoupon = $disableCoupon;
43 $this->init();
44 }
45
46 public static function make($disableCoupon = false): ?CartCheckoutHelper
47 {
48 static $instance = null;
49
50 if (!$instance) {
51 $instance = new self($disableCoupon);
52 }
53
54 return $instance;
55 }
56
57
58 public function init()
59 {
60
61 $this->storeSettings = new StoreSettings();
62 $cart = CartHelper::getCart();
63
64 if (!$cart) {
65 return;
66 }
67
68 $this->cart = $cart;
69
70 $this->validateCartItems();
71
72 if (
73 Arr::get($this->cart->checkout_data, 'disable_coupons') == 'yes' ||
74 $this->disableCoupon
75 ) {
76 return;
77 }
78
79 $this->applyCoupon();
80 }
81
82 public function hasSubscription(): string
83 {
84 $currentCart = $this->getCart();
85 if (!empty($currentCart->cart_data)) {
86 foreach ($currentCart->cart_data as $key => $value) {
87 if (Arr::get($value, 'other_info.payment_type') === 'subscription') {
88 return 'yes';
89 };
90 }
91 }
92 return 'no';
93 }
94
95 public function isZeroPayment(): bool
96 {
97 return $this->getItemsAmountTotal(false, false) <= 0 && $this->hasSubscription() !== 'yes';
98 }
99
100 protected function applyCoupon()
101 {
102 $this->couponDiscountData = $this->cart->getDiscountLines();
103 }
104
105 public function getCouponDiscountData(): array
106 {
107 return $this->cart->getDiscountLines();
108 }
109
110 public function getAppliedCouponCodes(): array
111 {
112 return $this->cart->coupons ?? [];
113 }
114
115 public function setCouponDiscountData(array $data)
116 {
117 $this->couponDiscountData = $data;
118 }
119
120 public function validateCartItems()
121 {
122
123 $variationIds = (new Collection($this->getItems()))->pluck('id')->toArray();
124 $variations = ProductVariation::query()
125 ->with(['product.detail', 'media'])
126 ->whereIn('id', $variationIds)->get();
127
128 $newCartItems = [];
129
130 // foreach ($variations as $variation) {
131 // if (isset($this->cart->cart_data[$variation->id])) {
132 // $quantity = Arr::get($this->cart->cart_data[$variation->id], 'quantity');
133 // $item = CartHelper::generateCartItemFromVariation($variation, $quantity);
134 // $newCartItems[$variation->id] = $item;
135 // }
136 //
137 // }
138 //
139 // $this->cart->cart_data = $newCartItems;
140 //
141 // $this->cart->update();
142
143 $this->prepareCartData($this->cart);
144
145 }
146
147 public function getCountryList(): array
148 {
149 return Helper::getCountryList();
150 }
151
152 /**
153 * @return StoreSettings
154 */
155 public function getStoreSettings(): StoreSettings
156 {
157 return $this->storeSettings;
158 }
159
160 public function setCart(Cart $cart)
161 {
162 $this->cart = $cart;
163 }
164
165 public function getCart()
166 {
167 return $this->cart;
168 }
169
170 protected function prepareCartData(Cart $cart)
171 {
172 $this->utmData = $cart->utm_data;
173 if ($checkoutData = $this->cart->checkout_data) {
174 $this->checkoutData = $checkoutData;
175 }
176 }
177
178
179 /**
180 * @param ProductVariation $variation
181 *
182 * @return Cart
183 */
184 public static function getCartFromVariation(ProductVariation $variation): Cart
185 {
186 return CartHelper::generateCartFromVariation($variation);
187 }
188
189
190 public function getSettings($setting = '')
191 {
192 if (!$this->storeSettings) {
193 $this->storeSettings = new StoreSettings();
194 }
195
196 if ($setting) {
197 return $this->storeSettings->get($setting);
198 }
199
200 return $this->storeSettings->get();
201 }
202
203 public function getItems(): array
204 {
205 if (empty($this->cart)) {
206 return [];
207 }
208 return $this->cart->cart_data ?? [];
209 }
210
211 public function getUtmData($data): array
212 {
213 $utmKeys = [
214 'utm_campaign',
215 'utm_content',
216 'utm_term',
217 'utm_source',
218 'utm_medium',
219 'utm_id',
220 'refer_url',
221 'fbclid',
222 'gclid'
223 ];
224
225 $utmData = [];
226 foreach ($utmKeys as $key) {
227 $value = Arr::get($data, $key);
228 if ($value) {
229 $utmData[$key] = sanitize_text_field($value);
230 }
231 }
232 return array_merge($utmData, $this->utmData ?? []);
233 }
234
235 public function isEmailLocked()
236 {
237 // To-do disabled this for now
238 return false;
239 // return !!$this->getUser();
240 }
241
242 public function getUserId()
243 {
244 global $current_user;
245 $userId = $current_user->ID ?? null;
246
247 if (!$userId && $this->cart && $this->cart->user_id) {
248 $userId = $this->cart->user_id;
249 }
250
251 return $userId;
252 }
253
254 public function getUser()
255 {
256 static $user;
257
258 if ($user) {
259 return $user;
260 }
261
262 $userId = $this->getUserId();
263
264 if (!$userId) {
265 return false;
266 }
267
268 $user = get_user_by('ID', $userId);
269
270 if ($user) {
271 return $user;
272 }
273 }
274
275 public function getCustomer($email = '')
276 {
277
278 if (empty($email)) {
279 return CustomerResource::getCurrentCustomer();
280 }
281 $customer = Customer::query();
282 $customer = $customer->where('email', $email);
283 $customer = $customer->with('billing_address')
284 ->with('shipping_address')
285 ->first();
286
287
288 if (!$customer && $this->cart && $this->cart->customer) {
289 $customer = $this->cart->customer;
290 }
291
292 return $customer ?? false;
293 }
294
295 public function requireShippingAddress(): bool
296 {
297 $shippableTypes = ['physical'];
298
299 foreach ($this->getItems() as $item) {
300 if (in_array($item['fulfillment_type'], $shippableTypes)) {
301 return true;
302 }
303 }
304 return false;
305 }
306
307
308 public function getEmail()
309 {
310 $user = $this->getUser();
311 if ($user) {
312 return $user->user_email;
313 }
314
315 if ($customer = $this->getCustomer()) {
316 return $customer->email;
317 }
318
319 if ($this->cart) {
320 return $this->cart->email;
321 }
322
323 }
324
325 public function getFullName()
326 {
327 return trim($this->getFirstName() . ' ' . $this->getLastName());
328 }
329
330 public function getFirstName()
331 {
332 if ($this->cart && $this->cart->first_name) {
333 return $this->cart->first_name;
334 }
335
336 $user = $this->getUser();
337 if (!empty($user->first_name)) {
338 return $user->first_name;
339 }
340
341 if ($customer = $this->getCustomer()) {
342 if ($customer->first_name) {
343 return $customer->first_name;
344 }
345 }
346
347 return '';
348 }
349
350
351 /**
352 * @param $productId
353 *
354 * @return array|null
355 */
356 public function getOriginalProduct($productId): ?array
357 {
358 return ProductResource::find($productId);
359 }
360
361 /**
362 * @param $itemId
363 *
364 * @return Builder|Builder[]|\FluentCart\Framework\Database\Orm\Collection|Model|null
365 */
366 public function getOriginalItem($itemId)
367 {
368 return ProductVariation::query()->find($itemId);
369 }
370
371 public function getLastName()
372 {
373 if ($this->cart && $this->cart->last_name) {
374 return $this->cart->last_name;
375 }
376
377 $user = $this->getUser();
378 if ($user && $user->last_name) {
379 return $user->last_name;
380 }
381
382 if ($customer = $this->getCustomer()) {
383 if ($customer->last_name) {
384 return $customer->last_name;
385 }
386 }
387
388 return '';
389 }
390
391 public function getBillingAddress($withNameEmail = false)
392 {
393 $checkoutBilling = Arr::get($this->checkoutData, 'billing', []);
394
395 if ($customer = $this->getCustomer()) {
396 $customerBilling = CustomerAddressResource::find($customer->id, ['type' => 'billing']);
397 $checkoutBilling = wp_parse_args($checkoutBilling, $customerBilling);
398 }
399
400 if ($withNameEmail) {
401 $checkoutBilling['first_name'] = $this->getFirstName();
402 $checkoutBilling['last_name'] = $this->getLastName();
403 $checkoutBilling['email'] = $this->getEmail();
404 }
405
406 return $checkoutBilling;
407 }
408
409 public function getShippingAddress()
410 {
411 $checkoutShipping = Arr::get($this->checkoutData, 'shipping', []);
412
413 //todo : will add dynamic shipping from saved item later
414
415 // $customerAddress = new CustomerAddress();
416 // if ($customer = $this->getCustomer()) {
417 // $primaryShipping = $customerAddress->getAddress($customer->id, 'shipping');
418 // $checkoutShipping = wp_parse_args($checkoutShipping, $primaryShipping);
419 // }
420 return $checkoutShipping;
421 }
422
423 public function getAddressBaseFields($type = 'billing'): array
424 {
425 $getCart = CartHelper::getCart();
426
427 $selectedCountry = Arr::get($getCart, 'checkout_data.form_data.' . $type . '_country');
428
429 if (empty($selectedCountry)) {
430 $HTTP_CF_IP_COUNTRY = Arr::get( App::request()->server(), 'HTTP_CF_IPCOUNTRY');
431 $selectedCountry = $HTTP_CF_IP_COUNTRY ?? $selectedCountry;
432 }
433
434 $states = [];
435 if (empty(Arr::get($getCart, 'checkout_data.form_data.' . $type . '_state'))) {
436 $states = [
437 [
438 'name' => __('Select an option', 'fluent-cart'),
439 'value' => ''
440 ]
441 ];
442 }
443
444 $addressLocale = [];
445 if (!empty($selectedCountry)) {
446 $states = array_merge($states, LocalizationManager::getInstance()->statesOptions($selectedCountry));
447 $addressLocale = LocalizationManager::getInstance()->addressLocales($selectedCountry);
448 }
449
450 $stateLabel = Arr::get($addressLocale, 'state.label', __('State', 'fluent-cart'));
451 $countries = [
452 [
453 'name' => __('Select a Country', 'fluent-cart'),
454 'value' => ''
455 ]
456 ];
457 $countries = array_merge($countries, $this->getCountryList());
458
459
460 if (empty($states) && !Arr::get($addressLocale, 'state.hidden')) {
461 $stateInput = [
462 'type' => 'text',
463 'data-type' => 'text',
464 'label' => '',
465 'required' => 'yes',
466 'autocomplete' => 'address-level2',
467 'placeholder' => $stateLabel,
468 'value' => '',
469 ];
470 } else {
471 $stateInput = [
472 'type' => 'select',
473 'data-type' => 'select',
474 'label' => '',
475 'options' => $states,
476 'required' => 'yes',
477 'autocomplete' => 'address-level2',
478 'placeholder' => $stateLabel,
479 'value' => Arr::get($getCart, 'checkout_data.form_data.' . $type . '_state') ?? '',
480 ];
481 }
482
483 return [
484 'address_section' => [
485 'type' => 'section',
486 'title' => __('Address', 'fluent-cart'),
487 'schema' => [
488 'label' => [
489 'type' => 'text',
490 'data-type' => 'text',
491 'label' => '',
492 'required' => 'yes',
493 'autocomplete' => 'label',
494 'value' => '',
495 'maxlength' => 15,
496 'placeholder' => esc_attr__('e.g Home, Office', 'fluent-cart'),
497 ],
498 'name' => [
499 'type' => 'text',
500 'data-type' => 'text',
501 'label' => '',
502 'required' => 'no',
503 'autocomplete' => 'name',
504 'placeholder' => esc_attr__('Name', 'fluent-cart'),
505 ],
506 'country' => [
507 'type' => 'select',
508 'options' => $countries,
509 'data-type' => 'text',
510 'label' => '',
511 'required' => 'yes',
512 'autocomplete' => 'country',
513 'placeholder' => esc_attr__('Country / Region', 'fluent-cart'),
514 'value' => $selectedCountry,
515 ],
516 'address_1' => [
517 'type' => 'text',
518 'data-type' => 'text',
519 'label' => '',
520 /* translators: use local order of street name and house number. */
521 'placeholder' => esc_attr__('Street Address', 'fluent-cart'),
522 'required' => 'yes',
523 'autocomplete' => 'address-line1',
524 'value' => Arr::get($getCart, 'checkout_data.form_data.' . $type . '_address_1'),
525 ],
526 'address_2' => [
527 'type' => 'text',
528 'data-type' => 'text',
529 'label' => '',
530 'label_class' => array(''),
531 'placeholder' => esc_attr__('Apt, suite, unit', 'fluent-cart'),
532 'autocomplete' => 'address-line2',
533 'value' => Arr::get($getCart, 'checkout_data.form_data.' . $type . '_address_2', ''),
534 ],
535 'state' => $stateInput,
536 'city_zip' => [
537 'type' => 'section',
538 'schema' => [
539 'city' => [
540 'type' => 'text',
541 'data-type' => 'text',
542 'label' => '',
543 'required' => 'yes',
544 'autocomplete' => 'address-level2',
545 'placeholder' => esc_attr__('Town / City', 'fluent-cart'),
546 'value' => Arr::get($getCart, 'checkout_data.form_data.' . $type . '_city'),
547 ],
548 'postcode' => [
549 'type' => 'text',
550 'data-type' => 'text',
551 'label' => '',
552 'required' => 'yes',
553 'validate' => array('postcode'),
554 'autocomplete' => 'postal-code',
555 'placeholder' => esc_attr__('Postcode / ZIP', 'fluent-cart'),
556 'value' => Arr::get($getCart, 'checkout_data.form_data.' . $type . '_postcode'),
557 ],
558 ]
559 ]
560 ]
561 ]
562 ];
563 }
564
565 public function getAddressFields($type = 'billing')
566 {
567 $addresses = [];
568 $customer = CustomerResource::getCurrentCustomer();
569 $getCart = CartHelper::getCart();
570
571 if (!empty($customer)) {
572 $customerId = $customer->id;
573 $addresses = CustomerAddressResource::get([
574 'type' => $type,
575 'customer_id' => $customerId,
576 'status' => 'active'
577 ]);
578 }
579
580 $requiredOnLoggedOut = $this->getAddressBaseFields($type);
581 $fieldsToUnset = ['name', 'address_2'];
582 foreach ($fieldsToUnset as $field) {
583 unset($requiredOnLoggedOut['address_section']['schema'][$field]);
584 }
585
586 $requireAdditionalAddress = (new StoreSettings())->get('additional_address_field');
587
588 if ($requireAdditionalAddress == 'yes') {
589
590 $schema = [
591 'company_name' => [
592 'id' => 'company_name',
593 'type' => 'text',
594 'data-type' => 'text',
595 'label' => '',
596 'autocomplete' => 'organization',
597 'placeholder' => esc_attr__('Company Name', 'fluent-cart'),
598 'value' => Arr::get($getCart, 'checkout_data.form_data.' . $type . '_company_name'),
599 ],
600 'phone' => [
601 'id' => 'phone',
602 'type' => 'text',
603 'data-type' => 'text',
604 'label' => '',
605 'disabled' => false,
606 'placeholder' => esc_attr__('Phone', 'fluent-cart'),
607 'value' => Arr::get($getCart, 'checkout_data.form_data.' . $type . '_phone'),
608 ]
609 ];
610
611
612 $requiredOnLoggedOut['address_section']['schema'] = array_merge(
613 $requiredOnLoggedOut['address_section']['schema'],
614 $schema
615 );
616 }
617
618 $addressLabel = $type === 'billing' ?
619 __('Billing Address', 'fluent-cart') :
620 __('Shipping Address', 'fluent-cart');
621
622 $requiredOnLoggedIn = [
623 'address' => [
624 'type' => 'section',
625 'title' => $addressLabel,
626 'schema' => [
627 'address' => [
628 'id' => 'address',
629 'type' => 'address_select',
630 'data-type' => 'hidden',
631 'required' => 'no',
632 'label' => '',
633 'disabled' => false,
634 'options' => $addresses,
635 'value' => Arr::get($getCart, 'checkout_data.form_data.' . $type . '_address_id'),
636 ]
637 ]
638 ]
639 ];
640
641 $customerName = $this->getFullName();
642 $customerEmail = $this->getEmail();
643 $fullNameDisabled = $type === 'billing' && is_user_logged_in() && !empty($customerName);
644 $savedFullName = Arr::get($getCart, 'checkout_data.form_data.' . $type . '_full_name');
645 $savedEmail = Arr::get($getCart, 'checkout_data.form_data.' . $type . '_email');
646 if (!empty($savedFullName)) {
647 $customerName = $savedFullName;
648 }
649 if (!empty($savedEmail)) {
650 $customerEmail = $savedEmail;
651 }
652
653 $fields = [
654 'personal_information' => [
655 'type' => 'section',
656 'schema' => [
657 'full_name' => [
658 'id' => 'full_name',
659 'type' => 'text',
660 'data-type' => 'text',
661 'label' => '',
662 'required' => 'yes',
663 'autocomplete' => 'given-name',
664 'value' => $customerName,
665 'placeholder' => esc_attr__('Full Name', 'fluent-cart'),
666 ],
667 'email' => [
668 'id' => 'email',
669 'type' => 'text',
670 'data-type' => 'email',
671 'required' => 'yes',
672 'label' => '',
673 'autocomplete' => 'email username',
674 'value' => $customerEmail,
675 'disabled' => is_user_logged_in(),
676 'placeholder' => esc_attr__('Email address', 'fluent-cart'),
677 ]
678 ]
679 ],
680 ];
681
682 $currentCustomer = CustomerResource::getCurrentCustomer();
683
684 $hasAddress = true;
685
686 if (empty($currentCustomer) || $currentCustomer->billing_address->count() === 0) {
687 $hasAddress = false;
688 }
689
690 $fields = $fields + ($hasAddress ? $requiredOnLoggedIn : $requiredOnLoggedOut);
691
692 return apply_filters('fluent_cart/checkout_address_fields', $fields, []);
693 }
694
695 public function getBillingAddressFields($viewData = [])
696 {
697 $labels = Arr::get($viewData, 'labels', []);
698 $fields = $this->getAddressFields();
699 $allowCreateAccount = Arr::get($viewData, 'block_allow_create_account', []);
700 $label = Arr::get($allowCreateAccount, 'label', __('Create My Account', 'fluent-cart'));
701 $customer = CustomerResource::getCurrentCustomer();
702
703 if (isset($fields['address_section'])) {
704 $fields['address_section']['title'] = $labels['billing_address'] ?? __('Billing Address', 'fluent-cart');
705 }
706
707 if ((new StoreSettings())->get('user_account_creation_mode') === 'user_choice') {
708 $isUserLoggedIn = is_user_logged_in();
709
710 // Show the view if the user is not logged in or does not have an account
711 if (!$isUserLoggedIn || ($customer === null)) {
712 $checked = $this->hasSubscription() === 'yes' ? 'yes' : 'no';
713 $disabled = $this->hasSubscription() === 'yes';
714 $fields['personal_information']['schema']['allow_create_account'] = [
715 'id' => 'allow_create',
716 'type' => 'checkbox',
717 'data-type' => 'text',
718 'label' => $label,
719 'skip_prefix' => true,
720 'autocomplete' => 'given-name',
721 'value' => 'yes',
722 'checked' => $checked,
723 'disabled' => $disabled
724 ];
725 }
726 }
727
728 unset($fields['address_section']['schema']['label']);
729
730 return apply_filters('fluent_cart/checkout_billing_fields', $fields, [
731 'viewData' => $viewData,
732 'customer' => $customer,
733 'labels' => $labels,
734 'has_subscription' => $this->hasSubscription()
735 ]);
736 }
737
738 public function getShippingAddressFields($viewData = [])
739 {
740 $labels = Arr::get($viewData, 'labels', []);
741 $fields = $this->getAddressFields('shipping');
742 $addressSchema = [];
743
744 if (isset($fields['address_section'])) {
745 $addressSchema = $fields['address_section']['schema'];
746 $fields['address_section']['title'] = $labels['shipping_address'] ?? __('Shipping Address', 'fluent-cart');
747 }
748
749 // Remove email field
750 if (isset($fields['personal_information']['schema']['email'])) {
751 unset($fields['personal_information']['schema']['email']);
752 unset($fields['tax_information']);
753 }
754
755 // Extract name field and remove personal information section
756 $fullNameField = $fields['personal_information']['schema'] ?? [];
757 unset($fields['personal_information']);
758
759 if (isset($fields['address_section']) && !empty($addressSchema) && is_array($addressSchema)) {
760 $fields['address_section']['schema'] = array_merge(
761 $fullNameField,
762 $addressSchema
763 );
764 }
765
766 // Remove label if user is not logged in
767 if (!is_user_logged_in()) {
768 unset($fields['address_section']['schema']['label']);
769 }
770
771 return apply_filters('fluent_cart/checkout_shipping_fields', $fields, [
772 'viewData' => $viewData,
773 'labels' => $labels,
774 ]);
775 }
776
777 public function getItemsAmountTotal($formatted = true, $withCurrency = true, $shippingTotal = 0)
778 {
779 $checkoutItems = new CheckoutService($this->getItems());
780
781 $subscriptionItems = $checkoutItems->subscriptions;
782 $onetimeItems = $checkoutItems->onetime;
783
784 $items = array_merge($onetimeItems, $subscriptionItems);
785
786 $total = OrderService::getItemsAmountTotal($items, false, $withCurrency, $shippingTotal);
787
788 if (!$formatted) {
789 return $total;
790 }
791
792 return Helper::toDecimal($total, $withCurrency);
793 }
794
795 public function getItemsAmountTotalWithShipping($shippingTotal = 0, $formatted = true, $withCurrency = true)
796 {
797 return $this->getItemsAmountTotal(true, true, $shippingTotal);
798 }
799
800 public function getItemsAmountSubtotal($formatted = true, $withCurrency = true)
801 {
802 $checkoutItems = new CheckoutService($this->getItems());
803 $subscriptionItems = $checkoutItems->subscriptions;
804 $onetimeItems = $checkoutItems->onetime;
805
806 $items = array_merge($onetimeItems, $subscriptionItems);
807
808
809 $subtotal = OrderService::getItemsAmountWithoutDiscount($items);
810
811 return $formatted ? Helper::toDecimal($subtotal, $withCurrency) : $subtotal;
812 }
813
814 public function getSignupFields()
815 {
816 $fields = array(
817 'full_name' => array(
818 'id' => 'full_name',
819 'type' => 'text',
820 'data-type' => 'text',
821 'label' => __('Full Name', 'fluent-cart'),
822 'required' => 'yes',
823 'autocomplete' => 'given-name',
824 'placeholder' => esc_attr__('e.g. James Brown', 'fluent-cart'),
825 ),
826 'email' => array(
827 'id' => 'billing_email',
828 'type' => 'text',
829 'data-type' => 'email',
830 'required' => 'yes',
831 'label' => __('Email Address', 'fluent-cart'),
832 'autocomplete' => 'email username',
833 'placeholder' => esc_attr__('e.g. [email protected]', 'fluent-cart'),
834 ),
835 'password' => array(
836 'id' => 'password',
837 'type' => 'text',
838 'data-type' => 'password',
839 'required' => 'no',
840 'label' => __('Password', 'fluent-cart'),
841 'autocomplete' => 'current-password',
842 'placeholder' => esc_attr__('Enter Strong password', 'fluent-cart'),
843 ),
844 );
845
846 return apply_filters('fluent_cart/checkout_signup_fields', $fields, []);
847 }
848
849 public function getLoginFields()
850 {
851 $fields = array(
852 'user_login' => array(
853 'id' => 'username_email',
854 'type' => 'text',
855 'data-type' => 'text',
856 'required' => 'yes',
857 'label' => __('Username or Email Address', 'fluent-cart'),
858 'autocomplete' => 'email username',
859 'placeholder' => esc_attr__('e.g. [email protected] or username', 'fluent-cart'),
860 ),
861 'password' => array(
862 'id' => 'password',
863 'type' => 'text',
864 'data-type' => 'password',
865 'required' => 'yes',
866 'label' => __('Password', 'fluent-cart'),
867 'autocomplete' => 'current-password',
868 'placeholder' => esc_attr__('Enter password', 'fluent-cart'),
869 ),
870 );
871
872 return apply_filters('fluent_cart/checkout_login_fields', $fields, []);
873 }
874
875 public function getCartHash()
876 {
877 if ($this->cart == null) {
878 return null;
879 }
880
881 return $this->cart->cart_hash;
882 }
883
884
885 public function toArray(): array
886 {
887 return [
888 'address_fields' => $this->getAddressFields(),
889 'billing_address' => $this->getBillingAddress(),
890 'billing_address_fields' => $this->getBillingAddressFields(),
891 'cart_hash' => $this->getCartHash(),
892 'customer' => $this->getCustomer(),
893 'info' => [
894 'email' => $this->getEmail(),
895 'first_name' => $this->getFirstName(),
896 'last_name' => $this->getLastName(),
897 'user_id' => $this->getUserId()
898 ],
899 'is_email_locked' => $this->isEmailLocked(),
900 'items' => $this->getItems(),
901 'settings' => $this->getSettings(),
902 'user' => $this->getUser(),
903 ];
904 }
905
906 public function getCouponFields()
907 {
908 $fields = array(
909 'coupon' => array(
910 'name_prefix' => 'coupon_',
911 'id' => 'coupon',
912 'type' => 'text',
913 'data-type' => 'text',
914 'label' => '',
915 'required' => 'no',
916 'placeholder' => __('Apply Here', 'fluent-cart'),
917 ),
918 'applied_coupons' => array(
919 'type' => 'hidden',
920 'data-type' => 'hidden',
921 'label' => '',
922 ),
923 );
924
925 return apply_filters('fluent_cart/checkout_coupon_fields', $fields, []);
926 }
927
928 public function getManualDiscountAmount()
929 {
930 if (empty($this->cart)) {
931 return 0;
932 }
933
934 if ($this->cart->order) {
935 return $this->cart->order->manual_discount_total;
936 }
937
938 return (int)Arr::get($this->cart->checkout_data, 'manual_discount.amount', 0);
939 }
940 }
941