PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.5.0
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.5.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.5.0, at app/Modules/Templating/AssetLoader.php

622 lines 22.1 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 ]
422 ]);
423
424 Vite::enqueueStyle(
425 $slug . '-fluentcart-drawer',
426 'public/cart-drawer/cart-drawer.scss',
427 );
428
429 Vite::enqueueStyle(
430 $slug . '-global-styles',
431 'public/globals/style.scss',
432 );
433 }
434
435 public static function loadCheckoutAssets($cart = null)
436 {
437 self::markFrontendAssetsRequired();
438
439 static $isLoaded = false;
440 if ($isLoaded) {
441 return;
442 }
443 $isLoaded = true;
444 if (!$cart) {
445 $cart = CartHelper::getCart();
446 }
447
448 static::loadCartAssets();
449
450 if (!$cart) {
451 return;
452 }
453
454 static $alreadyLoaded = false;
455 if ($alreadyLoaded) {
456 return;
457 }
458
459 $alreadyLoaded = true;
460
461 Vite::enqueueAllStyles(
462 [
463 [
464 'source' => 'public/checkout/style/checkout.scss',
465 ],
466 [
467 'source' => 'public/components/select/style/style.scss',
468 ]
469 ],
470 'checkout-page'
471 );
472 $scripts = [
473 [
474 'source' => 'public/checkout/FluentCartCheckout.js',
475 'dependencies' => ['fluent-cart-app'],
476 'inFooter' => true,
477 'handle' => 'fct-checkout'
478 ],
479 [
480 'source' => 'public/orderbump/orderbump.js',
481 'dependencies' => ['fluent-cart-app'],
482 'inFooter' => true,
483 'handle' => 'fct-orderbump'
484 ]
485 ];
486 Vite::enqueueAllScripts($scripts, 'fct-checkout');
487
488 self::localizeCheckoutData($cart);
489 }
490
491 private static function localizeCheckoutData(Cart $cart)
492 {
493 static $isLoaded = false;
494 if ($isLoaded) {
495 return;
496 }
497 $isLoaded = true;
498 $countryCode = (string)Arr::get($cart->checkout_data, 'form_data.billing_country');
499 $countryInfo = [];
500 if (!empty($countryCode)) {
501 $countryInfo[$countryCode] = LocalizationManager::getCountryInfoFromRequest(null, $countryCode);
502 $shippingCountryCode = (string)Arr::get($cart->checkout_data, 'form_data.shipping_country');
503 if (Arr::get($cart->checkout_data, 'form_data.ship_to_different') === 'yes' && $shippingCountryCode !== $countryCode) {
504 $countryInfo[$shippingCountryCode] = LocalizationManager::getCountryInfoFromRequest(null, $shippingCountryCode);
505 }
506 }
507
508
509 //if url has cart hash then it's an instant checkout
510 $hasInstantCheckout = App::request()->get(Helper::INSTANT_CHECKOUT_URL_PARAM);
511 $hasModalCheckout = App::request()->get('fluent-cart') === 'modal_checkout';
512 $isInstantCheckout = 'no';
513 if ($hasInstantCheckout || $hasModalCheckout) {
514 $isInstantCheckout = 'yes';
515 }
516
517 $data = [
518 'fluentcart_checkout_vars' => [
519 'rest' => Helper::getRestInfo(),
520 'ajaxurl' => admin_url('admin-ajax.php'),
521 'is_all_digital' => !$cart->requireShipping(),
522 'is_cart_locked' => $cart->checkout_data['is_locked'] ?? 'no',
523 'disable_coupons' => $cart->checkout_data['disable_coupons'] ?? 'no',
524 'payment_methods_with_custom_checkout_buttons' => apply_filters('fluent_cart/payment_methods_with_custom_checkout_buttons', []),
525 'tax_settings' => (new TaxModule())->getSettings(),
526 'submit_button' => [
527 'text' => __('Place Order', 'fluent-cart'),
528 ],
529 'trans' => TransStrings::checkoutPageString(),
530 'payments_trans' => TransStrings::paymentsString(),
531 'cart_hash' => $cart->cart_hash,
532 'is_instant_checkout' => $isInstantCheckout,
533 'is_modal_checkout' => $hasModalCheckout ? 'yes' : 'no',
534
535 ],
536 'fluentcart_checkout_info' => [
537 'baseUrl' => site_url(),
538 'rest_url' => Helper::getRestInfo()['url'],
539 'checkout_nonce' => wp_create_nonce('fluentcart'),
540 'ajax_url' => admin_url('admin-ajax.php'),
541 'is_user_logged_in' => is_user_logged_in(),
542 'is_admin' => current_user_can('manage_options'),
543 'has_subscription' => $cart->hasSubscription(),
544 'rest' => Helper::getRestInfo(),
545 'order_confirmation_url' => admin_url('admin-ajax.php?action=fluent_cart_place_order'),
546 'order_information_url' => URL::getApiUrl('/checkout/get-order-info'),
547 'custom_checkout_url' => URL::getApiUrl('/checkout'),
548 'redirect_url' => (new StoreSettings())->getCheckoutPage(),
549 'store_country' => (new StoreSettings())->get('store_country'),
550 'country_info' => $countryInfo,
551 'is_zero_payment' => $cart->isZeroPayment() ? 'yes' : 'no'
552 ]
553 ];
554
555 // Apply filters to allow modules to modify localized data
556 $data = apply_filters('fluent_cart/checkout/localize_data', $data, $cart);
557
558 foreach ($data as $key => $datum) {
559 wp_localize_script('fct-checkout', $key, $datum);
560 }
561 }
562
563 private static function markAssetLoaded($handle)
564 {
565 self::$loadedAssets[$handle] = true;
566 }
567
568 public static function enqueueProductInfoFrontendStyles()
569 {
570 self::markFrontendAssetsRequired();
571 static $isLoaded = false;
572 if ($isLoaded) {
573 return;
574 }
575 $isLoaded = true;
576 // Enqueue frontend styles for the product info block
577 Vite::enqueueStyle(
578 'fluentcart-single-product',
579 'public/single-product/single-product.scss'
580 );
581
582 // Enqueue related component styles
583 Vite::enqueueStyle(
584 'fluentcart-add-to-cart-btn-css',
585 'public/buttons/add-to-cart/style/style.scss'
586 );
587
588 Vite::enqueueStyle(
589 'fluentcart-direct-checkout-btn-css',
590 'public/buttons/direct-checkout/style/style.scss'
591 );
592 }
593
594
595 public static function enqueueThankYouPageAssets()
596 {
597 Vite::enqueueStyle(
598 'fluentcart-thank-you-css',
599 'public/receipt/style/thank_you.scss',
600 );
601 }
602
603 public static function loadMiniCartAssets()
604 {
605 self::markFrontendAssetsRequired();
606 static $isLoaded = false;
607 if ($isLoaded) {
608 return;
609 }
610 $isLoaded = true;
611
612 $app = fluentCart();
613 $slug = $app->config->get('app.slug');
614
615 Vite::enqueueStyle(
616 $slug . '-mini-cart',
617 'public/cart-drawer/mini-cart.scss',
618 );
619 }
620
621 }
622