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 | templates/booking-confirmation.php +75 -3 3.0.13 → 3.0.16 View file →
@@ -43,8 +43,15 @@
43 43 $booking_amount_due = (float) ($booking->amount_due ?? 0);
44 44 $booking_is_fully_paid = $booking_payment_status === 'paid' || $booking_amount_due <= 0.01;
45 45 $show_balance_paid_banner = $is_balance_paid_request && $booking_is_fully_paid;
46 46
47 +// A gateway may redirect back here with `?payment=cancelled` (user aborted the
48 +// payment at the provider) or `?payment=failed`. Show an informative notice only
49 +// when the booking is not already fully paid, so a genuinely-paid booking that
50 +// happens to carry a stale query arg never shows a misleading "cancelled" message.
51 +$payment_result_flag = isset($_GET['payment']) ? sanitize_key((string) $_GET['payment']) : '';
52 +$show_payment_cancelled_notice = in_array($payment_result_flag, ['cancelled', 'failed'], true) && !$booking_is_fully_paid;
53 +
47 54 // Resolve the most recent gateway used on this booking.
48 55 // `$booking->payment_gateway` is the *initial* method chosen at booking time
49 56 // (e.g. Pay Later), which is misleading when the customer later settled the
50 57 // balance via a different gateway (e.g. Stripe). Show the latest payment's
@@ -172,8 +179,26 @@
172 179 </div>
173 180 </div>
174 181 <?php endif; ?>
175 182
183 + <?php if ($show_payment_cancelled_notice) : ?>
184 + <div class="yatra-payment-cancelled-banner" role="status" aria-live="polite" style="margin: 16px 0; padding: 14px 18px; background: #fef3c7; border: 1px solid #fcd34d; border-left: 4px solid #d97706; border-radius: 8px; color: #92400e; display: flex; gap: 12px; align-items: flex-start;">
185 + <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="flex: 0 0 22px; width: 22px; height: 22px; margin-top: 1px;">
186 + <circle cx="12" cy="12" r="10"></circle>
187 + <line x1="12" y1="8" x2="12" y2="12"></line>
188 + <line x1="12" y1="16" x2="12.01" y2="16"></line>
189 + </svg>
190 + <div style="flex: 1; line-height: 1.45;">
191 + <strong style="display: block; margin-bottom: 2px;">
192 + <?php esc_html_e('Payment not completed.', 'yatra'); ?>
193 + </strong>
194 + <span>
195 + <?php esc_html_e('Your payment was cancelled and no charge was made. Your booking has been saved — you can complete payment anytime from your account.', 'yatra'); ?>
196 + </span>
197 + </div>
198 + </div>
199 + <?php endif; ?>
200 +
176 201 <?php
177 202 // Resolve featured image URL (handle attachment ID or direct URL).
178 203 // Falls back to the bundled trip-placeholder.svg so the confirmation
179 204 // card always renders with a visual on the left — never an empty
@@ -209,8 +234,45 @@
209 234 <div class="yatra-trip-info">
210 235 <h2 class="yatra-trip-name"><?php echo esc_html($booking->trip_title); ?></h2>
211 236
212 237 <?php if (!empty($booking->trip_average_rating) && $booking->trip_review_count >= 0) : ?>
238 + <?php
239 + // The confirmation page isn't a "booking page" (it has its
240 + // own route), so booking.css — which colours the rating
241 + // stars amber — is never enqueued here and the filled stars
242 + // fell back to the grey base colour. The rest of this page
243 + // is inline-styled, so rather than loading the whole
244 + // stylesheet (and risk restyling it) the rating rules are
245 + // scoped inline here, mirroring assets/css/booking.css.
246 + ?>
247 + <?php
248 + // IMPORTANT: these rules are deliberately scoped to
249 + // `.yatra-trip-rating .yatra-rating-stars .yatra-star*`
250 + // (specificity 0,3,0 / 0,4,1) and set `fill` directly on
251 + // the SVG — NOT just `color` + `fill="currentColor"`.
252 + // trip.css / booking.css define `.yatra-rating-stars
253 + // .yatra-star { color:#d1d5db }` (0,2,0) and colour the
254 + // "filled" state with a `.filled` (dot) class, not the
255 + // `-filled` (hyphen) class this markup uses. If either
256 + // stylesheet is present on the confirmation page, its
257 + // grey base out-specifies a plain `.yatra-star-filled`
258 + // and its amber rule never matches — so every star showed
259 + // grey even at 4.8. Winning on specificity + an explicit
260 + // fill makes the amber stick regardless of what's loaded.
261 + ?>
262 + <style>
263 + .yatra-trip-rating{display:flex;align-items:center;gap:12px;margin-bottom:12px}
264 + .yatra-trip-rating .yatra-rating-stars{display:inline-flex;gap:4px}
265 + .yatra-trip-rating .yatra-rating-stars .yatra-star{width:20px;height:20px;color:#e2e8f0;font-size:0;line-height:0}
266 + .yatra-trip-rating .yatra-rating-stars .yatra-star svg{width:100%;height:100%;display:block;fill:currentColor}
267 + .yatra-trip-rating .yatra-rating-stars .yatra-star-filled{color:#f59e0b}
268 + .yatra-trip-rating .yatra-rating-stars .yatra-star-filled svg{fill:#f59e0b}
269 + .yatra-trip-rating .yatra-rating-stars .yatra-star-half{position:relative;color:#e2e8f0}
270 + .yatra-trip-rating .yatra-rating-stars .yatra-star-half svg{fill:#e2e8f0}
271 + .yatra-trip-rating .yatra-rating-stars .yatra-star-half::after{content:"";position:absolute;top:0;left:0;bottom:0;width:50%;overflow:hidden;background:#f59e0b;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26'/%3E%3C/svg%3E") no-repeat left center / 200% 100%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26'/%3E%3C/svg%3E") no-repeat left center / 200% 100%}
272 + .yatra-trip-rating .yatra-rating-meta strong{color:#0f172a;margin-right:6px}
273 + .yatra-trip-rating .yatra-rating-meta span{color:#64748b;font-size:14px}
274 + </style>
213 275 <div class="yatra-trip-rating">
214 276 <div class="yatra-rating-stars">
215 277 <?php
216 278 // Shared with the reviews block and listing cards so every
@@ -245,9 +307,9 @@
245 307 </div>
246 308 <?php endif; ?>
247 309
248 310 <div class="yatra-trip-meta">
249 - <?php if (!empty($booking->duration_days)) : ?>
311 + <?php if (!empty($booking->duration_days) || !empty($booking->duration_hours)) : ?>
250 312 <span class="yatra-meta-item">
251 313 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
252 314 <circle cx="12" cy="12" r="10"></circle>
253 315 <polyline points="12 6 12 12 16 14"></polyline>
@@ -254,11 +316,21 @@
254 316 </svg>
255 317 <?php
256 318 $days = (int) ($booking->duration_days ?? 0);
257 319 $nights = (int) ($booking->duration_nights ?? 0);
320 + $hours = (int) ($booking->duration_hours ?? 0);
258 321
259 - if ($days > 0 && $nights > 0) {
322 + if ($hours > 0) {
323 + // Hour-based day tour: "8 Hours", not "1 Day".
260 324 printf(
325 + esc_html(
326 + /* translators: %d: number of hours. */
327 + _n('%d Hour', '%d Hours', $hours, 'yatra')
328 + ),
329 + $hours
330 + );
331 + } elseif ($days > 0 && $nights > 0) {
332 + printf(
261 333 /* translators: 1: number of days, 2: number of nights. */
262 334 esc_html__('%1$d Days / %2$d Nights', 'yatra'),
263 335 $days,
264 336 $nights
@@ -679,9 +751,9 @@
679 751 </div>
680 752
681 753 <div class="yatra-payment-method">
682 754 <span class="yatra-pm-label"><?php esc_html_e('Payment Method:', 'yatra'); ?></span>
683 - <span class="yatra-pm-value"><?php echo esc_html(ucwords(str_replace('_', ' ', (string) $display_payment_gateway))); ?></span>
755 + <span class="yatra-pm-value"><?php echo esc_html(yatra_payment_gateway_label((string) $display_payment_gateway)); ?></span>
684 756 </div>
685 757 </div>
686 758
687 759 <!-- Contact Info Card -->