*/ class QuizRepository extends ServiceEntityRepository { public function __construct(ManagerRegistry $registry, private readonly LoggerInterface $logger) { parent::__construct($registry, Quiz::class); } /** @throws ErrorClearingQuizException */ public function clearQuiz(Quiz $quiz): void { $em = $this->getEntityManager(); $em->beginTransaction(); try { $em->createQuery(<<setParameter('quiz', $quiz) ->execute(); $em->createQuery(<<setParameter('quiz', $quiz) ->execute(); $em->createQuery(<<setParameter('quiz', $quiz) ->execute(); } // @codeCoverageIgnoreStart catch (\Throwable $throwable) { $this->logger->error($throwable->getMessage()); $em->rollback(); throw new ErrorClearingQuizException(message: $throwable->getMessage(), code: $throwable->getCode(), previous: $throwable); } // @codeCoverageIgnoreEnd $em->commit(); } public function deleteQuiz(Quiz $quiz): void { $this->getEntityManager()->remove($quiz); $this->getEntityManager()->flush(); } /** * @throws DatetimeException * * @return list */ public function getScores(Quiz $quiz): array { $result = $this->getEntityManager()->createQuery(<<setParameter('quiz', $quiz)->getResult(); return array_map(static function (array $row): Result { \assert($row['start_time'] instanceof \DateTimeImmutable); return new Result( id: $row['id'], name: $row['name'], correct: (int) $row['correct'], corrections: $row['corrections'], penaltySeconds: $row['penaltySeconds'], time: $row['start_time']->diff(new DateTimeImmutable($row['end_time'])), score: $row['score'], ); }, $result); } public function fetchWithQuestions(Uuid $id): Quiz { return $this->getEntityManager()->createQuery(<<setParameter('id', $id)->getSingleResult(); } /** * Fetch quiz with all relations needed for error checking. * This includes: questions, answers, answer candidates, and season candidates. */ public function fetchWithQuestionsAndCandidates(Uuid $id): Quiz { return $this->getEntityManager()->createQuery(<<setParameter('id', $id)->getSingleResult(); } /** * Get given answers count per candidate for a quiz. * * @return array Array with candidate ID as key and count as value */ public function getGivenAnswersCountPerCandidate(Quiz $quiz): array { $results = $this->getEntityManager()->createQuery(<<setParameter('quiz', $quiz) ->setParameter('season', $quiz->season) ->getResult(); $counts = []; foreach ($results as $row) { $counts[$row['candidateId']->toString()] = (int) $row['answerCount']; } return $counts; } }