diff --git a/config/bundles.php b/config/bundles.php
index a60a43e..8de0245 100644
--- a/config/bundles.php
+++ b/config/bundles.php
@@ -1,5 +1,7 @@
['all' => true],
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
diff --git a/src/Controller/AbstractController.php b/src/Controller/AbstractController.php
new file mode 100644
index 0000000..1853af9
--- /dev/null
+++ b/src/Controller/AbstractController.php
@@ -0,0 +1,19 @@
+value;
+ }
+ parent::addFlash($type, $message);
+ }
+}
diff --git a/src/Controller/Admin/AnswerCrudController.php b/src/Controller/Admin/AnswerCrudController.php
index f50a78b..a98184f 100644
--- a/src/Controller/Admin/AnswerCrudController.php
+++ b/src/Controller/Admin/AnswerCrudController.php
@@ -1,5 +1,7 @@
self::SEASON_CODE_REGEX])]
public function enterName(
Request $request,
+ #[MapEntity(mapping: ['seasonCode' => 'seasonCode'])]
Season $season,
): Response {
$form = $this->createForm(EnterNameType::class);
@@ -64,22 +71,50 @@ class QuizController extends AbstractController
requirements: ['seasonCode' => self::SEASON_CODE_REGEX, 'nameHash' => self::CANDIDATE_HASH_REGEX],
)]
public function quizPage(
+ #[MapEntity(mapping: ['seasonCode' => 'seasonCode'])]
Season $season,
string $nameHash,
CandidateRepository $candidateRepository,
QuestionRepository $questionRepository,
+ AnswerRepository $answerRepository,
+ GivenAnswerRepository $givenAnswerRepository,
+ Request $request,
): 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');
+ if (false === $season->isPreregisterCandidates()) {
+ $candidate = new Candidate(Base64::base64_url_decode($nameHash));
+ $candidateRepository->save($candidate);
+ } else {
+ $this->addFlash(FlashType::Danger, 'Candidate not found');
- return $this->redirectToRoute('enter_name', ['seasonCode' => $season->getSeasonCode()]);
+ return $this->redirectToRoute('enter_name', ['seasonCode' => $season->getSeasonCode()]);
+ }
+ }
+
+ if ('POST' === $request->getMethod()) {
+ $answer = $answerRepository->findOneBy(['id' => $request->request->get('answer')]);
+
+ if (!$answer instanceof Answer) {
+ throw new BadRequestException('Invalid Answer ID');
+ }
+
+ $givenAnswer = new GivenAnswer();
+ $givenAnswer->setCandidate($candidate)
+ ->setAnswer($answer)
+ ->setQuiz($answer->getQuestion()->getQuiz());
+ $givenAnswerRepository->save($givenAnswer);
}
$question = $questionRepository->findNextQuestionForCandidate($candidate);
+ if (!$question instanceof Question) {
+ $this->addFlash(FlashType::Success, 'Quiz completed');
+
+ return $this->redirectToRoute('enter_name', ['seasonCode' => $season->getSeasonCode()]);
+ }
+
return $this->render('quiz/question.twig', ['candidate' => $candidate, 'question' => $question]);
}
}
diff --git a/src/Enum/FlashType.php b/src/Enum/FlashType.php
index e13d2e7..6ed9ae8 100644
--- a/src/Enum/FlashType.php
+++ b/src/Enum/FlashType.php
@@ -12,6 +12,6 @@ enum FlashType: string
case Danger = 'danger';
case Warning = 'warning';
case Info = 'info';
- case Ligt = 'light';
+ case Light = 'light';
case Dark = 'dark';
}
diff --git a/src/Form/EnterNameType.php b/src/Form/EnterNameType.php
index e5bdcd8..b130296 100644
--- a/src/Form/EnterNameType.php
+++ b/src/Form/EnterNameType.php
@@ -7,7 +7,6 @@ namespace App\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
-use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Contracts\Translation\TranslatorInterface;
class EnterNameType extends AbstractType
@@ -22,14 +21,6 @@ class EnterNameType extends AbstractType
->add('name', TextType::class,
['required' => true, 'label' => $this->translator->trans('Enter your name')],
)
-// ->add('submit', SubmitType::class, ['label' => 'Start quiz'])
;
}
-
- public function configureOptions(OptionsResolver $resolver): void
- {
- $resolver->setDefaults([
- // Configure your form options here
- ]);
- }
}
diff --git a/src/Helpers/Base64.php b/src/Helpers/Base64.php
index c2e72ef..991c9e5 100644
--- a/src/Helpers/Base64.php
+++ b/src/Helpers/Base64.php
@@ -14,7 +14,7 @@ class Base64
public static function base64_url_encode(string $input): string
{
- return strtr(base64_encode($input), '+/', '-_');
+ return rtrim(strtr(base64_encode($input), '+/', '-_'), '=');
}
/** @throws UrlException */
diff --git a/src/Repository/CandidateRepository.php b/src/Repository/CandidateRepository.php
index 5658785..cda370c 100644
--- a/src/Repository/CandidateRepository.php
+++ b/src/Repository/CandidateRepository.php
@@ -36,4 +36,13 @@ class CandidateRepository extends ServiceEntityRepository
->setParameter('name', $name)
->getQuery()->getOneOrNullResult();
}
+
+ public function save(Candidate $candidate, bool $flush = true): void
+ {
+ $this->getEntityManager()->persist($candidate);
+
+ if (true === $flush) {
+ $this->getEntityManager()->flush();
+ }
+ }
}
diff --git a/src/Repository/GivenAnswerRepository.php b/src/Repository/GivenAnswerRepository.php
index 598f1ed..116b418 100644
--- a/src/Repository/GivenAnswerRepository.php
+++ b/src/Repository/GivenAnswerRepository.php
@@ -17,4 +17,13 @@ class GivenAnswerRepository extends ServiceEntityRepository
{
parent::__construct($registry, GivenAnswer::class);
}
+
+ public function save(GivenAnswer $givenAnswer, bool $flush = true): void
+ {
+ $this->getEntityManager()->persist($givenAnswer);
+
+ if (true === $flush) {
+ $this->getEntityManager()->flush();
+ }
+ }
}
diff --git a/src/Repository/QuestionRepository.php b/src/Repository/QuestionRepository.php
index 37d6d7a..2bbb123 100644
--- a/src/Repository/QuestionRepository.php
+++ b/src/Repository/QuestionRepository.php
@@ -20,13 +20,13 @@ class QuestionRepository extends ServiceEntityRepository
parent::__construct($registry, Question::class);
}
- public function findNextQuestionForCandidate(Candidate $candidate): Question
+ 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')
+ ->select('q1')
->from(GivenAnswer::class, 'ga')
->join('ga.answer', 'a')
->join('a.question', 'q1')
@@ -38,6 +38,6 @@ class QuestionRepository extends ServiceEntityRepository
->setMaxResults(1)
->setParameter('candidate', $candidate)
->setParameter('quiz', $candidate->getSeason()->getActiveQuiz())
- ->getQuery()->getSingleResult();
+ ->getQuery()->getOneOrNullResult();
}
}
diff --git a/templates/quiz/question.twig b/templates/quiz/question.twig
index bee4556..142f6a3 100644
--- a/templates/quiz/question.twig
+++ b/templates/quiz/question.twig
@@ -3,7 +3,16 @@
Candiadte: {{ candidate.name }}
{{ question.question }}
- {% for answer in question.answers %}
- {{ answer.text }}
- {% endfor %}
+