mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-03-05 20:44:19 +01:00
WIP 3-3
This commit is contained in:
28
src/Controller/Admin/AnswerCrudController.php
Normal file
28
src/Controller/Admin/AnswerCrudController.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Entity\Answer;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
|
||||
|
||||
class AnswerCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
{
|
||||
return Answer::class;
|
||||
}
|
||||
|
||||
/*
|
||||
public function configureFields(string $pageName): iterable
|
||||
{
|
||||
return [
|
||||
IdField::new('id'),
|
||||
TextField::new('title'),
|
||||
TextEditorField::new('description'),
|
||||
];
|
||||
}
|
||||
*/
|
||||
}
|
||||
28
src/Controller/Admin/CandidateCrudController.php
Normal file
28
src/Controller/Admin/CandidateCrudController.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Entity\Candidate;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
|
||||
|
||||
class CandidateCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
{
|
||||
return Candidate::class;
|
||||
}
|
||||
|
||||
/*
|
||||
public function configureFields(string $pageName): iterable
|
||||
{
|
||||
return [
|
||||
IdField::new('id'),
|
||||
TextField::new('title'),
|
||||
TextEditorField::new('description'),
|
||||
];
|
||||
}
|
||||
*/
|
||||
}
|
||||
28
src/Controller/Admin/CorrectionCrudController.php
Normal file
28
src/Controller/Admin/CorrectionCrudController.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Entity\Correction;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
|
||||
|
||||
class CorrectionCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
{
|
||||
return Correction::class;
|
||||
}
|
||||
|
||||
/*
|
||||
public function configureFields(string $pageName): iterable
|
||||
{
|
||||
return [
|
||||
IdField::new('id'),
|
||||
TextField::new('title'),
|
||||
TextEditorField::new('description'),
|
||||
];
|
||||
}
|
||||
*/
|
||||
}
|
||||
66
src/Controller/Admin/DashboardController.php
Normal file
66
src/Controller/Admin/DashboardController.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Entity\Answer;
|
||||
use App\Entity\Candidate;
|
||||
use App\Entity\Correction;
|
||||
use App\Entity\GivenAnswer;
|
||||
use App\Entity\Question;
|
||||
use App\Entity\Quiz;
|
||||
use App\Entity\Season;
|
||||
use App\Entity\User;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
class DashboardController extends AbstractDashboardController
|
||||
{
|
||||
#[Route('/admin', name: 'admin')]
|
||||
public function index(): Response
|
||||
{
|
||||
// return parent::index();
|
||||
|
||||
// Option 1. You can make your dashboard redirect to some common page of your backend
|
||||
//
|
||||
$adminUrlGenerator = $this->container->get(AdminUrlGenerator::class);
|
||||
|
||||
return $this->redirect($adminUrlGenerator->setController(SeasonCrudController::class)->generateUrl());
|
||||
|
||||
// Option 2. You can make your dashboard redirect to different pages depending on the user
|
||||
//
|
||||
// if ('jane' === $this->getUser()->getUsername()) {
|
||||
// return $this->redirect('...');
|
||||
// }
|
||||
|
||||
// Option 3. You can render some custom template to display a proper dashboard with widgets, etc.
|
||||
// (tip: it's easier if your template extends from @EasyAdmin/page/content.html.twig)
|
||||
//
|
||||
// return $this->render('some/path/my-dashboard.html.twig');
|
||||
}
|
||||
|
||||
public function configureDashboard(): Dashboard
|
||||
{
|
||||
return Dashboard::new()
|
||||
->setTitle('TijdVoorDeTest');
|
||||
}
|
||||
|
||||
public function configureMenuItems(): iterable
|
||||
{
|
||||
yield MenuItem::linkToDashboard('Dashboard', 'fa fa-home');
|
||||
yield MenuItem::linkToCrud('Season', 'fas fa-list', Season::class);
|
||||
yield MenuItem::linkToCrud('Quiz', 'fas fa-list', Quiz::class);
|
||||
yield MenuItem::linkToCrud('Question', 'fas fa-list', Question::class);
|
||||
yield MenuItem::linkToCrud('Candidate', 'fas fa-list', Candidate::class);
|
||||
yield MenuItem::linkToCrud('Correction', 'fas fa-list', Correction::class);
|
||||
yield MenuItem::linkToCrud('User', 'fas fa-list', User::class);
|
||||
yield MenuItem::linkToCrud('Given Answer', 'fas fa-list', GivenAnswer::class);
|
||||
yield MenuItem::linkToCrud('Answer', 'fas fa-list', Answer::class);
|
||||
yield MenuItem::linkToLogout('Logout', 'fa fa-exit');
|
||||
}
|
||||
}
|
||||
28
src/Controller/Admin/GivenAnswerCrudController.php
Normal file
28
src/Controller/Admin/GivenAnswerCrudController.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Entity\GivenAnswer;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
|
||||
|
||||
class GivenAnswerCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
{
|
||||
return GivenAnswer::class;
|
||||
}
|
||||
|
||||
/*
|
||||
public function configureFields(string $pageName): iterable
|
||||
{
|
||||
return [
|
||||
IdField::new('id'),
|
||||
TextField::new('title'),
|
||||
TextEditorField::new('description'),
|
||||
];
|
||||
}
|
||||
*/
|
||||
}
|
||||
28
src/Controller/Admin/QuestionCrudController.php
Normal file
28
src/Controller/Admin/QuestionCrudController.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Entity\Question;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
|
||||
|
||||
class QuestionCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
{
|
||||
return Question::class;
|
||||
}
|
||||
|
||||
/*
|
||||
public function configureFields(string $pageName): iterable
|
||||
{
|
||||
return [
|
||||
IdField::new('id'),
|
||||
TextField::new('title'),
|
||||
TextEditorField::new('description'),
|
||||
];
|
||||
}
|
||||
*/
|
||||
}
|
||||
28
src/Controller/Admin/QuizCrudController.php
Normal file
28
src/Controller/Admin/QuizCrudController.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Entity\Quiz;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
|
||||
|
||||
class QuizCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
{
|
||||
return Quiz::class;
|
||||
}
|
||||
|
||||
/*
|
||||
public function configureFields(string $pageName): iterable
|
||||
{
|
||||
return [
|
||||
IdField::new('id'),
|
||||
TextField::new('title'),
|
||||
TextEditorField::new('description'),
|
||||
];
|
||||
}
|
||||
*/
|
||||
}
|
||||
28
src/Controller/Admin/SeasonCrudController.php
Normal file
28
src/Controller/Admin/SeasonCrudController.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Entity\Season;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
|
||||
|
||||
class SeasonCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
{
|
||||
return Season::class;
|
||||
}
|
||||
|
||||
/*
|
||||
public function configureFields(string $pageName): iterable
|
||||
{
|
||||
return [
|
||||
IdField::new('id'),
|
||||
TextField::new('title'),
|
||||
TextEditorField::new('description'),
|
||||
];
|
||||
}
|
||||
*/
|
||||
}
|
||||
28
src/Controller/Admin/UserCrudController.php
Normal file
28
src/Controller/Admin/UserCrudController.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controller\Admin;
|
||||
|
||||
use App\Entity\User;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
|
||||
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
|
||||
|
||||
class UserCrudController extends AbstractCrudController
|
||||
{
|
||||
public static function getEntityFqcn(): string
|
||||
{
|
||||
return User::class;
|
||||
}
|
||||
|
||||
/*
|
||||
public function configureFields(string $pageName): iterable
|
||||
{
|
||||
return [
|
||||
IdField::new('id'),
|
||||
TextField::new('title'),
|
||||
TextEditorField::new('description'),
|
||||
];
|
||||
}
|
||||
*/
|
||||
}
|
||||
34
src/Controller/LoginController.php
Normal file
34
src/Controller/LoginController.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||
|
||||
class LoginController extends AbstractController
|
||||
{
|
||||
#[Route(path: '/login', name: 'app_login')]
|
||||
public function login(AuthenticationUtils $authenticationUtils): Response
|
||||
{
|
||||
// get the login error if there is one
|
||||
$error = $authenticationUtils->getLastAuthenticationError();
|
||||
|
||||
// last username entered by the user
|
||||
$lastUsername = $authenticationUtils->getLastUsername();
|
||||
|
||||
return $this->render('login/login.html.twig', [
|
||||
'last_username' => $lastUsername,
|
||||
'error' => $error,
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route(path: '/logout', name: 'app_logout')]
|
||||
public function logout(): void
|
||||
{
|
||||
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
|
||||
}
|
||||
}
|
||||
72
src/Controller/QuizController.php
Normal file
72
src/Controller/QuizController.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller;
|
||||
|
||||
use App\Entity\Season;
|
||||
use App\Form\EnterNameType;
|
||||
use App\Form\SelectSeasonType;
|
||||
use App\Helpers\Base64;
|
||||
use Safe\Exceptions\UrlException;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Attribute\AsController;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
|
||||
#[AsController]
|
||||
class QuizController extends AbstractController
|
||||
{
|
||||
public const string SEASON_CODE_REGEX = '[A-Za-z\d]{5}';
|
||||
private const string CANDIDATE_HASH_REGEX = '[\w\-=]+';
|
||||
|
||||
#[Route(path: '/', name: 'select_season', methods: ['GET', 'POST'])]
|
||||
public function selectSeason(Request $request): Response
|
||||
{
|
||||
$form = $this->createForm(SelectSeasonType::class);
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$data = $form->getData();
|
||||
|
||||
return $this->redirectToRoute('enter_name', ['seasonCode' => $data['season_code']]);
|
||||
}
|
||||
|
||||
return $this->render('quiz/select_season.html.twig', ['form' => $form]);
|
||||
}
|
||||
|
||||
#[Route(path: '/{seasonCode}', name: 'enter_name', requirements: ['seasonCode' => self::SEASON_CODE_REGEX])]
|
||||
public function enterName(
|
||||
Request $request,
|
||||
Season $season,
|
||||
): Response {
|
||||
$form = $this->createForm(EnterNameType::class);
|
||||
|
||||
$form->handleRequest($request);
|
||||
|
||||
if ($form->isSubmitted() && $form->isValid()) {
|
||||
$data = $form->getData();
|
||||
$name = $data['name'];
|
||||
|
||||
return $this->redirectToRoute('quiz_page', ['seasonCode' => $season->getSeasonCode(), 'nameHash' => Base64::base64_url_encode($name)]);
|
||||
}
|
||||
|
||||
return $this->render('quiz/enter_name.twig', ['season' => $season, 'form' => $form]);
|
||||
}
|
||||
|
||||
#[Route(
|
||||
path: '/{seasonCode}/{nameHash}',
|
||||
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) {
|
||||
}
|
||||
|
||||
return $this->render('quiz/question.twig', ['season' => $season, 'name' => $name]);
|
||||
}
|
||||
}
|
||||
185
src/DataFixtures/KrtekFixtures.php
Normal file
185
src/DataFixtures/KrtekFixtures.php
Normal file
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\DataFixtures;
|
||||
|
||||
use App\Entity\Answer;
|
||||
use App\Entity\Candidate;
|
||||
use App\Entity\Question;
|
||||
use App\Entity\Quiz;
|
||||
use App\Entity\Season;
|
||||
use Doctrine\Bundle\FixturesBundle\Fixture;
|
||||
use Doctrine\Persistence\ObjectManager;
|
||||
|
||||
class KrtekFixtures extends Fixture
|
||||
{
|
||||
public function load(ObjectManager $manager): void
|
||||
{
|
||||
$season = new Season();
|
||||
$manager->persist($season);
|
||||
|
||||
$season->setName('Krtek Weekend')
|
||||
->setSeasonCode('12345')
|
||||
->setPreregisterCandidates(true);
|
||||
|
||||
$quiz1 = new Quiz();
|
||||
$manager->persist($quiz1);
|
||||
$quiz1->setName('Quiz 1')
|
||||
->setSeason($season);
|
||||
|
||||
$season->setActiveQuiz($quiz1)
|
||||
->addCandidate(new Candidate('Claudia'))
|
||||
->addCandidate(new Candidate('Eelco'))
|
||||
->addCandidate(new Candidate('Elise'))
|
||||
->addCandidate(new Candidate('Gert-Jan'))
|
||||
->addCandidate(new Candidate('Iris'))
|
||||
->addCandidate(new Candidate('Jari'))
|
||||
->addCandidate(new Candidate('Lara'))
|
||||
->addCandidate(new Candidate('Lotte'))
|
||||
->addCandidate(new Candidate('Myrthe'))
|
||||
->addCandidate(new Candidate('Philine'))
|
||||
->addCandidate(new Candidate('Remy'))
|
||||
->addCandidate(new Candidate('Robbert'))
|
||||
->addCandidate(new Candidate('Tom'))
|
||||
;
|
||||
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Is de Krtek een man of een vrouw?')
|
||||
->addAnswer(new Answer('Ja', true))
|
||||
->addAnswer(new Answer('Nee'))
|
||||
);
|
||||
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Hoeveel broers heeft de Krtek?')
|
||||
->addAnswer(new Answer('Geen', true))
|
||||
->addAnswer(new Answer('1'))
|
||||
->addAnswer(new Answer('2'))
|
||||
);
|
||||
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Wat is de lievelingsfeestdag van de Krtek?')
|
||||
->addAnswer(new Answer('Geen'))
|
||||
->addAnswer(new Answer('Diens eigen verjaardag'))
|
||||
->addAnswer(new Answer('Koningsdag'))
|
||||
->addAnswer(new Answer('Kerst', true))
|
||||
->addAnswer(new Answer('Oud en Nieuw'))
|
||||
);
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Hoe kwam de Krtek naar Kersteren vandaag?')
|
||||
->addAnswer(new Answer('Met het OV', true))
|
||||
->addAnswer(new Answer('Met de auto'))
|
||||
);
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Met wie keek de Kretek video bij binnenkomst?')
|
||||
->addAnswer(new Answer('Claudia'))
|
||||
->addAnswer(new Answer('Eelco'))
|
||||
->addAnswer(new Answer('Elise'))
|
||||
->addAnswer(new Answer('Gert-Jan'))
|
||||
->addAnswer(new Answer('Iris'))
|
||||
->addAnswer(new Answer('Jari'))
|
||||
->addAnswer(new Answer('Lara'))
|
||||
->addAnswer(new Answer('Lotte'))
|
||||
->addAnswer(new Answer('Myrthe'))
|
||||
->addAnswer(new Answer('Philine'))
|
||||
->addAnswer(new Answer('Remy'))
|
||||
->addAnswer(new Answer('Robbert'))
|
||||
->addAnswer(new Answer('Tom', true))
|
||||
);
|
||||
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Welk advies zou de Krtek zichzelf als kind geven?')
|
||||
->addAnswer(new Answer('Geef je vader een knuffel.'))
|
||||
->addAnswer(new Answer('Trek je wat minder aan van anderen.'))
|
||||
->addAnswer(new Answer('Luister meer naar je eigen gevoel in plaats van naar wat anderen vinden.'))
|
||||
->addAnswer(new Answer('Stel niet alles tot het laatste moment uit.'))
|
||||
->addAnswer(new Answer('Altijd doorgaan.'))
|
||||
->addAnswer(new Answer('Probeer ook eens buiten de lijntjes te kleuren', true))
|
||||
->addAnswer(new Answer('Ga als je groot bent op groepsreis! '))
|
||||
->addAnswer(new Answer('Trek minder aan van de mening van anderen, het is oké om anders te zijn.'))
|
||||
);
|
||||
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Wat voor soort schoenen droeg de Krtek bij het diner?')
|
||||
->addAnswer(new Answer('Sneakers'))
|
||||
->addAnswer(new Answer('Wandel-/bergschoenen', true))
|
||||
->addAnswer(new Answer('Lederen schoenen'))
|
||||
->addAnswer(new Answer('Pantoffels'))
|
||||
->addAnswer(new Answer('Hakken'))
|
||||
->addAnswer(new Answer('Geen schoenen, alleen sokken'))
|
||||
);
|
||||
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Met welk vervoersmiddel reist de Krtek het liefste?')
|
||||
->addAnswer(new Answer('Fiets', true))
|
||||
->addAnswer(new Answer('Auto'))
|
||||
->addAnswer(new Answer('Trein'))
|
||||
);
|
||||
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Heeft de Krtek een eigen auto?')
|
||||
->addAnswer(new Answer('Ja'))
|
||||
->addAnswer(new Answer('Nee', true))
|
||||
);
|
||||
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Van wie is de quote die de Krtek gepakt heeft')
|
||||
->addAnswer(new Answer('Karen'))
|
||||
->addAnswer(new Answer('Gilles de Coster'))
|
||||
->addAnswer(new Answer('Kees Tol'))
|
||||
->addAnswer(new Answer('Harry en John'))
|
||||
->addAnswer(new Answer('Georgina Verbaan'))
|
||||
->addAnswer(new Answer('Marc-Marie Huijbregts'))
|
||||
->addAnswer(new Answer('Fresia Cousiño Arias, Rik van de Westelaken'))
|
||||
->addAnswer(new Answer('Ellie Lust'))
|
||||
->addAnswer(new Answer('Bouba'))
|
||||
->addAnswer(new Answer('Jan Versteegh'))
|
||||
->addAnswer(new Answer('Dick Jol'))
|
||||
->addAnswer(new Answer('Karin de Groot'))
|
||||
->addAnswer(new Answer('Pieter'))
|
||||
->addAnswer(new Answer('Renée Fokker'))
|
||||
->addAnswer(new Answer('Sam, Davy', true))
|
||||
);
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Zou de Krtek molboekjes, jokers, vrijstellingen of topito’s uit iemands rugzak stelen om te kunnen winnen?')
|
||||
->addAnswer(new Answer('Ja'))
|
||||
->addAnswer(new Answer('Nee', true))
|
||||
);
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('In wat voor bed slaapt de Krtek dit weekend?')
|
||||
->addAnswer(new Answer('Éénpersoons, losstaand bed'))
|
||||
->addAnswer(new Answer('Éénpersoonsbed, tegen een ander bed aan', true))
|
||||
->addAnswer(new Answer('Tweepersoons bed'))
|
||||
);
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Hoeveel jaar heeft de Krtek gedaan over de middelbare school?')
|
||||
->addAnswer(new Answer('5'))
|
||||
->addAnswer(new Answer('6', true))
|
||||
->addAnswer(new Answer('7'))
|
||||
->addAnswer(new Answer('8'))
|
||||
);
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Waar zat de Krtek aan tafel bij het diner?')
|
||||
->addAnswer(new Answer('Met de rug naar de accommodatie'))
|
||||
->addAnswer(new Answer('Met de rug naar de buitenmuur', true))
|
||||
);
|
||||
$quiz1->addQuestion((new Question())
|
||||
->setQuestion('Wie is de Krtek?')
|
||||
->addAnswer(new Answer('Claudia', true))
|
||||
->addAnswer(new Answer('Eelco'))
|
||||
->addAnswer(new Answer('Elise'))
|
||||
->addAnswer(new Answer('Gert-Jan'))
|
||||
->addAnswer(new Answer('Iris'))
|
||||
->addAnswer(new Answer('Jari'))
|
||||
->addAnswer(new Answer('Lara'))
|
||||
->addAnswer(new Answer('Lotte'))
|
||||
->addAnswer(new Answer('Myrthe'))
|
||||
->addAnswer(new Answer('Philine'))
|
||||
->addAnswer(new Answer('Remy'))
|
||||
->addAnswer(new Answer('Robbert'))
|
||||
->addAnswer(new Answer('Tom'))
|
||||
);
|
||||
|
||||
$manager->flush();
|
||||
}
|
||||
}
|
||||
124
src/Entity/Answer.php
Normal file
124
src/Entity/Answer.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\AnswerRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
|
||||
use Symfony\Bridge\Doctrine\Types\UuidType;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
#[ORM\Entity(repositoryClass: AnswerRepository::class)]
|
||||
class Answer
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: UuidType::NAME)]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\CustomIdGenerator(class: UuidGenerator::class)]
|
||||
private Uuid $id;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'answers')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private Question $question;
|
||||
|
||||
/** @var Collection<int, Candidate> */
|
||||
#[ORM\ManyToMany(targetEntity: Candidate::class, inversedBy: 'answersOnCandidate')]
|
||||
private Collection $candidates;
|
||||
|
||||
/** @var Collection<int, GivenAnswer> */
|
||||
#[ORM\OneToMany(targetEntity: GivenAnswer::class, mappedBy: 'answer', orphanRemoval: true)]
|
||||
private Collection $givenAnswers;
|
||||
|
||||
public function __construct(
|
||||
#[ORM\Column(length: 255)]
|
||||
private string $text,
|
||||
#[ORM\Column]
|
||||
private bool $isRightAnswer = false,
|
||||
) {
|
||||
$this->candidates = new ArrayCollection();
|
||||
$this->givenAnswers = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): Uuid
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getText(): string
|
||||
{
|
||||
return $this->text;
|
||||
}
|
||||
|
||||
public function setText(string $text): static
|
||||
{
|
||||
$this->text = $text;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getQuestion(): Question
|
||||
{
|
||||
return $this->question;
|
||||
}
|
||||
|
||||
public function setQuestion(Question $question): static
|
||||
{
|
||||
$this->question = $question;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isRightAnswer(): ?bool
|
||||
{
|
||||
return $this->isRightAnswer;
|
||||
}
|
||||
|
||||
public function setRightAnswer(bool $isRightAnswer): static
|
||||
{
|
||||
$this->isRightAnswer = $isRightAnswer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return Collection<int, Candidate> */
|
||||
public function getCandidates(): Collection
|
||||
{
|
||||
return $this->candidates;
|
||||
}
|
||||
|
||||
public function addCandidate(Candidate $candidate): static
|
||||
{
|
||||
if (!$this->candidates->contains($candidate)) {
|
||||
$this->candidates->add($candidate);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeCandidate(Candidate $candidate): static
|
||||
{
|
||||
$this->candidates->removeElement($candidate);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return Collection<int, GivenAnswer> */
|
||||
public function getGivenAnswers(): Collection
|
||||
{
|
||||
return $this->givenAnswers;
|
||||
}
|
||||
|
||||
public function addGivenAnswer(GivenAnswer $givenAnswer): static
|
||||
{
|
||||
if (!$this->givenAnswers->contains($givenAnswer)) {
|
||||
$this->givenAnswers->add($givenAnswer);
|
||||
$givenAnswer->setAnswer($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
140
src/Entity/Candidate.php
Normal file
140
src/Entity/Candidate.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Helpers\Base64;
|
||||
use App\Repository\CandidateRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
|
||||
use Symfony\Bridge\Doctrine\Types\UuidType;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
#[ORM\Entity(repositoryClass: CandidateRepository::class)]
|
||||
class Candidate
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: UuidType::NAME, unique: true)]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\CustomIdGenerator(class: UuidGenerator::class)]
|
||||
private ?Uuid $id = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'candidates')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private Season $season;
|
||||
|
||||
/** @var Collection<int, Answer> */
|
||||
#[ORM\ManyToMany(targetEntity: Answer::class, mappedBy: 'candidates')]
|
||||
private Collection $answersOnCandidate;
|
||||
|
||||
/** @var Collection<int, GivenAnswer> */
|
||||
#[ORM\OneToMany(targetEntity: GivenAnswer::class, mappedBy: 'candidate', orphanRemoval: true)]
|
||||
private Collection $givenAnswers;
|
||||
|
||||
/** @var Collection<int, Correction> */
|
||||
#[ORM\OneToMany(targetEntity: Correction::class, mappedBy: 'candidate', orphanRemoval: true)]
|
||||
private Collection $corrections;
|
||||
|
||||
public function __construct(
|
||||
#[ORM\Column(length: 16)]
|
||||
private string $name,
|
||||
) {
|
||||
$this->answersOnCandidate = new ArrayCollection();
|
||||
$this->givenAnswers = new ArrayCollection();
|
||||
$this->corrections = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?Uuid
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getSeason(): Season
|
||||
{
|
||||
return $this->season;
|
||||
}
|
||||
|
||||
public function setSeason(Season $season): static
|
||||
{
|
||||
$this->season = $season;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): static
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return Collection<int, Answer> */
|
||||
public function getAnswersOnCandidate(): Collection
|
||||
{
|
||||
return $this->answersOnCandidate;
|
||||
}
|
||||
|
||||
public function addAnswersOnCandidate(Answer $answersOnCandidate): static
|
||||
{
|
||||
if (!$this->answersOnCandidate->contains($answersOnCandidate)) {
|
||||
$this->answersOnCandidate->add($answersOnCandidate);
|
||||
$answersOnCandidate->addCandidate($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeAnswersOnCandidate(Answer $answersOnCandidate): static
|
||||
{
|
||||
if ($this->answersOnCandidate->removeElement($answersOnCandidate)) {
|
||||
$answersOnCandidate->removeCandidate($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return Collection<int, GivenAnswer> */
|
||||
public function getGivenAnswers(): Collection
|
||||
{
|
||||
return $this->givenAnswers;
|
||||
}
|
||||
|
||||
public function addGivenAnswer(GivenAnswer $givenAnswer): static
|
||||
{
|
||||
if (!$this->givenAnswers->contains($givenAnswer)) {
|
||||
$this->givenAnswers->add($givenAnswer);
|
||||
$givenAnswer->setCandidate($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return Collection<int, Correction> */
|
||||
public function getCorrections(): Collection
|
||||
{
|
||||
return $this->corrections;
|
||||
}
|
||||
|
||||
public function addCorrection(Correction $correction): static
|
||||
{
|
||||
if (!$this->corrections->contains($correction)) {
|
||||
$this->corrections->add($correction);
|
||||
$correction->setCandidate($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getNameHash(): string
|
||||
{
|
||||
return Base64::base64_url_encode($this->name);
|
||||
}
|
||||
}
|
||||
74
src/Entity/Correction.php
Normal file
74
src/Entity/Correction.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\CorrectionRepository;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
|
||||
use Symfony\Bridge\Doctrine\Types\UuidType;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
#[ORM\Entity(repositoryClass: CorrectionRepository::class)]
|
||||
#[ORM\UniqueConstraint(columns: ['candidate_id', 'quiz_id'])]
|
||||
class Correction
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: UuidType::NAME, unique: true)]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\CustomIdGenerator(class: UuidGenerator::class)]
|
||||
private ?Uuid $id = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'corrections')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private Candidate $candidate;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'corrections')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private Quiz $quiz;
|
||||
|
||||
#[ORM\Column]
|
||||
private float $amount = 0;
|
||||
|
||||
public function getId(): ?Uuid
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getCandidate(): Candidate
|
||||
{
|
||||
return $this->candidate;
|
||||
}
|
||||
|
||||
public function setCandidate(Candidate $candidate): static
|
||||
{
|
||||
$this->candidate = $candidate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getQuiz(): Quiz
|
||||
{
|
||||
return $this->quiz;
|
||||
}
|
||||
|
||||
public function setQuiz(Quiz $quiz): static
|
||||
{
|
||||
$this->quiz = $quiz;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAmount(): ?float
|
||||
{
|
||||
return $this->amount;
|
||||
}
|
||||
|
||||
public function setAmount(float $amount): static
|
||||
{
|
||||
$this->amount = $amount;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
91
src/Entity/GivenAnswer.php
Normal file
91
src/Entity/GivenAnswer.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\GivenAnswerRepository;
|
||||
use Doctrine\DBAL\Types\Types;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Safe\DateTimeImmutable;
|
||||
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
|
||||
use Symfony\Bridge\Doctrine\Types\UuidType;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
#[ORM\Entity(repositoryClass: GivenAnswerRepository::class)]
|
||||
#[ORM\HasLifecycleCallbacks]
|
||||
class GivenAnswer
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: UuidType::NAME, unique: true)]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\CustomIdGenerator(class: UuidGenerator::class)]
|
||||
private ?Uuid $id = null;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'givenAnswers')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private Candidate $candidate;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private Quiz $quiz;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'givenAnswers')]
|
||||
#[ORM\JoinColumn(nullable: true)]
|
||||
private ?Answer $answer = null;
|
||||
|
||||
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: false)]
|
||||
private \DateTimeInterface $created;
|
||||
|
||||
public function getId(): ?Uuid
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getCandidate(): Candidate
|
||||
{
|
||||
return $this->candidate;
|
||||
}
|
||||
|
||||
public function setCandidate(Candidate $candidate): static
|
||||
{
|
||||
$this->candidate = $candidate;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getQuiz(): ?Quiz
|
||||
{
|
||||
return $this->quiz;
|
||||
}
|
||||
|
||||
public function setQuiz(Quiz $quiz): static
|
||||
{
|
||||
$this->quiz = $quiz;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getAnswer(): ?Answer
|
||||
{
|
||||
return $this->answer;
|
||||
}
|
||||
|
||||
public function setAnswer(?Answer $answer): static
|
||||
{
|
||||
$this->answer = $answer;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCreated(): ?\DateTimeInterface
|
||||
{
|
||||
return $this->created;
|
||||
}
|
||||
|
||||
#[ORM\PrePersist]
|
||||
public function setCreatedAtValue(): void
|
||||
{
|
||||
$this->created = new DateTimeImmutable();
|
||||
}
|
||||
}
|
||||
99
src/Entity/Question.php
Normal file
99
src/Entity/Question.php
Normal file
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\QuestionRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
|
||||
use Symfony\Bridge\Doctrine\Types\UuidType;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
#[ORM\Entity(repositoryClass: QuestionRepository::class)]
|
||||
class Question
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: UuidType::NAME)]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\CustomIdGenerator(class: UuidGenerator::class)]
|
||||
private ?Uuid $id = null;
|
||||
|
||||
#[ORM\Column(length: 255, nullable: false)]
|
||||
private string $question;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'questions')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private Quiz $quiz;
|
||||
|
||||
#[ORM\Column]
|
||||
private bool $enabled = true;
|
||||
|
||||
/** @var Collection<int, Answer> */
|
||||
#[ORM\OneToMany(targetEntity: Answer::class, mappedBy: 'question', cascade: ['persist'], orphanRemoval: true)]
|
||||
private Collection $answers;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->answers = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?Uuid
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getQuestion(): string
|
||||
{
|
||||
return $this->question;
|
||||
}
|
||||
|
||||
public function setQuestion(string $question): static
|
||||
{
|
||||
$this->question = $question;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getQuiz(): Quiz
|
||||
{
|
||||
return $this->quiz;
|
||||
}
|
||||
|
||||
public function setQuiz(Quiz $quiz): static
|
||||
{
|
||||
$this->quiz = $quiz;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isEnabled(): ?bool
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
public function setEnabled(bool $enabled): static
|
||||
{
|
||||
$this->enabled = $enabled;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return Collection<int, Answer> */
|
||||
public function getAnswers(): Collection
|
||||
{
|
||||
return $this->answers;
|
||||
}
|
||||
|
||||
public function addAnswer(Answer $answer): static
|
||||
{
|
||||
if (!$this->answers->contains($answer)) {
|
||||
$this->answers->add($answer);
|
||||
$answer->setQuestion($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
105
src/Entity/Quiz.php
Normal file
105
src/Entity/Quiz.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\QuizRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
|
||||
use Symfony\Bridge\Doctrine\Types\UuidType;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
#[ORM\Entity(repositoryClass: QuizRepository::class)]
|
||||
class Quiz
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: UuidType::NAME)]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\CustomIdGenerator(class: UuidGenerator::class)]
|
||||
private ?Uuid $id = null;
|
||||
|
||||
#[ORM\Column(length: 64)]
|
||||
private string $name;
|
||||
|
||||
#[ORM\ManyToOne(inversedBy: 'quizzes')]
|
||||
#[ORM\JoinColumn(nullable: false)]
|
||||
private Season $season;
|
||||
|
||||
/** @var Collection<int, Question> */
|
||||
#[ORM\OneToMany(targetEntity: Question::class, mappedBy: 'quiz', cascade: ['persist'], orphanRemoval: true)]
|
||||
private Collection $questions;
|
||||
|
||||
/** @var Collection<int, Correction> */
|
||||
#[ORM\OneToMany(targetEntity: Correction::class, mappedBy: 'quiz', orphanRemoval: true)]
|
||||
private Collection $corrections;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->questions = new ArrayCollection();
|
||||
$this->corrections = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?Uuid
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName(): ?string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): static
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSeason(): Season
|
||||
{
|
||||
return $this->season;
|
||||
}
|
||||
|
||||
public function setSeason(Season $season): static
|
||||
{
|
||||
$this->season = $season;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return Collection<int, Question> */
|
||||
public function getQuestions(): Collection
|
||||
{
|
||||
return $this->questions;
|
||||
}
|
||||
|
||||
public function addQuestion(Question $question): static
|
||||
{
|
||||
if (!$this->questions->contains($question)) {
|
||||
$this->questions->add($question);
|
||||
$question->setQuiz($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return Collection<int, Correction> */
|
||||
public function getCorrections(): Collection
|
||||
{
|
||||
return $this->corrections;
|
||||
}
|
||||
|
||||
public function addCorrection(Correction $correction): static
|
||||
{
|
||||
if (!$this->corrections->contains($correction)) {
|
||||
$this->corrections->add($correction);
|
||||
$correction->setQuiz($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
161
src/Entity/Season.php
Normal file
161
src/Entity/Season.php
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\SeasonRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
|
||||
use Symfony\Bridge\Doctrine\Types\UuidType;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
#[ORM\Entity(repositoryClass: SeasonRepository::class)]
|
||||
class Season
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: UuidType::NAME)]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\CustomIdGenerator(class: UuidGenerator::class)]
|
||||
private ?Uuid $id = null;
|
||||
|
||||
#[ORM\Column(length: 64)]
|
||||
private string $name;
|
||||
|
||||
#[ORM\Column(length: 5)]
|
||||
private string $seasonCode;
|
||||
|
||||
#[ORM\Column]
|
||||
private bool $preregisterCandidates;
|
||||
|
||||
/** @var Collection<int, Quiz> */
|
||||
#[ORM\OneToMany(targetEntity: Quiz::class, mappedBy: 'season', orphanRemoval: true)]
|
||||
private Collection $quizzes;
|
||||
|
||||
/** @var Collection<int, Candidate> */
|
||||
#[ORM\OneToMany(targetEntity: Candidate::class, mappedBy: 'season', cascade: ['persist'], orphanRemoval: true)]
|
||||
private Collection $candidates;
|
||||
|
||||
/** @var Collection<int, User> */
|
||||
#[ORM\ManyToMany(targetEntity: User::class, inversedBy: 'seasons')]
|
||||
private Collection $owners;
|
||||
|
||||
#[ORM\ManyToOne]
|
||||
private ?Quiz $ActiveQuiz = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->quizzes = new ArrayCollection();
|
||||
$this->candidates = new ArrayCollection();
|
||||
$this->owners = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?Uuid
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setName(string $name): static
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getSeasonCode(): ?string
|
||||
{
|
||||
return $this->seasonCode;
|
||||
}
|
||||
|
||||
public function setSeasonCode(string $seasonCode): static
|
||||
{
|
||||
$this->seasonCode = $seasonCode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isPreregisterCandidates(): bool
|
||||
{
|
||||
return $this->preregisterCandidates;
|
||||
}
|
||||
|
||||
public function setPreregisterCandidates(bool $preregisterCandidates): static
|
||||
{
|
||||
$this->preregisterCandidates = $preregisterCandidates;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return Collection<int, Quiz> */
|
||||
public function getQuizzes(): Collection
|
||||
{
|
||||
return $this->quizzes;
|
||||
}
|
||||
|
||||
public function addQuiz(Quiz $quiz): static
|
||||
{
|
||||
if (!$this->quizzes->contains($quiz)) {
|
||||
$this->quizzes->add($quiz);
|
||||
$quiz->setSeason($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return Collection<int, Candidate> */
|
||||
public function getCandidates(): Collection
|
||||
{
|
||||
return $this->candidates;
|
||||
}
|
||||
|
||||
public function addCandidate(Candidate $candidate): static
|
||||
{
|
||||
if (!$this->candidates->contains($candidate)) {
|
||||
$this->candidates->add($candidate);
|
||||
$candidate->setSeason($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @return Collection<int, User> */
|
||||
public function getOwners(): Collection
|
||||
{
|
||||
return $this->owners;
|
||||
}
|
||||
|
||||
public function addOwner(User $owner): static
|
||||
{
|
||||
if (!$this->owners->contains($owner)) {
|
||||
$this->owners->add($owner);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeOwner(User $owner): static
|
||||
{
|
||||
$this->owners->removeElement($owner);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getActiveQuiz(): ?Quiz
|
||||
{
|
||||
return $this->ActiveQuiz;
|
||||
}
|
||||
|
||||
public function setActiveQuiz(?Quiz $ActiveQuiz): static
|
||||
{
|
||||
$this->ActiveQuiz = $ActiveQuiz;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
143
src/Entity/User.php
Normal file
143
src/Entity/User.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Entity;
|
||||
|
||||
use App\Repository\UserRepository;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use Doctrine\Common\Collections\Collection;
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
use Symfony\Bridge\Doctrine\IdGenerator\UuidGenerator;
|
||||
use Symfony\Bridge\Doctrine\Types\UuidType;
|
||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
|
||||
#[ORM\Entity(repositoryClass: UserRepository::class)]
|
||||
#[ORM\Table(name: '`user`')]
|
||||
#[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_EMAIL', fields: ['email'])]
|
||||
class User implements UserInterface, PasswordAuthenticatedUserInterface
|
||||
{
|
||||
#[ORM\Id]
|
||||
#[ORM\Column(type: UuidType::NAME, unique: true)]
|
||||
#[ORM\GeneratedValue(strategy: 'CUSTOM')]
|
||||
#[ORM\CustomIdGenerator(class: UuidGenerator::class)]
|
||||
private ?Uuid $id = null;
|
||||
|
||||
#[ORM\Column(length: 180)]
|
||||
private string $email;
|
||||
|
||||
/** @var list<string> The user roles */
|
||||
#[ORM\Column]
|
||||
private array $roles = [];
|
||||
|
||||
/** @var string The hashed password */
|
||||
#[ORM\Column]
|
||||
private string $password;
|
||||
|
||||
/** @var Collection<int, Season> */
|
||||
#[ORM\ManyToMany(targetEntity: Season::class, mappedBy: 'owners')]
|
||||
private Collection $seasons;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->seasons = new ArrayCollection();
|
||||
}
|
||||
|
||||
public function getId(): ?Uuid
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
public function getEmail(): ?string
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
public function setEmail(string $email): static
|
||||
{
|
||||
$this->email = $email;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* A visual identifier that represents this user.
|
||||
*
|
||||
* @see UserInterface
|
||||
*
|
||||
* @return non-empty-string
|
||||
*/
|
||||
public function getUserIdentifier(): string
|
||||
{
|
||||
return $this->email;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see UserInterface
|
||||
*
|
||||
* @return non-empty-list<string>
|
||||
*/
|
||||
public function getRoles(): array
|
||||
{
|
||||
$roles = $this->roles;
|
||||
// guarantee every user at least has ROLE_USER
|
||||
$roles[] = 'ROLE_USER';
|
||||
|
||||
return array_unique($roles);
|
||||
}
|
||||
|
||||
/** @param list<string> $roles */
|
||||
public function setRoles(array $roles): static
|
||||
{
|
||||
$this->roles = $roles;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @see PasswordAuthenticatedUserInterface */
|
||||
public function getPassword(): ?string
|
||||
{
|
||||
return $this->password;
|
||||
}
|
||||
|
||||
public function setPassword(string $password): static
|
||||
{
|
||||
$this->password = $password;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @see UserInterface */
|
||||
public function eraseCredentials(): void
|
||||
{
|
||||
// If you store any temporary, sensitive data on the user, clear it here
|
||||
// $this->plainPassword = null;
|
||||
}
|
||||
|
||||
/** @return Collection<int, Season> */
|
||||
public function getSeasons(): Collection
|
||||
{
|
||||
return $this->seasons;
|
||||
}
|
||||
|
||||
public function addSeason(Season $season): static
|
||||
{
|
||||
if (!$this->seasons->contains($season)) {
|
||||
$this->seasons->add($season);
|
||||
$season->addOwner($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function removeSeason(Season $season): static
|
||||
{
|
||||
if ($this->seasons->removeElement($season)) {
|
||||
$season->removeOwner($this);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
35
src/Form/EnterNameType.php
Normal file
35
src/Form/EnterNameType.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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
|
||||
{
|
||||
public function __construct(private TranslatorInterface $translator)
|
||||
{
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->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
|
||||
]);
|
||||
}
|
||||
}
|
||||
31
src/Form/SelectSeasonType.php
Normal file
31
src/Form/SelectSeasonType.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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\Component\Validator\Constraints\Regex;
|
||||
|
||||
class SelectSeasonType extends AbstractType
|
||||
{
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
$builder
|
||||
->add('season_code', TextType::class,
|
||||
['required' => true, 'constraints' => new Regex(pattern: "/^[A-Za-z\d]{5}$/")],
|
||||
)
|
||||
// ->add('submit', SubmitType::class, ['label' => 'Start quiz'])
|
||||
;
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
// Configure your form options here
|
||||
]);
|
||||
}
|
||||
}
|
||||
25
src/Helpers/Base64.php
Normal file
25
src/Helpers/Base64.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
use Safe\Exceptions\UrlException;
|
||||
|
||||
class Base64
|
||||
{
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function base64_url_encode(string $input): string
|
||||
{
|
||||
return strtr(base64_encode($input), '+/=', '-_.');
|
||||
}
|
||||
|
||||
/** @throws UrlException */
|
||||
public static function base64_url_decode(string $input): string
|
||||
{
|
||||
return \Safe\base64_decode(strtr($input, '-_.', '+/='), true);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
||||
|
||||
20
src/Repository/AnswerRepository.php
Normal file
20
src/Repository/AnswerRepository.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Answer;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Answer>
|
||||
*/
|
||||
class AnswerRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Answer::class);
|
||||
}
|
||||
}
|
||||
34
src/Repository/CandidateRepository.php
Normal file
34
src/Repository/CandidateRepository.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Candidate;
|
||||
use App\Entity\Season;
|
||||
use App\Helpers\Base64;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Safe\Exceptions\UrlException;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Candidate>
|
||||
*/
|
||||
class CandidateRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Candidate::class);
|
||||
}
|
||||
|
||||
public function getCandidateByHash(Season $season, string $hash): ?Candidate
|
||||
{
|
||||
try {
|
||||
$name = Base64::base64_url_decode($hash);
|
||||
} catch (UrlException) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->findOneBy(['season' => $season, 'name' => $name]);
|
||||
}
|
||||
}
|
||||
20
src/Repository/CorrectionRepository.php
Normal file
20
src/Repository/CorrectionRepository.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
20
src/Repository/GivenAnswerRepository.php
Normal file
20
src/Repository/GivenAnswerRepository.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\GivenAnswer;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<GivenAnswer>
|
||||
*/
|
||||
class GivenAnswerRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, GivenAnswer::class);
|
||||
}
|
||||
}
|
||||
20
src/Repository/QuestionRepository.php
Normal file
20
src/Repository/QuestionRepository.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Question;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Question>
|
||||
*/
|
||||
class QuestionRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Question::class);
|
||||
}
|
||||
}
|
||||
20
src/Repository/QuizRepository.php
Normal file
20
src/Repository/QuizRepository.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Quiz;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Quiz>
|
||||
*/
|
||||
class QuizRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Quiz::class);
|
||||
}
|
||||
}
|
||||
20
src/Repository/SeasonRepository.php
Normal file
20
src/Repository/SeasonRepository.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\Season;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Season>
|
||||
*/
|
||||
class SeasonRepository extends ServiceEntityRepository
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, Season::class);
|
||||
}
|
||||
}
|
||||
32
src/Repository/UserRepository.php
Normal file
32
src/Repository/UserRepository.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Repository;
|
||||
|
||||
use App\Entity\User;
|
||||
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
||||
use Doctrine\Persistence\ManagerRegistry;
|
||||
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
|
||||
use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
|
||||
|
||||
/**
|
||||
* @extends ServiceEntityRepository<User>
|
||||
*
|
||||
* @implements PasswordUpgraderInterface<User>
|
||||
*/
|
||||
class UserRepository extends ServiceEntityRepository implements PasswordUpgraderInterface
|
||||
{
|
||||
public function __construct(ManagerRegistry $registry)
|
||||
{
|
||||
parent::__construct($registry, User::class);
|
||||
}
|
||||
|
||||
/** Used to upgrade (rehash) the user's password automatically over time. */
|
||||
public function upgradePassword(PasswordAuthenticatedUserInterface $user, string $newHashedPassword): void
|
||||
{
|
||||
$user->setPassword($newHashedPassword);
|
||||
$this->getEntityManager()->persist($user);
|
||||
$this->getEntityManager()->flush();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user