Refactor Candidate and Quiz entities, rename Correction to QuizCandidate, and update related workflows

This commit removes nullable Uuid properties for consistency, transitions the Correction entity to QuizCandidate with associated migrations, refactors queries and repositories, adjusts related routes and controllers to use the new entity, updates front-end assets for elimination workflows, and standardizes route requirements and naming conventions.
This commit is contained in:
2025-06-06 23:03:13 +02:00
parent 3e724ff1fb
commit beb8d13dde
27 changed files with 385 additions and 282 deletions

View File

@@ -5,12 +5,10 @@ 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 Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Query\Expr\Join;
use Doctrine\Persistence\ManagerRegistry;
use Safe\Exceptions\UrlException;
use Symfony\Component\Uid\Uuid;
@@ -56,20 +54,26 @@ class CandidateRepository extends ServiceEntityRepository
/** @return ResultList */
public function getScores(Quiz $quiz): array
{
$scoreTimeQb = $this->createQueryBuilder('c', 'c.id')
->select('c.id', 'c.name', 'sum(case when a.isRightAnswer = true then 1 else 0 end) as correct', 'max(ga.created) - min(ga.created) as time')
$scoreQb = $this->createQueryBuilder('c', 'c.id')
->select('c.id', 'c.name', 'sum(case when a.isRightAnswer = true then 1 else 0 end) as correct')
->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.id', 'cor.amount as corrections')
->innerJoin(Correction::class, 'cor', Join::WITH, 'cor.candidate = c and cor.quiz = :quiz')
$startTimeCorrectionQb = $this->createQueryBuilder('c', 'c.id')
->select('c.id', 'qc.corrections', 'max(ga.created) - qc.created as time')
->join('c.quizData', 'qc')
->join('c.givenAnswers', 'ga')
->where('qc.quiz = :quiz')
->groupBy('ga.quiz', 'c.id', 'qc.id')
->setParameter('quiz', $quiz);
$merged = array_merge_recursive($scoreTimeQb->getQuery()->getArrayResult(), $correctionsQb->getQuery()->getArrayResult());
$merged = array_merge_recursive(
$scoreQb->getQuery()->getArrayResult(),
$startTimeCorrectionQb->getQuery()->getArrayResult(),
);
return $this->sortResults($this->calculateScore($merged));
}

View File

@@ -1,20 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Repository;
use App\Entity\Correction;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<Correction>
*/
class CorrectionRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Correction::class);
}
}

View File

@@ -17,29 +17,4 @@ class EliminationRepository extends ServiceEntityRepository
{
parent::__construct($registry, Elimination::class);
}
// /**
// * @return Elimination[] Returns an array of Elimination objects
// */
// public function findByExampleField($value): array
// {
// return $this->createQueryBuilder('e')
// ->andWhere('e.exampleField = :val')
// ->setParameter('val', $value)
// ->orderBy('e.id', 'ASC')
// ->setMaxResults(10)
// ->getQuery()
// ->getResult()
// ;
// }
// public function findOneBySomeField($value): ?Elimination
// {
// return $this->createQueryBuilder('e')
// ->andWhere('e.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace App\Repository;
use App\Entity\Candidate;
use App\Entity\Quiz;
use App\Entity\QuizCandidate;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<QuizCandidate>
*/
class QuizCandidateRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, QuizCandidate::class);
}
/** @return bool true if a new entry was created */
public function createIfNotExist(Quiz $quiz, Candidate $candidate): bool
{
if (0 !== $this->count(['candidate' => $candidate, 'quiz' => $quiz])) {
return false;
}
$quizCandidate = new QuizCandidate($quiz, $candidate);
$this->getEntityManager()->persist($quizCandidate);
$this->getEntityManager()->flush();
return true;
}
}