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

1,004 lines 39.5 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 <?php if (!empty($item['setup_info'])): ?>
306 <p class="fct-thank-you-page-order-items-list-payment-info">
307 <?php echo wp_kses_post($item['setup_info']); ?>
308 </p>
309 <?php endif; ?>
310
311 <?php $this->renderBundleProducts($item); ?>
312 </div>
313 <div class="fct-thank-you-page-order-items-list-price">
314 <div class="fct-thank-you-page-order-items-list-price-inner">
315 <?php echo esc_html($item['formatted_total']); ?>
316 </div>
317 </div>
318 </div>
319
320
321 <?php endforeach; ?>
322
323 <?php $this->renderOrderTotal(); ?>
324
325 <!-- tax note -->
326 <?php $this->renderTaxNote(); ?>
327
328 </div>
329 <?php
330 }
331
332 public function renderThankYouPageInstructions()
333 {
334 $order = Arr::get($this->config, 'order', null);
335 if (!$order) {
336 return;
337 }
338 $transaction = $order->getLatestTransaction();
339 if ($transaction && !empty($transaction->payment_method)) {
340 $methodSlug = $transaction->payment_method;
341 }
342 if (GatewayManager::has($methodSlug)) {
343 $gatewayInstance = GatewayManager::getInstance($methodSlug);
344 if ($gatewayInstance && isset($gatewayInstance->settings)) {
345 $gatewaySettings = (array) $gatewayInstance->settings->get();
346 $thankYouPageInstructions = Arr::get($gatewaySettings, 'thank_you_page_instructions', '');
347 }
348 }
349
350 if (!empty($thankYouPageInstructions)) : ?>
351
352 <div style="max-width: 620px; margin: 15px auto 0; font-family: Arial, Helvetica, sans-serif;">
353 <div style="font-size: 14px; color: #2F3448; padding: 12px 0; border-top: 1px solid #e7eaee;">
354 <?php echo wp_kses_post($thankYouPageInstructions); ?>
355 </div>
356 </div>
357 <?php endif;
358 }
359
360 public function renderOrderTotal()
361 {
362 ?>
363 <div class="fct-thank-you-page-order-items-total">
364 <?php $this->renderSubtotal(); ?>
365 <?php $this->renderDiscount(); ?>
366 <?php $this->renderShipping(); ?>
367 <?php $this->renderFees(); ?>
368 <?php $this->renderTaxTotal(); ?>
369 <?php $this->renderShippingTax(); ?>
370
371 <?php $this->renderRefund(); ?>
372 <?php $this->renderTotal(); ?>
373 <?php $this->renderPaymentMethod(); ?>
374 </div>
375 <?php
376 }
377
378 public function renderTaxNote()
379 {
380 $order = Arr::get($this->config, 'order', null);
381 $taxtotal = $order->tax_total + $order->shipping_tax;
382 if (Arr::get($orderTaxRates->meta ?? [], 'vat_reverse.valid') && !$taxtotal): ?>
383 <div style="text-align: right; font-size: 14px; margin-top: 10px;">
384 <?php echo '*' . esc_html__('Tax to be paid on reverse charge basis', 'fluent-cart') ?>
385 </div>
386 <?php
387 endif;
388 }
389
390 public function renderSubtotal()
391 {
392 $order = Arr::get($this->config, 'order', null);
393 if ($order->subtotal != $order->total_amount || $order->tax_total > 0): ?>
394 <div class="fct-meta-line fct-thank-you-page-order-items-total-subtotal">
395 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
396 <?php echo esc_html__('Subtotal', 'fluent-cart'); ?>
397 </div>
398 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value"><?php echo esc_html(Helper::toDecimal($order->subtotal)); ?></div>
399 </div>
400 <?php endif;
401 }
402
403 public function renderDiscount()
404 {
405 $order = Arr::get($this->config, 'order', null);
406
407 if ($order->manual_discount_total + $order->coupon_discount_total > 0): ?>
408 <div class="fct-meta-line fct-thank-you-page-order-items-total-discount">
409 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
410 <?php echo esc_html__('Discount', 'fluent-cart'); ?>
411 </div>
412 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
413 - <?php echo esc_html(Helper::toDecimal($order->manual_discount_total + $order->coupon_discount_total)); ?>
414 </div>
415 </div>
416 <?php endif;
417 }
418
419 public function renderShipping()
420 {
421 $order = Arr::get($this->config, 'order', null);
422
423 if ($order->shipping_total > 0): ?>
424 <div class="fct-meta-line fct-thank-you-page-order-items-total-shipping">
425 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
426 <?php echo esc_html__('Shipping', 'fluent-cart'); ?>
427 </div>
428 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value"><?php echo esc_html(Helper::toDecimal($order->shipping_total)); ?></div>
429 </div>
430 <?php endif;
431 }
432
433 public function renderFees()
434 {
435 $order = Arr::get($this->config, 'order', null);
436 if (!$order || $order->fee_total <= 0) {
437 return;
438 }
439 $feeItems = $order->feeItems()->get();
440 foreach ($feeItems as $feeItem): ?>
441 <div class="fct-meta-line fct-thank-you-page-order-items-total-fee">
442 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
443 <?php echo esc_html($feeItem->title); ?>
444 </div>
445 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
446 <?php echo esc_html(Helper::toDecimal($feeItem->subtotal)); ?>
447 </div>
448 </div>
449 <?php endforeach;
450 }
451
452 public function renderTaxTotal()
453 {
454 $order = Arr::get($this->config, 'order', null);
455
456 if ($order->tax_total > 0): ?>
457 <div class="fct-meta-line fct-thank-you-page-order-items-total-tax">
458 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
459 <?php echo esc_html__('Total Tax', 'fluent-cart'); ?>
460 <?php echo $order->tax_behavior == 2 ? esc_html__('(Included)', 'fluent-cart') : esc_html__('(Excluded)', 'fluent-cart'); ?>
461 </div>
462 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
463 <?php echo esc_html(Helper::toDecimal($order->tax_total)); ?>
464 </div>
465 </div>
466 <?php endif;
467 }
468
469 public function renderShippingTax()
470 {
471 $order = Arr::get($this->config, 'order', null);
472
473 if ($order->shipping_tax > 0): ?>
474 <div class="fct-meta-line fct-thank-you-page-order-items-total-shipping-tax">
475 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
476 <?php echo esc_html__('Shipping Tax', 'fluent-cart'); ?>
477 <?php echo $order->tax_behavior == 2 ? esc_html__('(Included)', 'fluent-cart') : esc_html__('(Excluded)', 'fluent-cart'); ?>
478 </div>
479 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
480 <?php echo esc_html(Helper::toDecimal($order->shipping_tax)); ?>
481 </div>
482 </div>
483 <?php endif;
484 }
485
486 public function renderRefund()
487 {
488 $order = Arr::get($this->config, 'order', null);
489
490 if ($order->total_refund > 0): ?>
491 <div class="fct-meta-line fct-thank-you-page-order-items-total-refund">
492 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
493 <?php echo esc_html__('Refund', 'fluent-cart'); ?>
494 </div>
495 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
496 - <?php echo esc_html(Helper::toDecimal($order->total_refund)); ?>
497 </div>
498 </div>
499 <?php endif;
500 }
501
502 public function renderTotal()
503 {
504 $order = Arr::get($this->config, 'order', null);
505 ?>
506 <div class="fct-meta-line fct-thank-you-page-order-items-total-total">
507 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
508 <?php echo esc_html__('Total', 'fluent-cart'); ?>
509 </div>
510 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
511 <?php echo esc_html(Helper::toDecimal($order->total_amount - $order->total_refund)); ?>
512 </div>
513 </div>
514 <?php
515 }
516
517 public function renderPaymentMethod()
518 {
519 $order = Arr::get($this->config, 'order', null);
520 $transaction = $order->getLatestTransaction();
521 ?>
522 <div class="fct-meta-line fct-thank-you-page-order-items-total-payment-method">
523 <div class="fct-meta-line-label fct-thank-you-page-order-items-total-label">
524 <?php echo esc_html__('Payment Method', 'fluent-cart'); ?>
525 </div>
526 <div class="fct-meta-line-value fct-thank-you-page-order-items-total-value">
527 <?php if ($transaction->card_last_4) :
528 echo esc_html($transaction->card_brand) . ' ' . esc_html($transaction->card_last_4);
529 else:
530 $title = $transaction->payment_method;
531 $gateway = GatewayManager::getInstance($transaction->payment_method);
532 $title = $gateway ? $gateway->getMeta('title') : $title;
533 echo esc_html($title);
534 endif; ?>
535 </div>
536 </div>
537 <?php
538 }
539
540 public function renderSubscriptionItems()
541 {
542 $order = Arr::get($this->config, 'order', null);
543 $subscriptions = $order->subscriptions;
544
545 if ($subscriptions->count() == 0) {
546 return;
547 }
548 ?>
549 <div class="fct-thank-you-page-order-items-subscriptions">
550 <p class="fct-thank-you-page-order-items-subscriptions-heading">
551 <?php echo esc_html__('Subscription Details', 'fluent-cart'); ?>
552 </p>
553
554 <table class="fct-thank-you-page-order-items-subscriptions-table" role="presentation">
555 <tbody>
556 <?php foreach ($subscriptions as $subs): ?>
557 <tr>
558 <td class="fct-thank-you-page-order-items-subscriptions-table-file">
559 <p>
560 <?php echo esc_html($subs->item_name); ?>
561 </p>
562 </td>
563
564 <td class="fct-thank-you-page-order-items-subscriptions-billing-infos">
565 <div>
566 <?php if (!empty($subs->payment_info)) : ?>
567 <span>
568 <?php echo $subs->payment_info; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
569 </span>
570 <?php endif; ?>
571
572 <?php if (!empty($subs->next_billing_date)) : ?>
573 <p class="fct-thank-you-page-order-items-subscriptions-billing-infos-next-billing"><?php
574 echo sprintf(
575 /* translators: 1: Next billing date */
576 esc_html__('- Auto renews on %1$s', 'fluent-cart'),
577 esc_html(
578 \FluentCart\App\Services\DateTime\DateTime::gmtToTimezone($subs->next_billing_date)->format('M d, Y h:i A')
579 )
580 );
581 ?>
582 </p>
583 <?php endif; ?>
584 </div>
585 </td>
586 </tr>
587 <?php endforeach; ?>
588 </tbody>
589 </table>
590 </div>
591
592
593 <?php
594 // App::make('view')->render('invoice.parts.subscription_items', [
595 // 'subscriptions' => $order->subscriptions,
596 // 'order' => $order
597 // ]);
598 }
599
600 public function renderDownloads()
601 {
602 $order = Arr::get($this->config, 'order', null);
603 $downloads = $order->getDownloads();
604 if (!$downloads) {
605 return;
606 }
607 ?>
608 <div class="fct-thank-you-page-order-items-downloads">
609 <p class="fct-thank-you-page-order-items-downloads-heading">
610 <?php echo esc_html__('Downloads', 'fluent-cart'); ?>
611 </p>
612
613 <table class="fct-thank-you-page-order-items-downloads-table"
614 role="presentation">
615 <tbody>
616 <tr>
617 <td>
618 <table role="presentation" width="100%">
619 <tbody>
620 <?php foreach ($downloads as $downloadItem): ?>
621 <tr>
622 <td>
623 <?php if ($downloadItem['downloads']): ?>
624
625 <table role="presentation" width="100%">
626 <tbody>
627 <?php foreach ($downloadItem['downloads'] as $download): ?>
628 <tr>
629 <td class="fct-thank-you-page-order-items-downloads-table-file">
630 <p>
631 <?php echo esc_html($download['title']); ?>
632 <?php if ($download['file_size']): ?>
633 <span>(<?php echo esc_html(Helper::readableFileSize($download['file_size'])); ?>)</span>
634 <?php endif; ?>
635 </p>
636 </td>
637 <td class="fct-thank-you-page-order-items-downloads-button">
638 <a href="<?php echo esc_url($download['download_url'] ?? ''); ?>">
639 <?php echo esc_html__('Download', 'fluent-cart'); ?>
640 </a>
641 </td>
642 </tr>
643 <?php endforeach; ?>
644 </tbody>
645 </table>
646
647 <?php endif; ?>
648
649 </td>
650 </tr>
651 <?php endforeach; ?>
652 </tbody>
653 </table>
654 </td>
655 </tr>
656 </tbody>
657 </table>
658 </div>
659
660 <?php $this->renderDownloadsNotice(); ?>
661
662 <?php
663 }
664
665 public function renderDownloadsNotice($show_notice = false)
666 {
667 $showNotice = $show_notice ?? true;
668 ?>
669 <?php if (!$showNotice) {
670 return;
671 } ?>
672 <table
673 class="fct-thank-you-page-order-items-downloads-notice"
674 role="presentation">
675 <tbody>
676 <tr>
677 <td>
678 <p class="fct-thank-you-page-order-items-downloads-notice-title">
679 <?php echo esc_html__('Important', 'fluent-cart'); ?>
680 </p>
681 <p class="fct-thank-you-page-order-items-downloads-notice-content">
682 <?php echo esc_html__('This download link is valid for 7 days. After that, you can download the files again from your account
683 on our website.', 'fluent-cart'); ?>
684 </p>
685 </td>
686 </tr>
687 </tbody>
688 </table>
689 <?php
690 }
691
692 public function renderLicenseNotice($show_notice = false)
693 {
694 $showNotice = $show_notice ?? true;
695 ?>
696 <?php if (!$showNotice) {
697 return;
698 } ?>
699 <table
700 class="fct-thank-you-page-order-items-downloads-notice"
701 role="presentation">
702 <tbody>
703 <tr>
704 <td>
705 <p class="fct-thank-you-page-order-items-downloads-notice-title">
706 <?php echo esc_html__('Important', 'fluent-cart'); ?>
707 </p>
708 <p class="fct-thank-you-page-order-items-downloads-notice-content">
709 <?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'); ?>
710 </p>
711 </td>
712 </tr>
713 </tbody>
714 </table>
715 <?php
716 }
717
718 public function renderLicenses()
719 {
720 $order = Arr::get($this->config, 'order', null);
721 $licenses = $order->getLicenses();
722 if (!$licenses || $licenses->count() == 0) {
723 return;
724 }
725 ?>
726 <div class="fct-thank-you-page-order-items-licenses">
727 <p class="fct-thank-you-page-order-items-licenses-heading">
728 <?php echo esc_html__('Licenses', 'fluent-cart'); ?>
729 </p>
730 <table class="fct-thank-you-page-order-items-licenses-table" role="presentation">
731 <tbody>
732 <tr>
733 <td>
734 <table role="presentation">
735 <tbody>
736
737 <?php foreach ($licenses as $license): ?>
738 <tr>
739 <td class="fct-thank-you-page-order-items-licenses-table-file">
740 <p>
741 <?php echo esc_html($license->productVariant->variation_title); ?>:
742 <?php echo esc_html($license->license_key); ?>
743 </p>
744 </td>
745 </tr>
746 <?php endforeach; ?>
747 </tbody>
748 </table>
749 </td>
750 </tr>
751 </tbody>
752 </table>
753 </div>
754
755 <?php $this->renderLicenseNotice(); ?>
756 <?php
757 }
758
759 public function renderAddress()
760 {
761 $order = Arr::get($this->config, 'order', null);
762 if ($order->fulfillment_type === 'physical') : ?>
763 <div class="fct-thank-you-page-order-items-addresses">
764 <?php $this->renderBillToAddress(); ?>
765 <?php $this->renderShipToAddress(); ?>
766 </div>
767 <?php endif;
768 }
769
770 public function renderBillToAddress()
771 {
772 $order = Arr::get($this->config, 'order', null);
773 ?>
774 <div class="fct-thank-you-page-order-items-addresses-bill-to">
775 <h5>
776 <?php echo esc_html__('Bill To', 'fluent-cart'); ?>
777 </h5>
778 <?php
779 if (!empty($order->billing_address)) :
780 ?>
781 <div class="fct-thank-you-page-order-items-addresses-bill-to-address">
782 <?php echo esc_html($order->billing_address->getAddressAsText()); ?>
783 </div>
784
785 <div class="fct-thank-you-page-order-items-addresses-bill-to-email">
786 <?php echo esc_html($order->customer->email); ?>
787 </div>
788 <?php else: ?>
789 <div class="fct-thank-you-page-order-items-addresses-bill-to-name">
790 <?php echo esc_html($order->customer->full_name); ?>
791 </div>
792 <div class="fct-thank-you-page-order-items-addresses-bill-to-email">
793 <?php echo esc_html($order->customer->email); ?>
794 </div>
795 <?php endif; ?>
796 <?php
797 $phoneNumber = Arr::get($order->billing_address->meta ?? [], 'other_data.phone', '');
798 if ($phoneNumber !== ''):
799 ?>
800 <div class="fct-thank-you-page-order-items-addresses-bill-to-phone">
801 <?php echo esc_html($phoneNumber); ?>
802 </div>
803 <?php endif; ?>
804 <div class="fct-thank-you-page-order-items-addresses-bill-to-company-name">
805 <?php
806 $companyName = Arr::get($order->billing_address->meta ?? [], 'other_data.company_name', '');
807
808 if ($companyName === '') {
809 $companyName = Arr::get($orderTaxRates->meta ?? [], 'vat_reverse.name', '');
810 }
811 echo esc_html($companyName);
812 ?>
813 </div>
814 <div class="fct-thank-you-page-order-items-addresses-bill-to-vat-number">
815 <?php
816 $vatNumber = Arr::get($orderTaxRates->meta ?? [], 'vat_reverse.vat_number', '');
817 if ($vatNumber !== '') {
818 echo esc_html__('EU VAT', 'fluent-cart') . ': ' . esc_html($vatNumber);
819 }
820 ?>
821 </div>
822 </div>
823 <?php
824 }
825
826 public function renderShipToAddress()
827 {
828 $order = Arr::get($this->config, 'order', null);
829 ?>
830 <div class="fct-thank-you-page-order-items-addresses-ship-to">
831 <h5 class="fct-thank-you-page-order-items-addresses-ship-to-title">
832 <?php echo esc_html__('Ship To', 'fluent-cart'); ?>
833 </h5>
834 <?php if (!empty($order->shipping_address)) : ?>
835 <div class="fct-thank-you-page-order-items-addresses-ship-to-address">
836 <?php echo esc_html($order->shipping_address->getAddressAsText()); ?>
837 </div>
838 <!-- show phone number -->
839 <?php
840 $phone = Arr::get($order->shipping_address->meta ?? [], 'other_data.phone', '');
841 if ($phone !== ''):?>
842 <div class="fct-thank-you-page-order-items-addresses-ship-to-phone">
843 <?php echo esc_html($phone); ?>
844 </div>
845 <?php endif; ?>
846 <?php else: ?>
847 <div class="fct-thank-you-page-order-items-addresses-ship-to-name">
848 <?php echo esc_html($order->customer->full_name); ?>
849 </div>
850 <div class="fct-thank-you-page-order-items-addresses-ship-to-email">
851 <?php echo esc_html($order->customer->email); ?>
852 </div>
853 <?php endif; ?>
854 </div>
855 <?php
856 }
857
858 public function renderFooter()
859 {
860 ?>
861 <div class="fct-thank-you-page-footer">
862 <?php do_action('fluent_cart/receipt/thank_you/before_footer_buttons', $this->config); ?>
863 <?php $this->renderViewOrderButton(); ?>
864 <?php $this->renderDownloadReceiptButton(); ?>
865 <?php do_action('fluent_cart/receipt/thank_you/after_footer_buttons', $this->config); ?>
866 </div>
867 <?php
868 }
869
870 public function renderViewOrderButton()
871 {
872 $order = Arr::get($this->config, 'order', null);
873 $profilePage = $this->settings->getCustomerProfilePage();
874
875 ?>
876 <a
877 class="fct-thank-you-page-view-order-button"
878 href="<?php echo esc_url($profilePage . 'order/' . $order->uuid); ?>">
879 <?php echo esc_html__('View Order', 'fluent-cart'); ?>
880 </a>
881 <?php
882 }
883
884 public function renderDownloadReceiptButton()
885 {
886 $order = Arr::get($this->config, 'order', null);
887 ?>
888 <a
889 class="fct-thank-you-page-download-receipt-button"
890 href="<?php echo esc_url(\FluentCart\App\Services\URL::appendQueryParams(
891 home_url(),
892 [
893 'fluent-cart' => 'receipt',
894 'order_hash' => $order->uuid,
895 'download' => 1
896 ]
897 )) ?>">
898 <?php echo esc_html__('Download Receipt', 'fluent-cart'); ?>
899 </a>
900 <?php
901 }
902
903 /**
904 * Build a parent → bundle items relationship from flat order items
905 *
906 * Converts a flat order items list into:
907 * - Parent items
908 * - Each parent contains a ` bundle_items ` array
909 *
910 * @param array $orderItems
911 * @return array
912 */
913 protected function buildBundleItemsTree($orderItems)
914 {
915 if (!$orderItems) {
916 return [];
917 }
918
919 $parents = [];
920 $childrenByParent = [];
921
922 // Separate parents and children
923 foreach ($orderItems as $item) {
924 $parentId = Arr::get($item, 'line_meta.bundle_parent_item_id', null);
925
926 // If bundle child → group by parent ID
927 if ($parentId) {
928 $childrenByParent[$parentId][] = $item;
929
930 // Otherwise it's a parent item
931 } else {
932 $item['bundle_items'] = [];
933 $parents[$item['id']] = $item;
934 }
935 }
936
937 // Attach children to their parent
938 foreach ($childrenByParent as $parentId => $children) {
939 if (isset($parents[$parentId])) {
940 $parents[$parentId]['bundle_items'] = $children;
941 }
942 }
943
944 // Re-index a final array
945 return array_values($parents);
946 }
947
948 public function renderBundleProducts($item)
949 {
950 //dd($item);
951 if (!$item['bundle_items']) {
952 return;
953 }
954
955 $total = count($item['bundle_items']);
956 ?>
957 <div class="fct-bundle-products" data-fluent-cart-collapsibles>
958 <h4 class="fct-bundle-products-title">
959 <?php echo esc_html__('Bundle of', 'fluent-cart') . ':'; ?>
960 </h4>
961
962 <div class="fct-bundle-products-list">
963 <?php foreach (array_slice($item['bundle_items'], 0, 2) as $bundleItem): ?>
964 <p>
965 <?php echo esc_html(Arr::get($bundleItem, 'title', '')); ?>
966 </p>
967 <?php endforeach; ?>
968
969 <?php if ($total > 2): ?>
970 <div class="fct-bundle-products-more">
971 <div class="fct-bundle-products-more-list">
972 <?php foreach (array_slice($item['bundle_items'], 2) as $bundleItem): ?>
973 <p>
974 <?php echo esc_html(Arr::get($bundleItem, 'title', '')); ?>
975 </p>
976 <?php endforeach; ?>
977 </div>
978 </div>
979 <?php endif; ?>
980 </div>
981
982 <?php if ($total > 2) : ?>
983 <a href="#" class="fct-see-more-btn" data-fluent-cart-collapsible-toggle>
984 <span class="see-more-text">
985 <?php echo esc_html__('See More', 'fluent-cart'); ?>
986 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="7" viewBox="0 0 12 7" fill="none">
987 <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"/>
988 </svg>
989 </span>
990
991 <span class="see-less-text">
992 <?php echo esc_html__('See Less', 'fluent-cart'); ?>
993 <svg xmlns="http://www.w3.org/2000/svg" width="12" height="7" viewBox="0 0 14 8" fill="none">
994 <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"/>
995 </svg>
996 </span>
997 </a>
998 <?php endif; ?>
999 </div>
1000 <?php
1001 }
1002
1003 }
1004