diff --git a/src/Controller/QuizController.php b/src/Controller/QuizController.php index 5a4e96b..4edebed 100644 --- a/src/Controller/QuizController.php +++ b/src/Controller/QuizController.php @@ -4,11 +4,14 @@ declare(strict_types=1); namespace App\Controller; +use App\Entity\Candidate; use App\Entity\Season; +use App\Enum\FlashType; use App\Form\EnterNameType; use App\Form\SelectSeasonType; use App\Helpers\Base64; -use Safe\Exceptions\UrlException; +use App\Repository\CandidateRepository; +use App\Repository\QuestionRepository; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -60,13 +63,23 @@ class QuizController extends AbstractController name: 'quiz_page', requirements: ['seasonCode' => self::SEASON_CODE_REGEX, 'nameHash' => self::CANDIDATE_HASH_REGEX], )] - public function quizPage(Season $season, string $nameHash) - { - try { - $name = Base64::base64_url_decode($nameHash); - } catch (UrlException $e) { + public function quizPage( + Season $season, + string $nameHash, + CandidateRepository $candidateRepository, + QuestionRepository $questionRepository, + ): Response { + $candidate = $candidateRepository->getCandidateByHash($season, $nameHash); + + if (!$candidate instanceof Candidate) { + // Add option to add new candidate when preregister is disabled + $this->addFlash(FlashType::Danger->value, 'Candidate not found'); + + return $this->redirectToRoute('enter_name', ['seasonCode' => $season->getSeasonCode()]); } - return $this->render('quiz/question.twig', ['season' => $season, 'name' => $name]); + $question = $questionRepository->findNextQuestionForCandidate($candidate); + + return $this->render('quiz/question.twig', ['candidate' => $candidate, 'question' => $question]); } } diff --git a/src/DataFixtures/KrtekFixtures.php b/src/DataFixtures/KrtekFixtures.php index 2522c5b..77d8c64 100644 --- a/src/DataFixtures/KrtekFixtures.php +++ b/src/DataFixtures/KrtekFixtures.php @@ -34,8 +34,10 @@ class KrtekFixtures extends Fixture ->addCandidate(new Candidate('Philine')) ->addCandidate(new Candidate('Remy')) ->addCandidate(new Candidate('Robbert')) - ->addCandidate(new Candidate('Tom')) - ->addQuiz($this->createQuiz1($season)) + ->addCandidate(new Candidate('Tom')); + $quiz1 = $this->createQuiz1($season); + $season->addQuiz($quiz1) + ->setActiveQuiz($quiz1) ->addQuiz($this->createQuiz2($season)); $manager->flush(); @@ -49,8 +51,8 @@ class KrtekFixtures extends Fixture ->addQuestion((new Question()) ->setQuestion('Is de Krtek een man of een vrouw?') - ->addAnswer(new Answer('Ja', true)) - ->addAnswer(new Answer('Nee')) + ->addAnswer(new Answer('Vrouw', true)) + ->addAnswer(new Answer('Man')) ) ->addQuestion((new Question()) diff --git a/src/Enum/FlashType.php b/src/Enum/FlashType.php new file mode 100644 index 0000000..e13d2e7 --- /dev/null +++ b/src/Enum/FlashType.php @@ -0,0 +1,17 @@ +findOneBy(['season' => $season, 'name' => $name]); + return $this->createQueryBuilder('c') + ->where('c.season = :season') + ->andWhere('lower(c.name) = lower(:name)') + ->setParameter('season', $season) + ->setParameter('name', $name) + ->getQuery()->getOneOrNullResult(); } } diff --git a/src/Repository/QuestionRepository.php b/src/Repository/QuestionRepository.php index c8bc4b7..37d6d7a 100644 --- a/src/Repository/QuestionRepository.php +++ b/src/Repository/QuestionRepository.php @@ -4,6 +4,8 @@ declare(strict_types=1); namespace App\Repository; +use App\Entity\Candidate; +use App\Entity\GivenAnswer; use App\Entity\Question; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; @@ -17,4 +19,25 @@ class QuestionRepository extends ServiceEntityRepository { parent::__construct($registry, Question::class); } + + public function findNextQuestionForCandidate(Candidate $candidate): Question + { + $qb = $this->createQueryBuilder('q'); + + return $qb->join('q.quiz', 'qz') + ->andWhere($qb->expr()->notIn('q.id', $this->getEntityManager()->createQueryBuilder() + ->select('ga.id') + ->from(GivenAnswer::class, 'ga') + ->join('ga.answer', 'a') + ->join('a.question', 'q1') + ->andWhere($qb->expr()->isNotNull('ga.answer')) + ->andWhere('ga.candidate = :candidate') + ->andWhere('q1.quiz = :quiz') + ->getDQL())) + ->andWhere('qz = :quiz') + ->setMaxResults(1) + ->setParameter('candidate', $candidate) + ->setParameter('quiz', $candidate->getSeason()->getActiveQuiz()) + ->getQuery()->getSingleResult(); + } } diff --git a/templates/messages.html.twig b/templates/messages.html.twig deleted file mode 100644 index e69de29..0000000 diff --git a/templates/quiz/base.html.twig b/templates/quiz/base.html.twig index 50184fc..19fd1db 100644 --- a/templates/quiz/base.html.twig +++ b/templates/quiz/base.html.twig @@ -32,6 +32,14 @@
+ {% for label, messages in app.flashes() %} + {% for message in messages %} + + {% endfor %} + {% endfor %} {% block body %} {% endblock body %}
diff --git a/templates/quiz/question.twig b/templates/quiz/question.twig index d3e1db3..bee4556 100644 --- a/templates/quiz/question.twig +++ b/templates/quiz/question.twig @@ -1,6 +1,9 @@ {% extends "quiz/base.html.twig" %} {% block body %} - {{ season.name }} - {{ name }} -

Hello World!

+ Candiadte: {{ candidate.name }}
+ + {{ question.question }}
+ {% for answer in question.answers %} + {{ answer.text }} + {% endfor %} {% endblock body %}