PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.0
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.0
1.6.6 1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 All 49 releases
fluent-cart / app / Modules / Templating / AssetLoader.php

AssetLoader.php in FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler 1.6.0, at app/Modules/Templating/AssetLoader.php

632 lines 22.6 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\Modules\Templating;
4
5 use FluentCart\Api\CurrencySettings;
6 use FluentCart\Api\StoreSettings;
7 use FluentCart\App\App;
8 use FluentCart\App\Helpers\CartHelper;
9 use FluentCart\App\Helpers\Helper;
10 use FluentCart\App\Helpers\UtmHelper;
11 use FluentCart\App\Hooks\Cart\CartLoader;
12 use FluentCart\App\Hooks\Handlers\ShortCodes\CustomerProfileHandler;
13 use FluentCart\App\Models\Cart;
14 use FluentCart\App\Modules\Tax\TaxModule;
15 use FluentCart\App\Services\Localization\LocalizationManager;
16 use FluentCart\App\Services\Renderer\ProductFilterRender;
17 use FluentCart\App\Services\TemplateService;
18 use FluentCart\App\Services\Translations\TransStrings;
19 use FluentCart\App\Services\URL;
20 use FluentCart\App\Vite;
21 use FluentCart\App\Services\Renderer\CartRenderer;
22 use FluentCart\Framework\Support\Arr;
23 use FluentCart\Api\Resource\FrontendResource\CartResource;
24
25 class AssetLoader
26 {
27 static $loadedAssets = [];
28 protected static bool $frontendAssetsRequired = false;
29
30 public static function markFrontendAssetsRequired(): void
31 {
32 self::$frontendAssetsRequired = true;
33 }
34
35 public static function isFrontendAssetsMarked(): bool
36 {
37 return self::$frontendAssetsRequired;
38 }
39
40 public static function shouldLoadGlobalFrontendAssets(): bool
41 {
42 $shouldLoad = true;
43
44 return (bool) apply_filters('fluent_cart/frontend_assets/should_load_global', $shouldLoad, [
45 'page_type' => TemplateService::getCurrentFcPageType(),
46 'is_marked' => self::isFrontendAssetsMarked(),
47 'is_fluentcart_context' => self::isFluentCartContext(),
48 'is_instant_checkout' => (bool) App::request()->get(Helper::INSTANT_CHECKOUT_URL_PARAM),
49 'is_modal_checkout' => App::request()->get('fluent-cart') === 'modal_checkout',
50 ]);
51 }
52
53 public static function isFluentCartContext(): bool
54 {
55 if (self::isFrontendAssetsMarked()) {
56 return true;
57 }
58
59 $pageType = TemplateService::getCurrentFcPageType();
60 if (in_array($pageType, [
61 'single_product',
62 'product_taxonomy',
63 'shop',
64 'cart',
65 'checkout',
66 'registration',
67 'login'
68 ], true)) {
69 return true;
70 }
71
72 if (App::request()->get(Helper::INSTANT_CHECKOUT_URL_PARAM)) {
73 return true;
74 }
75
76 return App::request()->get('fluent-cart') === 'modal_checkout';
77 }
78
79 public static function register()
80 {
81 add_action('wp_enqueue_scripts', [self::class, 'enqueueAssets']);
82 }
83
84 public static function enqueueAssets()
85 {
86 $pageType = TemplateService::getCurrentFcPageType();
87
88 switch ($pageType) {
89 case 'single_product':
90 self::loadSingleProductAssets();
91 break;
92 case 'product_taxonomy':
93 case 'shop':
94 self::loadProductArchiveAssets();
95 break;
96 case 'customer_dashboard':
97 self::loadCustomerDashboardGlobalAssets();
98 break;
99 case 'cart':
100 self::loadCartAssets();
101 break;
102 case 'checkout':
103 self::loadCheckoutAssets();
104 break;
105 default:
106 return;
107 }
108 }
109
110 public static function loadSingleProductAssets()
111 {
112 self::markFrontendAssetsRequired();
113 static $isLoaded = false;
114 if ($isLoaded) {
115 return;
116 }
117 self::loadProductCardAssets();
118 $isLoaded = true;
119 $singlePageScripts = [
120 [
121 'source' => 'public/single-product/xzoom/xzoom.js',
122 'dependencies' => [],
123 'inFooter' => true,
124 ],
125 [
126 'source' => 'public/single-product/SingleProduct.js',
127 'dependencies' => [],
128 'inFooter' => true
129 ]
130 ];
131 $localizeData = [
132 'fluentcart_single_product_vars' => [
133 'trans' => TransStrings::singleProductPageString(),
134 'cart_button_text' => apply_filters('fluent_cart/product/add_to_cart_text', __('Add To Cart', 'fluent-cart'), []),
135 // App::storeSettings()->get('cart_button_text', __('Add to Cart', 'fluent-cart')),
136 'out_of_stock_button_text' => apply_filters('fluent_cart/product/out_of_stock_text', __('Not Available', 'fluent-cart'), []),
137
138 'buy_now_button_text' => apply_filters('fluent_cart/product/buy_now_button_text', __('Buy Now', 'fluent-cart'), []),
139 'in_stock_status' => Helper::IN_STOCK,
140 'out_of_stock_status' => Helper::OUT_OF_STOCK,
141 'enable_image_zoom' => (new StoreSettings())->get('enable_image_zoom_in_single_product'),
142 'enable_image_zoom_in_modal' => (new StoreSettings())->get('enable_image_zoom_in_modal')
143 ]
144 ];
145 Vite::enqueueAllScripts($singlePageScripts, 'fluent-cart-single-product-page', $localizeData);
146
147 $singlePageStyles = [
148 'public/single-product/single-product.scss',
149 'public/single-product/similar-product.scss',
150 'public/product-card/style/product-card.scss',
151 'public/single-product/xzoom/xzoom.css',
152 'public/buttons/add-to-cart/style/style.scss',
153 'public/buttons/direct-checkout/style/style.scss'
154 ];
155
156 Vite::enqueueAllStyles($singlePageStyles, 'fluent-cart-single-product-page');
157
158
159 }
160
161 public static function loadAddToCartCss()
162 {
163 self::markFrontendAssetsRequired();
164 $singlePageStyles = [
165 'public/buttons/add-to-cart/style/style.scss',
166 ];
167
168 Vite::enqueueAllStyles($singlePageStyles, 'fluent-cart-add-to-cart');
169 }
170
171 public static function loadModalCheckoutAssets()
172 {
173 static $isLoaded = false;
174 if ($isLoaded) {
175 return;
176 }
177
178 $isLoaded = true;
179
180 // $scripts = [
181 // 'source' => 'public/checkout/ModalCheckoutHandler.js',
182 // 'dependencies' => [],
183 // 'inFooter' => true
184 // ];
185
186 Vite::enqueueStyle(
187 'fluentcart-modal-checkout-css',
188 'public/checkout/style/modal-checkout.scss'
189 );
190
191 // Vite::enqueueAllScripts($scripts, 'fluent-cart-modal-checkout');
192 }
193
194 public static function loadProductCardAssets()
195 {
196 self::markFrontendAssetsRequired();
197 static $isLoaded = false;
198 if ($isLoaded) {
199 return;
200 }
201 $isLoaded = true;
202 $singlePageStyles = [
203 'public/product-card/style/product-card.scss',
204 ];
205 Vite::enqueueAllStyles($singlePageStyles, 'fluent-cart-product-card-page');
206 Vite::enqueueStyle(
207 'fluent-cart-sold-out-badge',
208 'admin/BlockEditor/SoldOutBadge/style/sold-out-badge-block-editor.scss'
209 );
210 Vite::enqueueStyle(
211 'fluent-cart-sale-badge',
212 'admin/BlockEditor/SaleBadge/style/sale-badge-block-editor.scss'
213 );
214 Vite::enqueueScript(
215 'fluent-cart-product-card-js',
216 'public/product-card/product-card.js',
217 [],
218 null,
219 true
220 );
221 }
222
223 public static function loadProductArchiveAssets()
224 {
225 self::markFrontendAssetsRequired();
226 static $isLoaded = false;
227 if ($isLoaded) {
228 return;
229 }
230 $isLoaded = true;
231 static::loadProductCardAssets();
232
233 $app = App::getInstance();
234 $slug = $app->config->get('app.slug');
235 Vite::enqueueStyle(
236 'fluentcart-product-card-page-css',
237 'public/product-card/style/product-card.scss'
238 );
239
240 Vite::enqueueStyle(
241 'fluentcart-single-product-css',
242 'public/single-product/single-product.scss'
243 );
244 Vite::enqueueStyle(
245 'fluentcart-similar-product-css',
246 'public/single-product/similar-product.scss'
247 );
248 Vite::enqueueStyle(
249 'fluentcart-add-to-cart-btn-css',
250 'public/buttons/add-to-cart/style/style.scss'
251 );
252 Vite::enqueueStyle(
253 'fluentcart-direct-checkout-btn-css',
254 'public/buttons/direct-checkout/style/style.scss'
255 );
256 Vite::enqueueStyle(
257 $slug . '-fluentcart-product-page-css',
258 'public/product-page/style/shop-app.scss',
259 );
260 Vite::enqueueStaticStyle(
261 $slug . '-fluentcart-product-filter-slider-css',
262 'public/lib/nouislider/nouislider-15.7.1.css',
263 );
264
265
266 ob_start();
267 ProductFilterRender::renderResponsiveFilter();
268 $responsiveFilterWrapper = ob_get_clean();
269
270 $assetsPath = $app['url.assets'];
271
272
273 Vite::enqueueScript(
274 $slug . '-fluentcart-product-page-js',
275 'public/product-page/ShopApp.js',
276 []
277 )->with([
278 'fluentcart_shop_vars' => [
279 'rest' => Helper::getRestInfo(),
280 'shop' => Helper::shopConfig(),
281 'currency_settings' => CurrencySettings::get(),
282 'checkout_page' => (new StoreSettings)->getCheckoutPage(),
283 'cart_image' => $assetsPath . 'images/cart.svg',
284 'cart_driver' => Helper::getCartDriver(),
285 'responsive_filter_wrapper' => $responsiveFilterWrapper,
286 'is_admin_bar_showing' => is_admin_bar_showing(),
287 'responsive_filter_breakpoint' => apply_filters('shop_app_responsive_filter_breakpoint', 768)
288 ],
289 'fluentCartRestVars' => [
290 'rest' => Helper::getRestInfo(),
291 'ajaxurl' => admin_url('admin-ajax.php')
292 ]
293 ]);
294 Vite::enqueueStaticScript(
295 $slug . '-fluentcart-product-filter-slider',
296 'public/lib/nouislider/nouislider-15.7.1.min.js',
297 [$slug . '-fluentcart-product-page-js']
298 );
299 Vite::enqueueScript(
300 'fluentcart-zoom-js',
301 'public/single-product/xzoom/xzoom.js',
302 []
303 );
304
305 Vite::enqueueScript(
306 'fluentcart-single-product-js',
307 'public/single-product/SingleProduct.js',
308 []
309 )->with([
310 'fluentcart_single_product_vars' => [
311 'trans' => TransStrings::singleProductPageString(),
312 'cart_button_text' => apply_filters('fluent_cart/product/add_to_cart_text', __('Add To Cart', 'fluent-cart'), []),
313 // App::storeSettings()->get('cart_button_text', __('Add to Cart', 'fluent-cart')),
314 'out_of_stock_button_text' => apply_filters('fluent_cart/product/out_of_stock_button_text', __('Not Available', 'fluent-cart'), []),
315 'buy_now_button_text' => apply_filters('fluent_cart/product/buy_now_button_text', __('Buy Now', 'fluent-cart'), []),
316 'in_stock_status' => Helper::IN_STOCK,
317 'out_of_stock_status' => Helper::OUT_OF_STOCK,
318 'enable_image_zoom' => (new StoreSettings())->get('enable_image_zoom_in_single_product')
319 ]
320 ]);
321 }
322
323 public static function loadCustomerDashboardGlobalAssets()
324 {
325 static $isLoaded = false;
326 if ($isLoaded) {
327 return;
328 }
329 $isLoaded = true;
330 Vite::enqueueStyle('fluent-cart-customer-profile-global',
331 'public/customer-profile/style/customer-profile-global.scss',
332 );
333 }
334
335 public static function loadCustomerDashboardAssets()
336 {
337 static $isLoaded = false;
338 if ($isLoaded) {
339 return;
340 }
341 $isLoaded = true;
342 Vite::enqueueStyle('fluentcart-customer-css',
343 'public/customer-profile/style/customer-profile.scss'
344 );
345
346 Vite::enqueueScript(
347 'fluentcart-customer-js',
348 'public/customer-profile/Start.js',
349 []
350 )->with(CustomerProfileHandler::getLocalizationData());
351
352 //will add script here/ skipping for now
353 }
354
355 public static function loadCartAssets()
356 {
357 self::markFrontendAssetsRequired();
358 static $isLoaded = false;
359 if ($isLoaded) {
360 return;
361 }
362 $isLoaded = true;
363 $app = fluentCart();
364 $slug = $app->config->get('app.slug');
365 Vite::enqueueStaticScript(
366 $slug . '-fluentcart-toastify-notify-style',
367 'public/lib/toastify/toastify-js-1.12.0.js',
368 [$slug . '-app',]
369 );
370
371 Vite::enqueueStaticStyle(
372 $slug . '-fluentcart-toastify-notify-js',
373 'public/lib/toastify/toastify.min-1.12.0.css',
374 );
375
376 $cart = CartHelper::getCart(null, false);
377
378 $isInstantCheckout = (bool) App::request()->get(Helper::INSTANT_CHECKOUT_URL_PARAM);
379
380 $cartItemLayout = '';
381 $emptyCartLayout = '';
382
383 if (!App::request()->get(Helper::INSTANT_CHECKOUT_URL_PARAM)) {
384 $cartItems = Arr::get(CartResource::getStatus(), 'cart_data', []);
385 $cartRenderer = new CartRenderer($cartItems);
386
387 ob_start();
388 $cartRenderer->renderDummyItems();
389 $cartItemLayout = ob_get_clean();
390 ob_start();
391
392 $cartRenderer->renderEmpty();
393
394 $emptyCartLayout = ob_get_clean();
395 }
396
397 Vite::enqueueScript(
398 $slug . '-app',
399 'public/globals/FluentCartApp.js',
400 []
401 )->with([
402 'fluentCartRestVars' => [
403 'rest' => Helper::getRestInfo(),
404 'ajaxurl' => admin_url('admin-ajax.php'),
405 ],
406 'fluentcart_drawer_vars' => [
407 'placeholder_image' => Vite::getAssetUrl('images/placeholder.svg'),
408 'cart_item_layout' => $cartItemLayout,
409 'empty_cart_layout' => $emptyCartLayout,
410 'cart_driver' => Helper::getCartDriver(),
411 'cart_image' => Vite::getAssetUrl('images/cart.svg'),
412 'currency_settings' => CurrencySettings::get(),
413 'has_active_cart' => !!$cart,
414 'is_drawer_hidden' => CartLoader::shouldHideCartDrawer(),
415 'is_admin_bar_showing' => is_admin_bar_showing(),
416 'cart_item_count' => $isInstantCheckout ? 0 : ($cart ? count($cart->cart_data ?? []) : 0),
417 'cart_total_quantity' => $isInstantCheckout ? 0 : ($cart ? array_sum(array_map(function ($item) { return (int) ($item['quantity'] ?? 1); }, $cart->cart_data ?? [])) : 0),
418 ],
419 'fluentcart_utm_vars' => [
420 'allowed_keys' => UtmHelper::allowedUtmParameterKey(),
421 'internal_domains' => UtmHelper::getInternalDomains()
422 ]
423 ]);
424
425 Vite::enqueueStyle(
426 $slug . '-fluentcart-drawer',
427 'public/cart-drawer/cart-drawer.scss',
428 );
429
430 Vite::enqueueStyle(
431 $slug . '-global-styles',
432 'public/globals/style.scss',
433 );
434 }
435
436 public static function loadCheckoutAssets($cart = null)
437 {
438 self::markFrontendAssetsRequired();
439
440 static $isLoaded = false;
441 if ($isLoaded) {
442 return;
443 }
444 $isLoaded = true;
445 if (!$cart) {
446 $cart = CartHelper::getCart();
447 }
448
449 static::loadCartAssets();
450
451 if (!$cart) {
452 return;
453 }
454
455 static $alreadyLoaded = false;
456 if ($alreadyLoaded) {
457 return;
458 }
459
460 $alreadyLoaded = true;
461
462 Vite::enqueueAllStyles(
463 [
464 [
465 'source' => 'public/checkout/style/checkout.scss',
466 ],
467 [
468 'source' => 'public/components/select/style/style.scss',
469 ]
470 ],
471 'checkout-page'
472 );
473 $scripts = [
474 [
475 'source' => 'public/checkout/FluentCartCheckout.js',
476 'dependencies' => ['fluent-cart-app'],
477 'inFooter' => true,
478 'handle' => 'fct-checkout'
479 ],
480 [
481 'source' => 'public/orderbump/orderbump.js',
482 'dependencies' => ['fluent-cart-app'],
483 'inFooter' => true,
484 'handle' => 'fct-orderbump'
485 ]
486 ];
487 Vite::enqueueAllScripts($scripts, 'fct-checkout');
488
489 self::localizeCheckoutData($cart);
490 }
491
492 private static function localizeCheckoutData(Cart $cart)
493 {
494 static $isLoaded = false;
495 if ($isLoaded) {
496 return;
497 }
498 $isLoaded = true;
499 $countryCode = (string)Arr::get($cart->checkout_data, 'form_data.billing_country');
500 $countryInfo = [];
501 if (!empty($countryCode)) {
502 $countryInfo[$countryCode] = LocalizationManager::getCountryInfoFromRequest(null, $countryCode);
503 $shippingCountryCode = (string)Arr::get($cart->checkout_data, 'form_data.shipping_country');
504 if (Arr::get($cart->checkout_data, 'form_data.ship_to_different') === 'yes' && $shippingCountryCode !== $countryCode) {
505 $countryInfo[$shippingCountryCode] = LocalizationManager::getCountryInfoFromRequest(null, $shippingCountryCode);
506 }
507 }
508
509
510 //if url has cart hash then it's an instant checkout
511 $hasInstantCheckout = App::request()->get(Helper::INSTANT_CHECKOUT_URL_PARAM);
512 $hasModalCheckout = App::request()->get('fluent-cart') === 'modal_checkout';
513 $isInstantCheckout = 'no';
514 if ($hasInstantCheckout || $hasModalCheckout) {
515 $isInstantCheckout = 'yes';
516 }
517
518 $checkoutErrorNotices = Arr::get($cart->checkout_data, '__checkout_error_notices', []);
519 if ($checkoutErrorNotices) {
520 $checkoutData = is_array($cart->checkout_data) ? $cart->checkout_data : [];
521 unset($checkoutData['__checkout_error_notices']);
522 $cart->checkout_data = $checkoutData;
523 $cart->save();
524 }
525
526 $data = [
527 'fluentcart_checkout_vars' => [
528 'rest' => Helper::getRestInfo(),
529 'ajaxurl' => admin_url('admin-ajax.php'),
530 'is_all_digital' => !$cart->requireShipping(),
531 'is_cart_locked' => $cart->checkout_data['is_locked'] ?? 'no',
532 'disable_coupons' => $cart->checkout_data['disable_coupons'] ?? 'no',
533 'notices' => array_values($checkoutErrorNotices),
534 'payment_methods_with_custom_checkout_buttons' => apply_filters('fluent_cart/payment_methods_with_custom_checkout_buttons', []),
535 'tax_settings' => (new TaxModule())->getSettings(),
536 'submit_button' => [
537 'text' => __('Place Order', 'fluent-cart'),
538 ],
539 'trans' => TransStrings::checkoutPageString(),
540 'payments_trans' => TransStrings::paymentsString(),
541 'cart_hash' => $cart->cart_hash,
542 'is_instant_checkout' => $isInstantCheckout,
543 'is_modal_checkout' => $hasModalCheckout ? 'yes' : 'no',
544
545 ],
546 'fluentcart_checkout_info' => [
547 'baseUrl' => site_url(),
548 'rest_url' => Helper::getRestInfo()['url'],
549 'checkout_nonce' => wp_create_nonce('fluentcart'),
550 'ajax_url' => admin_url('admin-ajax.php'),
551 'is_user_logged_in' => is_user_logged_in(),
552 'is_admin' => current_user_can('manage_options'),
553 'has_subscription' => $cart->hasSubscription(),
554 'rest' => Helper::getRestInfo(),
555 'order_confirmation_url' => admin_url('admin-ajax.php?action=fluent_cart_place_order'),
556 'order_information_url' => URL::getApiUrl('/checkout/get-order-info'),
557 'custom_checkout_url' => URL::getApiUrl('/checkout'),
558 'redirect_url' => (new StoreSettings())->getCheckoutPage(),
559 'store_country' => (new StoreSettings())->get('store_country'),
560 'country_info' => $countryInfo,
561 'is_zero_payment' => $cart->isZeroPayment() ? 'yes' : 'no'
562 ]
563 ];
564
565 // Apply filters to allow modules to modify localized data
566 $data = apply_filters('fluent_cart/checkout/localize_data', $data, $cart);
567
568 foreach ($data as $key => $datum) {
569 wp_localize_script('fct-checkout', $key, $datum);
570 }
571 }
572
573 private static function markAssetLoaded($handle)
574 {
575 self::$loadedAssets[$handle] = true;
576 }
577
578 public static function enqueueProductInfoFrontendStyles()
579 {
580 self::markFrontendAssetsRequired();
581 static $isLoaded = false;
582 if ($isLoaded) {
583 return;
584 }
585 $isLoaded = true;
586 // Enqueue frontend styles for the product info block
587 Vite::enqueueStyle(
588 'fluentcart-single-product',
589 'public/single-product/single-product.scss'
590 );
591
592 // Enqueue related component styles
593 Vite::enqueueStyle(
594 'fluentcart-add-to-cart-btn-css',
595 'public/buttons/add-to-cart/style/style.scss'
596 );
597
598 Vite::enqueueStyle(
599 'fluentcart-direct-checkout-btn-css',
600 'public/buttons/direct-checkout/style/style.scss'
601 );
602 }
603
604
605 public static function enqueueThankYouPageAssets()
606 {
607 Vite::enqueueStyle(
608 'fluentcart-thank-you-css',
609 'public/receipt/style/thank_you.scss',
610 );
611 }
612
613 public static function loadMiniCartAssets()
614 {
615 self::markFrontendAssetsRequired();
616 static $isLoaded = false;
617 if ($isLoaded) {
618 return;
619 }
620 $isLoaded = true;
621
622 $app = fluentCart();
623 $slug = $app->config->get('app.slug');
624
625 Vite::enqueueStyle(
626 $slug . '-mini-cart',
627 'public/cart-drawer/mini-cart.scss',
628 );
629 }
630
631 }
632