PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.4
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.4
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 1.3.20 1.3.19 All 49 releases
fluent-cart / app / Hooks / Handlers / BlockEditors / Checkout / InnerBlocks / InnerBlocks.php

InnerBlocks.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.6.4, at app/Hooks/Handlers/BlockEditors/Checkout/InnerBlocks/InnerBlocks.php

1,057 lines 36.9 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\Hooks\Handlers\BlockEditors\Checkout\InnerBlocks;
4
5 use FluentCart\Api\Contracts\CanEnqueue;
6 use FluentCart\Api\ModuleSettings;
7 use FluentCart\Api\StoreSettings;
8 use FluentCart\App\App;
9 use FluentCart\App\Helpers\CartHelper;
10 use FluentCart\App\Helpers\Helper;
11 use FluentCart\App\Modules\Tax\TaxModule;
12 use FluentCart\App\Services\Renderer\CartSummaryRender;
13 use FluentCart\App\Services\Renderer\CheckoutRenderer;
14 use FluentCart\App\Services\Translations\TransStrings;
15 use FluentCart\Framework\Support\Arr;
16 use FluentCartPro\App\Modules\Promotional\OrderBump\OrderBumpBoot;
17
18 class InnerBlocks
19 {
20 use CanEnqueue;
21
22 public static $parentBlock = 'fluent-cart/checkout';
23
24 public array $blocks = [];
25
26 private $cart = null;
27
28 private function getCart()
29 {
30 if ($this->cart === null) {
31 $this->cart = CartHelper::getCart();
32 }
33 return $this->cart;
34 }
35
36
37 public static function textBlockSupport(): array
38 {
39 return [
40 'html' => false,
41 'align' => ['left', 'center', 'right'],
42 'typography' => [
43 'fontSize' => true,
44 'lineHeight' => true
45 ],
46 'spacing' => [
47 'margin' => true,
48 'padding' => true
49 ],
50 'color' => [
51 'text' => true,
52 ],
53 '__experimentalBorder' => [
54 'radius' => true,
55 'color' => true,
56 'width' => true,
57 'style' => true
58 ]
59 ];
60 }
61
62 public static function buttonBlockSupport(): array
63 {
64 return [
65 'html' => false,
66 'align' => ['left', 'center', 'right'],
67 'typography' => [
68 'fontSize' => true,
69 'lineHeight' => true,
70 'fontWeight' => true,
71 'textTransform' => true,
72 ],
73 'spacing' => [
74 'margin' => true,
75 'padding' => true,
76 ],
77 'color' => [
78 'text' => true,
79 'background' => true,
80 ],
81 '__experimentalBorder' => [
82 'radius' => true,
83 'color' => true,
84 'width' => true,
85 'style' => true
86 ],
87 'shadow' => true,
88 ];
89 }
90
91
92 public static function register()
93 {
94 $self = new self();
95 $blocks = $self->getInnerBlocks();
96
97 foreach ($blocks as $block) {
98
99 register_block_type($block['slug'], [
100 'apiVersion' => 3,
101 'api_version' => 3,
102 'version' => 3,
103 'title' => $block['title'],
104 'category' => 'fluent-cart',
105 'parent' => array_merge($block['parent'] ?? [], [static::$parentBlock]),
106 'render_callback' => $block['callback'],
107 'supports' => Arr::get($block, 'supports', []),
108 'attributes' => Arr::get($block, 'attributes', []),
109 'uses_context' => Arr::get($block, 'uses_context', []),
110 ]);
111 }
112
113 add_action('enqueue_block_editor_assets', function () use ($self) {
114 $self->enqueueScripts();
115 });
116
117 }
118
119 public function getInnerBlocks(): array
120 {
121 return [
122 [
123 'title' => __('Checkout Name Fields', 'fluent-cart'),
124 'slug' => 'fluent-cart/checkout-name-fields',
125 'callback' => [$this, 'renderCheckoutNameFields'],
126 'component' => 'CheckoutNameFieldsBlock',
127 'icon' => 'editor-code',
128 'supports' => [
129 'html' => false,
130 'typography' => [
131 'fontSize' => false,
132 'lineHeight' => false
133 ],
134 'spacing' => [
135 'margin' => true,
136 'padding' => true
137 ],
138 'color' => [
139 'text' => false,
140 'background' => true,
141 ],
142 ],
143 'parent' => [
144 'fluent-cart/checkout',
145 'core/column',
146 'core/group'
147 ],
148 ],
149 [
150 'title' => __('Checkout Create Account Field', 'fluent-cart'),
151 'slug' => 'fluent-cart/checkout-create-account-field',
152 'callback' => [$this, 'renderCheckoutCreateAccountField'],
153 'component' => 'CheckoutCreateAccountFieldBlock',
154 'icon' => 'editor-code',
155 'supports' => static::textBlockSupport(),
156 'parent' => [
157 'fluent-cart/checkout',
158 'core/column',
159 'core/group'
160 ],
161 ],
162 [
163 'title' => __('Checkout Address Fields', 'fluent-cart'),
164 'slug' => 'fluent-cart/checkout-address-fields',
165 'callback' => [$this, 'renderCheckoutAddressFields'],
166 'component' => 'CheckoutAddressFieldsBlock',
167 'icon' => 'editor-code',
168 'supports' => [
169 'html' => false,
170 'typography' => [
171 'fontSize' => false,
172 'lineHeight' => false
173 ],
174 'spacing' => [
175 'margin' => true,
176 'padding' => true
177 ],
178 'color' => [
179 'text' => false,
180 'background' => true,
181 ],
182 '__experimentalBorder' => [
183 'radius' => true,
184 'color' => true,
185 'width' => true,
186 'style' => true
187 ]
188 ],
189 'parent' => [
190 'fluent-cart/checkout',
191 'core/column',
192 'core/group'
193 ],
194 ],
195 [
196 'title' => __('Billing Address Field', 'fluent-cart'),
197 'slug' => 'fluent-cart/checkout-billing-address-field',
198 'callback' => [$this, 'renderCheckoutBillingAddressField'],
199 'component' => 'CheckoutBillingAddressFieldBlock',
200 'icon' => 'editor-code',
201 'supports' => [
202 'html' => false,
203 'typography' => [
204 'fontSize' => false,
205 'lineHeight' => false
206 ],
207 'spacing' => [
208 'margin' => true,
209 'padding' => true
210 ],
211 'color' => [
212 'text' => false,
213 'background' => true,
214 ],
215 '__experimentalBorder' => [
216 'radius' => true,
217 'color' => true,
218 'width' => true,
219 'style' => true
220 ]
221 ],
222 'parent' => [
223 'fluent-cart/checkout-address-fields'
224 ],
225 ],
226 [
227 'title' => __('Shipping Address Field', 'fluent-cart'),
228 'slug' => 'fluent-cart/checkout-shipping-address-field',
229 'callback' => [$this, 'renderCheckoutShippingAddressField'],
230 'component' => 'CheckoutShippingAddressFieldBlock',
231 'icon' => 'editor-code',
232 'supports' => [
233 'html' => false,
234 'typography' => [
235 'fontSize' => false,
236 'lineHeight' => false
237 ],
238 'spacing' => [
239 'margin' => true,
240 'padding' => true
241 ],
242 'color' => [
243 'text' => false,
244 'background' => true,
245 ],
246 '__experimentalBorder' => [
247 'radius' => true,
248 'color' => true,
249 'width' => true,
250 'style' => true
251 ]
252 ],
253 'parent' => [
254 'fluent-cart/checkout-address-fields'
255 ],
256 ],
257 [
258 'title' => __('Ship to Different Field', 'fluent-cart'),
259 'slug' => 'fluent-cart/checkout-ship-to-different-field',
260 'callback' => [$this, 'renderCheckoutShipToDifferentField'],
261 'component' => 'CheckoutShipToDifferentFieldBlock',
262 'icon' => 'editor-code',
263 'supports' => [
264 'html' => false,
265 'align' => ['left', 'center', 'right'],
266 'typography' => [
267 'fontSize' => true,
268 'lineHeight' => true
269 ],
270 'spacing' => [
271 'margin' => true,
272 'padding' => true
273 ],
274 'color' => [
275 'text' => true,
276 ],
277 '__experimentalBorder' => [
278 'radius' => true,
279 'color' => true,
280 'width' => true,
281 'style' => true
282 ]
283 ],
284 'parent' => [
285 'fluent-cart/checkout-address-fields'
286 ],
287 ],
288 [
289 'title' => __('Checkout Shipping Methods', 'fluent-cart'),
290 'slug' => 'fluent-cart/checkout-shipping-methods',
291 'callback' => [$this, 'renderCheckoutShippingMethods'],
292 'component' => 'CheckoutShippingMethodsBlock',
293 'icon' => 'editor-code',
294 'supports' => static::textBlockSupport(),
295 'parent' => [
296 'fluent-cart/checkout',
297 'core/column',
298 'core/group'
299 ],
300 ],
301 [
302 'title' => __('Checkout Payment Methods', 'fluent-cart'),
303 'slug' => 'fluent-cart/checkout-payment-methods',
304 'callback' => [$this, 'renderCheckoutPaymentMethods'],
305 'component' => 'CheckoutPaymentMethodsBlock',
306 'icon' => 'editor-code',
307 'supports' => static::textBlockSupport(),
308 'parent' => [
309 'fluent-cart/checkout',
310 'core/column',
311 'core/group'
312 ],
313 ],
314 [
315 'title' => __('Checkout Agree Terms Field', 'fluent-cart'),
316 'slug' => 'fluent-cart/checkout-agree-terms-field',
317 'callback' => [$this, 'renderCheckoutAgreeTermsField'],
318 'component' => 'CheckoutAgreeTermsFieldBlock',
319 'icon' => 'editor-code',
320 'supports' => [
321 'html' => false,
322 'align' => ['left', 'center', 'right'],
323 'typography' => [
324 'fontSize' => true,
325 'lineHeight' => true
326 ],
327 'spacing' => [
328 'margin' => true
329 ],
330 'color' => [
331 'text' => true,
332 ]
333 ],
334 'parent' => [
335 'fluent-cart/checkout',
336 'core/column',
337 'core/group'
338 ],
339 ],
340 [
341 'title' => __('Checkout Submit Button', 'fluent-cart'),
342 'slug' => 'fluent-cart/checkout-submit-button',
343 'callback' => [$this, 'renderCheckoutSubmitButton'],
344 'component' => 'CheckoutSubmitButtonBlock',
345 'icon' => 'editor-code',
346 'supports' => static::buttonBlockSupport(),
347 'parent' => [
348 'fluent-cart/checkout',
349 'core/column',
350 'core/group'
351 ],
352 ],
353 [
354 'title' => __('Checkout Order Notes Field', 'fluent-cart'),
355 'slug' => 'fluent-cart/checkout-order-notes-field',
356 'callback' => [$this, 'renderCheckoutOrderNotesField'],
357 'component' => 'CheckoutOrderNotesFieldBlock',
358 'icon' => 'editor-code',
359 'supports' => static::textBlockSupport(),
360 'parent' => [
361 'fluent-cart/checkout',
362 'core/column',
363 'core/group'
364 ],
365 ],
366 [
367 'title' => __('Checkout Summary', 'fluent-cart'),
368 'slug' => 'fluent-cart/checkout-summary',
369 'callback' => [$this, 'renderCheckoutSummary'],
370 'component' => 'CheckoutSummaryBlock',
371 'icon' => 'editor-code',
372 'supports' => static::textBlockSupport(),
373 'parent' => [
374 'fluent-cart/checkout',
375 'core/column',
376 'core/group'
377 ],
378 ],
379 [
380 'title' => __('Order Summary', 'fluent-cart'),
381 'slug' => 'fluent-cart/checkout-order-summary',
382 'callback' => [$this, 'renderCheckoutOrderSummary'],
383 'component' => 'CheckoutOrderSummaryBlock',
384 'icon' => 'editor-code',
385 'supports' => static::textBlockSupport(),
386 'parent' => [
387 'fluent-cart/checkout-summary'
388 ],
389 ],
390 [
391 'title' => __('Summary Footer', 'fluent-cart'),
392 'slug' => 'fluent-cart/checkout-summary-footer',
393 'callback' => [$this, 'renderCheckoutSummaryFooter'],
394 'component' => 'CheckoutSummaryFooterBlock',
395 'icon' => 'editor-code',
396 'supports' => static::textBlockSupport(),
397 'parent' => [
398 'fluent-cart/checkout-summary'
399 ],
400 ],
401 [
402 'title' => __('Subtotal', 'fluent-cart'),
403 'slug' => 'fluent-cart/checkout-subtotal',
404 'callback' => [$this, 'renderCheckoutSubtotal'],
405 'component' => 'CheckoutSubtotalBlock',
406 'icon' => 'editor-code',
407 'supports' => static::textBlockSupport(),
408 'parent' => [
409 'fluent-cart/checkout-summary-footer'
410 ],
411 ],
412 [
413 'title' => __('Shipping', 'fluent-cart'),
414 'slug' => 'fluent-cart/checkout-shipping',
415 'callback' => [$this, 'renderCheckoutShipping'],
416 'component' => 'CheckoutShippingBlock',
417 'icon' => 'editor-code',
418 'supports' => static::textBlockSupport(),
419 'parent' => [
420 'fluent-cart/checkout-summary-footer'
421 ],
422 ],
423 [
424 'title' => __('Fees', 'fluent-cart'),
425 'slug' => 'fluent-cart/checkout-fees',
426 'callback' => [$this, 'renderCheckoutFees'],
427 'component' => 'CheckoutFeesBlock',
428 'icon' => 'editor-code',
429 'supports' => static::textBlockSupport(),
430 'parent' => [
431 'fluent-cart/checkout-summary-footer'
432 ],
433 ],
434 [
435 'title' => __('Coupon', 'fluent-cart'),
436 'slug' => 'fluent-cart/checkout-coupon',
437 'callback' => [$this, 'renderCheckoutCoupon'],
438 'component' => 'CheckoutCouponBlock',
439 'icon' => 'editor-code',
440 'supports' => static::textBlockSupport(),
441 'parent' => [
442 'fluent-cart/checkout-summary-footer'
443 ],
444 ],
445 [
446 'title' => __('Manual Discount', 'fluent-cart'),
447 'slug' => 'fluent-cart/checkout-manual-discount',
448 'callback' => [$this, 'renderCheckoutManualDiscount'],
449 'component' => 'CheckoutManualDiscountBlock',
450 'icon' => 'editor-code',
451 'supports' => static::textBlockSupport(),
452 'parent' => [
453 'fluent-cart/checkout-summary-footer'
454 ],
455 ],
456 [
457 'title' => __('Tax', 'fluent-cart'),
458 'slug' => 'fluent-cart/checkout-tax',
459 'callback' => [$this, 'renderCheckoutTax'],
460 'component' => 'CheckoutTaxBlock',
461 'icon' => 'editor-code',
462 'supports' => static::textBlockSupport(),
463 'parent' => [
464 'fluent-cart/checkout-summary-footer'
465 ],
466 ],
467 [
468 'title' => __('Shipping Tax', 'fluent-cart'),
469 'slug' => 'fluent-cart/checkout-shipping-tax',
470 'callback' => [$this, 'renderCheckoutShippingTax'],
471 'component' => 'CheckoutShippingTaxBlock',
472 'icon' => 'editor-code',
473 'supports' => static::textBlockSupport(),
474 'parent' => [
475 'fluent-cart/checkout-summary-footer'
476 ],
477 ],
478 [
479 'title' => __('Total', 'fluent-cart'),
480 'slug' => 'fluent-cart/checkout-total',
481 'callback' => [$this, 'renderCheckoutTotal'],
482 'component' => 'CheckoutTotalBlock',
483 'icon' => 'editor-code',
484 'supports' => static::textBlockSupport(),
485 'parent' => [
486 'fluent-cart/checkout-summary-footer'
487 ],
488 ],
489 [
490 'title' => __('Checkout Order Bump', 'fluent-cart'),
491 'slug' => 'fluent-cart/checkout-order-bump',
492 'callback' => [$this, 'renderCheckoutOrderBump'],
493 'component' => 'CheckoutOrderBumpBlock',
494 'icon' => 'editor-code',
495 'supports' => [
496 'html' => false,
497 'align' => ['left', 'center', 'right'],
498 'typography' => [
499 'fontSize' => false,
500 'lineHeight' => false
501 ],
502 'spacing' => [
503 'margin' => true,
504 'padding' => true
505 ],
506 'color' => [
507 'text' => false,
508 'background' => true,
509 ],
510 '__experimentalBorder' => [
511 'radius' => true,
512 'color' => true,
513 'width' => true,
514 'style' => true
515 ]
516 ],
517 'parent' => [
518 'fluent-cart/checkout',
519 'core/column',
520 'core/group'
521 ],
522 ],
523 [
524 'title' => __('Checkout EU VAT', 'fluent-cart'),
525 'slug' => 'fluent-cart/checkout-eu-vat',
526 'callback' => [$this, 'renderCheckoutEuVat'],
527 'component' => 'CheckoutEuVatBlock',
528 'icon' => 'editor-code',
529 'supports' => [
530 'html' => false,
531 'spacing' => [
532 'margin' => true,
533 'padding' => true
534 ],
535 '__experimentalBorder' => [
536 'radius' => true,
537 'color' => true,
538 'width' => true,
539 'style' => true
540 ]
541 ],
542 'parent' => [
543 'fluent-cart/checkout',
544 'core/column',
545 'core/group'
546 ],
547 ]
548 ];
549 }
550
551 public function renderCheckoutNameFields($attributes, $content, $block)
552 {
553 $atts = get_block_wrapper_attributes();
554 $cart = $this->getCart();
555 if (empty(Arr::get($cart, 'cart_data', []))) {
556 return '';
557 }
558
559 ob_start();
560 ?>
561 <div <?php echo $atts; ?>>
562 <?php
563 $renderer = new CheckoutRenderer($cart);
564 $renderer->renderNameFields();
565 $renderer->renderB2BToggle();
566 $renderer->renderCreateAccountField();
567 ?>
568 </div>
569 <?php
570 return ob_get_clean();
571 }
572
573 public function renderCheckoutCreateAccountField($attributes, $content, $block)
574 {
575 return '';
576 }
577
578 public function renderCheckoutAddressFields($attributes, $content, $block)
579 {
580 $atts = get_block_wrapper_attributes();
581
582 $cart = $this->getCart();
583 if (empty(Arr::get($cart, 'cart_data', []))) {
584 return '';
585 }
586
587 $innerBlocksContent = '';
588 if ($block instanceof \WP_Block && !empty($block->inner_blocks)) {
589 ob_start();
590 ?>
591 <div <?php echo $atts; ?>>
592 <?php
593 foreach ($block->inner_blocks as $inner_block) {
594 if (isset($inner_block->parsed_block)) {
595 echo $inner_block->render();
596 }
597 } ?>
598 </div>
599 <?php
600 $innerBlocksContent = ob_get_clean();
601 }
602 return $innerBlocksContent;
603 }
604
605 public function renderCheckoutBillingAddressField($attributes, $content, $block)
606 {
607 $atts = get_block_wrapper_attributes();
608 $cart = $this->getCart();
609
610 $addressTitle = Arr::get($attributes, 'addressTitle');
611
612 if (empty(Arr::get($cart, 'cart_data', []))) {
613 return '';
614 }
615
616 ob_start();
617 ?>
618 <div <?php echo $atts; ?>>
619 <?php
620 (new CheckoutRenderer($cart))->renderBillingAddressFields($addressTitle);
621 ?>
622 </div>
623 <?php
624 return ob_get_clean();
625
626 }
627
628 public function renderCheckoutShippingAddressField($attributes, $content, $block)
629 {
630 $atts = get_block_wrapper_attributes();
631 $cart = $this->getCart();
632 $addressTitle = Arr::get($attributes, 'addressTitle');
633 if (empty(Arr::get($cart, 'cart_data', [])) || !$cart->requireShipping()) {
634 return '';
635 }
636 ob_start();
637 ?>
638 <div <?php echo $atts; ?>>
639 <?php
640 (new CheckoutRenderer($cart))->renderShippingAddressFields($addressTitle);
641 ?>
642 </div>
643 <?php
644 return ob_get_clean();
645 }
646
647 public function renderCheckoutShipToDifferentField($attributes, $content, $block)
648 {
649 $atts = get_block_wrapper_attributes();
650 $cart = $this->getCart();
651 $title = Arr::get($attributes, 'ship_to_different_title');
652 if (empty(Arr::get($cart, 'cart_data', [])) || !$cart->requireShipping()) {
653 return '';
654 }
655 ob_start();
656 ?>
657 <div <?php echo $atts; ?>>
658 <?php
659 (new CheckoutRenderer($cart))->renderShipToDifferentField([
660 'title' => $title,
661 'wrapper_atts'=> $atts,
662 ]);
663 ?>
664 </div>
665 <?php
666 return ob_get_clean();
667
668 }
669
670 public function renderCheckoutShippingMethods($attributes, $content, $block)
671 {
672 $cart = $this->getCart();
673 if (empty(Arr::get($cart, 'cart_data', []))) {
674 return '';
675 }
676 $class = $cart->requireShipping() ? '' : 'is-hidden';
677 $atts = get_block_wrapper_attributes([
678 'class' => 'fct_checkout_shipping_methods ' . $class
679 ]);
680 ob_start();
681 ?>
682 <div <?php echo $atts; ?>>
683 <?php
684 (new CheckoutRenderer($cart))->renderShippingOptions();
685 ?>
686 </div>
687 <?php
688 return ob_get_clean();
689 }
690
691 public function renderCheckoutPaymentMethods($attributes, $content, $block)
692 {
693 $cart = $this->getCart();
694 if (empty(Arr::get($cart, 'cart_data', []))) {
695 return '';
696 }
697 $atts = get_block_wrapper_attributes([
698 'class' => 'fct_checkout_payment_methods',
699 'data-fluent-cart-checkout-payment-methods' => ''
700 ]);
701 ob_start(); ?>
702 <?php do_action('fluent_cart/before_payment_methods', ['cart' => $cart]); ?>
703 <div <?php echo $atts; ?>>
704 <?php
705 (new CheckoutRenderer($cart))->renderPaymentMethods();
706 ?>
707 </div>
708 <?php do_action('fluent_cart/after_payment_methods', ['cart' => $cart]); ?>
709 <?php
710 return ob_get_clean();
711 }
712
713 public function renderCheckoutEuVat($attributes, $content, $block)
714 {
715 // Deprecated: VAT is now rendered inside the B2B section by renderCheckoutNameFields.
716 // Returning empty prevents a second, unwrapped VAT field from appearing outside
717 // the [data-fluent-cart-b2b-section] toggle on checkouts that still have this
718 // block in their saved template.
719 return '';
720 }
721
722 public function renderCheckoutAgreeTermsField($attributes, $content, $block)
723 {
724 $cart = $this->getCart();
725 if (empty(Arr::get($cart, 'cart_data', []))) {
726 return '';
727 }
728 $title = Arr::get($attributes, 'terms_title');
729 $atts = get_block_wrapper_attributes();
730 ob_start();
731 ?>
732 <div <?php echo $atts; ?>>
733 <?php
734 (new CheckoutRenderer($cart))->agreeTerms([
735 'title' => $title,
736 'wrapper_atts'=> $atts,
737 ]);
738 ?>
739 </div>
740 <?php
741 return ob_get_clean();
742 }
743
744 public function renderCheckoutSubmitButton($attributes, $content, $block)
745 {
746 $cart = $this->getCart();
747 if (empty(Arr::get($cart, 'cart_data', []))) {
748 return '';
749 }
750
751 $atts = get_block_wrapper_attributes();
752 ob_start();
753 (new CheckoutRenderer($cart))->renderCheckoutButton($atts);
754 return ob_get_clean();
755 }
756
757 public function renderCheckoutOrderNotesField($attributes, $content, $block)
758 {
759 $cart = $this->getCart();
760 if (empty(Arr::get($cart, 'cart_data', []))) {
761 return '';
762 }
763 $atts = get_block_wrapper_attributes();
764 $title = Arr::get($attributes, 'title');
765 ob_start();
766 ?>
767 <div <?php echo $atts; ?>>
768 <?php (new CheckoutRenderer($cart))->renderOrderNoteField($title); ?>
769 </div>
770 <?php
771 return ob_get_clean();
772 }
773
774 public function renderCheckoutSummary($attributes, $content, $block)
775 {
776 $cart = $this->getCart();
777 if (empty(Arr::get($cart, 'cart_data', []))) {
778 return '';
779 }
780 $atts = get_block_wrapper_attributes([
781 'class' => 'fct_checkout_summary'
782 ]);
783
784 ob_start();
785 ?>
786 <div <?php echo $atts; ?>>
787 <div class="fct_summary active" data-fluent-cart-checkout-page-checkout-form-order-summary>
788 <?php (new CartSummaryRender($cart))->render(); ?>
789 </div>
790 </div>
791 <?php
792 return ob_get_clean();
793 }
794
795 public function renderCheckoutOrderSummary($attributes, $content, $block)
796 {
797 $cart = $this->getCart();
798 if (empty(Arr::get($cart, 'cart_data', []))) {
799 return '';
800 }
801 $atts = get_block_wrapper_attributes([
802 'class' => 'fct_items_wrapper',
803 'data-fluent-cart-checkout-item-wrapper' => ''
804 ]);
805 ob_start();
806 ?>
807 <div <?php echo $atts; ?>>
808 <?php
809 (new CartSummaryRender($cart))->renderItemsLists();
810 ?>
811 </div>
812 <?php
813 return ob_get_clean();
814 }
815
816 public function renderCheckoutSummaryFooter($attributes, $content, $block)
817 {
818 $cart = $this->getCart();
819 if (empty(Arr::get($cart, 'cart_data', []))) {
820 return '';
821 }
822 $innerBlocksContent = '';
823 if ($block instanceof \WP_Block && !empty($block->inner_blocks)) {
824 ob_start();
825 ?>
826 <div class="fct_summary_items">
827 <ul class="fct_summary_items_list">
828 <?php
829 $hasFeeBlock = false;
830 foreach ($block->inner_blocks as $inner_block) {
831 if (isset($inner_block->parsed_block)) {
832 if (Arr::get($inner_block->parsed_block, 'blockName') === 'fluent-cart/checkout-fees') {
833 $hasFeeBlock = true;
834 }
835 // Auto-render fees before the Coupon block if no explicit fees block exists
836 if (!$hasFeeBlock && Arr::get($inner_block->parsed_block, 'blockName') === 'fluent-cart/checkout-coupon') {
837 (new CartSummaryRender($cart))->renderFees();
838 $hasFeeBlock = true;
839 }
840 echo $inner_block->render();
841 }
842 }
843 // Fallback: render fees at the end if no fees block and no coupon block existed
844 if (!$hasFeeBlock) {
845 (new CartSummaryRender($cart))->renderFees();
846 }
847 ?>
848 </ul>
849 </div>
850 <?php
851 $innerBlocksContent = ob_get_clean();
852 }
853
854 return $innerBlocksContent;
855 }
856
857 public function renderCheckoutSubtotal($attributes, $content, $block)
858 {
859 $cart = $this->getCart();
860 if (empty(Arr::get($cart, 'cart_data', []))) {
861 return '';
862 }
863 $atts = get_block_wrapper_attributes();
864 ob_start();
865 (new CartSummaryRender($cart))->renderSubtotal($atts);
866 return ob_get_clean();
867 }
868
869 public function renderCheckoutShipping($attributes, $content, $block)
870 {
871 $cart = $this->getCart();
872 if (empty(Arr::get($cart, 'cart_data', []))) {
873 return '';
874 }
875 $atts = get_block_wrapper_attributes([
876 'class' => $cart->getShippingTotal() === 0 ? 'shipping-charge-hidden' : '',
877 'data-fluent-cart-checkout-shipping-amount-wrapper' => ''
878 ]);
879 ob_start();
880 (new CartSummaryRender($cart))->renderShipping($atts);
881 return ob_get_clean();
882 }
883
884 public function renderCheckoutFees($attributes, $content, $block)
885 {
886 $cart = $this->getCart();
887 if (empty(Arr::get($cart, 'cart_data', []))) {
888 return '';
889 }
890 ob_start();
891 (new CartSummaryRender($cart))->renderFees();
892 return ob_get_clean();
893 }
894
895 public function renderCheckoutCoupon($attributes, $content, $block)
896 {
897 $cart = $this->getCart();
898 if (empty(Arr::get($cart, 'cart_data', []))) {
899 return '';
900 }
901 $atts = get_block_wrapper_attributes([
902 'data-fluent-cart-checkout-page-applied-coupon' => ''
903 ]);
904 ob_start();
905 ?>
906 <li <?php echo $atts; ?>>
907 <?php
908 (new CartSummaryRender($cart))->showCouponField();
909 ?>
910 </li>
911 <?php
912 return ob_get_clean();
913 }
914
915 public function renderCheckoutManualDiscount($attributes, $content, $block)
916 {
917 $cart = $this->getCart();
918 if (empty(Arr::get($cart, 'cart_data', []))) {
919 return '';
920 }
921 ob_start();
922 (new CartSummaryRender($cart))->showUpgradeDiscount();
923 (new CartSummaryRender($cart))->showProrateCredit();
924 (new CartSummaryRender($cart))->showManualDiscount();
925 return ob_get_clean();
926 }
927
928 public function renderCheckoutTax($attributes, $content, $block)
929 {
930 $cart = $this->getCart();
931 if (empty(Arr::get($cart, 'cart_data', []))) {
932 return '';
933 }
934 $atts = get_block_wrapper_attributes();
935 ob_start();
936 (new TaxModule())->renderTaxRow($cart, $atts);
937 return ob_get_clean();
938 }
939
940 public function renderCheckoutShippingTax($attributes, $content, $block)
941 {
942 $cart = $this->getCart();
943 if (empty(Arr::get($cart, 'cart_data', []))) {
944 return '';
945 }
946 $atts = get_block_wrapper_attributes();
947 ob_start();
948 (new TaxModule())->renderShippingTaxRow($cart, $atts);
949 return ob_get_clean();
950 }
951
952 public function renderCheckoutTotal($attributes, $content, $block)
953 {
954 $cart = $this->getCart();
955 if (empty(Arr::get($cart, 'cart_data', []))) {
956 return '';
957 }
958 $atts = get_block_wrapper_attributes([
959 'class' => 'fct_summary_items_total',
960 'data-fluent-cart-checkout-page-current-total' => ''
961 ]);
962 ob_start();
963 (new CartSummaryRender($cart))->renderTotal($atts);
964 return ob_get_clean();
965 }
966
967 public function renderCheckoutOrderBump($attributes, $content, $block)
968 {
969 if (!App::isProActive() || !ModuleSettings::isActive('order_bump')) {
970 return '';
971 }
972
973 $cart = $this->getCart();
974 if (empty(Arr::get($cart, 'cart_data', []))) {
975 return '';
976 }
977
978 // A cart bound to an existing payment (custom payment link, renewal invoice, early
979 // installment) or already carrying an upgrade cannot take new items — the
980 // apply_order_bump handler refuses it, so rendering the bump would only offer a
981 // control that fails. Same predicate on both sides so they cannot drift.
982 if (!$cart->acceptsAdditionalItems()) {
983 return '';
984 }
985
986 $atts = get_block_wrapper_attributes();
987 $title = Arr::get($attributes, 'section_title');
988 ob_start();
989 ?>
990 <div <?php echo $atts; ?>>
991 <?php
992 (new OrderBumpBoot())->maybeShowBumps([
993 'cart' => $cart,
994 'section_title' => $title
995 ]);
996 ?>
997 </div>
998 <?php
999 return ob_get_clean();
1000 }
1001
1002
1003 protected function getLocalizationKey(): string
1004 {
1005 return 'fluent_cart_checkout_inner_blocks';
1006 }
1007
1008 public function localizeData(): array
1009 {
1010 return [
1011 $this->getLocalizationKey() => [
1012 'blocks' => Arr::except($this->getInnerBlocks(), ['callback']),
1013 ],
1014 'fluentcart_single_product_vars' => [
1015 'trans' => TransStrings::singleProductPageString(),
1016 'cart_button_text' => App::storeSettings()->get('cart_button_text', __('Add To Cart', 'fluent-cart')),
1017 'out_of_stock_button_text' => App::storeSettings()->get('out_of_stock_button_text', __('Not Available', 'fluent-cart')),
1018 'in_stock_status' => Helper::IN_STOCK,
1019 'out_of_stock_status' => Helper::OUT_OF_STOCK,
1020 'enable_image_zoom' => (new StoreSettings())->get('enable_image_zoom_in_single_product'),
1021 'enable_image_zoom_in_modal' => (new StoreSettings())->get('enable_image_zoom_in_modal')
1022 ]
1023 ];
1024 }
1025
1026
1027 public function getStyles(): array
1028 {
1029 return [
1030 'public/checkout/style/checkout.scss',
1031 'public/components/select/style/style.scss'
1032 ];
1033 }
1034
1035 public function getScripts(): array
1036 {
1037 $scripts = [
1038 [
1039 'source' => 'admin/BlockEditor/ReactSupport.js',
1040 'dependencies' => ['wp-blocks', 'wp-components']
1041 ],
1042 [
1043 'source' => 'admin/BlockEditor/Checkout/InnerBlocks/InnerBlocks.jsx',
1044 'dependencies' => ['wp-blocks', 'wp-components', 'wp-block-editor']
1045 ]
1046 ];
1047
1048 return $scripts;
1049 }
1050
1051 protected function generateEnqueueSlug(): string
1052 {
1053 return 'fluent_cart_checkout_inner_blocks';
1054 }
1055
1056 }
1057