PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.8
Yatra – Travel Booking & Tour Operator Software v3.0.2.8
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.8, at app/Providers/FrontendAssetsProvider.php

719 lines 26.4 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 // Regional settings
250 'timezone' => \Yatra\Services\SettingsService::getString('timezone', 'UTC'),
251 'dateFormat' => \Yatra\Services\SettingsService::getString('date_format', 'Y-m-d'),
252 'timeFormat' => \Yatra\Services\SettingsService::getString('time_format', 'H:i'),
253 // Currency/settings
254 'currency' => \Yatra\Services\SettingsService::getCurrency(),
255 'currencyPosition' => \Yatra\Services\SettingsService::getString('currency_position', 'before'),
256 'decimalPlaces' => (int) \Yatra\Services\SettingsService::getString('currency_decimals', '2'),
257 'thousandSeparator' => \Yatra\Services\SettingsService::getString('thousand_separator', ','),
258 'decimalSeparator' => \Yatra\Services\SettingsService::getString('decimal_separator', '.'),
259 'basePrice' => 0.0,
260 'currencySymbol' => function_exists('yatra_get_currency_symbol')
261 ? yatra_get_currency_symbol(\Yatra\Services\SettingsService::getCurrency())
262 : '$',
263 'availabilityDates' => [],
264 'groupDiscountsUrl' => rest_url('yatra/v1/discounts/group-discounts'),
265 ];
266
267 if ($has_trip) {
268 if (function_exists('yatra_single_trip_calculate_base_price')) {
269 $pricing_data = yatra_single_trip_calculate_base_price($trip);
270 $tripData['basePrice'] = (float) ($pricing_data['base_price'] ?? 0);
271 }
272 if (method_exists($trip, 'getAvailabilityDates')) {
273 $tripData['availabilityDates'] = array_values(array_filter(array_map(static function ($avail) {
274 if (is_object($avail)) {
275 return $avail->departure_date ?? $avail->date ?? null;
276 }
277 if (is_array($avail)) {
278 return $avail['departure_date'] ?? $avail['date'] ?? null;
279 }
280
281 return null;
282 }, $trip->getAvailabilityDates())));
283 }
284 }
285
286 wp_localize_script('yatra-trip', 'yatraTripData', $tripData);
287 $tripTitle = '';
288 if ($has_trip && isset($trip->title)) {
289 $tripTitle = is_string($trip->title) ? $trip->title : '';
290 }
291 wp_localize_script('yatra-booking', 'yatraBookingData', array_merge(
292 $tripData,
293 $this->getStripeFrontendBookingPayload(),
294 [
295 'tripTitle' => $tripTitle !== '' ? $tripTitle : ($tripData['tripTitle'] ?? 'Trip Booking'),
296 // booking page expects these keys; leave placeholders if not set on trip view
297 'isRemainingPayment' => false,
298 'remainingAmount' => 0,
299 'totalAmount' => 0,
300 'amountPaid' => 0,
301 ]
302 ));
303 }
304
305 /**
306 * Enqueue activity listing specific assets
307 *
308 * @return void
309 */
310 private function enqueueActivityListingAssets(): void
311 {
312 // Activity listing specific assets
313 $filePath = YATRA_PLUGIN_PATH . 'assets/css/activity.css';
314 if (file_exists($filePath)) {
315 wp_enqueue_style(
316 'yatra-activity-listing',
317 YATRA_PLUGIN_URL . 'assets/css/activity.css',
318 [],
319 YATRA_VERSION . '.' . filemtime($filePath)
320 );
321 }
322 }
323
324 /**
325 * Enqueue destination listing specific assets
326 *
327 * @return void
328 */
329 private function enqueueDestinationListingAssets(): void
330 {
331 // Destination listing specific assets
332 $filePath = YATRA_PLUGIN_PATH . 'assets/css/destination.css';
333 if (file_exists($filePath)) {
334 wp_enqueue_style(
335 'yatra-destination-listing',
336 YATRA_PLUGIN_URL . 'assets/css/destination.css',
337 [],
338 YATRA_VERSION . '.' . filemtime($filePath)
339 );
340 }
341 }
342
343 /**
344 * Enqueue booking specific assets
345 *
346 * @return void
347 */
348 private function enqueueBookingAssets(): void
349 {
350 // Enqueue booking-specific CSS
351 $bookingCss = YATRA_PLUGIN_PATH . 'assets/css/booking.css';
352 if (file_exists($bookingCss)) {
353 wp_enqueue_style(
354 'yatra-booking',
355 YATRA_PLUGIN_URL . 'assets/css/booking.css',
356 [],
357 YATRA_VERSION . '.' . filemtime($bookingCss)
358 );
359 }
360
361 // Enqueue booking-specific JavaScript
362 $bookingJs = YATRA_PLUGIN_PATH . 'assets/js/booking.js';
363 if (file_exists($bookingJs)) {
364 wp_enqueue_script(
365 'yatra-booking',
366 YATRA_PLUGIN_URL . 'assets/js/booking.js',
367 ['jquery'],
368 YATRA_VERSION . '.' . filemtime($bookingJs),
369 true
370 );
371 }
372
373 // Localize booking data for booking.js
374 $permalink_structure = get_option('permalink_structure') ?: '';
375 $is_plain = empty($permalink_structure);
376
377 $deposit_pct_store = (int) \Yatra\Services\SettingsService::get('deposit_percentage', 20);
378 $partial_pct_store = (int) \Yatra\Services\SettingsService::get('partial_payment_percentage', 30);
379 $deposit_pct_resolved = (int) apply_filters('yatra_deposit_percentage', $deposit_pct_store);
380 $partial_pct_resolved = (int) apply_filters('yatra_partial_payment_percentage', $partial_pct_store);
381 $flexible_payments_enabled = (bool) apply_filters('yatra_flexible_payments_enabled', false);
382 $flexible_module_on = class_exists(ModuleManager::class)
383 ? ModuleManager::isModuleEnabled('flexible_payments')
384 : false;
385
386 Logger::debug('Yatra booking localize: flexible payment snapshot', [
387 'context' => 'booking_localize',
388 'flexible_payments_enabled' => $flexible_payments_enabled,
389 'flexible_payments_module' => $flexible_module_on,
390 'partial_payment_setting' => (bool) \Yatra\Services\SettingsService::get('partial_payment', false),
391 'deposit_required_setting' => (bool) \Yatra\Services\SettingsService::get('deposit_required', false),
392 'deposit_percentage_store' => $deposit_pct_store,
393 'partial_percentage_store' => $partial_pct_store,
394 'deposit_percentage_resolved' => $deposit_pct_resolved,
395 'partial_percentage_resolved' => $partial_pct_resolved,
396 ]);
397
398 $bookingData = [
399 'apiUrl' => rest_url('yatra/v1'),
400 'restUrl' => rest_url(),
401 'siteUrl' => site_url(),
402 'bookingBase' => \Yatra\Services\SettingsService::getBookingBase(),
403 'permalinkStructure' => $is_plain ? 'plain' : $permalink_structure,
404 'nonce' => wp_create_nonce('wp_rest'),
405 'currency' => \Yatra\Services\SettingsService::getCurrency(),
406 'currencyPosition' => \Yatra\Services\SettingsService::getString('currency_position', 'before'),
407 'decimalPlaces' => (int) \Yatra\Services\SettingsService::getString('currency_decimals', '2'),
408 'thousandSeparator' => \Yatra\Services\SettingsService::getString('thousand_separator', ','),
409 'decimalSeparator' => \Yatra\Services\SettingsService::getString('decimal_separator', '.'),
410 // Payment gateways data
411 'paymentGateways' => apply_filters('yatra_payment_gateways', \Yatra\Services\SettingsService::get('payment_gateways', [])),
412 'paymentMethods' => \Yatra\Services\SettingsService::get('payment_methods', []),
413 'paymentTestMode' => \Yatra\Services\SettingsService::get('payment_test_mode', false),
414 'partialPayment' => \Yatra\Services\SettingsService::get('partial_payment', false),
415 'partialPaymentPercentage' => \Yatra\Services\SettingsService::get('partial_payment_percentage', 0),
416 // Flexible payments (Pro) — keep these keys stable for frontend booking.js.
417 // Values are resolved via generic filters so Pro can override without hard-coding premium logic here.
418 'depositRequired' => (bool) \Yatra\Services\SettingsService::get('deposit_required', false),
419 'depositPercentage' => $deposit_pct_resolved,
420 'partialPercentage' => $partial_pct_resolved,
421 'gatewayOrder' => \Yatra\Services\SettingsService::get('gateway_order', []),
422 'autoConfirmPayLater' => \Yatra\Services\SettingsService::get('auto_confirm_pay_later', true),
423 'allowWaitlist' => \Yatra\Services\SettingsService::isEnabled('allow_waitlist'),
424 'waitlistAutoConfirm' => \Yatra\Services\SettingsService::isEnabled('waitlist_auto_confirm'),
425 'gateways' => apply_filters('yatra_payment_gateways', \Yatra\Services\SettingsService::get('payment_gateways', [])),
426 'enabledGateways' => \Yatra\Services\SettingsService::get('payment_gateways', []),
427 ];
428
429 $bookingData = array_merge($bookingData, $this->getStripeFrontendBookingPayload());
430
431 wp_localize_script('yatra-booking', 'yatraBookingData', $bookingData);
432 }
433
434 /**
435 * Enqueue account page specific assets
436 *
437 * @return void
438 */
439 private function enqueueAccountAssets(): void
440 {
441 // Account bundle shares admin Vite chunks; CSS is extracted to admin/dist/css (ES modules do not auto-load it).
442 $reactVendorCss = YATRA_PLUGIN_PATH . 'assets/admin/dist/css/react-vendor.css';
443 if (file_exists($reactVendorCss)) {
444 wp_enqueue_style(
445 'yatra-account-react-vendor',
446 YATRA_PLUGIN_URL . 'assets/admin/dist/css/react-vendor.css',
447 [],
448 YATRA_VERSION . '.' . filemtime($reactVendorCss)
449 );
450 }
451
452 $accountUiCss = YATRA_PLUGIN_PATH . 'assets/admin/dist/css/index.css';
453 $accountUiDeps = file_exists($reactVendorCss) ? ['yatra-account-react-vendor'] : [];
454 if (file_exists($accountUiCss)) {
455 wp_enqueue_style(
456 'yatra-account-ui',
457 YATRA_PLUGIN_URL . 'assets/admin/dist/css/index.css',
458 $accountUiDeps,
459 YATRA_VERSION . '.' . filemtime($accountUiCss)
460 );
461 }
462
463 // Vite build outputs to assets/dist/js/account-page.js (ES module + shared chunks).
464 $accountJs = YATRA_PLUGIN_PATH . 'assets/dist/js/account-page.js';
465 if (!file_exists($accountJs)) {
466 return;
467 }
468
469 wp_enqueue_script(
470 'yatra-account-page',
471 YATRA_PLUGIN_URL . 'assets/dist/js/account-page.js',
472 [],
473 YATRA_VERSION . '.' . filemtime($accountJs),
474 true
475 );
476
477 wp_script_add_data('yatra-account-page', 'type', 'module');
478
479 wp_localize_script('yatra-account-page', 'yatraAccountPage', [
480 'apiUrl' => rest_url('yatra/v1'),
481 'nonce' => wp_create_nonce('wp_rest'),
482 'userId' => get_current_user_id(),
483 'siteUrl' => site_url(),
484 'logoutUrl' => wp_logout_url(home_url('/')),
485 'companyPhone' => \Yatra\Services\SettingsService::getString('company_phone', ''),
486 'companyName' => \Yatra\Services\SettingsService::getString('company_name', ''),
487 'companyEmail' => \Yatra\Services\SettingsService::getString('company_email', ''),
488 'currency' => \Yatra\Services\SettingsService::getCurrency(),
489 'currencyPosition' => \Yatra\Services\SettingsService::getString('currency_position', 'before'),
490 'decimalPlaces' => (int) \Yatra\Services\SettingsService::getString('currency_decimals', '2'),
491 'thousandSeparator' => \Yatra\Services\SettingsService::getString('thousand_separator', ','),
492 'decimalSeparator' => \Yatra\Services\SettingsService::getString('decimal_separator', '.'),
493 'locale' => get_locale(),
494 'translations' => $this->getFrontendTranslations(),
495 'wishlistEnabled' => \Yatra\Services\SettingsService::wishlistEnabled(),
496 ]);
497 }
498
499 /**
500 * Enqueue listing filters JavaScript
501 *
502 * @return void
503 */
504 private function enqueueListingFiltersJs(): void
505 {
506 $filtersJs = YATRA_PLUGIN_PATH . 'assets/js/listing-filters.js';
507 if (file_exists($filtersJs)) {
508 wp_enqueue_script(
509 'yatra-listing-filters',
510 YATRA_PLUGIN_URL . 'assets/js/listing-filters.js',
511 ['jquery'],
512 YATRA_VERSION . '.' . filemtime($filtersJs),
513 true
514 );
515
516 // Add currency formatting function
517 wp_add_inline_script('yatra-listing-filters', "
518 window.yatra_format_price = function(amount) {
519 if (!amount || amount == 0) return '" . esc_js(__('Contact for pricing', 'yatra')) . "';
520 const currency = window.yatraSettings?.currency || 'USD';
521 const symbol = window.yatraSettings?.currencySymbol || '$';
522 return symbol + amount.toLocaleString();
523 };
524 ");
525 }
526 }
527
528 /**
529 * Get frontend translations
530 *
531 * @return array
532 */
533 private function getFrontendTranslations(): array
534 {
535 return [
536 // Account page
537 'My Account' => __('My Account', 'yatra'),
538 'My Bookings' => __('My Bookings', 'yatra'),
539 'Account Settings' => __('Account Settings', 'yatra'),
540 'Logout' => __('Logout', 'yatra'),
541 'Login' => __('Login', 'yatra'),
542 'Register' => __('Register', 'yatra'),
543
544 // Booking related
545 'Booking Details' => __('Booking Details', 'yatra'),
546 'Booking Status' => __('Booking Status', 'yatra'),
547 'Total Amount' => __('Total Amount', 'yatra'),
548 'Payment Status' => __('Payment Status', 'yatra'),
549 'View Details' => __('View Details', 'yatra'),
550
551 // Common
552 'Loading...' => __('Loading...', 'yatra'),
553 'No data available' => __('No data available', 'yatra'),
554 'Error loading data' => __('Error loading data', 'yatra'),
555 'Please try again' => __('Please try again', 'yatra'),
556
557 // Currency and pricing
558 'Contact for pricing' => __('Contact for pricing', 'yatra'),
559 'Free' => __('Free', 'yatra'),
560 'Price' => __('Price', 'yatra'),
561
562 // Trip related
563 'Trip Details' => __('Trip Details', 'yatra'),
564 'Duration' => __('Duration', 'yatra'),
565 'Difficulty' => __('Difficulty', 'yatra'),
566 'Group Size' => __('Group Size', 'yatra'),
567
568 // Navigation
569 'Home' => __('Home', 'yatra'),
570 'Trips' => __('Trips', 'yatra'),
571 'Destinations' => __('Destinations', 'yatra'),
572 'Activities' => __('Activities', 'yatra'),
573 'About Us' => __('About Us', 'yatra'),
574 'Contact' => __('Contact', 'yatra'),
575 ];
576 }
577
578 /**
579 * Enqueue assets for specific shortcodes
580 *
581 * @param array $shortcodes Array of shortcodes that need assets
582 * @return void
583 */
584 public function enqueueShortcodeAssets(array $shortcodes): void
585 {
586 global $post;
587
588 if (!$post || !has_shortcode($post->post_content, $shortcodes)) {
589 return;
590 }
591
592 // Enqueue common frontend assets for shortcodes
593 $this->enqueueCommonAssets();
594
595 // Shortcode-specific assets can be added here based on $shortcodes array
596 foreach ($shortcodes as $shortcode) {
597 switch ($shortcode) {
598 case 'yatra_trip_listing':
599 $this->enqueueTripListingAssets();
600 break;
601 case 'yatra_cart':
602 case 'yatra_checkout':
603 $this->enqueueBookingAssets();
604 break;
605 case 'yatra_my_account':
606 $this->enqueueAccountAssets();
607 break;
608 }
609 }
610 }
611
612 /**
613 * Enqueue assets conditionally based on custom conditions
614 *
615 * @param callable $condition Function that returns true if assets should be enqueued
616 * @return void
617 */
618 public function enqueueConditionalAssets(callable $condition): void
619 {
620 if ($condition()) {
621 $this->enqueueAssets();
622 }
623 }
624
625 /**
626 * Get asset URL with versioning
627 *
628 * @param string $path Relative path to asset
629 * @param string $type 'css' or 'js'
630 * @return string Asset URL or empty string if file doesn't exist
631 */
632 public function getAssetUrl(string $path, string $type = 'css'): string
633 {
634 $basePath = $type === 'css' ? 'assets/css/' : 'assets/js/';
635 $fullPath = YATRA_PLUGIN_PATH . $basePath . $path;
636
637 if (!file_exists($fullPath)) {
638 return '';
639 }
640
641 $version = YATRA_VERSION . '.' . filemtime($fullPath);
642 return YATRA_PLUGIN_URL . $basePath . $path . '?ver=' . $version;
643 }
644
645 /**
646 * Check if asset file exists
647 *
648 * @param string $path Relative path to asset
649 * @param string $type 'css' or 'js'
650 * @return bool
651 */
652 public function assetExists(string $path, string $type = 'css'): bool
653 {
654 $basePath = $type === 'css' ? 'assets/css/' : 'assets/js/';
655 $fullPath = YATRA_PLUGIN_PATH . $basePath . $path;
656 return file_exists($fullPath);
657 }
658
659 /**
660 * Stripe Elements (assets/js/stripe.js) expects publishableKey under yatraBookingData.stripe.
661 * Mirror YatraPro StripeGateway::loadConfig() live/test selection; never expose secret keys.
662 *
663 * @return array<string, mixed>
664 */
665 private function getStripeFrontendBookingPayload(): array
666 {
667 $allConfigs = get_option('yatra_gateway_configs', []);
668 if (is_string($allConfigs)) {
669 $maybe = maybe_unserialize($allConfigs);
670 $allConfigs = is_array($maybe) ? $maybe : [];
671 }
672 if (!is_array($allConfigs)) {
673 $allConfigs = [];
674 }
675
676 $stripe = isset($allConfigs['stripe']) && is_array($allConfigs['stripe'])
677 ? $allConfigs['stripe']
678 : [];
679
680 $test = filter_var(\Yatra\Services\SettingsService::get('payment_test_mode', true), FILTER_VALIDATE_BOOLEAN);
681
682 $livePub = trim((string) ($stripe['live_publishable_key'] ?? ''));
683 $testPub = trim((string) ($stripe['test_publishable_key'] ?? ''));
684
685 $publishableKey = trim((string) ($stripe['api_key'] ?? ''));
686 if ($test) {
687 if ($testPub !== '') {
688 $publishableKey = $testPub;
689 }
690 } elseif ($livePub !== '') {
691 $publishableKey = $livePub;
692 }
693
694 // Match StripeGateway default + admin multi-select when unset (was dropped by old sanitizer).
695 $defaultMethods = 'card,google_pay,apple_pay';
696 $enabledMethods = $stripe['enabled_methods'] ?? $defaultMethods;
697 if (is_array($enabledMethods)) {
698 // stripe.js accepts an array of method ids
699 } elseif (!is_string($enabledMethods) || trim($enabledMethods) === '') {
700 $enabledMethods = $defaultMethods;
701 }
702
703 $companyCountry = trim((string) \Yatra\Services\SettingsService::get('company_country', ''));
704 if ($companyCountry === '') {
705 $companyCountry = 'US';
706 }
707
708 $payload = [
709 'stripe' => [
710 'publishableKey' => $publishableKey,
711 'enabledMethods' => $enabledMethods,
712 ],
713 'companyCountry' => $companyCountry,
714 ];
715
716 return apply_filters('yatra_booking_stripe_frontend_data', $payload, $stripe, $test);
717 }
718 }
719