PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.6
Yatra – Travel Booking & Tour Operator Software v3.0.2.6
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
yatra / app / Providers / FrontendAssetsProvider.php

FrontendAssetsProvider.php in Yatra – Travel Booking & Tour Operator Software 3.0.2.6, at app/Providers/FrontendAssetsProvider.php

715 lines 26.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Yatra\Providers;
6
7 use Yatra\Core\Modules\ModuleManager;
8 use Yatra\Utils\Logger;
9
10 /**
11 * Frontend Assets Provider
12 *
13 * Handles enqueuing of all frontend-related CSS and JavaScript assets
14 * Centralizes frontend asset management for better organization and maintainability
15 *
16 * @package Yatra\Providers
17 * @since 3.0.0
18 */
19 class FrontendAssetsProvider
20 {
21 /**
22 * Register the provider
23 *
24 * @return void
25 */
26 public function register(): void
27 {
28 // Hook into WordPress to enqueue assets
29 add_action('wp_enqueue_scripts', [$this, 'enqueueAssets']);
30 }
31
32 /**
33 * Enqueue frontend assets based on context
34 *
35 * @return void
36 */
37 public function enqueueAssets(): void
38 {
39 // Only run on frontend
40 if (is_admin()) {
41 return;
42 }
43
44 // Always enqueue common frontend assets
45 $this->enqueueCommonAssets();
46
47 // Enqueue page-specific assets
48 $this->enqueuePageSpecificAssets();
49 }
50
51 /**
52 * Enqueue common frontend assets
53 *
54 * @return void
55 */
56 private function enqueueCommonAssets(): void
57 {
58 // Enqueue common CSS
59 $this->enqueueCommonCss();
60
61 // Enqueue common JavaScript
62 $this->enqueueCommonJs();
63 }
64
65 /**
66 * Enqueue common CSS files
67 *
68 * @return void
69 */
70 private function enqueueCommonCss(): void
71 {
72 $cssFiles = [
73 'common' => 'common.css',
74 'listing' => 'listing.css',
75 'stripe' => 'stripe.css',
76 'trip' => 'trip.css',
77 'activity' => 'activity.css',
78 'destination' => 'destination.css',
79 'yatra-capacity' => 'yatra-capacity.css',
80 'video-player' => 'video-player.css',
81 'tour-viewer' => 'tour-viewer.css',
82 ];
83
84 foreach ($cssFiles as $handle => $filename) {
85 $filePath = YATRA_PLUGIN_PATH . "assets/css/{$filename}";
86 if (file_exists($filePath)) {
87 wp_enqueue_style(
88 "yatra-{$handle}",
89 YATRA_PLUGIN_URL . "assets/css/{$filename}",
90 [],
91 YATRA_VERSION . '.' . filemtime($filePath)
92 );
93 }
94 }
95 }
96
97 /**
98 * Enqueue common JavaScript files
99 *
100 * @return void
101 */
102 private function enqueueCommonJs(): void
103 {
104 $jsFiles = [
105 'api-helper' => 'api-helper.js',
106 'video-player' => 'video-player.js',
107 'tour-viewer' => 'tour-viewer.js',
108 'listing' => 'listing.js',
109 'listing-filters' => 'listing-filters.js',
110 'stripe' => 'stripe.js',
111 'trip' => 'trip.js',
112 ];
113
114 foreach ($jsFiles as $handle => $filename) {
115 $filePath = YATRA_PLUGIN_PATH . "assets/js/{$filename}";
116 if (file_exists($filePath)) {
117 // Set dependencies
118 $dependencies = ['jquery'];
119 if ($handle === 'trip') {
120 $dependencies[] = 'yatra-api-helper';
121 }
122
123 wp_enqueue_script(
124 "yatra-{$handle}",
125 YATRA_PLUGIN_URL . "assets/js/{$filename}",
126 $dependencies,
127 YATRA_VERSION . '.' . filemtime($filePath),
128 true
129 );
130 }
131 }
132
133 if (\Yatra\Services\SettingsService::wishlistEnabled()) {
134 $wishPath = YATRA_PLUGIN_PATH . 'assets/js/listing-wishlist.js';
135 if (file_exists($wishPath)) {
136 wp_enqueue_script(
137 'yatra-listing-wishlist',
138 YATRA_PLUGIN_URL . 'assets/js/listing-wishlist.js',
139 ['jquery'],
140 YATRA_VERSION . '.' . filemtime($wishPath),
141 true
142 );
143 wp_localize_script('yatra-listing-wishlist', 'yatraWishlistConfig', [
144 'enabled' => true,
145 'restUrl' => rest_url('yatra/v1'),
146 'nonce' => wp_create_nonce('wp_rest'),
147 'isLoggedIn' => is_user_logged_in(),
148 ]);
149 }
150 }
151 }
152
153 /**
154 * Enqueue page-specific assets
155 *
156 * @return void
157 */
158 private function enqueuePageSpecificAssets(): void
159 {
160 if (yatra_is_account_page()) {
161 $this->enqueueAccountAssets();
162
163 return;
164 }
165
166 // Check current page context and enqueue specific assets using helper functions
167 if (yatra_is_trip_listing()) {
168 $this->enqueueTripListingAssets();
169 }
170
171 if (yatra_is_single_trip()) {
172 $this->enqueueTripDetailAssets();
173 }
174
175 if (yatra_is_activity_listing()) {
176 $this->enqueueActivityListingAssets();
177 }
178
179 if (yatra_is_destination_listing()) {
180 $this->enqueueDestinationListingAssets();
181 }
182
183 if (yatra_is_booking_page()) {
184 $this->enqueueBookingAssets();
185 }
186
187 if (yatra_is_taxonomy_page()) {
188 // Taxonomy pages use the same assets as trip listing
189 $this->enqueueTripListingAssets();
190 }
191 }
192
193 /**
194 * Enqueue trip listing specific assets
195 *
196 * @return void
197 */
198 private function enqueueTripListingAssets(): void
199 {
200 $this->enqueueListingFiltersJs();
201 }
202
203 /**
204 * Enqueue trip detail specific assets
205 *
206 * @return void
207 */
208 private function enqueueTripDetailAssets(): void
209 {
210 // Enqueue booking assets for trip detail pages (booking forms)
211 $bookingJs = YATRA_PLUGIN_PATH . 'assets/js/booking.js';
212 if (file_exists($bookingJs)) {
213 wp_enqueue_script(
214 'yatra-booking',
215 YATRA_PLUGIN_URL . 'assets/js/booking.js',
216 ['jquery'],
217 YATRA_VERSION . '.' . filemtime($bookingJs),
218 true
219 );
220 }
221
222 // Localize trip page data for JS (trip.js, booking.js)
223 global $trip;
224
225 $permalink_structure = get_option('permalink_structure') ?: '';
226 $is_plain = empty($permalink_structure);
227
228 $trip_id = null;
229 $trip_slug = null;
230 $has_trip = isset($trip) && is_object($trip) && isset($trip->id);
231 if ($has_trip) {
232 $trip_id = (int) $trip->id;
233 }
234 if ($has_trip && isset($trip->slug)) {
235 $trip_slug = $trip->slug;
236 }
237
238 $tripData = [
239 'apiUrl' => rest_url('yatra/v1'),
240 'restUrl' => rest_url(),
241 'siteUrl' => site_url(),
242 'bookingBase' => \Yatra\Services\SettingsService::getBookingBase(),
243 'permalinkStructure' => $is_plain ? 'plain' : $permalink_structure,
244 'nonce' => wp_create_nonce('wp_rest'),
245 'tripId' => $trip_id,
246 'tripSlug' => $trip_slug,
247 'wishlistEnabled' => \Yatra\Services\SettingsService::wishlistEnabled(),
248 'isLoggedIn' => is_user_logged_in(),
249 // Currency/settings
250 'currency' => \Yatra\Services\SettingsService::getCurrency(),
251 'currencyPosition' => \Yatra\Services\SettingsService::getString('currency_position', 'before'),
252 'decimalPlaces' => (int) \Yatra\Services\SettingsService::getString('currency_decimals', '2'),
253 'thousandSeparator' => \Yatra\Services\SettingsService::getString('thousand_separator', ','),
254 'decimalSeparator' => \Yatra\Services\SettingsService::getString('decimal_separator', '.'),
255 'basePrice' => 0.0,
256 'currencySymbol' => function_exists('yatra_get_currency_symbol')
257 ? yatra_get_currency_symbol(\Yatra\Services\SettingsService::getCurrency())
258 : '$',
259 'availabilityDates' => [],
260 'groupDiscountsUrl' => rest_url('yatra/v1/discounts/group-discounts'),
261 ];
262
263 if ($has_trip) {
264 if (function_exists('yatra_single_trip_calculate_base_price')) {
265 $pricing_data = yatra_single_trip_calculate_base_price($trip);
266 $tripData['basePrice'] = (float) ($pricing_data['base_price'] ?? 0);
267 }
268 if (method_exists($trip, 'getAvailabilityDates')) {
269 $tripData['availabilityDates'] = array_values(array_filter(array_map(static function ($avail) {
270 if (is_object($avail)) {
271 return $avail->departure_date ?? $avail->date ?? null;
272 }
273 if (is_array($avail)) {
274 return $avail['departure_date'] ?? $avail['date'] ?? null;
275 }
276
277 return null;
278 }, $trip->getAvailabilityDates())));
279 }
280 }
281
282 wp_localize_script('yatra-trip', 'yatraTripData', $tripData);
283 $tripTitle = '';
284 if ($has_trip && isset($trip->title)) {
285 $tripTitle = is_string($trip->title) ? $trip->title : '';
286 }
287 wp_localize_script('yatra-booking', 'yatraBookingData', array_merge(
288 $tripData,
289 $this->getStripeFrontendBookingPayload(),
290 [
291 'tripTitle' => $tripTitle !== '' ? $tripTitle : ($tripData['tripTitle'] ?? 'Trip Booking'),
292 // booking page expects these keys; leave placeholders if not set on trip view
293 'isRemainingPayment' => false,
294 'remainingAmount' => 0,
295 'totalAmount' => 0,
296 'amountPaid' => 0,
297 ]
298 ));
299 }
300
301 /**
302 * Enqueue activity listing specific assets
303 *
304 * @return void
305 */
306 private function enqueueActivityListingAssets(): void
307 {
308 // Activity listing specific assets
309 $filePath = YATRA_PLUGIN_PATH . 'assets/css/activity.css';
310 if (file_exists($filePath)) {
311 wp_enqueue_style(
312 'yatra-activity-listing',
313 YATRA_PLUGIN_URL . 'assets/css/activity.css',
314 [],
315 YATRA_VERSION . '.' . filemtime($filePath)
316 );
317 }
318 }
319
320 /**
321 * Enqueue destination listing specific assets
322 *
323 * @return void
324 */
325 private function enqueueDestinationListingAssets(): void
326 {
327 // Destination listing specific assets
328 $filePath = YATRA_PLUGIN_PATH . 'assets/css/destination.css';
329 if (file_exists($filePath)) {
330 wp_enqueue_style(
331 'yatra-destination-listing',
332 YATRA_PLUGIN_URL . 'assets/css/destination.css',
333 [],
334 YATRA_VERSION . '.' . filemtime($filePath)
335 );
336 }
337 }
338
339 /**
340 * Enqueue booking specific assets
341 *
342 * @return void
343 */
344 private function enqueueBookingAssets(): void
345 {
346 // Enqueue booking-specific CSS
347 $bookingCss = YATRA_PLUGIN_PATH . 'assets/css/booking.css';
348 if (file_exists($bookingCss)) {
349 wp_enqueue_style(
350 'yatra-booking',
351 YATRA_PLUGIN_URL . 'assets/css/booking.css',
352 [],
353 YATRA_VERSION . '.' . filemtime($bookingCss)
354 );
355 }
356
357 // Enqueue booking-specific JavaScript
358 $bookingJs = YATRA_PLUGIN_PATH . 'assets/js/booking.js';
359 if (file_exists($bookingJs)) {
360 wp_enqueue_script(
361 'yatra-booking',
362 YATRA_PLUGIN_URL . 'assets/js/booking.js',
363 ['jquery'],
364 YATRA_VERSION . '.' . filemtime($bookingJs),
365 true
366 );
367 }
368
369 // Localize booking data for booking.js
370 $permalink_structure = get_option('permalink_structure') ?: '';
371 $is_plain = empty($permalink_structure);
372
373 $deposit_pct_store = (int) \Yatra\Services\SettingsService::get('deposit_percentage', 20);
374 $partial_pct_store = (int) \Yatra\Services\SettingsService::get('partial_payment_percentage', 30);
375 $deposit_pct_resolved = (int) apply_filters('yatra_deposit_percentage', $deposit_pct_store);
376 $partial_pct_resolved = (int) apply_filters('yatra_partial_payment_percentage', $partial_pct_store);
377 $flexible_payments_enabled = (bool) apply_filters('yatra_flexible_payments_enabled', false);
378 $flexible_module_on = class_exists(ModuleManager::class)
379 ? ModuleManager::isModuleEnabled('flexible_payments')
380 : false;
381
382 Logger::debug('Yatra booking localize: flexible payment snapshot', [
383 'context' => 'booking_localize',
384 'flexible_payments_enabled' => $flexible_payments_enabled,
385 'flexible_payments_module' => $flexible_module_on,
386 'partial_payment_setting' => (bool) \Yatra\Services\SettingsService::get('partial_payment', false),
387 'deposit_required_setting' => (bool) \Yatra\Services\SettingsService::get('deposit_required', false),
388 'deposit_percentage_store' => $deposit_pct_store,
389 'partial_percentage_store' => $partial_pct_store,
390 'deposit_percentage_resolved' => $deposit_pct_resolved,
391 'partial_percentage_resolved' => $partial_pct_resolved,
392 ]);
393
394 $bookingData = [
395 'apiUrl' => rest_url('yatra/v1'),
396 'restUrl' => rest_url(),
397 'siteUrl' => site_url(),
398 'bookingBase' => \Yatra\Services\SettingsService::getBookingBase(),
399 'permalinkStructure' => $is_plain ? 'plain' : $permalink_structure,
400 'nonce' => wp_create_nonce('wp_rest'),
401 'currency' => \Yatra\Services\SettingsService::getCurrency(),
402 'currencyPosition' => \Yatra\Services\SettingsService::getString('currency_position', 'before'),
403 'decimalPlaces' => (int) \Yatra\Services\SettingsService::getString('currency_decimals', '2'),
404 'thousandSeparator' => \Yatra\Services\SettingsService::getString('thousand_separator', ','),
405 'decimalSeparator' => \Yatra\Services\SettingsService::getString('decimal_separator', '.'),
406 // Payment gateways data
407 'paymentGateways' => apply_filters('yatra_payment_gateways', \Yatra\Services\SettingsService::get('payment_gateways', [])),
408 'paymentMethods' => \Yatra\Services\SettingsService::get('payment_methods', []),
409 'paymentTestMode' => \Yatra\Services\SettingsService::get('payment_test_mode', false),
410 'partialPayment' => \Yatra\Services\SettingsService::get('partial_payment', false),
411 'partialPaymentPercentage' => \Yatra\Services\SettingsService::get('partial_payment_percentage', 0),
412 // Flexible payments (Pro) — keep these keys stable for frontend booking.js.
413 // Values are resolved via generic filters so Pro can override without hard-coding premium logic here.
414 'depositRequired' => (bool) \Yatra\Services\SettingsService::get('deposit_required', false),
415 'depositPercentage' => $deposit_pct_resolved,
416 'partialPercentage' => $partial_pct_resolved,
417 'gatewayOrder' => \Yatra\Services\SettingsService::get('gateway_order', []),
418 'autoConfirmPayLater' => \Yatra\Services\SettingsService::get('auto_confirm_pay_later', true),
419 'allowWaitlist' => \Yatra\Services\SettingsService::isEnabled('allow_waitlist'),
420 'waitlistAutoConfirm' => \Yatra\Services\SettingsService::isEnabled('waitlist_auto_confirm'),
421 'gateways' => apply_filters('yatra_payment_gateways', \Yatra\Services\SettingsService::get('payment_gateways', [])),
422 'enabledGateways' => \Yatra\Services\SettingsService::get('payment_gateways', []),
423 ];
424
425 $bookingData = array_merge($bookingData, $this->getStripeFrontendBookingPayload());
426
427 wp_localize_script('yatra-booking', 'yatraBookingData', $bookingData);
428 }
429
430 /**
431 * Enqueue account page specific assets
432 *
433 * @return void
434 */
435 private function enqueueAccountAssets(): void
436 {
437 // Account bundle shares admin Vite chunks; CSS is extracted to admin/dist/css (ES modules do not auto-load it).
438 $reactVendorCss = YATRA_PLUGIN_PATH . 'assets/admin/dist/css/react-vendor.css';
439 if (file_exists($reactVendorCss)) {
440 wp_enqueue_style(
441 'yatra-account-react-vendor',
442 YATRA_PLUGIN_URL . 'assets/admin/dist/css/react-vendor.css',
443 [],
444 YATRA_VERSION . '.' . filemtime($reactVendorCss)
445 );
446 }
447
448 $accountUiCss = YATRA_PLUGIN_PATH . 'assets/admin/dist/css/index.css';
449 $accountUiDeps = file_exists($reactVendorCss) ? ['yatra-account-react-vendor'] : [];
450 if (file_exists($accountUiCss)) {
451 wp_enqueue_style(
452 'yatra-account-ui',
453 YATRA_PLUGIN_URL . 'assets/admin/dist/css/index.css',
454 $accountUiDeps,
455 YATRA_VERSION . '.' . filemtime($accountUiCss)
456 );
457 }
458
459 // Vite build outputs to assets/dist/js/account-page.js (ES module + shared chunks).
460 $accountJs = YATRA_PLUGIN_PATH . 'assets/dist/js/account-page.js';
461 if (!file_exists($accountJs)) {
462 return;
463 }
464
465 wp_enqueue_script(
466 'yatra-account-page',
467 YATRA_PLUGIN_URL . 'assets/dist/js/account-page.js',
468 [],
469 YATRA_VERSION . '.' . filemtime($accountJs),
470 true
471 );
472
473 wp_script_add_data('yatra-account-page', 'type', 'module');
474
475 wp_localize_script('yatra-account-page', 'yatraAccountPage', [
476 'apiUrl' => rest_url('yatra/v1'),
477 'nonce' => wp_create_nonce('wp_rest'),
478 'userId' => get_current_user_id(),
479 'siteUrl' => site_url(),
480 'logoutUrl' => wp_logout_url(home_url('/')),
481 'companyPhone' => \Yatra\Services\SettingsService::getString('company_phone', ''),
482 'companyName' => \Yatra\Services\SettingsService::getString('company_name', ''),
483 'companyEmail' => \Yatra\Services\SettingsService::getString('company_email', ''),
484 'currency' => \Yatra\Services\SettingsService::getCurrency(),
485 'currencyPosition' => \Yatra\Services\SettingsService::getString('currency_position', 'before'),
486 'decimalPlaces' => (int) \Yatra\Services\SettingsService::getString('currency_decimals', '2'),
487 'thousandSeparator' => \Yatra\Services\SettingsService::getString('thousand_separator', ','),
488 'decimalSeparator' => \Yatra\Services\SettingsService::getString('decimal_separator', '.'),
489 'locale' => get_locale(),
490 'translations' => $this->getFrontendTranslations(),
491 'wishlistEnabled' => \Yatra\Services\SettingsService::wishlistEnabled(),
492 ]);
493 }
494
495 /**
496 * Enqueue listing filters JavaScript
497 *
498 * @return void
499 */
500 private function enqueueListingFiltersJs(): void
501 {
502 $filtersJs = YATRA_PLUGIN_PATH . 'assets/js/listing-filters.js';
503 if (file_exists($filtersJs)) {
504 wp_enqueue_script(
505 'yatra-listing-filters',
506 YATRA_PLUGIN_URL . 'assets/js/listing-filters.js',
507 ['jquery'],
508 YATRA_VERSION . '.' . filemtime($filtersJs),
509 true
510 );
511
512 // Add currency formatting function
513 wp_add_inline_script('yatra-listing-filters', "
514 window.yatra_format_price = function(amount) {
515 if (!amount || amount == 0) return '" . esc_js(__('Contact for pricing', 'yatra')) . "';
516 const currency = window.yatraSettings?.currency || 'USD';
517 const symbol = window.yatraSettings?.currencySymbol || '$';
518 return symbol + amount.toLocaleString();
519 };
520 ");
521 }
522 }
523
524 /**
525 * Get frontend translations
526 *
527 * @return array
528 */
529 private function getFrontendTranslations(): array
530 {
531 return [
532 // Account page
533 'My Account' => __('My Account', 'yatra'),
534 'My Bookings' => __('My Bookings', 'yatra'),
535 'Account Settings' => __('Account Settings', 'yatra'),
536 'Logout' => __('Logout', 'yatra'),
537 'Login' => __('Login', 'yatra'),
538 'Register' => __('Register', 'yatra'),
539
540 // Booking related
541 'Booking Details' => __('Booking Details', 'yatra'),
542 'Booking Status' => __('Booking Status', 'yatra'),
543 'Total Amount' => __('Total Amount', 'yatra'),
544 'Payment Status' => __('Payment Status', 'yatra'),
545 'View Details' => __('View Details', 'yatra'),
546
547 // Common
548 'Loading...' => __('Loading...', 'yatra'),
549 'No data available' => __('No data available', 'yatra'),
550 'Error loading data' => __('Error loading data', 'yatra'),
551 'Please try again' => __('Please try again', 'yatra'),
552
553 // Currency and pricing
554 'Contact for pricing' => __('Contact for pricing', 'yatra'),
555 'Free' => __('Free', 'yatra'),
556 'Price' => __('Price', 'yatra'),
557
558 // Trip related
559 'Trip Details' => __('Trip Details', 'yatra'),
560 'Duration' => __('Duration', 'yatra'),
561 'Difficulty' => __('Difficulty', 'yatra'),
562 'Group Size' => __('Group Size', 'yatra'),
563
564 // Navigation
565 'Home' => __('Home', 'yatra'),
566 'Trips' => __('Trips', 'yatra'),
567 'Destinations' => __('Destinations', 'yatra'),
568 'Activities' => __('Activities', 'yatra'),
569 'About Us' => __('About Us', 'yatra'),
570 'Contact' => __('Contact', 'yatra'),
571 ];
572 }
573
574 /**
575 * Enqueue assets for specific shortcodes
576 *
577 * @param array $shortcodes Array of shortcodes that need assets
578 * @return void
579 */
580 public function enqueueShortcodeAssets(array $shortcodes): void
581 {
582 global $post;
583
584 if (!$post || !has_shortcode($post->post_content, $shortcodes)) {
585 return;
586 }
587
588 // Enqueue common frontend assets for shortcodes
589 $this->enqueueCommonAssets();
590
591 // Shortcode-specific assets can be added here based on $shortcodes array
592 foreach ($shortcodes as $shortcode) {
593 switch ($shortcode) {
594 case 'yatra_trip_listing':
595 $this->enqueueTripListingAssets();
596 break;
597 case 'yatra_cart':
598 case 'yatra_checkout':
599 $this->enqueueBookingAssets();
600 break;
601 case 'yatra_my_account':
602 $this->enqueueAccountAssets();
603 break;
604 }
605 }
606 }
607
608 /**
609 * Enqueue assets conditionally based on custom conditions
610 *
611 * @param callable $condition Function that returns true if assets should be enqueued
612 * @return void
613 */
614 public function enqueueConditionalAssets(callable $condition): void
615 {
616 if ($condition()) {
617 $this->enqueueAssets();
618 }
619 }
620
621 /**
622 * Get asset URL with versioning
623 *
624 * @param string $path Relative path to asset
625 * @param string $type 'css' or 'js'
626 * @return string Asset URL or empty string if file doesn't exist
627 */
628 public function getAssetUrl(string $path, string $type = 'css'): string
629 {
630 $basePath = $type === 'css' ? 'assets/css/' : 'assets/js/';
631 $fullPath = YATRA_PLUGIN_PATH . $basePath . $path;
632
633 if (!file_exists($fullPath)) {
634 return '';
635 }
636
637 $version = YATRA_VERSION . '.' . filemtime($fullPath);
638 return YATRA_PLUGIN_URL . $basePath . $path . '?ver=' . $version;
639 }
640
641 /**
642 * Check if asset file exists
643 *
644 * @param string $path Relative path to asset
645 * @param string $type 'css' or 'js'
646 * @return bool
647 */
648 public function assetExists(string $path, string $type = 'css'): bool
649 {
650 $basePath = $type === 'css' ? 'assets/css/' : 'assets/js/';
651 $fullPath = YATRA_PLUGIN_PATH . $basePath . $path;
652 return file_exists($fullPath);
653 }
654
655 /**
656 * Stripe Elements (assets/js/stripe.js) expects publishableKey under yatraBookingData.stripe.
657 * Mirror YatraPro StripeGateway::loadConfig() live/test selection; never expose secret keys.
658 *
659 * @return array<string, mixed>
660 */
661 private function getStripeFrontendBookingPayload(): array
662 {
663 $allConfigs = get_option('yatra_gateway_configs', []);
664 if (is_string($allConfigs)) {
665 $maybe = maybe_unserialize($allConfigs);
666 $allConfigs = is_array($maybe) ? $maybe : [];
667 }
668 if (!is_array($allConfigs)) {
669 $allConfigs = [];
670 }
671
672 $stripe = isset($allConfigs['stripe']) && is_array($allConfigs['stripe'])
673 ? $allConfigs['stripe']
674 : [];
675
676 $test = filter_var(\Yatra\Services\SettingsService::get('payment_test_mode', true), FILTER_VALIDATE_BOOLEAN);
677
678 $livePub = trim((string) ($stripe['live_publishable_key'] ?? ''));
679 $testPub = trim((string) ($stripe['test_publishable_key'] ?? ''));
680
681 $publishableKey = trim((string) ($stripe['api_key'] ?? ''));
682 if ($test) {
683 if ($testPub !== '') {
684 $publishableKey = $testPub;
685 }
686 } elseif ($livePub !== '') {
687 $publishableKey = $livePub;
688 }
689
690 // Match StripeGateway default + admin multi-select when unset (was dropped by old sanitizer).
691 $defaultMethods = 'card,google_pay,apple_pay';
692 $enabledMethods = $stripe['enabled_methods'] ?? $defaultMethods;
693 if (is_array($enabledMethods)) {
694 // stripe.js accepts an array of method ids
695 } elseif (!is_string($enabledMethods) || trim($enabledMethods) === '') {
696 $enabledMethods = $defaultMethods;
697 }
698
699 $companyCountry = trim((string) \Yatra\Services\SettingsService::get('company_country', ''));
700 if ($companyCountry === '') {
701 $companyCountry = 'US';
702 }
703
704 $payload = [
705 'stripe' => [
706 'publishableKey' => $publishableKey,
707 'enabledMethods' => $enabledMethods,
708 ],
709 'companyCountry' => $companyCountry,
710 ];
711
712 return apply_filters('yatra_booking_stripe_frontend_data', $payload, $stripe, $test);
713 }
714 }
715