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 | app/Core/Handlers/BookingConfirmationPageHandler.php +48 -30 3.0.2.6 → 3.0.16 View file →
@@ -29,30 +29,22 @@
29 29 if (!$booking) {
30 30 return false;
31 31 }
32 32
33 - // Prevent 404 handling
34 - $this->prevent404();
33 + // Configure $wp_query + virtual WP_Post so FSE block themes don't fall back to 404.html.
34 + $this->setupPageEnvironment('singular', [
35 + 'title' => __('Booking Confirmation', 'yatra'),
36 + // Keep the virtual post ID at 0 (like the account/login/booking
37 + // handlers). Using the booking row id made get_queried_object_id()
38 + // collide with a real wp_posts row of the same id, so SEO plugins /
39 + // WordPress emitted THAT page's title, description and OG tags on the
40 + // confirmation page. The booking is read from the `yatra_booking`
41 + // global, so no queried-object id is needed here.
42 + 'object_id' => 0,
43 + 'post_type' => 'page',
44 + 'post_name' => $confirmation_id,
45 + ]);
35 46
36 - // Load trip attributes for booking confirmation display
37 - if ($booking && !empty($booking->trip_id)) {
38 - try {
39 - $singleTripController = new \Yatra\Controllers\SingleTripController();
40 - // Use reflection to access private method
41 - $reflection = new \ReflectionClass($singleTripController);
42 - $method = $reflection->getMethod('getTripAttributes');
43 - $method->setAccessible(true);
44 - $attributes = $method->invoke($singleTripController, (int) $booking->trip_id);
45 -
46 - // Create a simple list of attribute names for tag display
47 - $booking->trip_attributes_list = array_map(function($attr) {
48 - return $attr['name'];
49 - }, $attributes);
50 - } catch (\Throwable $e) {
51 - $booking->trip_attributes_list = [];
52 - }
53 - }
54 -
55 47 // Set up global booking object
56 48 $this->setGlobal('yatra_booking', $booking);
57 49
58 50 // Set up query vars for backward compatibility
@@ -60,18 +52,44 @@
60 52 'yatra_booking_confirmation' => $confirmation_id,
61 53 'yatra_booking' => $booking,
62 54 ]);
63 55
64 - // Load the booking confirmation template
65 - $template_path = YATRA_PLUGIN_PATH . 'templates/booking-confirmation.php';
56 + // Ensure the payment gateways are registered before the template renders.
57 + // Gateways attach their confirmation-page hooks (e.g. Bank Transfer's
58 + // `yatra_booking_confirmation_after_details` renderer) in their
59 + // constructors, which only run once the registry is built. Without this,
60 + // the confirmation page fires the hook with no gateway listening, so the
61 + // bank-transfer account details never appear.
62 + if (class_exists('\\Yatra\\PaymentGateways\\PaymentGatewayRegistry')) {
63 + \Yatra\PaymentGateways\PaymentGatewayRegistry::getInstance();
64 + }
66 65
67 - if (!file_exists($template_path)) {
68 - $this->logError("Booking confirmation template not found: {$template_path}");
69 - return false;
66 + // Process a PayPal return before the template renders. PayPal redirects
67 + // the buyer back here with `?paypal=success` (a param only PayPal sets),
68 + // so this runs only on a genuine PayPal return and affects nothing else.
69 + // For Advanced mode it captures the approved order and confirms the
70 + // booking; for Simple mode it is a no-op (the IPN webhook confirms).
71 + // Idempotency is guaranteed by the gateway (paid-guard + transaction-id).
72 + if (isset($_GET['paypal']) && sanitize_key((string) $_GET['paypal']) === 'success'
73 + && class_exists('\\Yatra\\PaymentGateways\\PaymentGatewayRegistry')) {
74 + $paypal = \Yatra\PaymentGateways\PaymentGatewayRegistry::getInstance()->get('paypal');
75 + if ($paypal && method_exists($paypal, 'handlePaymentReturn')) {
76 + try {
77 + $paypal->handlePaymentReturn($booking, $bookingRepo);
78 + $reloaded = $bookingRepo->findByConfirmationSegment($confirmation_id);
79 + if ($reloaded) {
80 + $booking = $reloaded;
81 + $this->setGlobal('yatra_booking', $booking);
82 + $this->setQueryVars([
83 + 'yatra_booking_confirmation' => $confirmation_id,
84 + 'yatra_booking' => $booking,
85 + ]);
86 + }
87 + } catch (\Throwable $e) {
88 + // Best-effort: the page still renders; the webhook can reconcile.
89 + }
90 + }
70 91 }
71 92
72 - include $template_path;
73 - $this->exit();
74 -
75 - return true;
93 + return $this->selectTemplate('booking-confirmation', null, 'booking-confirmation');
76 94 }
77 95 }