PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.4
Yatra – Travel Booking & Tour Operator Software v3.0.4
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 / templates / partials / single-trip / content-sidebar.php

content-sidebar.php in Yatra – Travel Booking & Tour Operator Software 3.0.4, at templates/partials/single-trip/content-sidebar.php

506 lines 28.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) {
3 exit;
4 }
5 ?>
6 <aside class="yatra-trip-sidebar" id="booking">
7 <?php
8 // Group discounts (Advanced Discount / Pro): same payload as the public REST discoverability endpoint
9 $sidebar_has_group_discounts = false;
10 $sidebar_group_discount_cards = [];
11 if (function_exists('yatra_single_trip_get_group_discounts')) {
12 $gd = yatra_single_trip_get_group_discounts((int) $trip->getId());
13 $sidebar_has_group_discounts = !empty($gd['has_group_discounts']);
14 $sidebar_group_discount_cards = isset($gd['group_discounts_data']) && is_array($gd['group_discounts_data'])
15 ? $gd['group_discounts_data']
16 : [];
17 }
18
19 // Pro: check whether this trip has booking disabled (enquiry-only mode)
20 $booking_disabled = method_exists($trip, 'isBookingDisabled') && $trip->isBookingDisabled();
21
22 // Pricing — resolved via centralized TripPricingService (single source of truth)
23 // SingleTripController pre-computes effective_price_min, min_category_original_price, max_discount_percentage
24 $displayPricing = \Yatra\Services\TripPricingService::resolveDisplayPricing($trip);
25
26 $pricing = [
27 'has_price' => $displayPricing['effective_price_min'] > 0,
28 'current_price' => $displayPricing['effective_price_min'] > 0 ? yatra_format_price($displayPricing['effective_price_min']) : '',
29 'original_price' => $displayPricing['has_discount'] ? yatra_format_price($displayPricing['min_category_original_price']) : '',
30 'price_prefix' => $displayPricing['price_prefix'],
31 'has_discount' => $displayPricing['has_discount'],
32 'raw_current_price' => $displayPricing['effective_price_min'],
33 'raw_original_price' => $displayPricing['min_category_original_price'],
34 'is_traveler_based' => $displayPricing['has_traveler_pricing'],
35 ];
36
37 $discount = [
38 'has_discount' => $displayPricing['has_discount'] && $displayPricing['max_discount_percentage'] > 0,
39 'discount_text' => $displayPricing['max_discount_percentage'] > 0
40 ? sprintf(__('Save up to %d%%', 'yatra'), $displayPricing['max_discount_percentage']) : '',
41 'discount_percentage' => $displayPricing['max_discount_percentage'],
42 ];
43
44 $dp_display_sidebar = apply_filters('yatra_get_dynamic_pricing_display_settings', [
45 'show_original_price' => true,
46 'show_savings_badge' => true,
47 'show_urgency_messages' => false,
48 ]);
49 $dp_show_savings_sidebar = filter_var($dp_display_sidebar['show_savings_badge'] ?? true, FILTER_VALIDATE_BOOLEAN);
50 $show_strike_original_sidebar = filter_var($dp_display_sidebar['show_original_price'] ?? true, FILTER_VALIDATE_BOOLEAN);
51 $yatra_sidebar_urgency = function_exists('yatra_trip_card_dynamic_pricing_urgency_lines')
52 ? yatra_trip_card_dynamic_pricing_urgency_lines((int) $trip->getId(), [
53 'base_sale_price' => (float) ($displayPricing['effective_price_min'] ?? 0),
54 'base_original_price' => (float) ($displayPricing['min_category_original_price'] ?? 0),
55 'sale_price' => (float) ($displayPricing['effective_price_min'] ?? 0),
56 'original_price' => (float) ($displayPricing['min_category_original_price'] ?? 0),
57 'departure_date' => null,
58 'spots_remaining' => null,
59 'availability_id' => null,
60 'surface' => 'single_sidebar',
61 ])
62 : [];
63 ?>
64 <?php if ($booking_disabled): ?>
65 <div class="yatra-booking-card yatra-enquiry-only-card">
66 <!-- Price Display -->
67 <div class="yatra-booking-price">
68 <?php if ($discount['has_discount'] && $dp_show_savings_sidebar): ?>
69 <div class="yatra-booking-discount-badge">
70 <?php echo esc_html($discount['discount_text']); ?>
71 </div>
72 <?php endif; ?>
73 <div class="yatra-booking-price-main">
74 <?php if ($pricing['has_price']): ?>
75 <span class="yatra-booking-price-label-top"><?php echo esc_html__('From', 'yatra'); ?></span>
76 <?php if ($pricing['has_discount'] && !empty($pricing['original_price']) && $show_strike_original_sidebar): ?>
77 <span class="yatra-booking-price-original"><?php echo esc_html($pricing['original_price']); ?></span>
78 <?php endif; ?>
79 <span class="yatra-booking-price-amount" id="display-price"><?php echo esc_html($pricing['current_price']); ?></span>
80 <span class="yatra-booking-price-label"><?php echo esc_html__('per person', 'yatra'); ?></span>
81 <?php if (!empty($yatra_sidebar_urgency)) : ?>
82 <?php foreach ($yatra_sidebar_urgency as $yatra_sb_urg) : ?>
83 <div class="yatra-booking-dp-urgency" style="background-color:#fef3c7;color:#92400e;padding:6px 8px;border-radius:6px;margin-top:8px;font-size:12px;line-height:1.35;">
84 <?php echo esc_html((string) $yatra_sb_urg); ?>
85 </div>
86 <?php endforeach; ?>
87 <?php endif; ?>
88 <?php else: ?>
89 <span class="yatra-booking-price-amount yatra-contact-pricing" id="display-price"><?php echo esc_html__('Contact for pricing', 'yatra'); ?></span>
90 <?php endif; ?>
91 </div>
92 </div>
93
94 <!-- Enquiry-only notice -->
95 <div class="yatra-enquiry-notice" style="margin:12px 0 4px;padding:10px 12px;background:#f0f7ff;border:1px solid #cce0ff;border-radius:6px;font-size:0.85rem;color:#1a5fa8;display:flex;align-items:flex-start;gap:8px;">
96 <svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24" style="flex-shrink:0;margin-top:1px">
97 <circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/>
98 </svg>
99 <span><?php esc_html_e('This trip is available for enquiry only. Please contact us to discuss dates and availability.', 'yatra'); ?></span>
100 </div>
101
102 <!-- Enquiry button -->
103 <button type="button" class="yatra-booking-button" style="margin-top:12px;" id="open-enquiry-modal" onclick="window.YatraEnquiry?.open?.(); return false;">
104 <svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
105 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"/>
106 </svg>
107 <?php echo esc_html__('Send Enquiry', 'yatra'); ?>
108 </button>
109 </div>
110 <?php else: ?>
111 <div class="yatra-booking-card">
112
113 <?php if ($sidebar_has_group_discounts && !empty($sidebar_group_discount_cards)): ?>
114 <?php
115 $group_discount_cards = $sidebar_group_discount_cards;
116 $popover_context = 'booking';
117 $popover_uid = 'sb-' . (int) $trip->getId();
118 yatra_get_template('partials/single-trip/group-discount-booking-popover', compact('group_discount_cards', 'popover_context', 'popover_uid'));
119 ?>
120 <?php endif; ?>
121
122 <!-- Price Display -->
123 <div class="yatra-booking-price">
124 <?php if ($discount['has_discount'] && $dp_show_savings_sidebar): ?>
125 <div class="yatra-booking-discount-badge">
126 <?php echo esc_html($discount['discount_text']); ?>
127 </div>
128 <?php endif; ?>
129 <div class="yatra-booking-price-main">
130 <?php if ($pricing['has_price']): ?>
131 <?php if ($has_availability || $has_traveler_pricing): ?>
132 <span class="yatra-booking-price-label-top"><?php echo esc_html__('From', 'yatra'); ?></span>
133 <?php endif; ?>
134 <?php if ($pricing['has_discount'] && !empty($pricing['original_price']) && $show_strike_original_sidebar): ?>
135 <span class="yatra-booking-price-original"><?php echo esc_html($pricing['original_price']); ?></span>
136 <?php endif; ?>
137 <span class="yatra-booking-price-amount" id="display-price"><?php echo esc_html($pricing['current_price']); ?></span>
138 <span class="yatra-booking-price-label"><?php echo esc_html__('per person', 'yatra'); ?></span>
139 <?php if (!empty($yatra_sidebar_urgency)) : ?>
140 <?php foreach ($yatra_sidebar_urgency as $yatra_sb_urg) : ?>
141 <div class="yatra-booking-dp-urgency" style="background-color:#fef3c7;color:#92400e;padding:6px 8px;border-radius:6px;margin-top:8px;font-size:12px;line-height:1.35;">
142 <?php echo esc_html((string) $yatra_sb_urg); ?>
143 </div>
144 <?php endforeach; ?>
145 <?php endif; ?>
146 <?php else: ?>
147 <span class="yatra-booking-price-amount yatra-contact-pricing" id="display-price"><?php echo esc_html__('Contact for pricing', 'yatra'); ?></span>
148 <?php endif; ?>
149 </div>
150 </div>
151
152 <?php if ($trip->getBookingMode() === 'date_specific' && $has_availability): ?>
153 <!-- ========================================== -->
154 <!-- DATE-SPECIFIC BOOKING (Has Availability Dates/Rules) -->
155 <!-- ========================================== -->
156 <div class="yatra-availability-info">
157 <span class="yatra-availability-count">
158 <?php
159 $allAvailability = $trip->getAvailabilityDates();
160 $today = date('Y-m-d');
161
162 // Sidebar count should reflect the same resolved availability set (priority:
163 // manual > recurring rule > trip default). We keep it lightweight here:
164 // count upcoming departures (date + optional time) from the resolved list.
165 $filtered = array_filter($allAvailability, static function ($a) use ($today) {
166 if (!is_object($a)) {
167 return false;
168 }
169 $date = (string) ($a->departure_date ?? '');
170 if ($date === '' || $date < $today) {
171 return false;
172 }
173 return true;
174 });
175
176 // Priority: manual availability dates > recurring rules > trip default.
177 $bySource = [
178 'availability_date' => [],
179 'recurring_rule' => [],
180 'trip_default' => [],
181 '' => [],
182 ];
183 foreach ($filtered as $a) {
184 $src = strtolower(trim((string) ($a->source ?? '')));
185 if (!isset($bySource[$src])) {
186 $src = '';
187 }
188 $bySource[$src][] = $a;
189 }
190
191 $pick = [];
192 if (!empty($bySource['availability_date'])) {
193 $pick = $bySource['availability_date'];
194 } elseif (!empty($bySource['recurring_rule'])) {
195 $pick = $bySource['recurring_rule'];
196 } elseif (!empty($bySource['trip_default'])) {
197 $pick = $bySource['trip_default'];
198 } else {
199 $pick = $filtered;
200 }
201
202 // Count departures:
203 // - if availability entries include departure_time, count unique (date + time) as departures
204 // - otherwise count unique dates.
205 $hasTimeSlots = false;
206 foreach ($pick as $a) {
207 $t = isset($a->departure_time) ? trim((string) $a->departure_time) : '';
208 if ($t !== '' && $t !== '00:00:00') {
209 $hasTimeSlots = true;
210 break;
211 }
212 }
213
214 $unique = [];
215 foreach ($pick as $a) {
216 $date = (string) ($a->departure_date ?? '');
217 if ($date === '') {
218 continue;
219 }
220 if ($hasTimeSlots) {
221 $t = isset($a->departure_time) ? trim((string) $a->departure_time) : '';
222 if ($t !== '' && $t !== '00:00:00') {
223 $date .= '|' . $t;
224 } else {
225 // When some rows have time and others don't, avoid collapsing into date-only.
226 $date .= '|__no_time__';
227 }
228 }
229 $unique[$date] = true;
230 }
231 $countAvailable = count($unique);
232
233 // Pro feature: a Pro module can hook `yatra_use_date_dropdown`
234 // to replace the flatpickr calendar with a <select> of available
235 // departures, and supplies the option list via
236 // `yatra_single_trip_date_dropdown_options`. Free plugin renders
237 // calendar by default (filter returns false / [] when Pro is
238 // inactive or the setting is off).
239 $dropdown_options = (array) apply_filters('yatra_single_trip_date_dropdown_options', [], $trip, $pick);
240 $yatra_use_date_dropdown = (bool) apply_filters('yatra_use_date_dropdown', false, $trip)
241 && !empty($dropdown_options);
242
243 echo esc_html(sprintf(
244 _n('%d departure available', '%d departures available', $countAvailable, 'yatra'),
245 $countAvailable
246 ));
247 ?>
248 </span>
249 </div>
250
251 <form class="yatra-booking-form" data-booking-mode="date_specific">
252 <!-- Date Selection -->
253 <div class="yatra-booking-field-select<?php echo $yatra_use_date_dropdown ? ' yatra-date-as-dropdown' : ''; ?>">
254 <div class="yatra-booking-field-icon">
255 <?php echo yatra_svg_icon('calendar', 'yatra-icon-sm'); ?>
256 </div>
257 <?php if ($yatra_use_date_dropdown): ?>
258 <select id="travel_date"
259 name="travel_date"
260 class="yatra-booking-select yatra-date-dropdown"
261 required>
262 <option value=""><?php esc_html_e('Select a departure date', 'yatra'); ?></option>
263 <?php foreach ($dropdown_options as $opt): ?>
264 <option value="<?php echo esc_attr($opt['value']); ?>"
265 <?php if (!empty($opt['time'])): ?>data-departure-time="<?php echo esc_attr($opt['time']); ?>"<?php endif; ?>>
266 <?php echo esc_html($opt['label']); ?>
267 </option>
268 <?php endforeach; ?>
269 </select>
270 <?php else: ?>
271 <input type="text"
272 id="travel_date"
273 name="travel_date"
274 class="yatra-booking-select yatra-datepicker"
275 placeholder="<?php esc_attr_e('Select date', 'yatra'); ?>"
276 readonly
277 required>
278 <?php endif; ?>
279 <svg class="yatra-select-arrow" fill="none" stroke="currentColor" viewBox="0 0 24 24">
280 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
281 </svg>
282 </div>
283
284 <!-- Travelers Selection - Respects Trip's Pricing Type -->
285 <?php
286 // Use helper function to prepare traveler data
287 $traveler_data = \Yatra\Controllers\SingleTripController::prepareTravelerSelectorData($trip, 'availability');
288
289 if ($traveler_data['has_traveler_pricing']):
290 // Setup variables for traveler-selector.php
291 $root_id = '';
292 $root_class = 'yatra-booking-field-select yatra-participants-select yatra-availability-participants';
293 $container_attrs = [];
294
295 $display_id = 'participants-display';
296 $display_class = 'yatra-participants-display yatra-availability-participants-display';
297 $display_attrs = [];
298
299 $dropdown_id = 'quantity-selector';
300 $dropdown_class = 'yatra-booking-quantity-selector yatra-availability-quantity-selector';
301 $dropdown_attrs = [];
302
303 $display_text = $traveler_data['traveler_display_text'];
304 $icon_html = yatra_svg_icon('users', 'yatra-icon-sm');
305 $rows = $traveler_data['traveler_rows'];
306
307 include YATRA_PLUGIN_PATH . 'templates/partials/traveler-selector.php';
308 else:
309 // Regular Pricing: Simple number of travelers input
310 ?>
311 <div class="yatra-booking-field-group">
312 <label for="num_travelers" class="yatra-booking-field-label"><?php echo esc_html__('Number of Travelers', 'yatra'); ?></label>
313 <?php
314 // Setup variables for traveler-input-simple.php
315 $input_id = 'num_travelers';
316 $input_name = 'num_travelers';
317 $value = 1;
318 $min = $trip->getMinTravelers() ?: 1;
319 $max = $trip->getMaxTravelers() ?: 20;
320 $data_price = $base_price;
321
322 include YATRA_PLUGIN_PATH . 'templates/partials/traveler-input-simple.php';
323 ?>
324 </div>
325 <?php endif; ?>
326 <?php else: ?>
327 <!-- ========================================== -->
328 <!-- FLEXIBLE BOOKING MODE (No Specific Availability Configured) -->
329 <!-- ========================================== -->
330 <div class="yatra-availability-info yatra-flexible-booking-info">
331 <span class="yatra-availability-count">
332 <?php echo esc_html__('Flexible booking available', 'yatra'); ?>
333 </span>
334 <?php if (!empty($trip->getAvailableFrom()) || !empty($trip->getAvailableTo())): ?>
335 <span class="yatra-availability-note">
336 <?php
337 if (!empty($trip->getAvailableFrom()) && !empty($trip->getAvailableTo())) {
338 echo esc_html(sprintf(__('Available: %s - %s', 'yatra'),
339 date_i18n(get_option('date_format'), strtotime($trip->getAvailableFrom())),
340 date_i18n(get_option('date_format'), strtotime($trip->getAvailableTo()))
341 ));
342 } elseif (!empty($trip->getAvailableFrom())) {
343 echo esc_html(sprintf(__('Available from: %s', 'yatra'),
344 date_i18n(get_option('date_format'), strtotime($trip->getAvailableFrom()))
345 ));
346 } else {
347 echo esc_html(sprintf(__('Available until: %s', 'yatra'),
348 date_i18n(get_option('date_format'), strtotime($trip->getAvailableTo()))
349 ));
350 }
351 ?>
352 </span>
353 <?php endif; ?>
354 </div>
355
356 <form class="yatra-booking-form" data-booking-mode="flexible">
357 <!-- Date Selection (Flexible) -->
358 <?php
359 // Same Pro filter contract as the date_specific branch above.
360 // Flexible trips have no discrete availability set, so $pick is
361 // passed as null — the Pro hook synthesizes a list from the
362 // trip's available_from/to window.
363 $flex_dropdown_options = (array) apply_filters('yatra_single_trip_date_dropdown_options', [], $trip, null);
364 $flex_use_date_dropdown = (bool) apply_filters('yatra_use_date_dropdown', false, $trip)
365 && !empty($flex_dropdown_options);
366 ?>
367 <div class="yatra-booking-field-select<?php echo $flex_use_date_dropdown ? ' yatra-date-as-dropdown' : ''; ?>">
368 <div class="yatra-booking-field-icon">
369 <?php echo yatra_svg_icon('calendar', 'yatra-icon-sm'); ?>
370 </div>
371 <?php if ($flex_use_date_dropdown): ?>
372 <select id="travel_date"
373 name="travel_date"
374 class="yatra-booking-select yatra-date-dropdown"
375 required>
376 <option value=""><?php esc_html_e('Select a departure date', 'yatra'); ?></option>
377 <?php foreach ($flex_dropdown_options as $opt): ?>
378 <option value="<?php echo esc_attr($opt['value']); ?>"
379 <?php if (!empty($opt['time'])): ?>data-departure-time="<?php echo esc_attr($opt['time']); ?>"<?php endif; ?>>
380 <?php echo esc_html($opt['label']); ?>
381 </option>
382 <?php endforeach; ?>
383 </select>
384 <?php else: ?>
385 <input type="text"
386 id="travel_date"
387 name="travel_date"
388 class="yatra-booking-select yatra-datepicker"
389 placeholder="<?php esc_attr_e('Select date', 'yatra'); ?>"
390 data-min-date="<?php echo esc_attr($trip->getAvailableFrom() ?: date('Y-m-d')); ?>"
391 data-max-date="<?php echo esc_attr($trip->getAvailableTo() ?: ''); ?>"
392 readonly
393 required>
394 <?php endif; ?>
395 <svg class="yatra-select-arrow" fill="none" stroke="currentColor" viewBox="0 0 24 24">
396 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
397 </svg>
398 </div>
399
400 <!-- Travelers Selection -->
401 <?php
402 // Use helper function to prepare traveler data
403 $traveler_data = \Yatra\Controllers\SingleTripController::prepareTravelerSelectorData($trip, 'sidebar');
404
405 if ($traveler_data['has_traveler_pricing']):
406 // Setup variables for traveler-selector.php
407 $root_id = '';
408 $root_class = 'yatra-booking-field-select yatra-participants-select';
409 $container_attrs = [];
410
411 $display_id = 'participants-display';
412 $display_class = 'yatra-participants-display';
413 $display_attrs = [];
414
415 $dropdown_id = 'quantity-selector';
416 $dropdown_class = 'yatra-booking-quantity-selector';
417 $dropdown_attrs = [];
418
419 $display_text = $traveler_data['traveler_display_text'];
420 $icon_html = yatra_svg_icon('users', 'yatra-icon-sm');
421 $rows = $traveler_data['traveler_rows'];
422
423 include YATRA_PLUGIN_PATH . 'templates/partials/traveler-selector.php';
424 else:
425 // Regular Pricing: Simple number of travelers input
426 ?>
427 <div class="yatra-booking-field-group">
428 <label for="num_travelers" class="yatra-booking-field-label"><?php echo esc_html__('Number of Travelers', 'yatra'); ?></label>
429 <?php
430 // Setup variables for traveler-input-simple.php
431 $input_id = 'num_travelers';
432 $input_name = 'num_travelers';
433 $value = 1;
434 $min = $trip->getMinTravelers() ?: 1;
435 $max = $trip->getMaxTravelers() ?: 20;
436 $data_price = $base_price;
437
438 include YATRA_PLUGIN_PATH . 'templates/partials/traveler-input-simple.php';
439 ?>
440 </div>
441 <?php endif; ?>
442 <?php endif; ?>
443
444
445 <!-- Action Buttons -->
446 <button type="button" class="yatra-booking-button" id="check-availability-btn" data-trip-id="<?php echo esc_attr($trip->getId()); ?>">
447 <svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
448 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
449 </svg>
450 <?php echo esc_html__('Check Availability', 'yatra'); ?>
451 </button>
452
453 <button type="button" class="yatra-booking-enquiry-button" id="open-enquiry-modal" onclick="window.YatraEnquiry?.open?.(); return false;">
454 <svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
455 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"/>
456 </svg>
457 <?php echo esc_html__('Make Enquiry', 'yatra'); ?>
458 </button>
459
460 <!-- Cancellation Policy Trust Signal -->
461 <?php
462 $cancellation_policy = '';
463 if (method_exists($trip, 'getCancellationPolicy')) {
464 $cancellation_policy = $trip->getCancellationPolicy();
465 } elseif (isset($trip->cancellation_policy)) {
466 $cancellation_policy = $trip->cancellation_policy;
467 }
468
469 $cancellation_text = '';
470 if (!empty($cancellation_policy)) {
471 // Extract cancellation info from policy
472 $policy_lower = strtolower($cancellation_policy);
473 if (strpos($policy_lower, 'free') !== false || strpos($policy_lower, 'no charge') !== false) {
474 if (preg_match('/(\d+)\s*(hour|day|week)s?\s*before/i', $cancellation_policy, $matches)) {
475 $time_value = $matches[1];
476 $time_unit = $matches[2];
477 $cancellation_text = sprintf(
478 __('Free cancellation up to %d %s%s before', 'yatra'),
479 $time_value,
480 $time_unit,
481 $time_value > 1 ? 's' : ''
482 );
483 } else {
484 $cancellation_text = __('Free cancellation', 'yatra');
485 }
486 } else {
487 // Non-free cancellation, show brief info
488 $cancellation_text = __('Cancellation policy applies', 'yatra');
489 }
490 } else {
491 // Default fallback when no policy is set
492 $cancellation_text = __('Cancellation policy may apply', 'yatra');
493 }
494 ?>
495 <div class="yatra-booking-trust">
496 <div class="yatra-booking-trust-icon">
497 <?php echo yatra_svg_icon('check', 'yatra-icon-xs'); ?>
498 </div>
499 <div class="yatra-booking-trust-text">
500 <strong><?php echo esc_html($cancellation_text); ?></strong>
501 </div>
502 </div>
503 </form>
504 </div>
505 <?php endif; // end else (booking not disabled) ?>
506 </aside>