PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.3.22
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.3.22
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 / Services / Renderer / Receipt / ThankYouRender.php

ThankYouRender.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.3.22, at app/Services/Renderer/Receipt/ThankYouRender.php

999 lines 39.2 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\Services\Renderer\Receipt;
4
5 use FluentCart\Api\StoreSettings;
6 use FluentCart\App\App;
7 use FluentCart\App\Helpers\Helper;
8 use FluentCart\App\Modules\Tax\TaxModule;
9 use FluentCart\App\Modules\Templating\AssetLoader;
10 use FluentCart\App\Vite;
11 use FluentCart\Framework\Support\Arr;
12 use FluentCart\App\Modules\PaymentMethods\Core\GatewayManager;
13
14 class ThankYouRender
15 {
16
17 protected $config = null;
18
19 protected $settings = null;
20
21 protected $is_first_time = false;
22
23 protected $order_operation = null;
24
25
26 public function __construct($config)
27 {
28 $this->config = $config;
29
30 $this->is_first_time = Arr::get($this->config, 'is_first_time', false);
31 $this->order_operation = Arr::get($this->config, 'order_operation', false);
32
33 $this->settings = new StoreSettings();
34 AssetLoader::enqueueThankYouPageAssets();
35
36 }
37
38 public function renderWrapperStart()
39 {
40 ?>
41 <div class="fct-thank-you-page">
42 <div class="fct-thank-you-page-inner">
43 <div class="fct-thank-you-page-content email-template-content">
44 <?php
45 }
46
47 public function renderWrapperEnd()
48 {
49 ?>
50 </div>
51 </div>
52 </div>
53 <?php
54 }
55
56 public function render($hide_wrapper = false)
57 {
58 $order = Arr::get($this->config, 'order', null);
59
60 if (!$order) {
61 return;
62 }
63 ?>
64 <?php if (!$hide_wrapper) {
65 $this->renderWrapperStart();
66 } ?>
67 <?php do_action('fluent_cart/receipt/thank_you/before_header', $this->config); ?>
68 <?php $this->renderHeader(); ?>
69 <?php do_action('fluent_cart/receipt/thank_you/after_header', $this->config); ?>
70
71 <?php do_action('fluent_cart/receipt/thank_you/before_body', $this->config); ?>
72 <?php $this->renderBody(); ?>
73 <?php do_action('fluent_cart/receipt/thank_you/after_body', $this->config); ?>
74 <?php if (!$hide_wrapper) {
75 $this->renderWrapperEnd();
76 } ?>
77
78 <?php
79
80 $this->renderFooter();
81
82 do_action('fluent_cart/after_receipt', [
83 'order' => $order,
84 'is_first_time' => $this->is_first_time ?? false,
85 'order_operation' => $this->order_operation ?? null
86 ]);
87
88 if (!empty($this->is_first_time)) {
89 do_action('fluent_cart/after_receipt_first_time', [
90 'order' => $order,
91 'order_operation' => $this->order_operation ?? null
92 ]);
93 }
94 }
95
96 public function renderHeader()
97 {
98 $bgColor = '#d4edda';
99 $titleColor = '#155724';
100 $iconBg = '#155724bd';
101
102 $order = Arr::get($this->config, 'order', null);
103
104 if ($order->payment_status !== 'paid') {
105 $bgColor = '#fff3cd';
106 $titleColor = '#856404';
107 $iconBg = '#856404bd';
108 }
109 ?>
110 <div class="fct-thank-you-page-header" style="background: <?php echo esc_attr($bgColor); ?>;">
111 <?php if ($order->payment_status !== 'paid') : ?>
112 <div class="fct-thank-you-page-header-icon" style="background: <?php echo esc_attr($iconBg); ?>;">
113 <svg class="w-64 h-64" xmlns="http://www.w3.org/2000/svg"
114 viewBox="0 0 1024 1024" fill="currentColor">
115 <path
116 d="M480 674V192c0-18 14-32 32-32s32 14 32 32v482h-64zm0 63h64v60h-64v-60zM0 512C0 229 229 0 512 0s512 229 512 512-229 512-512 512S0 795 0 512zm961 0c0-247-202-448-449-448S64 265 64 512s201 448 448 448 449-201 449-448z"></path>
117 </svg>
118 </div>
119 <h1 class="fct-thank-you-page-header-title" style="color:<?php echo esc_attr($titleColor); ?>">
120 <?php echo esc_html__('Payment Pending!', 'fluent-cart'); ?>
121 </h1>
122
123 <?php else: ?>
124 <div class="fct-thank-you-page-header-icon" style="background: <?php echo esc_attr($iconBg); ?>;">
125 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"
126 stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
127 <polyline points="20,6 9,17 4,12"></polyline>
128 </svg>
129 </div>
130 <h1 class="fct-thank-you-page-header-title" style="color:<?php echo esc_attr($titleColor); ?>;">
131 <?php echo esc_html__('Purchase Successful!', 'fluent-cart'); ?>
132 </h1>
133 <?php endif; ?>
134
135 <?php do_action('fluent_cart/receipt/thank_you/after_header_title', $this->config); ?>
136
137 </div>
138
139 <?php
140 }
141
142 public function renderBody()
143 {
144 $order = Arr::get($this->config, 'order', null);
145
146 if (!$order) {
147 return;
148 }
149 ?>
150 <div class="fct-thank-you-page-body">
151 <div class="fct-thank-you-page-body-inner">
152 <div class="fct-thank-you-page-body-content">
153 <div class="fct-thank-you-page-body-content-inner">
154 <?php do_action('fluent_cart/receipt/thank_you/before_order_header', $this->config); ?>
155 <?php $this->renderOrderHeader(); ?>
156 <?php do_action('fluent_cart/receipt/thank_you/after_order_header', $this->config); ?>
157
158 <?php $this->renderStoreTaxInformation(); ?>
159
160 <?php do_action('fluent_cart/receipt/thank_you/before_order_items', $this->config); ?>
161 <?php $this->renderOrderItems(); ?>
162 <?php do_action('fluent_cart/receipt/thank_you/after_order_items', $this->config); ?>
163
164 <?php $this->renderSubscriptionItems(); ?>
165
166 <?php $this->renderDownloads(); ?>
167
168 <?php $this->renderLicenses(); ?>
169
170 <?php $this->renderAddress(); ?>
171
172 <?php $this->renderThankYouPageInstructions(); ?>
173
174 </div>
175 </div>
176 </div>
177 </div>
178
179 <?php
180 }
181
182 public function renderOrderHeader()
183 {
184 $order = Arr::get($this->config, 'order', null);
185 $profilePage = $this->settings->getCustomerProfilePage();
186 ?>
187 <div class="no-print">
188 <div class="no-print-title">
189 <?php
190 echo sprintf(
191 /* translators: %s is the customer's full name */
192 esc_html__('Hello %s!', 'fluent-cart'),
193 esc_html($order->customer->full_name)
194 );
195 ?>
196 </div>
197 <?php if ($order->payment_status === 'paid') : ?>
198 <p>
199 <?php
200 printf(
201 '%s<strong style="color: #007bff;"><a href="%s">#%s</a></strong>%s',
202 esc_html__('Your order ', 'fluent-cart'),
203 esc_url($profilePage . 'order/' . $order->uuid),
204 esc_html($order->invoice_no),
205 esc_html__(' has been placed successfully.', 'fluent-cart')
206 );
207 ?>
208 </p>
209 <?php else: ?>
210 <p>
211
212 <?php
213 printf(
214 '<strong style="color: #007bff;"><a href="%s">%s</a></strong> %s <a style="color: #007bff;" target="_blank" href="%s">%s</a>.',
215 esc_url($profilePage . 'order/' . $order->uuid),
216 esc_html__('Your order', 'fluent-cart'),
217 esc_html__('has payment due. You can pay from', 'fluent-cart'),
218 esc_url(\FluentCart\App\Services\Payments\PaymentHelper::getCustomPaymentLink($order->uuid)),
219 esc_html__('here', 'fluent-cart')
220 );
221 ?>
222
223 </p>
224 <?php endif; ?>
225
226 </div>
227
228 <?php
229 }
230
231 public function renderStoreTaxInformation()
232 {
233 $order = Arr::get($this->config, 'order', null);
234
235 $orderTaxRates = $order->orderTaxRates->first();
236 if ($order->tax_total > 0 || $orderTaxRates): ?>
237 <div class="fct_invoice_tax_content">
238 <?php
239 if ($orderTaxRates) {
240 $storeVatNumber = Arr::get($orderTaxRates->meta, 'store_vat_number', '');
241 $taxcountry = Arr::get($orderTaxRates->meta ?? [], 'tax_country', '');
242 if ($storeVatNumber !== '') {
243 echo '<p>' . esc_html(TaxModule::getCountryTaxTitle($taxcountry)) . ': ' . esc_html($storeVatNumber) . '</p>';
244 }
245 }
246 ?>
247 </div>
248 <?php endif;
249 }
250
251 public function renderOrderItems()
252 {
253 $order = Arr::get($this->config, 'order', null);
254
255 if ($order->order_items) : ?>
256 <div class="fct-thank-you-page-order-items">
257 <?php $this->renderOrderItemsHeader(); ?>
258
259 <?php $this->renderOrderItemsBody(); ?>
260 </div>
261 <?php endif;
262 }
263
264 public function renderOrderItemsHeader()
265 {
266 ?>
267 <div class="fct-thank-you-page-order-items-header">
268 <div class="fct-thank-you-page-order-items-header-row">
269 <?php echo esc_html__('Item', 'fluent-cart'); ?>
270 </div>
271 <div class="fct-thank-you-page-order-items-header-row">
272 <?php echo esc_html__('Total', 'fluent-cart'); ?>
273 </div>
274 </div>
275 <?php
276 }
277
278 public function renderOrderItemsBody()
279 {
280 $order = Arr::get($this->config, 'order', null);
281 ?>
282 <div class="fct-thank-you-page-order-items-body">
283 <?php
284 $orderItems = $order->getProductItems()->toArray();
285 $orderItems = $this->buildBundleItemsTree($orderItems);
286
287 foreach ($orderItems as $item) :
288 ?>
289 <div class="fct-thank-you-page-order-items-list">
290 <div class="fct-thank-you-page-order-items-list-title">
291 <p class="fct-thank-you-page-order-items-list-quantity">
292 <?php echo esc_html($item['post_title']); ?>
293 <?php if ($item['quantity'] > 1): ?>
294 <span>x <?php echo esc_html(Helper::translateNumber($item['quantity'])); ?></span>
295 <?php endif; ?>
296 </p>
297 <p class="fct-thank-you-page-order-items-list-variant-title">
298 - <?php echo esc_html($item['title']); ?>
299 </p>
300 <?php if ($item['payment_type'] === 'subscription' && !empty($item['payment_info'])): ?>
301 <p class="fct-thank-you-page-order-items-list-payment-info">
302 <?php echo wp_kses_post($item['payment_info']) ?>
303 </p>
304 <?php endif; ?>
305
306 <?php $this->renderBundleProducts($item); ?>
307 </div>
308 <div class="fct-thank-you-page-order-items-list-price">
309 <div class="fct-thank-you-page-order-items-list-price-inner">
310 <?php echo esc_html($item['formatted_total']); ?>
311 </div>
312 </div>
313 </div>
314
315
316 <?php endforeach; ?>
317
318 <?php $this->renderOrderTotal(); ?>
319
320 <!-- tax note -->
321 <?php $this->renderTaxNote(); ?>
322
323 </div>
324 <?php
325 }
326
327 public function renderThankYouPageInstructions()
328 {
329 $order = Arr::get($this->config, 'order', null);
330 if (!$order) {
331 return;
332 }
333 $transaction = $order->getLatestTransaction();
334 if ($transaction && !empty($transaction->payment_method)) {
335 $methodSlug = $transaction->payment_method;
336 }
337 if (GatewayManager::has($methodSlug)) {
338 $gatewayInstance = GatewayManager::getInstance($methodSlug);
339 if ($gatewayInstance && isset($gatewayInstance->settings)) {
340 $gatewaySettings = (array) $gatewayInstance->settings->get();
341 $thankYouPageInstructions = Arr::get($gatewaySettings, 'thank_you_page_instructions', '');
342 }
343 }
344
345 if (!empty($thankYouPageInstructions)) : ?>
346
347 <div style="max-width: 620px; margin: 15px auto 0; font-family: Arial, Helvetica, sans-serif;">
348 <div style="font-size: 14px; color: #2F3448; padding: 12px 0; border-top: 1px solid #e7eaee;">
349 <?php echo wp_kses_post($thankYouPageInstructions); ?>
350 </div>
351 </div>
352 <?php endif;
353 }
354
355 public function renderOrderTotal()
356 {
357 ?>
358 <div class="fct-thank-you-page-order-items-total">
359 <?php $this->renderSubtotal(); ?>
360 <?php $this->renderDiscount(); ?>
361 <?php $this->renderShipping(); ?>
362 <?php $this->renderFees(); ?>
363 <?php $this->renderTaxTotal(); ?>
364 <?php $this->renderShippingTax(); ?>
365
366 <?php $this->renderRefund(); ?>
367 <?php $this->renderTotal(); ?>
368 <?php $this->renderPaymentMethod(); ?>
369 </div>
370 <?php
371 }
372
373 public function renderTaxNote()
374 {
375 $order = Arr::get($this->config, 'order', null);
376 $taxtotal = $order->tax_total + $order->shipping_tax;
377 if (Arr::get($orderTaxRates->meta ?? [], 'vat_reverse.valid') && !$taxtotal): ?>
378 <div style="text-align: right; font-size: 14px; margin-top: 10px;">
379 <?php echo '*' . esc_html__('Tax to be paid on reverse charge basis', 'fluent-cart') ?>
380 </div>
381 <?php
382 endif;
383 }
384
385 public function renderSubtotal()
386 {
387 $order = Arr::get($this->config, 'order', null);
388 if ($order->subtotal != $order->total_amount || $order->tax_total > 0): ?>
389 <div class="fct-meta-line fct-thank-you-page-order-items-total-subtotal">
390 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
391 <?php echo esc_html__('Subtotal', 'fluent-cart'); ?>
392 </div>
393 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value"><?php echo esc_html(Helper::toDecimal($order->subtotal)); ?></div>
394 </div>
395 <?php endif;
396 }
397
398 public function renderDiscount()
399 {
400 $order = Arr::get($this->config, 'order', null);
401
402 if ($order->manual_discount_total + $order->coupon_discount_total > 0): ?>
403 <div class="fct-meta-line fct-thank-you-page-order-items-total-discount">
404 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
405 <?php echo esc_html__('Discount', 'fluent-cart'); ?>
406 </div>
407 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
408 - <?php echo esc_html(Helper::toDecimal($order->manual_discount_total + $order->coupon_discount_total)); ?>
409 </div>
410 </div>
411 <?php endif;
412 }
413
414 public function renderShipping()
415 {
416 $order = Arr::get($this->config, 'order', null);
417
418 if ($order->shipping_total > 0): ?>
419 <div class="fct-meta-line fct-thank-you-page-order-items-total-shipping">
420 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
421 <?php echo esc_html__('Shipping', 'fluent-cart'); ?>
422 </div>
423 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value"><?php echo esc_html(Helper::toDecimal($order->shipping_total)); ?></div>
424 </div>
425 <?php endif;
426 }
427
428 public function renderFees()
429 {
430 $order = Arr::get($this->config, 'order', null);
431 if (!$order || $order->fee_total <= 0) {
432 return;
433 }
434 $feeItems = $order->feeItems()->get();
435 foreach ($feeItems as $feeItem): ?>
436 <div class="fct-meta-line fct-thank-you-page-order-items-total-fee">
437 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
438 <?php echo esc_html($feeItem->title); ?>
439 </div>
440 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
441 <?php echo esc_html(Helper::toDecimal($feeItem->subtotal)); ?>
442 </div>
443 </div>
444 <?php endforeach;
445 }
446
447 public function renderTaxTotal()
448 {
449 $order = Arr::get($this->config, 'order', null);
450
451 if ($order->tax_total > 0): ?>
452 <div class="fct-meta-line fct-thank-you-page-order-items-total-tax">
453 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
454 <?php echo esc_html__('Total Tax', 'fluent-cart'); ?>
455 <?php echo $order->tax_behavior == 2 ? esc_html__('(Included)', 'fluent-cart') : esc_html__('(Excluded)', 'fluent-cart'); ?>
456 </div>
457 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
458 <?php echo esc_html(Helper::toDecimal($order->tax_total)); ?>
459 </div>
460 </div>
461 <?php endif;
462 }
463
464 public function renderShippingTax()
465 {
466 $order = Arr::get($this->config, 'order', null);
467
468 if ($order->shipping_tax > 0): ?>
469 <div class="fct-meta-line fct-thank-you-page-order-items-total-shipping-tax">
470 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
471 <?php echo esc_html__('Shipping Tax', 'fluent-cart'); ?>
472 <?php echo $order->tax_behavior == 2 ? esc_html__('(Included)', 'fluent-cart') : esc_html__('(Excluded)', 'fluent-cart'); ?>
473 </div>
474 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
475 <?php echo esc_html(Helper::toDecimal($order->shipping_tax)); ?>
476 </div>
477 </div>
478 <?php endif;
479 }
480
481 public function renderRefund()
482 {
483 $order = Arr::get($this->config, 'order', null);
484
485 if ($order->total_refund > 0): ?>
486 <div class="fct-meta-line fct-thank-you-page-order-items-total-refund">
487 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
488 <?php echo esc_html__('Refund', 'fluent-cart'); ?>
489 </div>
490 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
491 - <?php echo esc_html(Helper::toDecimal($order->total_refund)); ?>
492 </div>
493 </div>
494 <?php endif;
495 }
496
497 public function renderTotal()
498 {
499 $order = Arr::get($this->config, 'order', null);
500 ?>
501 <div class="fct-meta-line fct-thank-you-page-order-items-total-total">
502 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
503 <?php echo esc_html__('Total', 'fluent-cart'); ?>
504 </div>
505 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
506 <?php echo esc_html(Helper::toDecimal($order->total_amount - $order->total_refund)); ?>
507 </div>
508 </div>
509 <?php
510 }
511
512 public function renderPaymentMethod()
513 {
514 $order = Arr::get($this->config, 'order', null);
515 $transaction = $order->getLatestTransaction();
516 ?>
517 <div class="fct-meta-line fct-thank-you-page-order-items-total-payment-method">
518 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
519 <?php echo esc_html__('Payment Method', 'fluent-cart'); ?>
520 </div>
521 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
522 <?php if ($transaction->card_last_4) :
523 echo esc_html($transaction->card_brand) . ' ' . esc_html($transaction->card_last_4);
524 else:
525 $title = $transaction->payment_method;
526 $gateway = GatewayManager::getInstance($transaction->payment_method);
527 $title = $gateway ? $gateway->getMeta('title') : $title;
528 echo esc_html($title);
529 endif; ?>
530 </div>
531 </div>
532 <?php
533 }
534
535 public function renderSubscriptionItems()
536 {
537 $order = Arr::get($this->config, 'order', null);
538 $subscriptions = $order->subscriptions;
539
540 if ($subscriptions->count() == 0) {
541 return;
542 }
543 ?>
544 <div class="fct-thank-you-page-order-items-subscriptions">
545 <p class="fct-thank-you-page-order-items-subscriptions-heading">
546 <?php echo esc_html__('Subscription Details', 'fluent-cart'); ?>
547 </p>
548
549 <table class="fct-thank-you-page-order-items-subscriptions-table" role="presentation">
550 <tbody>
551 <?php foreach ($subscriptions as $subs): ?>
552 <tr>
553 <td class="fct-thank-you-page-order-items-subscriptions-table-file">
554 <p>
555 <?php echo esc_html($subs->item_name); ?>
556 </p>
557 </td>
558
559 <td class="fct-thank-you-page-order-items-subscriptions-billing-infos">
560 <div>
561 <?php if (!empty($subs->payment_info)) : ?>
562 <span>
563 <?php echo $subs->payment_info; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
564 </span>
565 <?php endif; ?>
566
567 <?php if (!empty($subs->next_billing_date)) : ?>
568 <p class="fct-thank-you-page-order-items-subscriptions-billing-infos-next-billing"><?php
569 echo sprintf(
570 /* translators: 1: Next billing date */
571 esc_html__('- Auto renews on %1$s', 'fluent-cart'),
572 esc_html(
573 \FluentCart\App\Services\DateTime\DateTime::anyTimeToGmt($subs->next_billing_date)->format('M d, Y h:i A')
574 )
575 );
576 ?>
577 </p>
578 <?php endif; ?>
579 </div>
580 </td>
581 </tr>
582 <?php endforeach; ?>
583 </tbody>
584 </table>
585 </div>
586
587
588 <?php
589 // App::make('view')->render('invoice.parts.subscription_items', [
590 // 'subscriptions' => $order->subscriptions,
591 // 'order' => $order
592 // ]);
593 }
594
595 public function renderDownloads()
596 {
597 $order = Arr::get($this->config, 'order', null);
598 $downloads = $order->getDownloads();
599 if (!$downloads) {
600 return;
601 }
602 ?>
603 <div class="fct-thank-you-page-order-items-downloads">
604 <p class="fct-thank-you-page-order-items-downloads-heading">
605 <?php echo esc_html__('Downloads', 'fluent-cart'); ?>
606 </p>
607
608 <table class="fct-thank-you-page-order-items-downloads-table"
609 role="presentation">
610 <tbody>
611 <tr>
612 <td>
613 <table role="presentation" width="100%">
614 <tbody>
615 <?php foreach ($downloads as $downloadItem): ?>
616 <tr>
617 <td>
618 <?php if ($downloadItem['downloads']): ?>
619
620 <table role="presentation">
621 <tbody>
622 <?php foreach ($downloadItem['downloads'] as $download): ?>
623 <tr>
624 <td class="fct-thank-you-page-order-items-downloads-table-file">
625 <p>
626 <?php echo esc_html($download['title']); ?>
627 <?php if ($download['file_size']): ?>
628 <span>(<?php echo esc_html(Helper::readableFileSize($download['file_size'])); ?>)</span>
629 <?php endif; ?>
630 </p>
631 </td>
632 <td class="fct-thank-you-page-order-items-downloads-button">
633 <a href="<?php echo esc_url($download['download_url'] ?? ''); ?>">
634 <?php echo esc_html__('Download', 'fluent-cart'); ?>
635 </a>
636 </td>
637 </tr>
638 <?php endforeach; ?>
639 </tbody>
640 </table>
641
642 <?php endif; ?>
643
644 </td>
645 </tr>
646 <?php endforeach; ?>
647 </tbody>
648 </table>
649 </td>
650 </tr>
651 </tbody>
652 </table>
653 </div>
654
655 <?php $this->renderDownloadsNotice(); ?>
656
657 <?php
658 }
659
660 public function renderDownloadsNotice($show_notice = false)
661 {
662 $showNotice = $show_notice ?? true;
663 ?>
664 <?php if (!$showNotice) {
665 return;
666 } ?>
667 <table
668 class="fct-thank-you-page-order-items-downloads-notice"
669 role="presentation">
670 <tbody>
671 <tr>
672 <td>
673 <p class="fct-thank-you-page-order-items-downloads-notice-title">
674 <?php echo esc_html__('Important', 'fluent-cart'); ?>
675 </p>
676 <p class="fct-thank-you-page-order-items-downloads-notice-content">
677 <?php echo esc_html__('This download link is valid for 7 days. After that, you can download the files again from your account
678 on our website.', 'fluent-cart'); ?>
679 </p>
680 </td>
681 </tr>
682 </tbody>
683 </table>
684 <?php
685 }
686
687 public function renderLicenseNotice($show_notice = false)
688 {
689 $showNotice = $show_notice ?? true;
690 ?>
691 <?php if (!$showNotice) {
692 return;
693 } ?>
694 <table
695 class="fct-thank-you-page-order-items-downloads-notice"
696 role="presentation">
697 <tbody>
698 <tr>
699 <td>
700 <p class="fct-thank-you-page-order-items-downloads-notice-title">
701 <?php echo esc_html__('Important', 'fluent-cart'); ?>
702 </p>
703 <p class="fct-thank-you-page-order-items-downloads-notice-content">
704 <?php echo esc_html__('This download link is valid for 7 days. After that, you can download the files again from your account on our website.', 'fluent-cart'); ?>
705 </p>
706 </td>
707 </tr>
708 </tbody>
709 </table>
710 <?php
711 }
712
713 public function renderLicenses()
714 {
715 $order = Arr::get($this->config, 'order', null);
716 $licenses = $order->getLicenses();
717 if (!$licenses || $licenses->count() == 0) {
718 return;
719 }
720 ?>
721 <div class="fct-thank-you-page-order-items-licenses">
722 <p class="fct-thank-you-page-order-items-licenses-heading">
723 <?php echo esc_html__('Licenses', 'fluent-cart'); ?>
724 </p>
725 <table class="fct-thank-you-page-order-items-licenses-table" role="presentation">
726 <tbody>
727 <tr>
728 <td>
729 <table role="presentation">
730 <tbody>
731
732 <?php foreach ($licenses as $license): ?>
733 <tr>
734 <td class="fct-thank-you-page-order-items-licenses-table-file">
735 <p>
736 <?php echo esc_html($license->productVariant->variation_title); ?>:
737 <?php echo esc_html($license->license_key); ?>
738 </p>
739 </td>
740 </tr>
741 <?php endforeach; ?>
742 </tbody>
743 </table>
744 </td>
745 </tr>
746 </tbody>
747 </table>
748 </div>
749
750 <?php $this->renderLicenseNotice(); ?>
751 <?php
752 }
753
754 public function renderAddress()
755 {
756 $order = Arr::get($this->config, 'order', null);
757 if ($order->fulfillment_type === 'physical') : ?>
758 <div class="fct-thank-you-page-order-items-addresses">
759 <?php $this->renderBillToAddress(); ?>
760 <?php $this->renderShipToAddress(); ?>
761 </div>
762 <?php endif;
763 }
764
765 public function renderBillToAddress()
766 {
767 $order = Arr::get($this->config, 'order', null);
768 ?>
769 <div class="fct-thank-you-page-order-items-addresses-bill-to">
770 <h5>
771 <?php echo esc_html__('Bill To', 'fluent-cart'); ?>
772 </h5>
773 <?php
774 if (!empty($order->billing_address)) :
775 ?>
776 <div class="fct-thank-you-page-order-items-addresses-bill-to-address">
777 <?php echo esc_html($order->billing_address->getAddressAsText()); ?>
778 </div>
779
780 <div class="fct-thank-you-page-order-items-addresses-bill-to-email">
781 <?php echo esc_html($order->customer->email); ?>
782 </div>
783 <?php else: ?>
784 <div class="fct-thank-you-page-order-items-addresses-bill-to-name">
785 <?php echo esc_html($order->customer->full_name); ?>
786 </div>
787 <div class="fct-thank-you-page-order-items-addresses-bill-to-email">
788 <?php echo esc_html($order->customer->email); ?>
789 </div>
790 <?php endif; ?>
791 <?php
792 $phoneNumber = Arr::get($order->billing_address->meta ?? [], 'other_data.phone', '');
793 if ($phoneNumber !== ''):
794 ?>
795 <div class="fct-thank-you-page-order-items-addresses-bill-to-phone">
796 <?php echo esc_html($phoneNumber); ?>
797 </div>
798 <?php endif; ?>
799 <div class="fct-thank-you-page-order-items-addresses-bill-to-company-name">
800 <?php
801 $companyName = Arr::get($order->billing_address->meta ?? [], 'other_data.company_name', '');
802
803 if ($companyName === '') {
804 $companyName = Arr::get($orderTaxRates->meta ?? [], 'vat_reverse.name', '');
805 }
806 echo esc_html($companyName);
807 ?>
808 </div>
809 <div class="fct-thank-you-page-order-items-addresses-bill-to-vat-number">
810 <?php
811 $vatNumber = Arr::get($orderTaxRates->meta ?? [], 'vat_reverse.vat_number', '');
812 if ($vatNumber !== '') {
813 echo esc_html__('EU VAT', 'fluent-cart') . ': ' . esc_html($vatNumber);
814 }
815 ?>
816 </div>
817 </div>
818 <?php
819 }
820
821 public function renderShipToAddress()
822 {
823 $order = Arr::get($this->config, 'order', null);
824 ?>
825 <div class="fct-thank-you-page-order-items-addresses-ship-to">
826 <h5 class="fct-thank-you-page-order-items-addresses-ship-to-title">
827 <?php echo esc_html__('Ship To', 'fluent-cart'); ?>
828 </h5>
829 <?php if (!empty($order->shipping_address)) : ?>
830 <div class="fct-thank-you-page-order-items-addresses-ship-to-address">
831 <?php echo esc_html($order->shipping_address->getAddressAsText()); ?>
832 </div>
833 <!-- show phone number -->
834 <?php
835 $phone = Arr::get($order->shipping_address->meta ?? [], 'other_data.phone', '');
836 if ($phone !== ''):?>
837 <div class="fct-thank-you-page-order-items-addresses-ship-to-phone">
838 <?php echo esc_html($phone); ?>
839 </div>
840 <?php endif; ?>
841 <?php else: ?>
842 <div class="fct-thank-you-page-order-items-addresses-ship-to-name">
843 <?php echo esc_html($order->customer->full_name); ?>
844 </div>
845 <div class="fct-thank-you-page-order-items-addresses-ship-to-email">
846 <?php echo esc_html($order->customer->email); ?>
847 </div>
848 <?php endif; ?>
849 </div>
850 <?php
851 }
852
853 public function renderFooter()
854 {
855 ?>
856 <div class="fct-thank-you-page-footer">
857 <?php do_action('fluent_cart/receipt/thank_you/before_footer_buttons', $this->config); ?>
858 <?php $this->renderViewOrderButton(); ?>
859 <?php $this->renderDownloadReceiptButton(); ?>
860 <?php do_action('fluent_cart/receipt/thank_you/after_footer_buttons', $this->config); ?>
861 </div>
862 <?php
863 }
864
865 public function renderViewOrderButton()
866 {
867 $order = Arr::get($this->config, 'order', null);
868 $profilePage = $this->settings->getCustomerProfilePage();
869
870 ?>
871 <a
872 class="fct-thank-you-page-view-order-button"
873 href="<?php echo esc_url($profilePage . 'order/' . $order->uuid); ?>">
874 <?php echo esc_html__('View Order', 'fluent-cart'); ?>
875 </a>
876 <?php
877 }
878
879 public function renderDownloadReceiptButton()
880 {
881 $order = Arr::get($this->config, 'order', null);
882 ?>
883 <a
884 class="fct-thank-you-page-download-receipt-button"
885 href="<?php echo esc_url(\FluentCart\App\Services\URL::appendQueryParams(
886 home_url(),
887 [
888 'fluent-cart' => 'receipt',
889 'order_hash' => $order->uuid,
890 'download' => 1
891 ]
892 )) ?>">
893 <?php echo esc_html__('Download Receipt', 'fluent-cart'); ?>
894 </a>
895 <?php
896 }
897
898 /**
899 * Build a parent → bundle items relationship from flat order items
900 *
901 * Converts a flat order items list into:
902 * - Parent items
903 * - Each parent contains a ` bundle_items ` array
904 *
905 * @param array $orderItems
906 * @return array
907 */
908 protected function buildBundleItemsTree($orderItems)
909 {
910 if (!$orderItems) {
911 return [];
912 }
913
914 $parents = [];
915 $childrenByParent = [];
916
917 // Separate parents and children
918 foreach ($orderItems as $item) {
919 $parentId = Arr::get($item, 'line_meta.bundle_parent_item_id', null);
920
921 // If bundle child → group by parent ID
922 if ($parentId) {
923 $childrenByParent[$parentId][] = $item;
924
925 // Otherwise it's a parent item
926 } else {
927 $item['bundle_items'] = [];
928 $parents[$item['id']] = $item;
929 }
930 }
931
932 // Attach children to their parent
933 foreach ($childrenByParent as $parentId => $children) {
934 if (isset($parents[$parentId])) {
935 $parents[$parentId]['bundle_items'] = $children;
936 }
937 }
938
939 // Re-index a final array
940 return array_values($parents);
941 }
942
943 public function renderBundleProducts($item)
944 {
945 //dd($item);
946 if (!$item['bundle_items']) {
947 return;
948 }
949
950 $total = count($item['bundle_items']);
951 ?>
952 <div class="fct-bundle-products" data-fluent-cart-collapsibles>
953 <h4 class="fct-bundle-products-title">
954 <?php echo esc_html__('Bundle of', 'fluent-cart') . ':'; ?>
955 </h4>
956
957 <div class="fct-bundle-products-list">
958 <?php foreach (array_slice($item['bundle_items'], 0, 2) as $bundleItem): ?>
959 <p>
960 <?php echo esc_html(Arr::get($bundleItem, 'title', '')); ?>
961 </p>
962 <?php endforeach; ?>
963
964 <?php if ($total > 2): ?>
965 <div class="fct-bundle-products-more">
966 <div class="fct-bundle-products-more-list">
967 <?php foreach (array_slice($item['bundle_items'], 2) as $bundleItem): ?>
968 <p>
969 <?php echo esc_html(Arr::get($bundleItem, 'title', '')); ?>
970 </p>
971 <?php endforeach; ?>
972 </div>
973 </div>
974 <?php endif; ?>
975 </div>
976
977 <?php if ($total > 2) : ?>
978 <a href="#" class="fct-see-more-btn" data-fluent-cart-collapsible-toggle>
979 <span class="see-more-text">
980 <?php echo esc_html__('See More', 'fluent-cart'); ?>
981 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="7" viewBox="0 0 12 7" fill="none">
982 <path d="M0.75 0.75L5.04289 5.04289C5.37623 5.37623 5.54289 5.54289 5.75 5.54289C5.95711 5.54289 6.12377 5.37623 6.45711 5.04289L10.75 0.75" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
983 </svg>
984 </span>
985
986 <span class="see-less-text">
987 <?php echo esc_html__('See Less', 'fluent-cart'); ?>
988 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="7" viewBox="0 0 14 8" fill="none">
989 <path d="M0.75 6.54297L6.04289 1.25008C6.37623 0.916742 6.54289 0.750076 6.75 0.750076C6.95711 0.750076 7.12377 0.916742 7.45711 1.25008L12.75 6.54297" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
990 </svg>
991 </span>
992 </a>
993 <?php endif; ?>
994 </div>
995 <?php
996 }
997
998 }
999