PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.15
Yatra – Travel Booking & Tour Operator Software v3.0.15
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 2.0.10 All 83 releases
yatra / app / Repositories / BookingDepartureRepository.php

BookingDepartureRepository.php in Yatra – Travel Booking & Tour Operator Software 3.0.15, at app/Repositories/BookingDepartureRepository.php

331 lines 9.7 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\Repositories;
6
7 use Yatra\Database\Tables\BookingDeparturesTable;
8
9 /**
10 * Booking Departure Repository
11 * Manages the relationship between bookings and departures
12 *
13 * Table: wp_yatra_booking_departures
14 */
15 class BookingDepartureRepository extends BaseRepository
16 {
17 /**
18 * Check if booking_departures table exists
19 */
20 public function tableExists(): bool
21 {
22 $table = $this->getTableName();
23 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
24 $exists = $this->wpdb->get_var($this->wpdb->prepare("SHOW TABLES LIKE %s", $table));
25 return $exists === $table;
26 }
27
28 /**
29 * Create booking_departures table if missing
30 */
31 private function createTable(): void
32 {
33 if (!function_exists('dbDelta')) {
34 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
35 }
36 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
37 dbDelta(\Yatra\Database\Tables\BookingDeparturesTable::getSchema());
38 }
39
40 /**
41 * Get table name
42 */
43 protected function getTableName(): string
44 {
45 return BookingDeparturesTable::getTableName();
46 }
47
48 /**
49 * Link a booking to a departure
50 *
51 * @param int $bookingId Booking ID
52 * @param int $departureId Departure ID
53 * @return bool Success
54 */
55 public function link(int $bookingId, int $departureId): bool
56 {
57 $table = $this->getTableName();
58
59 // Ensure table exists and detect optional columns (older installs may differ).
60 $columns = $this->wpdb->get_col("DESCRIBE {$table}") ?: [];
61 $hasTravelDate = in_array('travel_date', $columns, true);
62 $hasDepartureTime = in_array('departure_time', $columns, true);
63
64 // Check if relationship already exists
65 $existing = $this->wpdb->get_var($this->wpdb->prepare(
66 "SELECT id FROM `{$table}` WHERE booking_id = %d AND departure_id = %d LIMIT 1",
67 $bookingId,
68 $departureId
69 ));
70
71 if ($existing) {
72 // Already linked; best-effort backfill date/time if the columns exist and are empty.
73 if ($hasTravelDate || $hasDepartureTime) {
74 $update = [];
75
76 $booking = (new BookingRepository())->find($bookingId);
77 $departure = (new DepartureRepository())->find($departureId);
78
79 $travelDate = '';
80 if (is_object($departure)) {
81 $travelDate = (string) ($departure->start_date ?? $departure->date ?? '');
82 }
83 if ($travelDate === '' && is_object($booking)) {
84 $travelDate = (string) ($booking->travel_date ?? $booking->start_date ?? '');
85 }
86
87 $time = '';
88 if (is_object($departure)) {
89 $time = (string) ($departure->time ?? '');
90 }
91 if ($time !== '') {
92 $ts = strtotime($time);
93 $time = $ts !== false ? date('H:i:s', $ts) : $time;
94 }
95
96 if ($hasTravelDate && $travelDate !== '') {
97 $update['travel_date'] = $travelDate;
98 }
99 if ($hasDepartureTime && $time !== '' && $time !== '00:00:00') {
100 $update['departure_time'] = $time;
101 }
102
103 if (!empty($update)) {
104 $this->wpdb->update($table, $update, ['id' => (int) $existing]);
105 }
106 }
107
108 return true;
109 }
110
111 $booking = (new BookingRepository())->find($bookingId);
112 $departure = (new DepartureRepository())->find($departureId);
113
114 $travelDate = '';
115 if (is_object($departure)) {
116 $travelDate = (string) ($departure->start_date ?? $departure->date ?? '');
117 }
118 if ($travelDate === '' && is_object($booking)) {
119 $travelDate = (string) ($booking->travel_date ?? $booking->start_date ?? '');
120 }
121
122 $time = '';
123 if (is_object($departure)) {
124 $time = (string) ($departure->time ?? '');
125 }
126 if ($time !== '') {
127 $ts = strtotime($time);
128 $time = $ts !== false ? date('H:i:s', $ts) : $time;
129 }
130
131 // Build insert payload compatible with both new and legacy schemas.
132 $insert = [
133 'booking_id' => $bookingId,
134 'departure_id' => $departureId,
135 'created_at' => current_time('mysql'),
136 ];
137 $formats = ['%d', '%d', '%s'];
138
139 if ($hasTravelDate) {
140 // travel_date is NOT NULL in the new schema; fail safe to booking travel_date.
141 if ($travelDate === '' && is_object($booking) && !empty($booking->travel_date)) {
142 $travelDate = (string) $booking->travel_date;
143 }
144 if ($travelDate === '') {
145 // If we can't infer a date, don't attempt insert (would violate NOT NULL in new schema).
146 return false;
147 }
148 $insert['travel_date'] = $travelDate;
149 $formats[] = '%s';
150 }
151 if ($hasDepartureTime) {
152 $insert['departure_time'] = ($time !== '' && $time !== '00:00:00') ? $time : null;
153 $formats[] = '%s';
154 }
155
156 $result = $this->wpdb->insert(
157 $table,
158 $insert,
159 $formats
160 );
161
162 return $result !== false;
163 }
164
165 /**
166 * Unlink a booking from a departure
167 *
168 * @param int $bookingId Booking ID
169 * @param int|null $departureId Optional departure ID (if null, removes all links for booking)
170 * @return bool Success
171 */
172 public function unlink(int $bookingId, ?int $departureId = null): bool
173 {
174 $table = $this->getTableName();
175
176 if ($departureId !== null) {
177 // Delete specific link
178 $result = $this->wpdb->delete(
179 $table,
180 [
181 'booking_id' => $bookingId,
182 'departure_id' => $departureId,
183 ],
184 ['%d', '%d']
185 );
186 } else {
187 // Delete all links for this booking
188 $result = $this->wpdb->delete(
189 $table,
190 ['booking_id' => $bookingId],
191 ['%d']
192 );
193 }
194
195 return $result !== false;
196 }
197
198 /**
199 * Get departure ID for a booking
200 *
201 * @param int $bookingId Booking ID
202 * @return int|null Departure ID or null if not linked
203 */
204 public function getDepartureIdForBooking(int $bookingId): ?int
205 {
206 $table = $this->getTableName();
207
208 $departureId = $this->wpdb->get_var($this->wpdb->prepare(
209 "SELECT departure_id FROM `{$table}` WHERE booking_id = %d LIMIT 1",
210 $bookingId
211 ));
212
213 return $departureId ? (int) $departureId : null;
214 }
215
216 /**
217 * Get all booking IDs for a departure
218 *
219 * @param int $departureId Departure ID
220 * @return array Array of booking IDs
221 */
222 public function getBookingIdsForDeparture(int $departureId): array
223 {
224 $table = $this->getTableName();
225
226 $rows = $this->wpdb->get_col($this->wpdb->prepare(
227 "SELECT booking_id FROM `{$table}` WHERE departure_id = %d",
228 $departureId
229 ));
230
231 $ids = [];
232 foreach ($rows as $id) {
233 $id = (int) $id;
234 if ($id > 0) {
235 $ids[] = $id;
236 }
237 }
238
239 return $ids;
240 }
241
242 /**
243 * Count bookings for a departure
244 *
245 * @param int $departureId Departure ID
246 * @return int Count
247 */
248 public function countBookingsForDeparture(int $departureId): int
249 {
250 $table = $this->getTableName();
251
252 $count = $this->wpdb->get_var($this->wpdb->prepare(
253 "SELECT COUNT(*) FROM `{$table}` WHERE departure_id = %d",
254 $departureId
255 ));
256
257 return (int) $count;
258 }
259
260 /**
261 * Update departure for a booking (handle date change)
262 *
263 * @param int $bookingId Booking ID
264 * @param int $newDepartureId New departure ID
265 * @return int|null Old departure ID (if existed)
266 */
267 public function updateDepartureForBooking(int $bookingId, int $newDepartureId): ?int
268 {
269 if (!$this->tableExists()) {
270 $this->createTable(); // Ensure table exists before trying to update
271 }
272
273 $table = $this->getTableName();
274
275 // Get old departure ID
276 $oldDepartureId = $this->getDepartureIdForBooking($bookingId);
277
278 // Remove old link
279 if ($oldDepartureId) {
280 $this->unlink($bookingId, $oldDepartureId);
281 }
282
283 // Create new link
284 $this->link($bookingId, $newDepartureId);
285
286 return $oldDepartureId;
287 }
288
289 /**
290 * Delete all links for a booking (when booking is deleted)
291 *
292 * @param int $bookingId Booking ID
293 * @return bool Success
294 */
295 public function deleteByBookingId(int $bookingId): bool
296 {
297 if (!$this->tableExists()) {
298 return false;
299 }
300
301 $table = $this->getTableName();
302
303 $result = $this->wpdb->delete(
304 $table,
305 ['booking_id' => $bookingId],
306 ['%d']
307 );
308
309 return $result !== false;
310 }
311
312 /**
313 * Delete all booking relationships for a departure
314 *
315 * @param int $departureId Departure ID
316 * @return bool Success
317 */
318 public function deleteByDepartureId(int $departureId): bool
319 {
320 $table = $this->getTableName();
321
322 $result = $this->wpdb->delete(
323 $table,
324 ['departure_id' => $departureId],
325 ['%d']
326 );
327
328 return $result !== false;
329 }
330 }
331