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 / templates / partials / availability-card.php

availability-card.php in Yatra – Travel Booking & Tour Operator Software 3.0.2.6, at templates/partials/availability-card.php

501 lines 30.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Single departure card for trip availability (included in a loop).
4 * @package Yatra
5 * @var array $card @var int $index @var object $trip_data @var string $pricing_type @var string $selected_date_filter
6 */
7 defined('ABSPATH') || exit;
8 $card = $card ?? [];
9 $index = (int) ($index ?? 0);
10 $trip_data = $trip_data ?? (object) [];
11 $pricing_type = $pricing_type ?? 'regular';
12 $selected_date_filter = $selected_date_filter ?? '';
13 $trip_id = !empty($trip_data->id) ? (int) $trip_data->id : 0;
14 $max_travelers = (int) ($trip_data->max_travelers ?? 20);
15 $item_id = isset($card['id']) ? (string) $card['id'] : (string) $index;
16
17 // Get pricing from card (already calculated with dynamic pricing in Controller)
18 $sale_price = (float) ($card['sale_price'] ?? 0);
19 $original_price = (float) ($card['original_price'] ?? 0);
20
21 // For traveler-based pricing, use first category price for initial total
22 $initial_total_price = $sale_price;
23 if (!empty($card['pricing_type']) && $card['pricing_type'] === 'traveler_based' && !empty($card['traveler_pricing'])) {
24 $first_traveler = is_array($card['traveler_pricing']) ? $card['traveler_pricing'][0] : null;
25 if ($first_traveler) {
26 $first_traveler = is_array($first_traveler) ? (object) $first_traveler : $first_traveler;
27 $initial_total_price = (float) ($first_traveler->effective_price ?? $first_traveler->discounted_price ?? $first_traveler->original_price ?? $sale_price);
28 }
29 }
30
31 $seats_available = (int) ($card['seats_available'] ?? 0);
32 $is_limited = !empty($card['is_limited']);
33 $card_status = $card['status'] ?? 'available';
34 $is_sold_out = isset($card['is_sold_out']) && $card['is_sold_out'];
35 if ($is_sold_out || $card_status === 'sold_out') {
36 $card_status = 'sold_out';
37 }
38
39 // Match Y-m-d even if DB returns datetime (e.g. 2026-08-13 00:00:00)
40 $yatra_card_date_norm = static function ($v): string {
41 $v = trim((string) $v);
42 return preg_match('/^(\d{4}-\d{2}-\d{2})/', $v, $m) ? $m[1] : $v;
43 };
44 $sel_norm = $yatra_card_date_norm($selected_date_filter ?? '');
45 $card_date_norm = $yatra_card_date_norm($card['data_date'] ?? '');
46 $is_selected_card = ($sel_norm !== '' && $card_date_norm !== '' && $sel_norm === $card_date_norm);
47 $should_be_open = $is_selected_card || $index === 0;
48 ?>
49 <div class="yatra-availability-card <?php echo $should_be_open ? 'open' : ''; ?> <?php echo $is_selected_card ? 'selected' : ''; ?> <?php echo $is_limited ? 'limited' : ''; ?> yatra-card-status-<?php echo esc_attr($card_status); ?>"
50 data-availability-id="<?php echo esc_attr($item_id); ?>"
51 data-month="<?php echo esc_attr($card['data_month'] ?? ''); ?>"
52 data-date="<?php echo esc_attr($card['data_date'] ?? ''); ?>"
53 data-price="<?php echo esc_attr($sale_price); ?>"
54 data-seats="<?php echo esc_attr($seats_available); ?>"
55 data-item="<?php echo esc_attr($item_id); ?>"
56 data-index="<?php echo esc_attr($index); ?>">
57
58 <!-- Card Header (Clickable) -->
59 <div class="yatra-availability-card-header yatra-availability-toggle" role="button" tabindex="0" aria-label="<?php esc_attr_e('Toggle availability details', 'yatra'); ?>">
60
61 <?php
62 // Placeholder for discount badge (will be set after price calculation)
63 $final_discount_badge = '';
64 ?>
65 <?php if (!empty($card['date_display'])): ?>
66 <!-- Day Trip: Show date as header -->
67 <div class="yatra-card-date-header">
68 <?php echo yatra_svg_icon('calendar', 'yatra-icon-sm'); ?>
69 <?php echo esc_html($card['date_display']); ?>
70 </div>
71 <?php endif; ?>
72 <div class="yatra-card-header-grid <?php echo !empty($card['date_display']) ? 'yatra-day-trip-grid' : ''; ?>">
73
74 <!-- Start/Departure -->
75 <div class="yatra-card-header-item">
76 <div class="yatra-card-header-label"><?php echo esc_html($card['from_label'] ?? __('Departure', 'yatra')); ?></div>
77 <div class="yatra-card-header-date"><?php echo esc_html($card['from_date'] ?? ''); ?></div>
78 <div class="yatra-card-header-location"><?php echo esc_html($card['from_location'] ?? ''); ?></div>
79 </div>
80
81 <!-- End/Return -->
82 <div class="yatra-card-header-item">
83 <div class="yatra-card-header-label"><?php echo esc_html($card['to_label'] ?? __('Return', 'yatra')); ?></div>
84 <div class="yatra-card-header-date"><?php echo esc_html($card['to_date'] ?? ''); ?></div>
85 <div class="yatra-card-header-location"><?php echo esc_html($card['to_location'] ?? ''); ?></div>
86 </div>
87
88 <!-- Seats -->
89 <div class="yatra-card-header-item">
90 <div class="yatra-card-header-label"><?php esc_html_e('Seats remaining', 'yatra'); ?></div>
91 <div class="yatra-card-header-seats <?php echo $is_limited ? 'limited' : ''; ?>"><?php echo esc_html($card['seats'] ?? '0'); ?></div>
92 <div class="yatra-card-header-sub"><?php esc_html_e('per departure', 'yatra'); ?></div>
93 </div>
94
95 <!-- Price -->
96 <div class="yatra-card-header-price">
97 <div class="yatra-card-price-group">
98 <?php
99 // Pricing is already calculated with dynamic pricing in Controller
100 $display_sale_price = $sale_price;
101 $display_original_price = $original_price;
102
103 // Show discount badge if there's a discount
104 $final_discount_badge = '';
105 if (!empty($card['discount_text'])) {
106 $final_discount_badge = '<div class="yatra-card-discount-badge yatra-badge-discount">' . esc_html($card['discount_text']) . '</div>';
107 }
108
109 echo '<span class="yatra-sale-price">' . yatra_format_price($display_sale_price) . '</span>';
110 ?>
111 </div>
112 <span class="yatra-price-label"><?php echo esc_html__('per person', 'yatra'); ?></span>
113 </div>
114
115 <!-- Toggle Arrow -->
116 <div class="yatra-card-header-arrow">
117 <svg width="20" height="20" viewBox="0 0 20 20" fill="none">
118 <path d="M5 7.5L10 12.5L15 7.5" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
119 </svg>
120 </div>
121 </div>
122
123 <!-- Badges Container (Status + Discount) -->
124 <div class="yatra-card-badges-container">
125 <!-- Status Badge -->
126 <?php
127 $card_status = $card['status'] ?? 'available';
128 $is_sold_out = isset($card['is_sold_out']) && $card['is_sold_out'];
129
130 // Determine status display
131 if ($is_sold_out || $card_status === 'sold_out') {
132 echo '<div class="yatra-badge-status yatra-badge-sold-out">' . esc_html__('Sold Out', 'yatra') . '</div>';
133 } elseif ($card_status === 'limited') {
134 echo '<div class="yatra-badge-status yatra-badge-limited">' . esc_html__('Limited', 'yatra') . '</div>';
135 } elseif ($card_status === 'blocked') {
136 echo '<div class="yatra-badge-status yatra-badge-blocked">' . esc_html__('Blocked', 'yatra') . '</div>';
137 } elseif ($card_status === 'closed') {
138 echo '<div class="yatra-badge-status yatra-badge-closed">' . esc_html__('Closed', 'yatra') . '</div>';
139 } elseif ($card_status === 'cancelled') {
140 echo '<div class="yatra-badge-status yatra-badge-cancelled">' . esc_html__('Cancelled', 'yatra') . '</div>';
141 } else {
142 echo '<div class="yatra-badge-status yatra-badge-available">' . esc_html__('Available', 'yatra') . '</div>';
143 }
144 ?>
145
146 <!-- Discount Badge -->
147 <?php
148 if (!empty($final_discount_badge)) {
149 echo $final_discount_badge;
150 }
151 ?>
152 </div>
153 </div>
154
155 <!-- Card Body (Expandable) -->
156 <div class="yatra-availability-card-body">
157 <div class="yatra-card-body-content">
158 <div class="yatra-card-info-grid">
159 <div class="yatra-card-info-item">
160 <div class="yatra-card-info-icon">
161 <?php echo yatra_svg_icon('calendar', 'yatra-icon-sm'); ?>
162 </div>
163 <div class="yatra-card-info-content">
164 <div class="yatra-card-info-label"><?php esc_html_e('Duration', 'yatra'); ?></div>
165 <div class="yatra-card-info-value">
166 <?php
167 $duration_days = (int) ($trip_data->duration_days ?? 1);
168 echo esc_html($duration_days . ' ' . _n('Day', 'Days', $duration_days, 'yatra'));
169 ?>
170 </div>
171 </div>
172 </div>
173
174 <div class="yatra-card-info-item">
175 <div class="yatra-card-info-icon">
176 <?php echo yatra_svg_icon('users', 'yatra-icon-sm'); ?>
177 </div>
178 <div class="yatra-card-info-content">
179 <div class="yatra-card-info-label"><?php esc_html_e('Seats left', 'yatra'); ?></div>
180 <div class="yatra-card-info-value"><?php echo esc_html(sprintf(_n('%d seat', '%d seats', $seats_available, 'yatra'), $seats_available)); ?></div>
181 </div>
182 </div>
183
184 <?php
185 $cancellation_policy = '';
186 if (method_exists($trip_data, 'getCancellationPolicy')) {
187 $cancellation_policy = $trip_data->getCancellationPolicy();
188 } elseif (isset($trip_data->cancellation_policy)) {
189 $cancellation_policy = $trip_data->cancellation_policy;
190 }
191
192 $cancellation_label = '';
193 $cancellation_value = '';
194 if (!empty($cancellation_policy)) {
195 // Extract cancellation info from policy
196 $policy_lower = strtolower($cancellation_policy);
197 if (strpos($policy_lower, 'free') !== false || strpos($policy_lower, 'no charge') !== false) {
198 $cancellation_label = __('Free Cancellation', 'yatra');
199 if (preg_match('/(\d+)\s*(hour|day|week)s?\s*before/i', $cancellation_policy, $matches)) {
200 $time_value = $matches[1];
201 $time_unit = $matches[2];
202 $cancellation_value = sprintf(
203 __('Up to %d %s%s before', 'yatra'),
204 $time_value,
205 $time_unit,
206 $time_value > 1 ? 's' : ''
207 );
208 } else {
209 $cancellation_value = __('No charge', 'yatra');
210 }
211 } else {
212 // Non-free cancellation
213 $cancellation_label = __('Cancellation Policy', 'yatra');
214 $cancellation_value = __('See details', 'yatra');
215 }
216 } else {
217 // Default fallback when no policy is set
218 $cancellation_label = __('Cancellation Policy', 'yatra');
219 $cancellation_value = __('May apply', 'yatra');
220 }
221 ?>
222 <div class="yatra-card-info-item">
223 <div class="yatra-card-info-icon">
224 <?php echo yatra_svg_icon('check', 'yatra-icon-sm'); ?>
225 </div>
226 <div class="yatra-card-info-content">
227 <div class="yatra-card-info-label"><?php echo esc_html($cancellation_label); ?></div>
228 <div class="yatra-card-info-value"><?php echo esc_html($cancellation_value); ?></div>
229 </div>
230 </div>
231 </div>
232
233 <div class="yatra-card-traveler-section">
234 <label class="yatra-card-traveler-label"><?php esc_html_e('Travelers', 'yatra'); ?></label>
235
236 <?php
237 // Use card-level pricing type as source of truth
238 $card_pricing_type = $card['pricing_type'] ?? $pricing_type ?? 'regular';
239 $card_price_types = [];
240 $dp_enabled = apply_filters('yatra_dynamic_pricing_enabled', false);
241
242 // Use availability-specific traveler_pricing for traveler-based pricing
243 if ($card_pricing_type === 'traveler_based' && !empty($card['traveler_pricing'])) {
244 $card_price_types = $card['traveler_pricing'];
245 }
246
247 // Normalize traveler pricing to objects if array
248 $normalized_price_types = [];
249 foreach ($card_price_types as $cpt) {
250 if (is_array($cpt)) {
251 $normalized_price_types[] = (object) $cpt;
252 } else {
253 $normalized_price_types[] = $cpt;
254 }
255 }
256 ?>
257
258 <?php if ($card_pricing_type === 'traveler_based' && !empty($normalized_price_types)): ?>
259 <!-- Traveler-based pricing: Show dynamic categories -->
260 <?php
261 // Build traveler rows directly from card-level traveler_pricing data
262 $traveler_rows = [];
263 $display_parts = [];
264 foreach ($normalized_price_types as $pt_index => $pt) {
265 $pt_label = $pt->category_label ?? $pt->label ?? __('Traveler', 'yatra');
266 $pt_pricing_mode = $pt->pricing_mode ?? 'per_person';
267 $pt_is_per_group = ($pt_pricing_mode === 'per_group');
268 $pt_category_id = $pt->category_id ?? $pt_index;
269 $pt_default = $pt_index === 0 ? 1 : 0;
270 $pt_min_qty = 0;
271 $pt_max_qty = (int) min($seats_available, $max_travelers);
272
273 // Determine price with fallback chain
274 $pt_price = 0;
275 if (isset($pt->effective_price) && $pt->effective_price > 0) {
276 $pt_price = (float) $pt->effective_price;
277 } elseif (isset($pt->discounted_price) && $pt->discounted_price > 0) {
278 $pt_price = (float) $pt->discounted_price;
279 } elseif (isset($pt->original_price) && $pt->original_price > 0) {
280 $pt_price = (float) $pt->original_price;
281 }
282
283 // Apply dynamic pricing to traveler category prices
284 if ($dp_enabled && $pt_price > 0) {
285 $pt_price = apply_filters('yatra_availability_price', $pt_price, $trip_id, [
286 'departure_date' => $card['date'] ?? null,
287 'spots_remaining' => $card['spots_remaining'] ?? null,
288 'availability_id' => $item_id,
289 'price_type_id' => $pt->id ?? ($pt->price_type_id ?? null),
290 ]);
291 }
292
293 // Age info
294 $pt_age_text = '';
295 $pt_age_min = isset($pt->age_min) ? (int) $pt->age_min : null;
296 $pt_age_max = isset($pt->age_max) ? (int) $pt->age_max : null;
297 if ($pt_age_min !== null || $pt_age_max !== null) {
298 if ($pt_age_min !== null && $pt_age_max !== null) {
299 $pt_age_text = sprintf(__('(Age %d-%d)', 'yatra'), $pt_age_min, $pt_age_max);
300 } elseif ($pt_age_min !== null) {
301 $pt_age_text = sprintf(__('(Age %d+)', 'yatra'), $pt_age_min);
302 } else {
303 $pt_age_text = sprintf(__('(Up to age %d)', 'yatra'), $pt_age_max);
304 }
305 }
306
307 // Build pricing label for per_group mode
308 $pricing_label = '';
309 if ($pt_is_per_group) {
310 if (!empty($pt->min_pax) && !empty($pt->max_pax)) {
311 $pricing_label = sprintf(__('per group (%d-%d pax)', 'yatra'), $pt->min_pax, $pt->max_pax);
312 } elseif (!empty($pt->max_pax)) {
313 $pricing_label = sprintf(__('per group (up to %d pax)', 'yatra'), $pt->max_pax);
314 } elseif (!empty($pt->min_pax)) {
315 $pricing_label = sprintf(__('per group (%d+ pax)', 'yatra'), $pt->min_pax);
316 } else {
317 $pricing_label = __('per group', 'yatra');
318 }
319 }
320
321 // Build price HTML
322 $pt_price_html = '';
323 if ($pt_price > 0) {
324 $pt_price_html = '<div class="yatra-quantity-price-wrapper">';
325 $pt_price_html .= '<span class="yatra-quantity-price">' . yatra_format_price($pt_price) . '</span>';
326 if ($pt_is_per_group) {
327 $pt_price_html .= '<span class="yatra-pricing-mode-label yatra-pricing-mode-group">' . esc_html($pricing_label) . '</span>';
328 }
329 $pt_price_html .= '</div>';
330 }
331
332 $input_id = 'traveler_' . $pt_category_id;
333
334 $traveler_rows[] = [
335 'label' => $pt_label,
336 'subtitle' => $pt_age_text,
337 'price_html' => $pt_price_html,
338 'row_attrs' => [
339 'data-category-id' => $pt_category_id,
340 'data-price' => $pt_price,
341 'data-pricing-mode' => $pt_pricing_mode,
342 ],
343 'minus_disabled' => $pt_default <= $pt_min_qty,
344 'plus_disabled' => $pt_default >= $pt_max_qty,
345 'minus_attrs' => [
346 'data-target' => $input_id,
347 'data-item' => $item_id,
348 'data-category' => $pt_category_id,
349 'aria-label' => sprintf(__('Decrease %s', 'yatra'), $pt_label),
350 ],
351 'plus_attrs' => [
352 'data-target' => $input_id,
353 'data-item' => $item_id,
354 'data-category' => $pt_category_id,
355 'aria-label' => sprintf(__('Increase %s', 'yatra'), $pt_label),
356 ],
357 'input_attrs' => [
358 'id' => $input_id,
359 'name' => 'travelers[' . $pt_category_id . ']',
360 'value' => $pt_default,
361 'min' => $pt_min_qty,
362 'max' => $pt_max_qty,
363 'data-item' => $item_id,
364 'data-category' => $pt_category_id,
365 'data-category-label' => $pt_label,
366 'data-price' => $pt_price,
367 'data-pricing-mode' => $pt_pricing_mode,
368 ],
369 ];
370
371 if ($pt_default > 0) {
372 $display_parts[] = $pt_label . ' x ' . $pt_default;
373 }
374 }
375
376 $traveler_display_text = !empty($display_parts) ? implode(', ', $display_parts) : __('Select travelers', 'yatra');
377
378 // Setup variables for traveler-selector.php using availability-specific data
379 $root_id = '';
380 $root_class = 'yatra-booking-field-select yatra-participants-select yatra-availability-participants';
381 $container_attrs = [
382 'data-item' => $item_id,
383 ];
384
385 $display_id = 'participants-display';
386 $display_class = 'yatra-participants-display yatra-availability-participants-display';
387 $display_attrs = [
388 'data-item' => $item_id,
389 ];
390
391 $dropdown_id = '';
392 $dropdown_class = 'yatra-booking-quantity-selector yatra-availability-quantity-selector';
393 $dropdown_attrs = [
394 'data-item' => $item_id,
395 ];
396
397 $display_text = $traveler_display_text;
398 $icon_html = yatra_svg_icon('users', 'yatra-icon-sm');
399 $rows = $traveler_rows;
400
401 include YATRA_PLUGIN_PATH . 'templates/partials/traveler-selector.php';
402 ?>
403 <?php else: ?>
404 <!-- Regular pricing: Show simple number of travelers -->
405 <div class="yatra-booking-travelers-simple yatra-availability-travelers-simple" data-item="<?php echo esc_attr($item_id); ?>">
406 <div class="yatra-booking-field-icon">
407 <?php echo yatra_svg_icon('users', 'yatra-icon-sm'); ?>
408 </div>
409 <div class="yatra-quantity-controls-inline">
410 <button type="button" class="yatra-quantity-btn yatra-quantity-minus" data-target="num-travelers-<?php echo esc_attr($item_id); ?>" aria-label="<?php esc_attr_e('Decrease travelers', 'yatra'); ?>" disabled>
411 <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
412 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 12H4"/>
413 </svg>
414 </button>
415 <input type="number"
416 id="num-travelers-<?php echo esc_attr($item_id); ?>"
417 class="yatra-quantity-input-simple yatra-availability-num-travelers"
418 data-item="<?php echo esc_attr($item_id); ?>"
419 value="1"
420 min="1"
421 max="<?php echo esc_attr(min($seats_available, $max_travelers)); ?>"
422 readonly
423 data-price="<?php echo esc_attr($sale_price); ?>">
424 <button type="button" class="yatra-quantity-btn yatra-quantity-plus" data-target="num-travelers-<?php echo esc_attr($item_id); ?>" aria-label="<?php esc_attr_e('Increase travelers', 'yatra'); ?>">
425 <svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
426 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>
427 </svg>
428 </button>
429 </div>
430 <span class="yatra-travelers-label"><?php esc_html_e('travelers', 'yatra'); ?></span>
431 </div>
432 <?php endif; ?>
433
434 <div class="yatra-card-action-help"><?php esc_html_e('Select travelers to update the total, then click Book Now.', 'yatra'); ?></div>
435 </div>
436 </div>
437
438 <!-- Booking Row at Bottom -->
439 <div class="yatra-card-booking-row">
440 <div class="yatra-card-total-box">
441 <div class="yatra-card-total-label"><?php esc_html_e('Total', 'yatra'); ?></div>
442 <div class="yatra-card-total-note" data-item="<?php echo esc_attr($item_id); ?>"><?php esc_html_e('for 1 traveler', 'yatra'); ?></div>
443 <div class="yatra-card-total-amount" data-item="<?php echo esc_attr($item_id); ?>" data-base-price="<?php echo esc_attr($initial_total_price); ?>">
444 <?php
445 $formatted_total = yatra_format_price($initial_total_price);
446 echo esc_html($formatted_total);
447 ?>
448 </div>
449 </div>
450 <?php
451 // Prepare price_types JSON for JavaScript
452 $price_types_json = '';
453 if (!empty($normalized_price_types)) {
454 $price_types_for_js = array_map(function($pt) {
455 $pt = (object) $pt;
456 return [
457 'category_id' => $pt->category_id ?? null,
458 'category_label' => $pt->category_label ?? $pt->label ?? '',
459 'original_price' => $pt->original_price ?? 0,
460 'sale_price' => $pt->sale_price ?? null,
461 'discounted_price' => $pt->discounted_price ?? null,
462 'effective_price' => $pt->effective_price ?? $pt->sale_price ?? $pt->discounted_price ?? $pt->original_price ?? 0,
463 'age_min' => $pt->age_min ?? null,
464 'age_max' => $pt->age_max ?? null,
465 ];
466 }, $normalized_price_types);
467 $price_types_json = wp_json_encode($price_types_for_js);
468 }
469
470 // Get departure time - prefer card data, fallback to from_date if it looks like time
471 $card_departure_time = '';
472 if (!empty($card['departure_time'])) {
473 $card_departure_time = $card['departure_time'];
474 } elseif (!empty($card['from_date']) && preg_match('/^\d{1,2}:\d{2}\s*(AM|PM)?$/i', $card['from_date'])) {
475 $card_departure_time = $card['from_date'];
476 }
477
478 // Is this a day trip?
479 $is_card_day_trip = !empty($card['is_day_trip']) || !empty($card['date_display']);
480 ?>
481 <button type="button"
482 class="yatra-card-book-btn"
483 data-trip-id="<?php echo esc_attr($trip_id); ?>"
484 data-availability-id="<?php echo esc_attr($item_id); ?>"
485 data-date="<?php echo esc_attr($card['data_date'] ?? ''); ?>"
486 data-departure-time="<?php echo esc_attr($card_departure_time); ?>"
487 data-is-day-trip="<?php echo $is_card_day_trip ? '1' : '0'; ?>"
488 data-pricing-type="<?php echo esc_attr($card_pricing_type); ?>"
489 data-price-types="<?php echo esc_attr($price_types_json); ?>"
490 data-price="<?php echo esc_attr($sale_price); ?>"
491 data-item="<?php echo esc_attr($item_id); ?>">
492 <?php echo yatra_svg_icon('shopping-cart', 'yatra-icon-sm'); ?>
493 <span class="yatra-card-book-btn-text">
494 <span class="yatra-card-book-btn-title"><?php esc_html_e('Book Now', 'yatra'); ?></span>
495 <span class="yatra-card-book-btn-subtitle"><?php esc_html_e('Continue to booking', 'yatra'); ?></span>
496 </span>
497 </button>
498 </div>
499 </div>
500 </div>
501