Refactor code for improved readability and consistency; add flash message handling and enhance quiz functionality
Some checks failed
CI / Tests (push) Failing after 9s
CI / Docker Lint (push) Successful in 4s

This commit is contained in:
2025-03-12 23:18:13 +01:00
parent 448daed6ea
commit acf5c06fcc
21 changed files with 309 additions and 80 deletions

View File

@@ -5,14 +5,20 @@ declare(strict_types=1);
namespace App\Repository;
use App\Entity\Candidate;
use App\Entity\Correction;
use App\Entity\Quiz;
use App\Entity\Season;
use App\Helpers\Base64;
use DateInterval;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\Persistence\ManagerRegistry;
use Safe\Exceptions\UrlException;
/**
* @extends ServiceEntityRepository<Candidate>
*
* @phpstan-type ResultArray array<string, array{0: Candidate, correct: int, time: DateInterval, corrections?: float, score: float}>
*/
class CandidateRepository extends ServiceEntityRepository
{
@@ -41,8 +47,54 @@ class CandidateRepository extends ServiceEntityRepository
{
$this->getEntityManager()->persist($candidate);
if (true === $flush) {
if ($flush) {
$this->getEntityManager()->flush();
}
}
/** @return ResultArray */
public function getScores(Quiz $quiz): array
{
$scoreTimeQb = $this->createQueryBuilder('c', 'c.id')
->select('c', 'sum(case when a.isRightAnswer = true then 1 else 0 end) as correct', 'max(ga.created) - min(ga.created) as time')
->join('c.givenAnswers', 'ga')
->join('ga.answer', 'a')
->where('ga.quiz = :quiz')
->groupBy('c.id')
->setParameter('quiz', $quiz);
$correctionsQb = $this->createQueryBuilder('c', 'c.id')
->select('c', 'cor.amount as corrections')
->innerJoin(Correction::class, 'cor', Join::WITH, 'cor.candidate = c and cor.quiz = :quiz')
->setParameter('quiz', $quiz);
$merged = array_merge_recursive($scoreTimeQb->getQuery()->getArrayResult(), $correctionsQb->getQuery()->getArrayResult());
return $this->sortResults($this->calculateScore($merged));
}
/**
* @param array<string, array{0: Candidate, correct: int, time: \DateInterval, corrections?: float}> $in
*
* @return ResultArray
*/
private function calculateScore(array $in): array
{
return array_map(static fn ($candidate): array => [
...$candidate,
'score' => $candidate['correct'] + ($candidate['corrections'] ?? 0.0),
], $in);
}
/**
* @param ResultArray $results
*
* @return ResultArray
*/
private function sortResults(array $results): array
{
usort($results, static fn ($a, $b): int => $b['score'] <=> $a['score']);
return $results;
}
}