PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.16
Yatra – Travel Booking & Tour Operator Software v3.0.16
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
← All changes | app/Providers/FrontendAssetsProvider.php +239 -2 3.0.7 → 3.0.16 View file →
@@ -30,8 +30,50 @@
30 30 add_action('wp_enqueue_scripts', [$this, 'enqueueAssets']);
31 31 }
32 32
33 33 /**
34 + * Resolve the effective trip-listing card layout for one listing.
35 + *
36 + * The site-wide Design setting (`frontend_listing_card_layout`) is the
37 + * default; a shortcode/block may pass a per-instance override. Anything that
38 + * is not a concrete layout (empty, "inherit", or an unknown value) falls
39 + * back to the global setting, so existing shortcodes/blocks are unchanged.
40 + *
41 + * @param string $override Per-instance override (card_layout / cardLayout).
42 + * @return string One of: standard | compact_mobile | compact_all.
43 + */
44 + public static function resolveListingLayout(string $override = ''): string
45 + {
46 + $override = strtolower(trim($override));
47 + if (in_array($override, ['standard', 'compact_mobile', 'compact_all'], true)) {
48 + return $override;
49 + }
50 +
51 + $global = \Yatra\Services\SettingsService::getString('frontend_listing_card_layout', 'standard');
52 + return in_array($global, ['standard', 'compact_mobile', 'compact_all'], true) ? $global : 'standard';
53 + }
54 +
55 + /**
56 + * Map a resolved layout to the container CSS class(es) the listing CSS keys
57 + * off. Placed on the listing container (archive .yatra-listing-page, or the
58 + * shortcode/block wrapper) so each listing can carry its own layout and an
59 + * override never leaks into other listings on the same page.
60 + *
61 + * @param string $layout standard | compact_mobile | compact_all
62 + * @return string Space-separated class list ('' for standard).
63 + */
64 + public static function listingLayoutClasses(string $layout): string
65 + {
66 + if ($layout === 'compact_mobile') {
67 + return 'yatra-listing-compact';
68 + }
69 + if ($layout === 'compact_all') {
70 + return 'yatra-listing-compact yatra-listing-compact--all';
71 + }
72 + return '';
73 + }
74 +
75 + /**
34 76 * Register Font Awesome (optional) and common.css so block editor + shortcode styles can
35 77 * depend on `yatra-common` (shared @keyframes: yatra-spin, yatra-shimmer, etc.).
36 78 */
37 79 /**
@@ -286,14 +328,22 @@
286 328 'yatra',
287 329 YATRA_PLUGIN_PATH . 'i18n/languages'
288 330 );
289 331 }
332 + // Wishlist "Login" should send guests to the configured
333 + // My Account page (Settings → Permalink slug), not the raw
334 + // wp-login.php screen. Fall back to wp_login_url() only when
335 + // no account base is configured so the button never dead-ends.
336 + $yatraAccountBase = \Yatra\Services\SettingsService::getAccountBase();
337 + $yatraAccountLoginUrl = $yatraAccountBase !== ''
338 + ? home_url('/' . trim($yatraAccountBase, '/') . '/')
339 + : wp_login_url();
290 340 wp_localize_script('yatra-listing-wishlist', 'yatraWishlistConfig', [
291 341 'enabled' => true,
292 342 'restUrl' => rest_url('yatra/v1'),
293 343 'nonce' => wp_create_nonce('wp_rest'),
294 344 'isLoggedIn' => is_user_logged_in(),
295 - 'loginUrl' => wp_login_url(),
345 + 'loginUrl' => $yatraAccountLoginUrl,
296 346 'i18n' => [
297 347 'loginRequired' => __('Login Required', 'yatra'),
298 348 'loginPrompt' => __('Please login to save trips to your wishlist.', 'yatra'),
299 349 'login' => __('Login', 'yatra'),
@@ -386,8 +436,13 @@
386 436 );
387 437 }
388 438 }
389 439
440 + // International phone-number widget (country flag + dial code) used by
441 + // the booking form's tel fields.
442 + $this->enqueuePhoneInputAssets();
443 + $this->enqueueCountrySelectAssets();
444 +
390 445 // Mobile sticky-sidebar + flatpickr init for the single-trip page. Lives in a
391 446 // dedicated file rather than as inline <script> in the partial because
392 447 // WordPress core's `convert_chars` filter (hooked to the_content) rewrites the
393 448 // `&&` operators inside inline scripts as `&#038;&#038;` — JS parsers don't
@@ -437,8 +492,16 @@
437 492 'tripId' => $trip_id,
438 493 'tripSlug' => $trip_slug,
439 494 'wishlistEnabled' => \Yatra\Services\SettingsService::wishlistEnabled(),
440 495 'isLoggedIn' => is_user_logged_in(),
496 + // Wishlist "Login" (guest) → the configured My Account page
497 + // (Settings → Permalink slug), NOT wp-login.php. Without this key
498 + // trip.js falls back to a hardcoded '/wp-login.php'. Falls back to
499 + // wp_login_url() only when no account base slug is configured.
500 + 'loginUrl' => (function () {
501 + $base = \Yatra\Services\SettingsService::getAccountBase();
502 + return $base !== '' ? home_url('/' . trim($base, '/') . '/') : wp_login_url();
503 + })(),
441 504 // Regional settings
442 505 'timezone' => \Yatra\Services\SettingsService::getString('timezone', 'UTC'),
443 506 'dateFormat' => \Yatra\Services\SettingsService::getString('date_format', 'Y-m-d'),
444 507 'timeFormat' => \Yatra\Services\SettingsService::getString('time_format', 'H:i'),
@@ -518,8 +581,106 @@
518 581 ));
519 582 }
520 583
521 584 /**
585 + * Enqueue the country selector widget (assets/js/country-select.js +
586 + * assets/css/country-select.css).
587 + *
588 + * Upgrades every `type => country` field (Country, Nationality, on both the
589 + * contact and traveler sections) into a searchable dropdown showing the
590 + * national flag, matching the phone country-code control. Purely additive:
591 + * the underlying <select> still renders and submits, so a site that never
592 + * loads this script behaves exactly as before.
593 + *
594 + * Idempotent, so it is safe to call from every path that renders the form.
595 + *
596 + * @return void
597 + */
598 + private function enqueueCountrySelectAssets(): void
599 + {
600 + if (wp_script_is('yatra-country-select', 'enqueued')) {
601 + return;
602 + }
603 +
604 + $css = YATRA_PLUGIN_PATH . 'assets/css/country-select.css';
605 + if (file_exists($css)) {
606 + wp_enqueue_style(
607 + 'yatra-country-select',
608 + YATRA_PLUGIN_URL . 'assets/css/country-select.css',
609 + [],
610 + YATRA_VERSION . '.' . filemtime($css)
611 + );
612 + }
613 +
614 + $js = YATRA_PLUGIN_PATH . 'assets/js/country-select.js';
615 + if (!file_exists($js)) {
616 + return;
617 + }
618 +
619 + wp_enqueue_script(
620 + 'yatra-country-select',
621 + YATRA_PLUGIN_URL . 'assets/js/country-select.js',
622 + [],
623 + YATRA_VERSION . '.' . filemtime($js),
624 + true
625 + );
626 +
627 + wp_localize_script('yatra-country-select', 'yatraCountrySelectData', [
628 + 'i18n' => [
629 + 'search' => __('Search country', 'yatra'),
630 + 'noResults' => __('No matches', 'yatra'),
631 + ],
632 + ]);
633 + }
634 +
635 + /**
636 + * Enqueue the international phone-number widget (assets/js/phone-input.js +
637 + * assets/css/phone-input.css) and localize its country + dial-code dataset.
638 + *
639 + * Self-contained (reads its own `yatraPhoneData` global) and idempotent, so
640 + * it can be called from every path that renders the booking form. Country
641 + * data is the single source of truth in {@see FormatHelper}.
642 + *
643 + * @return void
644 + */
645 + private function enqueuePhoneInputAssets(): void
646 + {
647 + if (wp_script_is('yatra-phone-input', 'enqueued')) {
648 + return;
649 + }
650 +
651 + $css = YATRA_PLUGIN_PATH . 'assets/css/phone-input.css';
652 + if (file_exists($css)) {
653 + wp_enqueue_style(
654 + 'yatra-phone-input',
655 + YATRA_PLUGIN_URL . 'assets/css/phone-input.css',
656 + [],
657 + YATRA_VERSION . '.' . filemtime($css)
658 + );
659 + }
660 +
661 + $js = YATRA_PLUGIN_PATH . 'assets/js/phone-input.js';
662 + if (!file_exists($js)) {
663 + return;
664 + }
665 + wp_enqueue_script(
666 + 'yatra-phone-input',
667 + YATRA_PLUGIN_URL . 'assets/js/phone-input.js',
668 + [],
669 + YATRA_VERSION . '.' . filemtime($js),
670 + true
671 + );
672 + wp_localize_script('yatra-phone-input', 'yatraPhoneData', [
673 + 'countries' => \Yatra\Helpers\FormatHelper::getPhoneCountries(),
674 + 'priority' => \Yatra\Helpers\FormatHelper::getPhonePriority(),
675 + 'i18n' => [
676 + 'search' => __('Search country', 'yatra'),
677 + 'noResults' => __('No matches', 'yatra'),
678 + ],
679 + ]);
680 + }
681 +
682 + /**
522 683 * Enqueue activity listing specific assets
523 684 *
524 685 * @return void
525 686 */
@@ -573,20 +734,57 @@
573 734 YATRA_VERSION . '.' . filemtime($bookingCss)
574 735 );
575 736 }
576 737
738 + // Flatpickr — used by booking.js to upgrade Date-of-Birth (and other
739 + // date) inputs to a picker with fast, typeable year navigation. The
740 + // single-trip page already ships flatpickr (see single-trip.php); the
741 + // dedicated booking page did not, so enqueue it here. booking.js
742 + // self-guards on `typeof flatpickr`, so this is safe either way.
743 + wp_enqueue_style(
744 + 'yatra-flatpickr',
745 + 'https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css',
746 + [],
747 + YATRA_VERSION
748 + );
749 + wp_enqueue_script(
750 + 'yatra-flatpickr',
751 + 'https://cdn.jsdelivr.net/npm/flatpickr',
752 + [],
753 + YATRA_VERSION,
754 + true
755 + );
756 +
577 757 // Enqueue booking-specific JavaScript
578 758 $bookingJs = YATRA_PLUGIN_PATH . 'assets/js/booking.js';
579 759 if (file_exists($bookingJs)) {
760 + // booking.js renders user-facing strings via wp.i18n.__() (the
761 + // "Processing..." button label and the per-gateway info messages
762 + // shown when a payment method is selected). It therefore needs
763 + // wp-i18n as a dependency AND wp_set_script_translations so its
764 + // Jed catalog loads — mirroring the trip-detail enqueue above.
765 + // Without these, those strings stay English on the standalone
766 + // booking page regardless of site locale.
580 767 wp_enqueue_script(
581 768 'yatra-booking',
582 769 YATRA_PLUGIN_URL . 'assets/js/booking.js',
583 - ['jquery'],
770 + ['jquery', 'yatra-flatpickr', 'wp-i18n'],
584 771 YATRA_VERSION . '.' . filemtime($bookingJs),
585 772 true
586 773 );
774 + if (function_exists('wp_set_script_translations')) {
775 + wp_set_script_translations(
776 + 'yatra-booking',
777 + 'yatra',
778 + YATRA_PLUGIN_PATH . 'i18n/languages'
779 + );
780 + }
587 781 }
588 782
783 + // International phone-number widget (country flag + dial code).
784 + $this->enqueuePhoneInputAssets();
785 + $this->enqueueCountrySelectAssets();
786 +
589 787 // Load each available gateway's own client scripts on the checkout page
590 788 // (e.g. Square Web Payments SDK + square.js, Authorize.Net Accept.js +
591 789 // its handler, Razorpay SDK + its handler). Every gateway's
592 790 // enqueueScripts() self-guards on isAvailable(), so only enabled +
@@ -659,8 +857,15 @@
659 857 'allowWaitlist' => \Yatra\Services\SettingsService::isEnabled('allow_waitlist'),
660 858 'waitlistAutoConfirm' => \Yatra\Services\SettingsService::isEnabled('waitlist_auto_confirm'),
661 859 'gateways' => $this->getGatewayFrontendConfigs(),
662 860 'enabledGateways' => $this->sanitizeGatewayConfigsForFrontend(\Yatra\Services\SettingsService::get('payment_gateways', [])),
861 + // Server-side translated UI strings for booking.js. PHP __() resolves via .mo
862 + // (reliable), so these stay translatable even when the JS-translation JSON
863 + // chain (wp_set_script_translations) doesn't load on a given setup.
864 + 'i18n' => [
865 + 'complete_booking' => __('Complete Booking', 'yatra'),
866 + 'pay_now' => __('Pay Now', 'yatra'),
867 + ],
663 868 ];
664 869
665 870 $bookingData = array_merge($bookingData, $this->getStripeFrontendBookingPayload());
666 871
@@ -727,8 +932,14 @@
727 932 'decimalPlaces' => \Yatra\Services\SettingsService::getPriceDecimals(),
728 933 'thousandSeparator' => \Yatra\Services\SettingsService::getString('thousand_separator', ','),
729 934 'decimalSeparator' => \Yatra\Services\SettingsService::getString('decimal_separator', '.'),
730 935 'locale' => get_locale(),
936 + // Global date/time format so the customer account pages render dates
937 + // in the operator's configured format (Settings → General), not a
938 + // hardcoded browser style. Keys mirror what the admin app receives.
939 + 'date_format' => \Yatra\Services\SettingsService::getString('date_format', 'Y-m-d'),
940 + 'time_format' => \Yatra\Services\SettingsService::getString('time_format', 'H:i'),
941 + 'timezone' => \Yatra\Services\SettingsService::getString('timezone', 'UTC'),
731 942 // Full ISO country map (code => name) so the account profile can show
732 943 // full country names and render the country dropdown. Mirrors the
733 944 // admin (`yatraAdmin.countries`); honours the `yatra_countries_list` filter.
734 945 'countries' => class_exists('\\Yatra\\Helpers\\FormatHelper')
@@ -868,8 +1079,34 @@
868 1079 'Booking Status' => __('Booking Status', 'yatra'),
869 1080 'Total Amount' => __('Total Amount', 'yatra'),
870 1081 'Payment Status' => __('Payment Status', 'yatra'),
871 1082 'View Details' => __('View Details', 'yatra'),
1083 +
1084 + // Traveler / contact / emergency field labels on the account page.
1085 + // Keep in sync with the `fieldLabel()` map in account/BookingDetails.tsx.
1086 + 'First Name' => __('First Name', 'yatra'),
1087 + 'Last Name' => __('Last Name', 'yatra'),
1088 + 'Full Name' => __('Full Name', 'yatra'),
1089 + 'Name' => __('Name', 'yatra'),
1090 + 'Email' => __('Email', 'yatra'),
1091 + 'Phone' => __('Phone', 'yatra'),
1092 + 'Mobile' => __('Mobile', 'yatra'),
1093 + 'Date of Birth' => __('Date of Birth', 'yatra'),
1094 + 'Gender' => __('Gender', 'yatra'),
1095 + 'Nationality' => __('Nationality', 'yatra'),
1096 + 'Country' => __('Country', 'yatra'),
1097 + 'Address' => __('Address', 'yatra'),
1098 + 'City' => __('City', 'yatra'),
1099 + 'State' => __('State', 'yatra'),
1100 + 'Postal Code' => __('Postal Code', 'yatra'),
1101 + 'Zip Code' => __('Zip Code', 'yatra'),
1102 + 'Passport' => __('Passport', 'yatra'),
1103 + 'Passport Number' => __('Passport Number', 'yatra'),
1104 + 'Passport Expiry' => __('Passport Expiry', 'yatra'),
1105 + 'Dietary Requirements' => __('Dietary Requirements', 'yatra'),
1106 + 'Special Requirements' => __('Special Requirements', 'yatra'),
1107 + 'Relationship' => __('Relationship', 'yatra'),
1108 + 'Company' => __('Company', 'yatra'),
872 1109
873 1110 // Common
874 1111 'Loading...' => __('Loading...', 'yatra'),
875 1112 'No data available' => __('No data available', 'yatra'),