| @@ -44,19 +44,43 @@ | ||
| 44 | 44 | // Get all trip data using Trip model getter methods |
| 45 | 45 | $title = $trip->getTitle(); |
| 46 | 46 | $duration = $trip->getDuration(); |
| 47 | 47 | $difficulty = $trip->getDifficulty(); |
| 48 | -// Calculate rating directly from reviews array (working correctly) | |
| 48 | + | |
| 49 | +// Prefer the SQL-aggregated average_rating / review_count that the | |
| 50 | +// repository attaches to every listing row (AVG(r.rating) / | |
| 51 | +// COUNT(DISTINCT r.id) over approved reviews). Falling back to a PHP | |
| 52 | +// recount over `$trip->reviews` is only there for legacy callers that | |
| 53 | +// hand-populate the reviews array without the aggregates. | |
| 54 | +// | |
| 55 | +// Earlier this block ALWAYS recounted from `$trip->reviews` — which | |
| 56 | +// (a) forced the listing service into an N+1 of `findApprovedByTripId` | |
| 57 | +// per displayed trip just to feed the recount, and (b) silently | |
| 58 | +// rendered 0 stars on shortcode/block paths that already pass | |
| 59 | +// aggregates with `reviews => []`. | |
| 60 | +$sql_avg = isset($trip->average_rating) ? (float) $trip->average_rating : null; | |
| 61 | +if ($sql_avg === null && isset($trip->avg_rating)) { | |
| 62 | + $sql_avg = (float) $trip->avg_rating; | |
| 63 | +} | |
| 64 | +$sql_count = isset($trip->review_count) ? (int) $trip->review_count : null; | |
| 65 | +if ($sql_count === null && isset($trip->reviews_count)) { | |
| 66 | + $sql_count = (int) $trip->reviews_count; | |
| 67 | +} | |
| 68 | + | |
| 49 | 69 | $reviews = $trip->reviews ?? []; |
| 50 | -$review_count = count($reviews); | |
| 51 | -$average_rating = 0; | |
| 52 | - | |
| 53 | -if ($review_count > 0) { | |
| 54 | - $total_rating = 0; | |
| 55 | - foreach ($reviews as $review) { | |
| 56 | - $total_rating += (float) ($review->rating ?? 0); | |
| 70 | +if ($sql_avg !== null || $sql_count !== null) { | |
| 71 | + $average_rating = $sql_avg !== null ? round($sql_avg, 1) : 0; | |
| 72 | + $review_count = $sql_count !== null ? $sql_count : count($reviews); | |
| 73 | +} else { | |
| 74 | + $review_count = count($reviews); | |
| 75 | + $average_rating = 0; | |
| 76 | + if ($review_count > 0) { | |
| 77 | + $total_rating = 0; | |
| 78 | + foreach ($reviews as $review) { | |
| 79 | + $total_rating += (float) ($review->rating ?? 0); | |
| 80 | + } | |
| 81 | + $average_rating = round($total_rating / $review_count, 1); | |
| 57 | 82 | } |
| 58 | - $average_rating = round($total_rating / $review_count, 1); | |
| 59 | 83 | } |
| 60 | 84 | |
| 61 | 85 | $rating = [ |
| 62 | 86 | 'average_rating' => $average_rating, |