duration_days ?? 1);
echo esc_html($duration_days . ' ' . _n('Day', 'Days', $duration_days, 'yatra'));
?>
getCancellationPolicy();
} elseif (isset($trip_data->cancellation_policy)) {
$cancellation_policy = $trip_data->cancellation_policy;
}
$cancellation_label = '';
$cancellation_value = '';
if (!empty($cancellation_policy)) {
// Extract cancellation info from policy
$policy_lower = strtolower($cancellation_policy);
if (strpos($policy_lower, 'free') !== false || strpos($policy_lower, 'no charge') !== false) {
$cancellation_label = __('Free Cancellation', 'yatra');
if (preg_match('/(\d+)\s*(hour|day|week)s?\s*before/i', $cancellation_policy, $matches)) {
$time_value = $matches[1];
$time_unit = $matches[2];
$cancellation_value = sprintf(
__('Up to %d %s%s before', 'yatra'),
$time_value,
$time_unit,
$time_value > 1 ? 's' : ''
);
} else {
$cancellation_value = __('No charge', 'yatra');
}
} else {
// Non-free cancellation
$cancellation_label = __('Cancellation Policy', 'yatra');
$cancellation_value = __('See details', 'yatra');
}
} else {
// Default fallback when no policy is set
$cancellation_label = __('Cancellation Policy', 'yatra');
$cancellation_value = __('May apply', 'yatra');
}
?>
$pt) {
$pt_label = $pt->category_label ?? $pt->label ?? __('Traveler', 'yatra');
$pt_pricing_mode = $pt->pricing_mode ?? 'per_person';
$pt_is_per_group = ($pt_pricing_mode === 'per_group');
$pt_category_id = $pt->category_id ?? $pt_index;
$pt_default = $pt_index === 0 ? 1 : 0;
$pt_min_qty = 0;
$pt_max_qty = (int) min($seats_available, $max_travelers);
// Determine price with fallback chain
$pt_price = 0;
if (isset($pt->effective_price) && $pt->effective_price > 0) {
$pt_price = (float) $pt->effective_price;
} elseif (isset($pt->discounted_price) && $pt->discounted_price > 0) {
$pt_price = (float) $pt->discounted_price;
} elseif (isset($pt->original_price) && $pt->original_price > 0) {
$pt_price = (float) $pt->original_price;
}
// Apply dynamic pricing to traveler category prices
if ($dp_enabled && $pt_price > 0) {
$pt_price = apply_filters('yatra_availability_price', $pt_price, $trip_id, [
'departure_date' => $card['date'] ?? null,
'spots_remaining' => $card['spots_remaining'] ?? null,
'availability_id' => $item_id,
'price_type_id' => $pt->id ?? ($pt->price_type_id ?? null),
]);
}
// Age info
$pt_age_text = '';
$pt_age_min = isset($pt->age_min) ? (int) $pt->age_min : null;
$pt_age_max = isset($pt->age_max) ? (int) $pt->age_max : null;
if ($pt_age_min !== null || $pt_age_max !== null) {
if ($pt_age_min !== null && $pt_age_max !== null) {
$pt_age_text = sprintf(__('(Age %d-%d)', 'yatra'), $pt_age_min, $pt_age_max);
} elseif ($pt_age_min !== null) {
$pt_age_text = sprintf(__('(Age %d+)', 'yatra'), $pt_age_min);
} else {
$pt_age_text = sprintf(__('(Up to age %d)', 'yatra'), $pt_age_max);
}
}
// Build pricing label for per_group mode
$pricing_label = '';
if ($pt_is_per_group) {
if (!empty($pt->min_pax) && !empty($pt->max_pax)) {
$pricing_label = sprintf(__('per group (%d-%d pax)', 'yatra'), $pt->min_pax, $pt->max_pax);
} elseif (!empty($pt->max_pax)) {
$pricing_label = sprintf(__('per group (up to %d pax)', 'yatra'), $pt->max_pax);
} elseif (!empty($pt->min_pax)) {
$pricing_label = sprintf(__('per group (%d+ pax)', 'yatra'), $pt->min_pax);
} else {
$pricing_label = __('per group', 'yatra');
}
}
// Build price HTML
$pt_price_html = '';
if ($pt_price > 0) {
$pt_price_html = '
';
$pt_price_html .= '' . yatra_format_price($pt_price) . '';
if ($pt_is_per_group) {
$pt_price_html .= '' . esc_html($pricing_label) . '';
}
$pt_price_html .= '
';
}
$input_id = 'traveler_' . $pt_category_id;
$traveler_rows[] = [
'label' => $pt_label,
'subtitle' => $pt_age_text,
'price_html' => $pt_price_html,
'row_attrs' => [
'data-category-id' => $pt_category_id,
'data-price' => $pt_price,
'data-pricing-mode' => $pt_pricing_mode,
],
'minus_disabled' => $pt_default <= $pt_min_qty,
'plus_disabled' => $pt_default >= $pt_max_qty,
'minus_attrs' => [
'data-target' => $input_id,
'data-item' => $item_id,
'data-category' => $pt_category_id,
'aria-label' => sprintf(__('Decrease %s', 'yatra'), $pt_label),
],
'plus_attrs' => [
'data-target' => $input_id,
'data-item' => $item_id,
'data-category' => $pt_category_id,
'aria-label' => sprintf(__('Increase %s', 'yatra'), $pt_label),
],
'input_attrs' => [
'id' => $input_id,
'name' => 'travelers[' . $pt_category_id . ']',
'value' => $pt_default,
'min' => $pt_min_qty,
'max' => $pt_max_qty,
'data-item' => $item_id,
'data-category' => $pt_category_id,
'data-category-label' => $pt_label,
'data-price' => $pt_price,
'data-pricing-mode' => $pt_pricing_mode,
],
];
if ($pt_default > 0) {
$display_parts[] = $pt_label . ' x ' . $pt_default;
}
}
$traveler_display_text = !empty($display_parts) ? implode(', ', $display_parts) : __('Select travelers', 'yatra');
// Setup variables for traveler-selector.php using availability-specific data
$root_id = '';
$root_class = 'yatra-booking-field-select yatra-participants-select yatra-availability-participants';
$container_attrs = [
'data-item' => $item_id,
];
$display_id = 'participants-display';
$display_class = 'yatra-participants-display yatra-availability-participants-display';
$display_attrs = [
'data-item' => $item_id,
];
$dropdown_id = '';
$dropdown_class = 'yatra-booking-quantity-selector yatra-availability-quantity-selector';
$dropdown_attrs = [
'data-item' => $item_id,
];
$display_text = $traveler_display_text;
$icon_html = yatra_svg_icon('users', 'yatra-icon-sm');
$rows = $traveler_rows;
include YATRA_PLUGIN_PATH . 'templates/partials/traveler-selector.php';
?>