PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.7
Yatra – Travel Booking & Tour Operator Software v3.0.2.7
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 / app / Core / Routing / PrettyRouteMatcher.php

PrettyRouteMatcher.php in Yatra – Travel Booking & Tour Operator Software 3.0.2.7, at app/Core/Routing/PrettyRouteMatcher.php

233 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Yatra\Core\Routing;
6
7 use Yatra\Services\SettingsService;
8
9 /**
10 * Matches request paths served as path-based (pretty) URLs.
11 * Used for: plain-permalink mode 404 when path looks like a plugin pretty URL, and by {@see Router}.
12 */
13 final class PrettyRouteMatcher
14 {
15 /**
16 * @return array<string, mixed>|null Same shape as {@see Router} route_data
17 */
18 public static function match(string $path): ?array
19 {
20 $path = trim($path, '/');
21
22 // 1. Email verification
23 if (preg_match('/^yatra-verify-email\/([a-zA-Z0-9_-]+)$/', $path, $matches)) {
24 return [
25 'type' => 'email_verification',
26 'token' => $matches[1],
27 ];
28 }
29
30 // 2. Dedicated login slug (rewrite: ^login/?$)
31 if ($path === 'login') {
32 return [
33 'type' => 'login',
34 'page' => 'main',
35 'base' => 'login',
36 ];
37 }
38
39 // 3. Account page
40 $account_base = SettingsService::getAccountBase();
41 $account_route = self::matchAccountRoute($path, $account_base);
42 if ($account_route !== null) {
43 return $account_route;
44 }
45
46 // 4. Trip archive pagination: {trip_base}/page/{n}
47 $trip_base = SettingsService::getTripBase();
48 if (preg_match('/^' . preg_quote($trip_base, '/') . '\/page\/(\d+)\/?$/', $path, $matches)) {
49 return [
50 'type' => 'listing',
51 'listing_type' => 'trip',
52 'base' => $trip_base,
53 'paged' => max(1, (int) $matches[1]),
54 ];
55 }
56
57 // 5. Single trip
58 if (preg_match('/^' . preg_quote($trip_base, '/') . '\/([^\/]+)\/?$/', $path, $matches)) {
59 if ($matches[1] !== 'page') {
60 return [
61 'type' => 'trip',
62 'slug' => $matches[1],
63 'base' => $trip_base,
64 ];
65 }
66 }
67
68 // 6. Taxonomy (pagination before single slug)
69 $bases = [
70 'destination' => SettingsService::getString('destination_base', 'destination'),
71 'activity' => SettingsService::getString('activity_base', 'activity'),
72 'category' => SettingsService::getString('trip_category_base', 'trip-category'),
73 ];
74
75 foreach ($bases as $type => $base) {
76 if (preg_match('/^' . preg_quote($base, '/') . '\/([^\/]+)\/page\/(\d+)\/?$/', $path, $matches)) {
77 return [
78 'type' => 'taxonomy',
79 'taxonomy_type' => $type,
80 'slug' => $matches[1],
81 'base' => $base,
82 'paged' => max(1, (int) $matches[2]),
83 ];
84 }
85 }
86
87 foreach ($bases as $type => $base) {
88 if (preg_match('/^' . preg_quote($base, '/') . '\/([^\/]+)\/?$/', $path, $matches)) {
89 return [
90 'type' => 'taxonomy',
91 'taxonomy_type' => $type,
92 'slug' => $matches[1],
93 'base' => $base,
94 ];
95 }
96 }
97
98 // 7. Listing roots
99 foreach ($bases as $type => $base) {
100 if ($path === $base) {
101 return [
102 'type' => 'listing',
103 'listing_type' => $type,
104 'base' => $base,
105 ];
106 }
107 }
108
109 if ($path === $trip_base) {
110 return [
111 'type' => 'listing',
112 'listing_type' => 'trip',
113 'base' => $trip_base,
114 ];
115 }
116
117 // 8. Booking confirmation (pageless: /{booking_base}/confirmation/{ref}/ + legacy slug)
118 $booking_base = SettingsService::getBookingBase();
119 if (preg_match('/^' . preg_quote($booking_base, '/') . '\/confirmation\/([a-zA-Z0-9_-]+)$/', $path, $matches)) {
120 return [
121 'type' => 'booking_confirmation',
122 'confirmation_id' => $matches[1],
123 ];
124 }
125
126 if (preg_match('/^booking-confirmation\/([a-zA-Z0-9_-]+)$/', $path, $matches)) {
127 return [
128 'type' => 'booking_confirmation',
129 'confirmation_id' => $matches[1],
130 ];
131 }
132
133 // 9. Remaining checkout (rewrite) and legacy checkout/ path
134 if (preg_match('/^remaining-checkout\/([a-zA-Z0-9_-]+)$/', $path, $matches)) {
135 return [
136 'type' => 'checkout',
137 'token' => $matches[1],
138 ];
139 }
140
141 if (preg_match('/^checkout\/([a-zA-Z0-9_-]+)$/', $path, $matches)) {
142 return [
143 'type' => 'checkout',
144 'token' => $matches[1],
145 ];
146 }
147
148 // 10. Booking hub / trip booking
149 if (!SettingsService::useCustomBookingPage()) {
150 if (preg_match('/^' . preg_quote($booking_base, '/') . '\/([^\/]+)\/?$/', $path, $matches)) {
151 return [
152 'type' => 'booking',
153 'page' => 'main',
154 'base' => $booking_base,
155 'trip' => $matches[1],
156 ];
157 }
158 if ($path === $booking_base) {
159 return [
160 'type' => 'booking',
161 'page' => 'main',
162 'base' => $booking_base,
163 ];
164 }
165 }
166
167 return null;
168 }
169
170 /**
171 * @return array{type: string, page: string, base: string}|null
172 */
173 private static function matchAccountRoute(string $path, string $account_base): ?array
174 {
175 $path_trim = rtrim($path, '/');
176 $base_trim = rtrim($account_base, '/');
177
178 if ($path_trim === $base_trim) {
179 $tab = isset($_GET['tab']) ? sanitize_key((string) $_GET['tab']) : '';
180
181 return [
182 'type' => 'account',
183 'page' => self::accountQueryTabToPage($tab),
184 'base' => $account_base,
185 ];
186 }
187
188 $quoted = preg_quote($account_base, '/');
189 if (preg_match('/^' . $quoted . '\/([^\/]+)/', $path, $m)) {
190 $page = self::accountPathSegmentToPage($m[1]);
191 if ($page === null) {
192 return null;
193 }
194
195 return [
196 'type' => 'account',
197 'page' => $page,
198 'base' => $account_base,
199 ];
200 }
201
202 return null;
203 }
204
205 private static function accountQueryTabToPage(string $tab): string
206 {
207 $allowed = ['dashboard', 'bookings', 'payments', 'documents', 'profile', 'saved-trips'];
208 if ($tab === '' || !in_array($tab, $allowed, true)) {
209 return 'dashboard';
210 }
211
212 return $tab;
213 }
214
215 private static function accountPathSegmentToPage(string $segment): ?string
216 {
217 $segment = sanitize_title($segment);
218 $map = [
219 'dashboard' => 'dashboard',
220 'profile' => 'profile',
221 'bookings' => 'bookings',
222 'payments' => 'payments',
223 'documents' => 'documents',
224 'support' => 'dashboard',
225 'saved-trips' => 'saved-trips',
226 'wishlist' => 'saved-trips',
227 'settings' => 'profile',
228 ];
229
230 return $map[$segment] ?? null;
231 }
232 }
233