PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.10
Yatra – Travel Booking & Tour Operator Software v3.0.10
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 2.0.10 All 83 releases
yatra / app / Shortcodes / SearchShortcode.php

SearchShortcode.php in Yatra – Travel Booking & Tour Operator Software 3.0.10, at app/Shortcodes/SearchShortcode.php

165 lines 6.5 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\Shortcodes;
6
7 /**
8 * Search Shortcode
9 *
10 * Displays advanced tour search functionality
11 */
12 class SearchShortcode extends BaseShortcode
13 {
14 private static bool $tripSearchAssetsQueued = false;
15
16 public function __construct()
17 {
18 parent::__construct('yatra_search', [
19 'show_filters' => 'yes',
20 'show_categories' => 'yes',
21 'show_destinations' => 'yes',
22 'show_activities' => 'yes',
23 'show_price_range' => 'yes',
24 'show_duration' => 'yes',
25 'show_difficulty' => 'yes',
26 'placeholder' => 'Search for tours...',
27 'button_text' => 'Search Tours',
28 // Per-field visibility overrides. Empty string = inherit the global
29 // Settings → Search & Listing toggle (so [yatra_search] is unchanged).
30 // Pass yes/no (or true/false, on/off, 1/0) to force a field on/off for
31 // this one placement, e.g. [yatra_search budget="no" keyword="yes"].
32 'keyword' => '',
33 'destination' => '',
34 'activities' => '',
35 'duration' => '',
36 'budget' => '',
37 ]);
38
39 // [yatra_search] may appear in posts, widgets, builders, FSE templates, or do_shortcode()
40 // with no reliable way to detect that before output. Enqueue on every public frontend
41 // request so styles always print in wp_head (avoids FOUC). Rules are scoped to
42 // .yatra-trip-search-shortcode in trip-search-shortcode.css.
43 add_action('wp_enqueue_scripts', [self::class, 'enqueueTripSearchAssets'], 10);
44 }
45
46 /**
47 * Enqueue trip search bar CSS/JS for head output. Idempotent per request.
48 */
49 public static function enqueueTripSearchAssets(): void
50 {
51 if (is_admin() || is_feed()) {
52 return;
53 }
54 if (self::$tripSearchAssetsQueued) {
55 return;
56 }
57 self::$tripSearchAssetsQueued = true;
58
59 $tripSearchCssPath = YATRA_PLUGIN_PATH . 'assets/css/shortcodes/trip-search-shortcode.css';
60 $tripSearchCssVer = is_readable($tripSearchCssPath)
61 ? (string) filemtime($tripSearchCssPath)
62 : YATRA_VERSION;
63 wp_enqueue_style(
64 'yatra-trip-search-shortcode',
65 YATRA_PLUGIN_URL . 'assets/css/shortcodes/trip-search-shortcode.css',
66 [],
67 $tripSearchCssVer
68 );
69
70 $tripSearchJsPath = YATRA_PLUGIN_PATH . 'assets/js/trip-search-shortcode.js';
71 $tripSearchJsVer = is_readable($tripSearchJsPath)
72 ? (string) filemtime($tripSearchJsPath)
73 : YATRA_VERSION;
74 wp_enqueue_script(
75 'yatra-trip-search-shortcode',
76 YATRA_PLUGIN_URL . 'assets/js/trip-search-shortcode.js',
77 ['jquery'],
78 $tripSearchJsVer,
79 true
80 );
81
82 $listing_url = \function_exists('yatra_get_trip_listing_url')
83 ? \yatra_get_trip_listing_url()
84 : \trailingslashit(\home_url('/trip/'));
85
86 wp_localize_script(
87 'yatra-trip-search-shortcode',
88 'yatraTripSearchConfig',
89 [
90 'listingUrl' => $listing_url,
91 ]
92 );
93 }
94
95 /**
96 * Render the search shortcode content
97 */
98 protected function renderContent(array $atts): string
99 {
100 $atts = shortcode_atts($this->default_attributes, $atts, $this->tag);
101
102 // Same source as trip listing sidebar filters: published classifications.
103 // TripRepository::*ForSearch() only returned rows linked via trip_classifications,
104 // so empty relations hid all dropdown options.
105 $destinationRepository = new \Yatra\Repositories\DestinationRepository();
106 $activityRepository = new \Yatra\Repositories\ActivityRepository();
107 $destinations = $destinationRepository->getPublished();
108 $activities = $activityRepository->getPublished();
109 $tripListingService = new \Yatra\Services\TripListingService();
110 $tripRepository = new \Yatra\Repositories\TripRepository();
111
112 $listing_url = \function_exists('yatra_get_trip_listing_url')
113 ? \yatra_get_trip_listing_url()
114 : \trailingslashit(\home_url('/trip/'));
115
116 return $this->loadTemplate('shortcodes/trip-search.php', [
117 'atts' => $atts,
118 'destinations' => $destinations,
119 'activities' => $activities,
120 'listing_url' => $listing_url,
121 'duration_bounds' => $tripRepository->getDurationDaysBounds(),
122 'budget_presets' => $tripListingService->getSearchBudgetPresets(),
123 'field_visibility' => $this->resolveFieldVisibility($atts),
124 ]);
125 }
126
127 /**
128 * Resolve which search fields are visible for THIS shortcode instance.
129 *
130 * Each field follows the rule: an explicit shortcode attribute wins; when the
131 * attribute is omitted (empty), inherit the global Settings → Search & Listing
132 * toggle. This keeps a bare [yatra_search] identical to before while allowing
133 * per-placement overrides like [yatra_search budget="no"].
134 *
135 * @param array<string,mixed> $atts Resolved shortcode attributes.
136 * @return array<string,bool> Keyed by field: keyword/destination/activities/duration/budget.
137 */
138 private function resolveFieldVisibility(array $atts): array
139 {
140 $resolve = static function ($attr_value, string $setting_key): bool {
141 $value = strtolower(trim((string) $attr_value));
142 if ($value === '') {
143 // No override → inherit the global toggle (defaults to true).
144 return \Yatra\Services\SettingsService::isEnabled($setting_key);
145 }
146 if (\in_array($value, ['1', 'yes', 'true', 'on', 'show'], true)) {
147 return true;
148 }
149 if (\in_array($value, ['0', 'no', 'false', 'off', 'hide'], true)) {
150 return false;
151 }
152 // Unrecognised value → fall back to the global toggle, never guess.
153 return \Yatra\Services\SettingsService::isEnabled($setting_key);
154 };
155
156 return [
157 'keyword' => $resolve($atts['keyword'] ?? '', 'search_show_keyword'),
158 'destination' => $resolve($atts['destination'] ?? '', 'search_show_destination'),
159 'activities' => $resolve($atts['activities'] ?? '', 'search_show_activities'),
160 'duration' => $resolve($atts['duration'] ?? '', 'search_show_duration'),
161 'budget' => $resolve($atts['budget'] ?? '', 'search_show_budget'),
162 ];
163 }
164 }
165