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/Repositories/TripRepository.php +56 -1 3.0.11 → 3.0.16 View file →
@@ -18,8 +18,9 @@
18 18 use Yatra\Utils\Cache;
19 19 use Yatra\Utils\QueryCache;
20 20 use Yatra\Database\Tables\TripAvailabilityDatesTable;
21 21 use Yatra\Database\Tables\TripAvailabilityRulesTable;
22 +use Yatra\Database\Tables\DeparturesTable;
22 23 use Yatra\Constants\ClassificationTypes;
23 24
24 25 /**
25 26 * Trip Repository
@@ -270,8 +271,9 @@
270 271 * Create trip row; {@see afterWrite} handles cache; fires action `yatra_trip_created` once per insert.
271 272 */
272 273 public function create(array $data): int
273 274 {
275 + $data = $this->dropUnsupportedDurationHours($data);
274 276 $id = parent::create($data);
275 277 do_action('yatra_trip_created', $id);
276 278
277 279 return $id;
@@ -277,12 +279,32 @@
277 279 return $id;
278 280 }
279 281
280 282 /**
283 + * Defensive: if the `duration_hours` column is somehow missing (a failed or
284 + * pending column-add migration on a restrictive host), drop it from the
285 + * write set so a normal trip save still succeeds instead of erroring on an
286 + * unknown column. The hour-based feature simply stays off until the column
287 + * exists — it never breaks saving.
288 + *
289 + * @param array<string, mixed> $data
290 + * @return array<string, mixed>
291 + */
292 + protected function dropUnsupportedDurationHours(array $data): array
293 + {
294 + if (array_key_exists('duration_hours', $data) && !$this->tripTableHasColumn('duration_hours')) {
295 + unset($data['duration_hours']);
296 + }
297 +
298 + return $data;
299 + }
300 +
301 + /**
281 302 * Override update method to provide proper field formats
282 303 */
283 304 public function update(int $id, array $data): bool
284 305 {
306 + $data = $this->dropUnsupportedDurationHours($data);
285 307 $data = $this->sanitizeData($data);
286 308 $data['updated_at'] = current_time('mysql');
287 309
288 310 // Build format array based on field types
@@ -400,8 +422,21 @@
400 422 return self::$tripColumnExistsCache[$column];
401 423 }
402 424
403 425 /**
426 + * Public, cached column-existence check for the trips table.
427 + *
428 + * Lets raw SELECTs outside this repository (booking confirmation join,
429 + * similar-trips query) add columns introduced by later upgrades — e.g.
430 + * `duration_hours` — without failing on an install whose ALTER has not
431 + * run yet (see InstallerService::maybeAddTripDurationHoursColumn()).
432 + */
433 + public function hasTripColumn(string $column): bool
434 + {
435 + return $this->tripTableHasColumn($column);
436 + }
437 +
438 + /**
404 439 * SQL expression for trip "current" list price (matches TripPricingService::resolveRegularCurrentPrice).
405 440 */
406 441 protected function sqlTripEffectiveListPrice(): string
407 442 {
@@ -810,9 +845,29 @@
810 845 if (!empty($filters['duration_max']) && $filters['duration_max'] > 0) {
811 846 $wheres[] = "CAST(t.duration_days AS UNSIGNED) <= %d";
812 847 $params[] = $filters['duration_max'];
813 848 }
814 -
849 +
850 + // Availability date filter ("available from this date onward"): keep only
851 + // trips that have a departure starting ON OR AFTER the selected date, so
852 + // a customer who picks a date sees every trip they could still travel on
853 + // from then. A departure matches when its effective start date (the
854 + // explicit start_date, else the single `date`) is >= the chosen day and
855 + // it has not been cancelled — the date bound alone excludes past dates
856 + // when the picker's min=today is respected, so no reliance on a possibly
857 + // stale 'past' status. Clause + param are appended together so the WHERE
858 + // ordering stays in sync with $params (see the count/main queries).
859 + if (!empty($filters['available_date'])) {
860 + $departures_table = DeparturesTable::getTableName();
861 + $wheres[] = "EXISTS (
862 + SELECT 1 FROM {$departures_table} yd
863 + WHERE yd.trip_id = t.id
864 + AND COALESCE(NULLIF(yd.start_date, '0000-00-00'), yd.date) >= %s
865 + AND yd.status <> 'cancelled'
866 + )";
867 + $params[] = $filters['available_date'];
868 + }
869 +
815 870 // Rating filter
816 871 if (!empty($filters['rating_min']) && $filters['rating_min'] > 0) {
817 872 $having_clauses[] = "AVG(r.rating) >= %f";
818 873 $rating_params[] = $filters['rating_min'];