PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.7.1
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.7.1
1.7.1 1.7.0 1.6.6 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 All 51 releases
← All changes | app/Services/Renderer/ModalCheckoutRenderer.php +95 -39 1.6.4 → 1.7.1 View file →
@@ -3,19 +3,12 @@
3 3 namespace FluentCart\App\Services\Renderer;
4 4
5 5 use FluentCart\Api\PaymentMethods;
6 6 use FluentCart\Api\Resource\CustomerResource;
7 -use FluentCart\Api\Resource\FrontendResource\CustomerAddressResource;
8 7 use FluentCart\Api\StoreSettings;
9 -use FluentCart\App\App;
10 -use FluentCart\App\Helpers\AddressHelper;
11 -use FluentCart\App\Helpers\CartHelper;
12 8 use FluentCart\App\Helpers\Helper;
13 9 use FluentCart\App\Models\Cart;
14 -use FluentCart\App\Models\ProductVariation;
15 -use FluentCart\App\Services\Localization\LocalizationManager;
16 10 use FluentCart\App\Services\URL;
17 -use FluentCart\App\Vite;
18 11 use FluentCart\Framework\Support\Arr;
19 12 use FluentCart\App\Models\ProductMeta;
20 13
21 14 class ModalCheckoutRenderer
@@ -277,9 +270,9 @@
277 270 $couponDiscount = (int) Arr::get($this->cart->cart_data, '0.coupon_discount', 0);
278 271 $subtotalRaw = (int) Arr::get($this->cart->cart_data, '0.subtotal', 0);
279 272 $lineTotalRaw = (int) Arr::get($this->cart->cart_data, '0.line_total', 0);
280 273 $hasCouponDiscount = $couponDiscount > 0 && $lineTotalRaw < $subtotalRaw;
281 - $media = Arr::get($this->cart->cart_data, '0.featured_media', '');
274 + $media = Helper::productImageOrPlaceholder(Arr::get($this->cart->cart_data, '0.featured_media', ''));
282 275
283 276 // Mirror CartItemRenderer's event payload so the shared line-item hooks
284 277 // (e.g. the per-item tax breakdown) also fire in modal checkout.
285 278 $lineItemEventInfo = [
@@ -537,8 +530,58 @@
537 530
538 531 }
539 532
540 533
534 + /**
535 + * First/Last name inputs for the modal. Enabling either in Checkout Fields
536 + * replaces the single Full name input. The field definitions come from
537 + * CheckoutFieldsSchema, shared with the regular checkout; the modal only
538 + * moves the label out of the placeholder.
539 + *
540 + * First name is always rendered and required, because checkout validation
541 + * always asks for it in this mode. That keeps an older saved configuration
542 + * with only Last name enabled working.
543 + *
544 + * @return array[] field configs for FormFieldRenderer::renderField()
545 + */
546 + private function getFirstLastNameFields(): array
547 + {
548 + $schema = CheckoutFieldsSchema::getNameEmailFieldsSchema($this->cart);
549 + $fields = [];
550 +
551 + foreach (['billing_first_name', 'billing_last_name'] as $name) {
552 + $field = Arr::get($schema, 'fields.' . $name);
553 + if ($name === 'billing_first_name') {
554 + $field = wp_parse_args($field ?: [], [
555 + 'name' => $name,
556 + 'id' => $name,
557 + 'type' => 'text',
558 + 'data-type' => 'text',
559 + 'aria-label' => __('First Name', 'fluent-cart'),
560 + 'autocomplete' => 'given-name',
561 + 'value' => '',
562 + ]);
563 + $field['required'] = 'yes';
564 + }
565 +
566 + if (!$field) {
567 + continue;
568 + }
569 +
570 + $field['label'] = Arr::get($field, 'aria-label') . (Arr::get($field, 'required') ? ' *' : '');
571 + $field['placeholder'] = $name === 'billing_first_name' ? __('Jon', 'fluent-cart') : __('Doe', 'fluent-cart');
572 +
573 + $customerValue = $this->customer->{str_replace('billing_', '', $name)} ?? '';
574 + if ($customerValue) {
575 + $field['value'] = $customerValue;
576 + }
577 +
578 + $fields[] = $field;
579 + }
580 +
581 + return $fields;
582 + }
583 +
541 584 public function renderCheckoutBilling() {
542 585 $user = wp_get_current_user();
543 586 $formRender = new FormFieldRenderer();
544 587 $fullName = trim(
@@ -555,31 +598,44 @@
555 598 $emailField = Arr::get($fieldsSchema, 'basic_info.email', []);
556 599 $isRequiredFullName = Arr::get($fullNameField, 'required', 'no') === 'yes' ? 'yes' : '';
557 600 $isRequiredEmail = Arr::get($emailField, 'required', 'no') === 'yes' ? 'yes' : '';
558 601
602 + $isFullName = CheckoutFieldsSchema::isFullNameRequired();
603 + $firstLastNameFields = $isFullName ? [] : $this->getFirstLastNameFields();
604 + // First and last name share one row, so email gets the next row to itself.
605 + $emailColClass = count($firstLastNameFields) === 2 ? 'col-12' : 'col-6';
606 +
559 607 ?>
560 608 <div class="fct-modal-checkout-billing-wrap">
561 609 <!-- Account Details -->
562 610 <div class="fct-modal-account-details" data-fct-checkout-form-section>
563 611 <div class="fct-modal-form-info">
564 - <div class="fct-modal-form-field col-6">
612 + <?php if ($isFullName) : ?>
613 + <div class="fct-modal-form-field col-6">
614 + <?php
615 + $formRender->renderField([
616 + 'label' => esc_attr__('Full name', 'fluent-cart') . ($isRequiredFullName ? ' *' : ''),
617 + 'id' => 'billing_full_name',
618 + 'type' => 'text',
619 + 'placeholder' => __('Jon Doe', 'fluent-cart'),
620 + 'name' => 'billing_full_name',
621 + 'autocomplete' => 'given-name',
622 + 'aria-label' => esc_attr__('Full name', 'fluent-cart'),
623 + 'required' => $isRequiredFullName,
624 + 'value' => $fullName
625 + ]);
626 + ?>
627 + </div>
628 + <?php else : ?>
629 + <?php foreach ($firstLastNameFields as $nameField) : ?>
630 + <div class="fct-modal-form-field col-6">
631 + <?php $formRender->renderField($nameField); ?>
632 + </div>
633 + <?php endforeach; ?>
634 + <?php endif; ?>
635 + <div class="fct-modal-form-field <?php echo esc_attr($emailColClass); ?>">
565 636 <?php
566 637 $formRender->renderField([
567 - 'label' => esc_attr__('Full name', 'fluent-cart') . ($isRequiredFullName ? ' *' : ''),
568 - 'id' => 'billing_full_name',
569 - 'type' => 'text',
570 - 'placeholder' => __('Jon Doe', 'fluent-cart'),
571 - 'name' => 'billing_full_name',
572 - 'autocomplete' => 'given-name',
573 - 'aria-label' => esc_attr__('Full name', 'fluent-cart'),
574 - 'required' => $isRequiredFullName,
575 - 'value' => $fullName
576 - ]);
577 - ?>
578 - </div>
579 - <div class="fct-modal-form-field col-6">
580 - <?php
581 - $formRender->renderField([
582 638 'label' => esc_attr__('Email address', 'fluent-cart') . ($isRequiredEmail ? ' *' : ''),
583 639 'id' => 'billing_email',
584 640 'type' => 'text',
585 641 'placeholder' => '[email protected]',
@@ -591,23 +647,8 @@
591 647 'disabled' => (bool)($this->customer->email ?? $user->user_email)
592 648 ]);
593 649 ?>
594 650 </div>
595 -
596 -<!-- <div class="fct-modal-form-field col-3">-->
597 -<!-- --><?php
598 -// $formRender->renderField([
599 -// 'label' => __('Last name', 'fluent-cart'),
600 -// 'id' => 'billing_last_name',
601 -// 'type' => 'text',
602 -// 'placeholder' => __('Doe', 'fluent-cart'),
603 -// 'name' => 'billing_last_name',
604 -// 'autocomplete' => 'given-name',
605 -// 'required' => true,
606 -// 'value' => $this->customer->last_name ?? ''
607 -// ]);
608 -// ?>
609 -<!-- </div>-->
610 651 </div>
611 652
612 653 <?php $this->checkoutRenderer->renderCreateAccountField(); ?>
613 654
@@ -688,8 +729,23 @@
688 729 // reset() not [0] — array_filter above preserves keys, so key 0 may be gone.
689 730 $firstMethod = reset($activePaymentMethods);
690 731 $selectedPaymentMethod = $firstMethod ? $firstMethod->getMeta('route') : '';
691 732 }
733 +
734 + /**
735 + * The payment method rendered as checked. An add-on that renders its own
736 + * selector outside this list (e.g. saved payment methods) returns a route
737 + * that is not in the list, so no gateway here is checked — the page then
738 + * arrives with the add-on's choice already selected instead of a gateway
739 + * being checked first and switched over by JS after load.
740 + *
741 + * @param string $selectedPaymentMethod
742 + * @param array $context ['cart' => Cart, 'payment_methods' => array]
743 + */
744 + $selectedPaymentMethod = (string) apply_filters('fluent_cart/checkout/selected_payment_method', $selectedPaymentMethod, [
745 + 'cart' => $this->cart,
746 + 'payment_methods' => $activePaymentMethods
747 + ]);
692 748
693 749 $checkoutMethodStyle = $this->storeSettings->get('checkout_method_style', 'logo');
694 750
695 751 ?>