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/Services/TripListingService.php +44 -27 3.0.2.9 → 3.0.16 View file →
@@ -189,8 +189,18 @@
189 189 $filters['duration'] = $preset;
190 190 }
191 191 }
192 192
193 + // Availability date: keep only a valid Y-m-d calendar date. Trips are
194 + // then filtered to those with a departure on that date (see
195 + // TripRepository::findWithFilters).
196 + if (!empty($params['available_date']) && is_string($params['available_date'])) {
197 + $date = \Yatra\Helpers\TripListingFilterBuilder::normalizeAvailableDate($params['available_date']);
198 + if ($date !== '') {
199 + $filters['available_date'] = $date;
200 + }
201 + }
202 +
193 203 // Horizontal search "budget" presets (min-max or min+) → price range when explicit prices not set
194 204 if (
195 205 empty($filters['price_min']) && empty($filters['price_max'])
196 206 && !empty($params['budget']) && is_string($params['budget'])
@@ -371,27 +381,36 @@
371 381 }
372 382
373 383 // Get filtered trips from repository
374 384 $tripResult = $this->tripRepository->findWithFilters($filters, $page, $perPage);
375 -
376 - // Load reviews for each trip (same approach as SingleTripController)
377 - $tripsWithReviews = [];
385 +
386 + // average_rating + review_count are aggregated in the listing
387 + // SQL ({@see TripRepository::findWithFilters()} — `AVG(r.rating)`
388 + // / `COUNT(DISTINCT r.id)` over the LEFT-JOINed approved-reviews
389 + // rows), so the listing card has everything it needs to render
390 + // the star block without an extra round-trip per trip.
391 + //
392 + // A previous version called `findApprovedByTripId(LIMIT 10)`
393 + // here for every displayed trip — an N+1 with a JOIN to
394 + // wp_users — and recomputed the average from the truncated
395 + // list. That was both slow and *less accurate* than the SQL
396 + // aggregate (capped at 10 reviews per trip). Drop it.
397 + //
398 + // `reviews` stays present-but-empty for templates that probe
399 + // the property defensively (`is_array($trip->reviews)`).
378 400 foreach ($tripResult['trips'] as $trip) {
379 - // Load reviews for this trip
380 - $trip->reviews = $this->getReviewsForTrip((int) $trip->id);
381 -
382 - // Calculate rating stats (same as SingleTripController)
383 - $trip->average_rating = $this->calculateAverageRating($trip->reviews);
384 - $trip->review_count = count($trip->reviews);
385 -
386 - $tripsWithReviews[] = $trip;
401 + if (!isset($trip->reviews)) {
402 + $trip->reviews = [];
403 + }
404 + $trip->review_count = (int) ($trip->review_count ?? 0);
405 + $trip->average_rating = (float) ($trip->average_rating ?? 0);
387 406 }
388 -
407 +
389 408 // Get filter options for UI (cached separately)
390 409 $filterOptions = $this->getFilterOptions();
391 -
410 +
392 411 return [
393 - 'trips' => $tripsWithReviews,
412 + 'trips' => $tripResult['trips'],
394 413 'total' => $tripResult['total'],
395 414 'pages' => $tripResult['pages'],
396 415 'page' => $tripResult['page'],
397 416 'per_page' => $tripResult['per_page'],
@@ -540,24 +559,22 @@
540 559
541 560 $filters = [$taxonomyType => $slug];
542 561
543 562 $result = $this->tripRepository->findWithFilters($filters, 1, $limit);
544 -
545 - // Load reviews for each trip (same approach as getFilteredTrips)
546 - $tripsWithReviews = [];
563 +
564 + // Rating + count come from the listing SQL aggregate; see
565 + // {@see self::buildTripListingResult()} for why we don't reload
566 + // approved reviews per trip here (was an N+1).
547 567 foreach ($result['trips'] as $trip) {
548 - // Load reviews for this trip
549 - $trip->reviews = $this->getReviewsForTrip((int) $trip->id);
550 -
551 - // Calculate rating stats (same as SingleTripController)
552 - $trip->average_rating = $this->calculateAverageRating($trip->reviews);
553 - $trip->review_count = count($trip->reviews);
554 -
555 - $tripsWithReviews[] = $trip;
568 + if (!isset($trip->reviews)) {
569 + $trip->reviews = [];
570 + }
571 + $trip->review_count = (int) ($trip->review_count ?? 0);
572 + $trip->average_rating = (float) ($trip->average_rating ?? 0);
556 573 }
557 -
574 +
558 575 return [
559 - 'trips' => $tripsWithReviews,
576 + 'trips' => $result['trips'],
560 577 'total' => $result['total']
561 578 ];
562 579 }
563 580