auditionCache = $auditionCache; $this->entryCache = $entryCache; } /** * Cache all scoring guides * @return \Illuminate\Database\Eloquent\Collection */ public function getScoringGuides(): \Illuminate\Database\Eloquent\Collection { $cacheKey = 'scoringGuides'; return Cache::remember($cacheKey, 3600, fn() => ScoringGuide::with('subscores')->get()); } /** * Retrieve a single scoring guide from the cache * @param $id * @return ScoringGuide */ public function getScoringGuide($id): ScoringGuide { return $this->getScoringGuides()->firstWhere('id', $id); } /** * Clear the scoring guide cache * @return void */ public function clearScoringGuideCache(): void { Cache::forget('scoringGuides'); } /** * Get final scores array for the requested entry. The first element is the total score. The following elements are sums * of each subscore in tiebreaker order * @param Entry $entry * @return array */ public function entryTotalScores(Entry $entry) { $cacheKey = 'entry' . $entry->id . 'totalScores'; return Cache::remember($cacheKey, 3600, fn() => $this->calculateFinalScoreArray($entry->audition->scoring_guide_id, $entry->scoreSheets)); } /** * Calculate and cache scores for all entries for the provided audition ID * @param $auditionId * @return void */ public function calculateScoresForAudition($auditionId) { $audition = $this->auditionCache->getAudition($auditionId); $scoringGuideId = $audition->scoring_guide_id; $entries = Entry::where('audition_id',$auditionId)->with('scoreSheets')->get(); foreach ($entries as $entry) { $cacheKey = 'entry' . $entry->id . 'totalScores'; if (Cache::has($cacheKey)) continue; $thisTotalScore = $this->calculateFinalScoreArray($scoringGuideId, $entry->scoreSheets); Cache::put($cacheKey,$thisTotalScore,3600); } } /** * Calculate final score using teh provided scoring guide and score sheets. Returns an array of scores * The first element is the total score. The following elements are the sum of each subscore * in tiebreaker order. * @param $scoringGuideId * @param array|Collection $scoreSheets * @return array */ public function calculateFinalScoreArray($scoringGuideId, array|Collection $scoreSheets): array { $sg = $this->getScoringGuide($scoringGuideId); // TODO cache the scoring guides with their subscores $subscores = $sg->subscores->sortBy('tiebreak_order'); // Init final scores array $finalScoresArray = []; foreach ($subscores as $subscore) { $finalScoresArray[$subscore->id] = 0; } foreach($scoreSheets as $sheet) { foreach ($sheet->subscores as $ss) { $finalScoresArray[$ss['subscore_id']] += $ss['score']; } } // calculate weighted final score $totalScore = 0; $totalWeight = 0; foreach ($subscores as $subscore) { $totalScore += ($finalScoresArray[$subscore->id] * $subscore->weight); $totalWeight += $subscore->weight; } $totalScore = ($totalScore / $totalWeight); array_unshift($finalScoresArray,$totalScore); return $finalScoresArray; } }