| 1 |
<?php |
| 2 |
|
| 3 |
namespace FluentCart\App\Services\Renderer; |
| 4 |
|
| 5 |
use FluentCart\Api\StoreSettings; |
| 6 |
use FluentCart\App\Helpers\Helper; |
| 7 |
use FluentCart\App\Models\Cart; |
| 8 |
use FluentCart\App\Services\Tax\TaxManager; |
| 9 |
use FluentCart\Framework\Support\Arr; |
| 10 |
|
| 11 |
class CartSummaryRender |
| 12 |
{ |
| 13 |
|
| 14 |
protected $cart; |
| 15 |
|
| 16 |
public function __construct(Cart $cart) |
| 17 |
{ |
| 18 |
$this->cart = $cart; |
| 19 |
} |
| 20 |
|
| 21 |
public function render($withWrapper = true) |
| 22 |
{ |
| 23 |
if (!$this->cart) { |
| 24 |
return ''; |
| 25 |
} |
| 26 |
?> |
| 27 |
<?php if($withWrapper): ?> |
| 28 |
<div class="fct_summary_box" data-fluent-cart-checkout-page-cart-items-wrapper> |
| 29 |
<?php endif; ?> |
| 30 |
<div class="fct_checkout_form_section"> |
| 31 |
<?php $this->renderOrderSummarySectionHeading(); ?> |
| 32 |
|
| 33 |
|
| 34 |
<div class="fct_form_section_body" id="order_summary_panel" role="region" aria-labelledby="order_summary_label"> |
| 35 |
<div class="fct_form_section_body_inner"> |
| 36 |
<div data-fluent-cart-checkout-item-wrapper class="fct_items_wrapper"> |
| 37 |
<?php $this->renderItemsLists(); ?> |
| 38 |
</div> |
| 39 |
<?php $this->renderItemsFooter(); ?> |
| 40 |
</div> |
| 41 |
</div><!-- .fct_form_section_body --> |
| 42 |
</div> |
| 43 |
<?php if($withWrapper): ?> |
| 44 |
</div> |
| 45 |
<?php endif; ?> |
| 46 |
<?php |
| 47 |
} |
| 48 |
|
| 49 |
public function renderOrderSummarySectionHeading() |
| 50 |
{ |
| 51 |
?> |
| 52 |
<div class="fct_form_section_header" role="heading" aria-level="2"> |
| 53 |
<div |
| 54 |
data-fluent-cart-checkout-cart-items-toggle |
| 55 |
class="fct_toggle_content" |
| 56 |
aria-expanded="true" |
| 57 |
aria-controls="order_summary_panel" |
| 58 |
> |
| 59 |
<h4 id="order_summary_label"><?php echo __('Order summary', 'fluent-cart'); ?></h4> |
| 60 |
<div class="fct_toggle_icon" aria-hidden="true"> |
| 61 |
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="6" viewBox="0 0 10 6" |
| 62 |
fill="none"> |
| 63 |
<path |
| 64 |
d="M1 1L4.29289 4.29289C4.62623 4.62623 4.79289 4.79289 5 4.79289C5.20711 4.79289 5.37377 4.62623 5.70711 4.29289L9 1" |
| 65 |
stroke="currentColor" stroke-width="1.5" stroke-linecap="round" |
| 66 |
stroke-linejoin="round"></path> |
| 67 |
</svg> |
| 68 |
</div> |
| 69 |
</div><!-- .fct_toggle_content --> |
| 70 |
|
| 71 |
<div class="fct_summary_toggle_total"> |
| 72 |
<span |
| 73 |
id="order_summary_total" |
| 74 |
class="value" |
| 75 |
data-fluent-cart-checkout-estimated-total |
| 76 |
aria-labelledby="order_summary_label" |
| 77 |
> |
| 78 |
<?php |
| 79 |
echo esc_html(Helper::toDecimal($this->cart->getEstimatedTotal())); ?> |
| 80 |
</span> |
| 81 |
</div> |
| 82 |
</div><!-- .fct_form_section_header --> |
| 83 |
<?php |
| 84 |
} |
| 85 |
|
| 86 |
public function renderItemsLists() |
| 87 |
{ |
| 88 |
$items = $this->cart->cart_data; |
| 89 |
if (!$items) { |
| 90 |
return ''; |
| 91 |
} |
| 92 |
?> |
| 93 |
<div class="fct_line_items"> |
| 94 |
<?php foreach ($items as $item) { |
| 95 |
(new CartItemRenderer($item, $this->cart))->render(); |
| 96 |
} |
| 97 |
?> |
| 98 |
</div> |
| 99 |
<?php |
| 100 |
} |
| 101 |
|
| 102 |
public function renderItemsFooter() |
| 103 |
{ |
| 104 |
$hideCouponField = (new StoreSettings())->get('hide_coupon_field') === 'yes'; |
| 105 |
$hideCouponField = $hideCouponField || Arr::get($this->cart->checkout_data, 'disable_coupons', 'no') === 'yes'; |
| 106 |
?> |
| 107 |
<div class="fct_summary_items"> |
| 108 |
<ul class="fct_summary_items_list"> |
| 109 |
<?php |
| 110 |
$this->renderSubtotal(); |
| 111 |
?> |
| 112 |
|
| 113 |
<?php $this->maybeShowCustomCartSummaries(); ?> |
| 114 |
|
| 115 |
<?php if ($this->cart->requireShipping()): |
| 116 |
$this->renderShipping(); |
| 117 |
?> |
| 118 |
<?php endif ?> |
| 119 |
|
| 120 |
<?php $this->renderFees(); ?> |
| 121 |
|
| 122 |
<?php |
| 123 |
$extraLines = apply_filters('fluent_cart/checkout/summary_extra_lines', [], [ |
| 124 |
'cart' => $this->cart, |
| 125 |
]); |
| 126 |
|
| 127 |
if (!is_array($extraLines)) { |
| 128 |
$extraLines = []; |
| 129 |
} |
| 130 |
|
| 131 |
foreach ($extraLines as $extraLine) : |
| 132 |
if (!is_array($extraLine) || !isset($extraLine['label'], $extraLine['amount'])) { |
| 133 |
continue; |
| 134 |
} |
| 135 |
?> |
| 136 |
<li> |
| 137 |
<span class="fct_summary_label"><?php echo esc_html($extraLine['label']); ?></span> |
| 138 |
<span class="fct_summary_value"><?php echo esc_html(Helper::toDecimal($extraLine['amount'])); ?></span> |
| 139 |
</li> |
| 140 |
<?php endforeach; ?> |
| 141 |
|
| 142 |
<li data-fluent-cart-checkout-page-applied-coupon> |
| 143 |
<?php $this->showCouponApplied(); ?> |
| 144 |
</li> |
| 145 |
|
| 146 |
<?php if (!$hideCouponField): ?> |
| 147 |
<li> |
| 148 |
<?php $this->showCouponField(); ?> |
| 149 |
</li> |
| 150 |
<?php endif ?> |
| 151 |
|
| 152 |
<?php do_action('fluent_cart/checkout/before_summary_total', [ 'cart' => $this->cart ]); ?> |
| 153 |
|
| 154 |
<?php $this->showUpgradeDiscount(); ?> |
| 155 |
<?php $this->showProrateCredit(); ?> |
| 156 |
<?php $this->showManualDiscount(); ?> |
| 157 |
|
| 158 |
<?php |
| 159 |
$this->renderTotal(); |
| 160 |
?> |
| 161 |
</ul> |
| 162 |
</div> |
| 163 |
<?php |
| 164 |
} |
| 165 |
|
| 166 |
public function renderSubtotal($atts = '') |
| 167 |
{ |
| 168 |
?> |
| 169 |
<li <?php echo $atts; ?>> |
| 170 |
<span class="fct_summary_label"> <?php esc_html_e('Subtotal', 'fluent-cart'); ?></span> |
| 171 |
<span class="fct_summary_value" data-fluent-cart-checkout-subtotal> |
| 172 |
<?php echo esc_html(Helper::toDecimal($this->cart->getItemsSubtotal())); ?> |
| 173 |
</span> |
| 174 |
</li> |
| 175 |
<?php |
| 176 |
} |
| 177 |
|
| 178 |
public function renderShipping($atts = '') |
| 179 |
{ |
| 180 |
if ($atts) { |
| 181 |
echo '<li ' . $atts . '>'; |
| 182 |
} else { |
| 183 |
echo '<li class="' . ($this->cart->getShippingTotal() === 0 ? 'shipping-charge-hidden' : '') . '" data-fluent-cart-checkout-shipping-amount-wrapper>'; |
| 184 |
} |
| 185 |
?> |
| 186 |
<span class="fct_summary_label"><?php esc_html_e('Shipping', 'fluent-cart'); ?></span> |
| 187 |
<span class="fct_summary_value" data-fluent-cart-checkout-shipping-amount data-shipping-method-id=""> |
| 188 |
<?php |
| 189 |
echo esc_html(Helper::toDecimal($this->cart->getShippingTotal())); |
| 190 |
?> |
| 191 |
</span> |
| 192 |
<?php |
| 193 |
echo '</li>'; |
| 194 |
} |
| 195 |
|
| 196 |
public function renderFees() |
| 197 |
{ |
| 198 |
$fees = $this->cart->getFees(); |
| 199 |
if (empty($fees)) { |
| 200 |
return; |
| 201 |
} |
| 202 |
foreach ($fees as $fee) { |
| 203 |
?> |
| 204 |
<li class="fct_fee_row" data-fluent-cart-checkout-fee="<?php echo esc_attr($fee['key']); ?>"> |
| 205 |
<span class="fct_summary_label"><?php echo esc_html($fee['label']); ?></span> |
| 206 |
<span class="fct_summary_value" data-fluent-cart-checkout-fee-amount="<?php echo esc_attr($fee['key']); ?>"> |
| 207 |
<?php echo esc_html(Helper::toDecimal($fee['amount'])); ?> |
| 208 |
</span> |
| 209 |
</li> |
| 210 |
<?php |
| 211 |
} |
| 212 |
} |
| 213 |
|
| 214 |
public function renderTotal($atts = '') |
| 215 |
{ |
| 216 |
?> |
| 217 |
<li <?php echo empty($atts) ? ' class="fct_summary_items_total" data-fluent-cart-checkout-page-current-total' : $atts; ?>> |
| 218 |
<span class="fct_summary_label"><?php _e('Total','fluent-cart'); ?></span> |
| 219 |
<span class="fct_summary_value" data-fluent-cart-checkout-estimated-total> |
| 220 |
<?php |
| 221 |
echo esc_html(Helper::toDecimal($this->cart->getEstimatedTotal())); |
| 222 |
?> |
| 223 |
</span> |
| 224 |
</li> |
| 225 |
<?php |
| 226 |
} |
| 227 |
|
| 228 |
public function maybeShowCustomCartSummaries() |
| 229 |
{ |
| 230 |
$isCustomCheckout = Arr::get($this->cart->checkout_data, 'custom_checkout') === 'yes'; |
| 231 |
if (!$isCustomCheckout) { |
| 232 |
return ''; |
| 233 |
} |
| 234 |
|
| 235 |
$customerDiscountAmount = Arr::get($this->cart->checkout_data, 'custom_checkout_data.discount_total', 0); |
| 236 |
$formattedCustomDiscountAmount = Helper::toDecimal($customerDiscountAmount); |
| 237 |
$customShippingAmount = Arr::get($this->cart->checkout_data, 'custom_checkout_data.shipping_total', 0); |
| 238 |
$formattedCustomShippingAmount = Helper::toDecimal($customShippingAmount); |
| 239 |
|
| 240 |
$checkoutShippingData = $this->cart->checkout_data['shipping_data'] ?? []; |
| 241 |
$shippingMethodId = Arr::get($checkoutShippingData, 'shipping_method_id', ''); |
| 242 |
$shippingCharge = Arr::get($checkoutShippingData, 'shipping_charge', 0); // checking if shipping charge is again set from checkout |
| 243 |
|
| 244 |
?> |
| 245 |
<?php if ($customerDiscountAmount) { |
| 246 |
$this->renderDiscountDetailRow(); |
| 247 |
} |
| 248 |
if ($customShippingAmount && !$shippingCharge){ |
| 249 |
$this->renderShippingDetailRow(); |
| 250 |
} |
| 251 |
} |
| 252 |
|
| 253 |
public function renderDiscountDetailRow() |
| 254 |
{ |
| 255 |
$customerDiscountAmount = Arr::get($this->cart->checkout_data, 'custom_checkout_data.discount_total', 0); |
| 256 |
$formattedCustomDiscountAmount = Helper::toDecimal($customerDiscountAmount); |
| 257 |
?> |
| 258 |
<li> |
| 259 |
<span class="fct_summary_label"> <?php esc_html_e('Discount', 'fluent-cart'); ?></span> |
| 260 |
<span class="fct_summary_value" data-fluent-cart-checkout-subtotal> |
| 261 |
-<?php echo esc_html($formattedCustomDiscountAmount); ?> |
| 262 |
</span> |
| 263 |
</li> |
| 264 |
<?php |
| 265 |
} |
| 266 |
|
| 267 |
public function renderShippingDetailRow() |
| 268 |
{ |
| 269 |
$customShippingAmount = Arr::get($this->cart->checkout_data, 'custom_checkout_data.shipping_total', 0); |
| 270 |
$formattedCustomShippingAmount = Helper::toDecimal($customShippingAmount); |
| 271 |
?> |
| 272 |
<li> |
| 273 |
<span class="fct_summary_label"> <?php esc_html_e('Shipping', 'fluent-cart'); ?></span> |
| 274 |
<span class="fct_summary_value" data-fluent-cart-checkout-subtotal> |
| 275 |
<?php echo esc_html($formattedCustomShippingAmount); ?> |
| 276 |
</span> |
| 277 |
</li> |
| 278 |
<?php |
| 279 |
} |
| 280 |
|
| 281 |
public function showCouponApplied() |
| 282 |
{ |
| 283 |
$discounts = $this->cart->getDiscountLines(); |
| 284 |
|
| 285 |
if (!$discounts) { |
| 286 |
return; |
| 287 |
} |
| 288 |
|
| 289 |
?> |
| 290 |
|
| 291 |
<div class="fct_coupon_applied" data-fluent-cart-checkout-page-discount-container> |
| 292 |
<?php foreach ($discounts as $couponCode => $discount_data): ?> |
| 293 |
<div class="fct_coupon_applied_item"> |
| 294 |
<div class="fct_coupon_info"> |
| 295 |
<span class="fct_coupon"> |
| 296 |
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 16 16" fill="none"> |
| 297 |
<ellipse cx="1" cy="1" rx="1" ry="1" transform="matrix(1 0 0 -1 10.6667 5.3335)" stroke="#2F3448" |
| 298 |
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> |
| 299 |
<path |
| 300 |
d="M1.8495 7.42921C1.18073 8.17611 1.16635 9.30298 1.78012 10.0957C2.99809 11.6688 4.33117 13.0018 5.90423 14.2198C6.69694 14.8336 7.82382 14.8192 8.57072 14.1504C10.5986 12.3347 12.4557 10.4372 14.2479 8.35189C14.4251 8.14572 14.536 7.89304 14.5608 7.62234C14.6708 6.42524 14.8968 2.97637 13.9602 2.03975C13.0236 1.10313 9.57469 1.3291 8.37759 1.43909C8.10689 1.46397 7.8542 1.57481 7.64804 1.75199C5.56276 3.54422 3.66521 5.40132 1.8495 7.42921Z" |
| 301 |
stroke="#2F3448" stroke-width="1.5"/> |
| 302 |
<path d="M4.66669 9.3335L6.66669 11.3335" stroke="#2F3448" stroke-width="1.5" |
| 303 |
stroke-linecap="round" stroke-linejoin="round"/> |
| 304 |
</svg> |
| 305 |
|
| 306 |
<?php echo esc_html($discount_data['formatted_title']) ?> |
| 307 |
</span> |
| 308 |
<a |
| 309 |
href="#" |
| 310 |
class="fct_remove_coupon" |
| 311 |
data-remove-coupon |
| 312 |
data-coupon="<?php echo esc_attr($couponCode); ?>" |
| 313 |
> |
| 314 |
<?php echo esc_html__('Remove', 'fluent-cart'); ?> |
| 315 |
</a> |
| 316 |
</div> |
| 317 |
<div class="fct_coupon_price"> |
| 318 |
– <?php echo esc_html($discount_data['actual_formatted_discount']) ?> |
| 319 |
</div> |
| 320 |
</div> |
| 321 |
<?php endforeach; ?> |
| 322 |
</div> |
| 323 |
|
| 324 |
<?php |
| 325 |
} |
| 326 |
|
| 327 |
public function showManualDiscount($atts = '') |
| 328 |
{ |
| 329 |
$manualDiscount = Arr::get($this->cart->checkout_data, 'manual_discount', []); |
| 330 |
|
| 331 |
if (!$manualDiscount || !Arr::get($manualDiscount, 'amount', 0)) { |
| 332 |
return; |
| 333 |
} |
| 334 |
|
| 335 |
$title = Arr::get($manualDiscount, 'title', __('Manual Discount', 'fluent-cart')); |
| 336 |
$amount = Arr::get($manualDiscount, 'amount', 0); |
| 337 |
$formattedAmount = Helper::toDecimal($amount); |
| 338 |
?> |
| 339 |
<li> |
| 340 |
<span class="fct_summary_label" aria-label="<?php echo esc_attr($title); ?>"> <?php echo esc_html($title); ?></span> |
| 341 |
<span class="fct_summary_value" data-fluent-cart-checkout-manual-discount aria-label="<?php echo esc_attr($formattedAmount); ?>"> |
| 342 |
-<?php echo esc_html($formattedAmount); ?> |
| 343 |
</span> |
| 344 |
</li> |
| 345 |
<?php |
| 346 |
} |
| 347 |
|
| 348 |
public function showUpgradeDiscount($atts = '') |
| 349 |
{ |
| 350 |
$upgradeDiscount = Arr::get($this->cart->checkout_data, 'upgrade_discount', []); |
| 351 |
|
| 352 |
if (!$upgradeDiscount || !Arr::get($upgradeDiscount, 'amount', 0)) { |
| 353 |
return; |
| 354 |
} |
| 355 |
|
| 356 |
$title = Arr::get($upgradeDiscount, 'title', __('Upgrade Discount', 'fluent-cart')); |
| 357 |
$amount = Arr::get($upgradeDiscount, 'amount', 0); |
| 358 |
$formattedAmount = Helper::toDecimal($amount); |
| 359 |
?> |
| 360 |
<li> |
| 361 |
<span class="fct_summary_label" aria-label="<?php echo esc_attr($title); ?>"> <?php echo esc_html($title); ?></span> |
| 362 |
<span class="fct_summary_value" data-fluent-cart-checkout-upgrade-discount aria-label="<?php echo esc_attr($formattedAmount); ?>"> |
| 363 |
-<?php echo esc_html($formattedAmount); ?> |
| 364 |
</span> |
| 365 |
</li> |
| 366 |
<?php |
| 367 |
} |
| 368 |
|
| 369 |
public function showProrateCredit($atts = '') |
| 370 |
{ |
| 371 |
$prorateCredit = Arr::get($this->cart->checkout_data, 'prorate_credit', []); |
| 372 |
|
| 373 |
if (!$prorateCredit || !Arr::get($prorateCredit, 'amount', 0)) { |
| 374 |
return; |
| 375 |
} |
| 376 |
|
| 377 |
$title = Arr::get($prorateCredit, 'title', __('Prorate Credit', 'fluent-cart')); |
| 378 |
$amount = Arr::get($prorateCredit, 'amount', 0); |
| 379 |
$formattedAmount = Helper::toDecimal($amount); |
| 380 |
?> |
| 381 |
<li> |
| 382 |
<span class="fct_summary_label" aria-label="<?php echo esc_attr($title); ?>"> <?php echo esc_html($title); ?></span> |
| 383 |
<span class="fct_summary_value" data-fluent-cart-checkout-prorate-credit aria-label="<?php echo esc_attr($formattedAmount); ?>"> |
| 384 |
-<?php echo esc_html($formattedAmount); ?> |
| 385 |
</span> |
| 386 |
</li> |
| 387 |
<?php |
| 388 |
} |
| 389 |
|
| 390 |
public function showCouponField() |
| 391 |
{ |
| 392 |
?> |
| 393 |
<div class="fct_coupon"> |
| 394 |
<div class="fct_coupon_toggle"> |
| 395 |
<a |
| 396 |
aria-expanded="false" |
| 397 |
aria-controls="coupon_section" |
| 398 |
href="#" |
| 399 |
data-fluent-cart-checkout-page-coupon-field-toggle |
| 400 |
> |
| 401 |
<?php echo esc_html__('Have a Coupon?', 'fluent-cart'); ?> |
| 402 |
</a> |
| 403 |
</div> |
| 404 |
|
| 405 |
<div |
| 406 |
id="coupon_section" |
| 407 |
class="fct_coupon_field" |
| 408 |
hidden |
| 409 |
data-fluent-cart-checkout-page-coupon-container |
| 410 |
role="region" |
| 411 |
aria-label="<?php esc_attr_e('Coupon entry area', 'fluent-cart'); ?>" |
| 412 |
> |
| 413 |
<label for="coupon" class="sr-only"> |
| 414 |
<?php echo esc_html__('Enter coupon code', 'fluent-cart'); ?> |
| 415 |
</label> |
| 416 |
|
| 417 |
<span class="fct_coupon_icon" aria-hidden="true"> |
| 418 |
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" fill="none"> |
| 419 |
<g clip-path="url(#clip0_3365_10538)"> |
| 420 |
<ellipse cx="1.125" cy="1.125" rx="1.125" ry="1.125" transform="matrix(1 0 0 -1 12 6)" |
| 421 |
stroke="#8b8d9a" stroke-width="1.5" stroke-linecap="round" |
| 422 |
stroke-linejoin="round"/> |
| 423 |
<path |
| 424 |
d="M2.08067 8.35795C1.32831 9.19822 1.31213 10.4659 2.00262 11.3578C3.37284 13.1274 4.87255 14.6272 6.64225 15.9974C7.53405 16.6879 8.80178 16.6717 9.64205 15.9193C11.9234 13.8766 14.0127 11.7419 16.0289 9.39596C16.2282 9.16403 16.3529 8.87976 16.3809 8.57522C16.5047 7.22849 16.7589 3.3485 15.7052 2.29481C14.6515 1.24111 10.7715 1.49532 9.42478 1.61907C9.12024 1.64706 8.83597 1.77175 8.60404 1.97109C6.25809 3.98734 4.12335 6.07658 2.08067 8.35795Z" |
| 425 |
stroke="#8b8d9a" stroke-width="1.5"/> |
| 426 |
<path d="M5.25002 10.5L7.50002 12.75" stroke="#8b8d9a" stroke-width="1.5" |
| 427 |
stroke-linecap="round" stroke-linejoin="round"/> |
| 428 |
</g> |
| 429 |
<defs> |
| 430 |
<clipPath id="clip0_3365_10538"> |
| 431 |
<rect width="18" height="18" fill="white"/> |
| 432 |
</clipPath> |
| 433 |
</defs> |
| 434 |
</svg> |
| 435 |
</span> |
| 436 |
|
| 437 |
<div data-fluent-cart-checkout-page-form-input-wrapper class="fct_coupon_input_wrapper"> |
| 438 |
<input |
| 439 |
class="fct_coupon_input" |
| 440 |
type=text |
| 441 |
name=coupon |
| 442 |
placeholder="<?php esc_attr_e('Apply Here', 'fluent-cart'); ?>" |
| 443 |
data-required=no |
| 444 |
data-type=input |
| 445 |
id=coupon |
| 446 |
autocomplete="off" |
| 447 |
/> |
| 448 |
</div> |
| 449 |
|
| 450 |
<button type='submit' data-fluent-cart-checkout-page-coupon-validate> |
| 451 |
<?php echo esc_html__('Apply', 'fluent-cart'); ?> |
| 452 |
</button> |
| 453 |
</div> |
| 454 |
</div> |
| 455 |
<?php |
| 456 |
} |
| 457 |
|
| 458 |
} |
| 459 |
|