mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-03-06 04:44:19 +01:00
Move getScores from Candidate to Quiz
This commit is contained in:
@@ -19,7 +19,6 @@ use Tvdt\Entity\Candidate;
|
|||||||
use Tvdt\Entity\Quiz;
|
use Tvdt\Entity\Quiz;
|
||||||
use Tvdt\Entity\Season;
|
use Tvdt\Entity\Season;
|
||||||
use Tvdt\Exception\ErrorClearingQuizException;
|
use Tvdt\Exception\ErrorClearingQuizException;
|
||||||
use Tvdt\Repository\CandidateRepository;
|
|
||||||
use Tvdt\Repository\QuizCandidateRepository;
|
use Tvdt\Repository\QuizCandidateRepository;
|
||||||
use Tvdt\Repository\QuizRepository;
|
use Tvdt\Repository\QuizRepository;
|
||||||
use Tvdt\Security\Voter\SeasonVoter;
|
use Tvdt\Security\Voter\SeasonVoter;
|
||||||
@@ -29,7 +28,7 @@ use Tvdt\Security\Voter\SeasonVoter;
|
|||||||
class QuizController extends AbstractController
|
class QuizController extends AbstractController
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly CandidateRepository $candidateRepository,
|
private readonly QuizRepository $quizRepository,
|
||||||
private readonly TranslatorInterface $translator,
|
private readonly TranslatorInterface $translator,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@@ -44,7 +43,7 @@ class QuizController extends AbstractController
|
|||||||
return $this->render('backoffice/quiz.html.twig', [
|
return $this->render('backoffice/quiz.html.twig', [
|
||||||
'season' => $season,
|
'season' => $season,
|
||||||
'quiz' => $quiz,
|
'quiz' => $quiz,
|
||||||
'result' => $this->candidateRepository->getScores($quiz),
|
'result' => $this->quizRepository->getScores($quiz),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ namespace Tvdt\Factory;
|
|||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Tvdt\Entity\Elimination;
|
use Tvdt\Entity\Elimination;
|
||||||
use Tvdt\Entity\Quiz;
|
use Tvdt\Entity\Quiz;
|
||||||
use Tvdt\Repository\CandidateRepository;
|
use Tvdt\Repository\QuizRepository;
|
||||||
|
|
||||||
final readonly class EliminationFactory
|
final readonly class EliminationFactory
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private CandidateRepository $candidateRepository,
|
private QuizRepository $quizRepository,
|
||||||
private EntityManagerInterface $em,
|
private EntityManagerInterface $em,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ final readonly class EliminationFactory
|
|||||||
$elimination = new Elimination($quiz);
|
$elimination = new Elimination($quiz);
|
||||||
$this->em->persist($elimination);
|
$this->em->persist($elimination);
|
||||||
|
|
||||||
$scores = $this->candidateRepository->getScores($quiz);
|
$scores = $this->quizRepository->getScores($quiz);
|
||||||
|
|
||||||
$simpleScores = [];
|
$simpleScores = [];
|
||||||
|
|
||||||
|
|||||||
@@ -6,12 +6,8 @@ namespace Tvdt\Repository;
|
|||||||
|
|
||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
use Safe\DateTimeImmutable;
|
|
||||||
use Safe\Exceptions\DatetimeException;
|
|
||||||
use Safe\Exceptions\UrlException;
|
use Safe\Exceptions\UrlException;
|
||||||
use Tvdt\Dto\Result;
|
|
||||||
use Tvdt\Entity\Candidate;
|
use Tvdt\Entity\Candidate;
|
||||||
use Tvdt\Entity\Quiz;
|
|
||||||
use Tvdt\Entity\Season;
|
use Tvdt\Entity\Season;
|
||||||
use Tvdt\Helpers\Base64;
|
use Tvdt\Helpers\Base64;
|
||||||
|
|
||||||
@@ -42,40 +38,4 @@ class CandidateRepository extends ServiceEntityRepository
|
|||||||
->setParameter('name', $name)
|
->setParameter('name', $name)
|
||||||
->getOneOrNullResult();
|
->getOneOrNullResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws DatetimeException
|
|
||||||
*
|
|
||||||
* @return list<Result>
|
|
||||||
*/
|
|
||||||
public function getScores(Quiz $quiz): array
|
|
||||||
{
|
|
||||||
$result = $this->getEntityManager()->createQuery(<<<DQL
|
|
||||||
select
|
|
||||||
c.id,
|
|
||||||
c.name,
|
|
||||||
sum(case when a.isRightAnswer = true then 1 else 0 end) as correct,
|
|
||||||
qc.corrections,
|
|
||||||
max(ga.created) as end_time,
|
|
||||||
qc.created as start_time,
|
|
||||||
(sum(case when a.isRightAnswer = true then 1 else 0 end) + qc.corrections) as score
|
|
||||||
from Tvdt\Entity\Candidate c
|
|
||||||
join c.givenAnswers ga
|
|
||||||
join ga.answer a
|
|
||||||
join c.quizData qc
|
|
||||||
where qc.quiz = :quiz and ga.quiz = :quiz
|
|
||||||
group by ga.quiz, c.id, qc.id
|
|
||||||
order by score desc, max(ga.created) - qc.created asc
|
|
||||||
DQL
|
|
||||||
)->setParameter('quiz', $quiz)->getResult();
|
|
||||||
|
|
||||||
return array_map(static fn (array $row): Result => new Result(
|
|
||||||
id: $row['id'],
|
|
||||||
name: $row['name'],
|
|
||||||
correct: (int) $row['correct'],
|
|
||||||
corrections: $row['corrections'],
|
|
||||||
time: new DateTimeImmutable($row['end_time'])->diff($row['start_time']),
|
|
||||||
score: $row['score'],
|
|
||||||
), $result);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ namespace Tvdt\Repository;
|
|||||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||||
use Doctrine\Persistence\ManagerRegistry;
|
use Doctrine\Persistence\ManagerRegistry;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
|
use Safe\DateTimeImmutable;
|
||||||
|
use Safe\Exceptions\DatetimeException;
|
||||||
|
use Tvdt\Dto\Result;
|
||||||
use Tvdt\Entity\Quiz;
|
use Tvdt\Entity\Quiz;
|
||||||
use Tvdt\Exception\ErrorClearingQuizException;
|
use Tvdt\Exception\ErrorClearingQuizException;
|
||||||
|
|
||||||
@@ -60,4 +63,40 @@ class QuizRepository extends ServiceEntityRepository
|
|||||||
$this->getEntityManager()->remove($quiz);
|
$this->getEntityManager()->remove($quiz);
|
||||||
$this->getEntityManager()->flush();
|
$this->getEntityManager()->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @throws DatetimeException
|
||||||
|
*
|
||||||
|
* @return list<Result>
|
||||||
|
*/
|
||||||
|
public function getScores(Quiz $quiz): array
|
||||||
|
{
|
||||||
|
$result = $this->getEntityManager()->createQuery(<<<DQL
|
||||||
|
select
|
||||||
|
c.id,
|
||||||
|
c.name,
|
||||||
|
sum(case when a.isRightAnswer = true then 1 else 0 end) as correct,
|
||||||
|
qc.corrections,
|
||||||
|
max(ga.created) as end_time,
|
||||||
|
qc.created as start_time,
|
||||||
|
(sum(case when a.isRightAnswer = true then 1 else 0 end) + qc.corrections) as score
|
||||||
|
from Tvdt\Entity\Candidate c
|
||||||
|
join c.givenAnswers ga
|
||||||
|
join ga.answer a
|
||||||
|
join c.quizData qc
|
||||||
|
where qc.quiz = :quiz and ga.quiz = :quiz
|
||||||
|
group by ga.quiz, c.id, qc.id
|
||||||
|
order by score desc, max(ga.created) - qc.created asc
|
||||||
|
DQL
|
||||||
|
)->setParameter('quiz', $quiz)->getResult();
|
||||||
|
|
||||||
|
return array_map(static fn (array $row): Result => new Result(
|
||||||
|
id: $row['id'],
|
||||||
|
name: $row['name'],
|
||||||
|
correct: (int) $row['correct'],
|
||||||
|
corrections: $row['corrections'],
|
||||||
|
time: new DateTimeImmutable($row['end_time'])->diff($row['start_time']),
|
||||||
|
score: $row['score'],
|
||||||
|
), $result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,9 +53,4 @@ final class CandidateRepositoryTest extends DatabaseTestCase
|
|||||||
);
|
);
|
||||||
$this->assertNotInstanceOf(Candidate::class, $result);
|
$this->assertNotInstanceOf(Candidate::class, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetScores(): void
|
|
||||||
{
|
|
||||||
$this->markTestIncomplete('TODO: Make fixtures first and write good test.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,4 +42,9 @@ final class QuizRepositoryTest extends DatabaseTestCase
|
|||||||
|
|
||||||
$this->assertCount(1, $krtekSeason->quizzes);
|
$this->assertCount(1, $krtekSeason->quizzes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetScores(): void
|
||||||
|
{
|
||||||
|
$this->markTestIncomplete('TODO: Make fixtures first and write good test.');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user