Change namespace to Tvdt

This commit is contained in:
2025-09-28 18:14:58 +02:00
parent cfb69c8dab
commit 81e471a760
98 changed files with 531 additions and 534 deletions

View File

@@ -2,10 +2,10 @@
declare(strict_types=1);
namespace App\Controller;
namespace Tvdt\Controller;
use App\Enum\FlashType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as AbstractBaseController;
use Tvdt\Enum\FlashType;
abstract class AbstractController extends AbstractBaseController
{

View File

@@ -2,10 +2,10 @@
declare(strict_types=1);
namespace App\Controller\Admin;
namespace Tvdt\Controller\Admin;
use App\Entity\Answer;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use Tvdt\Entity\Answer;
/** @extends AbstractCrudController<Answer> */
class AnswerCrudController extends AbstractCrudController

View File

@@ -2,10 +2,10 @@
declare(strict_types=1);
namespace App\Controller\Admin;
namespace Tvdt\Controller\Admin;
use App\Entity\Candidate;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use Tvdt\Entity\Candidate;
/** @extends AbstractCrudController<Candidate> */
class CandidateCrudController extends AbstractCrudController

View File

@@ -2,22 +2,22 @@
declare(strict_types=1);
namespace App\Controller\Admin;
namespace Tvdt\Controller\Admin;
use App\Entity\Answer;
use App\Entity\Candidate;
use App\Entity\GivenAnswer;
use App\Entity\Question;
use App\Entity\Quiz;
use App\Entity\QuizCandidate;
use App\Entity\Season;
use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Attribute\AdminDashboard;
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 Tvdt\Entity\Answer;
use Tvdt\Entity\Candidate;
use Tvdt\Entity\GivenAnswer;
use Tvdt\Entity\Question;
use Tvdt\Entity\Quiz;
use Tvdt\Entity\QuizCandidate;
use Tvdt\Entity\Season;
use Tvdt\Entity\User;
#[AdminDashboard(routePath: '/admin', routeName: 'admin')]
class DashboardController extends AbstractDashboardController

View File

@@ -2,10 +2,10 @@
declare(strict_types=1);
namespace App\Controller\Admin;
namespace Tvdt\Controller\Admin;
use App\Entity\GivenAnswer;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use Tvdt\Entity\GivenAnswer;
/** @extends AbstractCrudController<GivenAnswer> */
class GivenAnswerCrudController extends AbstractCrudController

View File

@@ -2,10 +2,10 @@
declare(strict_types=1);
namespace App\Controller\Admin;
namespace Tvdt\Controller\Admin;
use App\Entity\Question;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use Tvdt\Entity\Question;
/** @extends AbstractCrudController<Question> */
class QuestionCrudController extends AbstractCrudController

View File

@@ -2,10 +2,10 @@
declare(strict_types=1);
namespace App\Controller\Admin;
namespace Tvdt\Controller\Admin;
use App\Entity\QuizCandidate;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use Tvdt\Entity\QuizCandidate;
/** @extends AbstractCrudController<QuizCandidate> */
class QuizCorrectionCrudController extends AbstractCrudController

View File

@@ -2,10 +2,10 @@
declare(strict_types=1);
namespace App\Controller\Admin;
namespace Tvdt\Controller\Admin;
use App\Entity\Quiz;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use Tvdt\Entity\Quiz;
/** @extends AbstractCrudController<Quiz> */
class QuizCrudController extends AbstractCrudController

View File

@@ -2,10 +2,10 @@
declare(strict_types=1);
namespace App\Controller\Admin;
namespace Tvdt\Controller\Admin;
use App\Entity\Season;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use Tvdt\Entity\Season;
/** @extends AbstractCrudController<Season> */
class SeasonCrudController extends AbstractCrudController

View File

@@ -2,10 +2,10 @@
declare(strict_types=1);
namespace App\Controller\Admin;
namespace Tvdt\Controller\Admin;
use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use Tvdt\Entity\User;
/** @extends AbstractCrudController<User> */
class UserCrudController extends AbstractCrudController

View File

@@ -2,14 +2,8 @@
declare(strict_types=1);
namespace App\Controller\Backoffice;
namespace Tvdt\Controller\Backoffice;
use App\Controller\AbstractController;
use App\Entity\Season;
use App\Entity\User;
use App\Form\CreateSeasonFormType;
use App\Repository\SeasonRepository;
use App\Service\QuizSpreadsheetService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\Request;
@@ -18,6 +12,12 @@ use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Tvdt\Controller\AbstractController;
use Tvdt\Entity\Season;
use Tvdt\Entity\User;
use Tvdt\Form\CreateSeasonFormType;
use Tvdt\Repository\SeasonRepository;
use Tvdt\Service\QuizSpreadsheetService;
#[AsController]
#[IsGranted('ROLE_USER')]
@@ -28,7 +28,7 @@ final class BackofficeController extends AbstractController
private readonly Security $security,
) {}
#[Route('/backoffice/', name: 'app_backoffice_index')]
#[Route('/backoffice/', name: 'tvdt_backoffice_index')]
public function index(): Response
{
$user = $this->getUser();
@@ -43,7 +43,7 @@ final class BackofficeController extends AbstractController
]);
}
#[Route('/backoffice/season/add', name: 'app_backoffice_season_add', priority: 10)]
#[Route('/backoffice/season/add', name: 'tvdt_backoffice_season_add', priority: 10)]
public function addSeason(Request $request, EntityManagerInterface $em): Response
{
$season = new Season();
@@ -61,13 +61,13 @@ final class BackofficeController extends AbstractController
$em->persist($season);
$em->flush();
return $this->redirectToRoute('app_backoffice_season', ['seasonCode' => $season->getSeasonCode()]);
return $this->redirectToRoute('tvdt_backoffice_season', ['seasonCode' => $season->getSeasonCode()]);
}
return $this->render('backoffice/season_add.html.twig', ['form' => $form]);
}
#[Route('/backoffice/template', name: 'app_backoffice_template', priority: 10)]
#[Route('/backoffice/template', name: 'tvdt_backoffice_template', priority: 10)]
public function getTemplate(QuizSpreadsheetService $excel): Response
{
$response = new StreamedResponse($excel->generateTemplate());

View File

@@ -2,36 +2,36 @@
declare(strict_types=1);
namespace App\Controller\Backoffice;
namespace Tvdt\Controller\Backoffice;
use App\Controller\AbstractController;
use App\Entity\Elimination;
use App\Entity\Quiz;
use App\Entity\Season;
use App\Factory\EliminationFactory;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Requirement\Requirement;
use Tvdt\Controller\AbstractController;
use Tvdt\Entity\Elimination;
use Tvdt\Entity\Quiz;
use Tvdt\Entity\Season;
use Tvdt\Factory\EliminationFactory;
final class PrepareEliminationController extends AbstractController
{
#[Route(
'/backoffice/season/{seasonCode:season}/quiz/{quiz}/elimination/prepare',
name: 'app_prepare_elimination',
name: 'tvdt_prepare_elimination',
requirements: ['seasonCode' => self::SEASON_CODE_REGEX, 'quiz' => Requirement::UUID],
)]
public function index(Season $season, Quiz $quiz, EliminationFactory $eliminationFactory): Response
{
$elimination = $eliminationFactory->createEliminationFromQuiz($quiz);
return $this->redirectToRoute('app_prepare_elimination_view', ['elimination' => $elimination->getId()]);
return $this->redirectToRoute('tvdt_prepare_elimination_view', ['elimination' => $elimination->getId()]);
}
#[Route(
'/backoffice/elimination/{elimination}',
name: 'app_prepare_elimination_view',
name: 'tvdt_prepare_elimination_view',
requirements: ['elimination' => Requirement::UUID],
)]
public function viewElimination(Elimination $elimination, Request $request, EntityManagerInterface $em): Response
@@ -41,7 +41,7 @@ final class PrepareEliminationController extends AbstractController
$em->flush();
if ($request->request->getBoolean('start')) {
return $this->redirectToRoute('app_elimination', ['elimination' => $elimination->getId()]);
return $this->redirectToRoute('tvdt_elimination', ['elimination' => $elimination->getId()]);
}
$this->addFlash('success', 'Elimination updated');

View File

@@ -2,17 +2,8 @@
declare(strict_types=1);
namespace App\Controller\Backoffice;
namespace Tvdt\Controller\Backoffice;
use App\Controller\AbstractController;
use App\Entity\Candidate;
use App\Entity\Quiz;
use App\Entity\Season;
use App\Exception\ErrorClearingQuizException;
use App\Repository\CandidateRepository;
use App\Repository\QuizCandidateRepository;
use App\Repository\QuizRepository;
use App\Security\Voter\SeasonVoter;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
@@ -23,6 +14,15 @@ use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Requirement\Requirement;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Contracts\Translation\TranslatorInterface;
use Tvdt\Controller\AbstractController;
use Tvdt\Entity\Candidate;
use Tvdt\Entity\Quiz;
use Tvdt\Entity\Season;
use Tvdt\Exception\ErrorClearingQuizException;
use Tvdt\Repository\CandidateRepository;
use Tvdt\Repository\QuizCandidateRepository;
use Tvdt\Repository\QuizRepository;
use Tvdt\Security\Voter\SeasonVoter;
#[AsController]
#[IsGranted('ROLE_USER')]
@@ -35,7 +35,7 @@ class QuizController extends AbstractController
#[Route(
'/backoffice/season/{seasonCode:season}/quiz/{quiz}',
name: 'app_backoffice_quiz',
name: 'tvdt_backoffice_quiz',
requirements: ['seasonCode' => self::SEASON_CODE_REGEX, 'quiz' => Requirement::UUID],
)]
#[IsGranted(SeasonVoter::EDIT, subject: 'season')]
@@ -50,7 +50,7 @@ class QuizController extends AbstractController
#[Route(
'/backoffice/season/{seasonCode:season}/quiz/{quiz}/enable',
name: 'app_backoffice_enable',
name: 'tvdt_backoffice_enable',
requirements: ['seasonCode' => self::SEASON_CODE_REGEX, 'quiz' => Requirement::UUID.'|null'],
)]
#[IsGranted(SeasonVoter::EDIT, subject: 'season')]
@@ -60,15 +60,15 @@ class QuizController extends AbstractController
$em->flush();
if ($quiz instanceof Quiz) {
return $this->redirectToRoute('app_backoffice_quiz', ['seasonCode' => $season->getSeasonCode(), 'quiz' => $quiz->getId()]);
return $this->redirectToRoute('tvdt_backoffice_quiz', ['seasonCode' => $season->getSeasonCode(), 'quiz' => $quiz->getId()]);
}
return $this->redirectToRoute('app_backoffice_season', ['seasonCode' => $season->getSeasonCode()]);
return $this->redirectToRoute('tvdt_backoffice_season', ['seasonCode' => $season->getSeasonCode()]);
}
#[Route(
'/backoffice/quiz/{quiz}/clear',
name: 'app_backoffice_quiz_clear',
name: 'tvdt_backoffice_quiz_clear',
requirements: ['quiz' => Requirement::UUID],
)]
#[IsGranted(SeasonVoter::EDIT, subject: 'quiz')]
@@ -81,12 +81,12 @@ class QuizController extends AbstractController
$this->addFlash('error', $this->translator->trans('Error clearing quiz'));
}
return $this->redirectToRoute('app_backoffice_quiz', ['seasonCode' => $quiz->getSeason()->getSeasonCode(), 'quiz' => $quiz->getId()]);
return $this->redirectToRoute('tvdt_backoffice_quiz', ['seasonCode' => $quiz->getSeason()->getSeasonCode(), 'quiz' => $quiz->getId()]);
}
#[Route(
'/backoffice/quiz/{quiz}/delete',
name: 'app_backoffice_quiz_delete',
name: 'tvdt_backoffice_quiz_delete',
requirements: ['quiz' => Requirement::UUID],
)]
#[IsGranted(SeasonVoter::DELETE, subject: 'quiz')]
@@ -96,12 +96,12 @@ class QuizController extends AbstractController
$this->addFlash('success', $this->translator->trans('Quiz deleted'));
return $this->redirectToRoute('app_backoffice_season', ['seasonCode' => $quiz->getSeason()->getSeasonCode()]);
return $this->redirectToRoute('tvdt_backoffice_season', ['seasonCode' => $quiz->getSeason()->getSeasonCode()]);
}
#[Route(
'/backoffice/quiz/{quiz}/candidate/{candidate}/modify_correction',
name: 'app_backoffice_modify_correction',
name: 'tvdt_backoffice_modify_correction',
requirements: ['quiz' => Requirement::UUID, 'candidate' => Requirement::UUID],
)]
#[IsGranted(SeasonVoter::EDIT, subject: 'quiz')]
@@ -115,6 +115,6 @@ class QuizController extends AbstractController
$quizCandidateRepository->setCorrectionsForCandidate($quiz, $candidate, $corrections);
return $this->redirectToRoute('app_backoffice_quiz', ['seasonCode' => $quiz->getSeason()->getSeasonCode(), 'quiz' => $quiz->getId()]);
return $this->redirectToRoute('tvdt_backoffice_quiz', ['seasonCode' => $quiz->getSeason()->getSeasonCode(), 'quiz' => $quiz->getId()]);
}
}

View File

@@ -2,18 +2,8 @@
declare(strict_types=1);
namespace App\Controller\Backoffice;
namespace Tvdt\Controller\Backoffice;
use App\Controller\AbstractController;
use App\Entity\Candidate;
use App\Entity\Quiz;
use App\Entity\Season;
use App\Enum\FlashType;
use App\Form\AddCandidatesFormType;
use App\Form\SettingsForm;
use App\Form\UploadQuizFormType;
use App\Security\Voter\SeasonVoter;
use App\Service\QuizSpreadsheetService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
@@ -22,6 +12,16 @@ use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Contracts\Translation\TranslatorInterface;
use Tvdt\Controller\AbstractController;
use Tvdt\Entity\Candidate;
use Tvdt\Entity\Quiz;
use Tvdt\Entity\Season;
use Tvdt\Enum\FlashType;
use Tvdt\Form\AddCandidatesFormType;
use Tvdt\Form\SettingsForm;
use Tvdt\Form\UploadQuizFormType;
use Tvdt\Security\Voter\SeasonVoter;
use Tvdt\Service\QuizSpreadsheetService;
#[AsController]
#[IsGranted('ROLE_USER')]
@@ -34,7 +34,7 @@ class SeasonController extends AbstractController
#[Route(
'/backoffice/season/{seasonCode:season}',
name: 'app_backoffice_season',
name: 'tvdt_backoffice_season',
requirements: ['seasonCode' => self::SEASON_CODE_REGEX],
)]
#[IsGranted(SeasonVoter::EDIT, subject: 'season')]
@@ -56,7 +56,7 @@ class SeasonController extends AbstractController
#[Route(
'/backoffice/season/{seasonCode:season}/add-candidate',
name: 'app_backoffice_add_candidates',
name: 'tvdt_backoffice_add_candidates',
requirements: ['seasonCode' => self::SEASON_CODE_REGEX],
priority: 10,
)]
@@ -74,7 +74,7 @@ class SeasonController extends AbstractController
$this->em->flush();
return $this->redirectToRoute('app_backoffice_season', ['seasonCode' => $season->getSeasonCode()]);
return $this->redirectToRoute('tvdt_backoffice_season', ['seasonCode' => $season->getSeasonCode()]);
}
return $this->render('backoffice/season_add_candidates.html.twig', ['form' => $form]);
@@ -82,7 +82,7 @@ class SeasonController extends AbstractController
#[Route(
'/backoffice/season/{seasonCode:season}/add-quiz',
name: 'app_backoffice_quiz_add',
name: 'tvdt_backoffice_quiz_add',
requirements: ['seasonCode' => self::SEASON_CODE_REGEX],
priority: 10,
)]
@@ -106,7 +106,7 @@ class SeasonController extends AbstractController
$this->addFlash(FlashType::Success, $this->translator->trans('Quiz Added!'));
return $this->redirectToRoute('app_backoffice_season', ['seasonCode' => $season->getSeasonCode()]);
return $this->redirectToRoute('tvdt_backoffice_season', ['seasonCode' => $season->getSeasonCode()]);
}
return $this->render('/backoffice/quiz_add.html.twig', ['form' => $form, 'season' => $season]);

View File

@@ -2,15 +2,8 @@
declare(strict_types=1);
namespace App\Controller;
namespace Tvdt\Controller;
use App\Entity\Candidate;
use App\Entity\Elimination;
use App\Enum\FlashType;
use App\Form\EliminationEnterNameType;
use App\Helpers\Base64;
use App\Repository\CandidateRepository;
use App\Security\Voter\SeasonVoter;
use Symfony\Bridge\Doctrine\Attribute\MapEntity;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@@ -19,6 +12,13 @@ use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Requirement\Requirement;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Symfony\Contracts\Translation\TranslatorInterface;
use Tvdt\Entity\Candidate;
use Tvdt\Entity\Elimination;
use Tvdt\Enum\FlashType;
use Tvdt\Form\EliminationEnterNameType;
use Tvdt\Helpers\Base64;
use Tvdt\Repository\CandidateRepository;
use Tvdt\Security\Voter\SeasonVoter;
use function Symfony\Component\Translation\t;
@@ -28,7 +28,7 @@ final class EliminationController extends AbstractController
{
public function __construct(private readonly TranslatorInterface $translator) {}
#[Route('/elimination/{elimination}', name: 'app_elimination', requirements: ['elimination' => Requirement::UUID])]
#[Route('/elimination/{elimination}', name: 'tvdt_elimination', requirements: ['elimination' => Requirement::UUID])]
#[IsGranted(SeasonVoter::ELIMINATION, 'elimination')]
public function index(#[MapEntity] Elimination $elimination, Request $request): Response
{
@@ -39,7 +39,7 @@ final class EliminationController extends AbstractController
if ($form->isSubmitted() && $form->isValid()) {
$name = $form->get('name')->getData();
return $this->redirectToRoute('app_elimination_candidate', ['elimination' => $elimination->getId(), 'candidateHash' => Base64::base64UrlEncode($name)]);
return $this->redirectToRoute('tvdt_elimination_candidate', ['elimination' => $elimination->getId(), 'candidateHash' => Base64::base64UrlEncode($name)]);
}
return $this->render('quiz/elimination/index.html.twig', [
@@ -48,7 +48,7 @@ final class EliminationController extends AbstractController
]);
}
#[Route('/elimination/{elimination}/{candidateHash}', name: 'app_elimination_candidate', requirements: ['elimination' => Requirement::UUID, 'candidateHash' => self::CANDIDATE_HASH_REGEX])]
#[Route('/elimination/{elimination}/{candidateHash}', name: 'tvdt_elimination_candidate', requirements: ['elimination' => Requirement::UUID, 'candidateHash' => self::CANDIDATE_HASH_REGEX])]
#[IsGranted(SeasonVoter::ELIMINATION, 'elimination')]
public function candidateScreen(Elimination $elimination, string $candidateHash, CandidateRepository $candidateRepository): Response
{
@@ -58,7 +58,7 @@ final class EliminationController extends AbstractController
t('Cound not find candidate with name %name%', ['%name%' => Base64::base64UrlDecode($candidateHash)])->trans($this->translator),
);
return $this->redirectToRoute('app_elimination', ['elimination' => $elimination->getId()]);
return $this->redirectToRoute('tvdt_elimination', ['elimination' => $elimination->getId()]);
}
$screenColour = $elimination->getScreenColour($candidate->getName());
@@ -66,7 +66,7 @@ final class EliminationController extends AbstractController
if (null === $screenColour) {
$this->addFlash(FlashType::Warning, $this->translator->trans('Cound not find candidate with name %name% in elimination.', ['%name%' => $candidate->getName()]));
return $this->redirectToRoute('app_elimination', ['elimination' => $elimination->getId()]);
return $this->redirectToRoute('tvdt_elimination', ['elimination' => $elimination->getId()]);
}
return $this->render('quiz/elimination/candidate.html.twig', [

View File

@@ -2,20 +2,20 @@
declare(strict_types=1);
namespace App\Controller;
namespace Tvdt\Controller;
use App\Enum\FlashType;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\Translation\TranslatorInterface;
use Tvdt\Enum\FlashType;
#[AsController]
final class LoginController extends AbstractController
{
#[Route(path: '/login', name: 'app_login_login')]
#[Route(path: '/login', name: 'tvdt_login_login')]
public function login(AuthenticationUtils $authenticationUtils, TranslatorInterface $translator): Response
{
// get the login error if there is one
@@ -34,7 +34,7 @@ final class LoginController extends AbstractController
]);
}
#[Route(path: '/logout', name: 'app_login_logout')]
#[Route(path: '/logout', name: 'tvdt_login_logout')]
public function logout(): never
{
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');

View File

@@ -2,37 +2,37 @@
declare(strict_types=1);
namespace App\Controller;
namespace Tvdt\Controller;
use App\Entity\Answer;
use App\Entity\Candidate;
use App\Entity\GivenAnswer;
use App\Entity\Question;
use App\Entity\Quiz;
use App\Entity\Season;
use App\Enum\FlashType;
use App\Form\EnterNameType;
use App\Form\SelectSeasonType;
use App\Helpers\Base64;
use App\Repository\AnswerRepository;
use App\Repository\CandidateRepository;
use App\Repository\GivenAnswerRepository;
use App\Repository\QuestionRepository;
use App\Repository\QuizCandidateRepository;
use App\Repository\SeasonRepository;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
use Tvdt\Entity\Answer;
use Tvdt\Entity\Candidate;
use Tvdt\Entity\GivenAnswer;
use Tvdt\Entity\Question;
use Tvdt\Entity\Quiz;
use Tvdt\Entity\Season;
use Tvdt\Enum\FlashType;
use Tvdt\Form\EnterNameType;
use Tvdt\Form\SelectSeasonType;
use Tvdt\Helpers\Base64;
use Tvdt\Repository\AnswerRepository;
use Tvdt\Repository\CandidateRepository;
use Tvdt\Repository\GivenAnswerRepository;
use Tvdt\Repository\QuestionRepository;
use Tvdt\Repository\QuizCandidateRepository;
use Tvdt\Repository\SeasonRepository;
#[AsController]
final class QuizController extends AbstractController
{
public function __construct(private readonly TranslatorInterface $translator) {}
#[Route(path: '/', name: 'app_quiz_select_season', methods: ['GET', 'POST'])]
#[Route(path: '/', name: 'tvdt_quiz_select_season', methods: ['GET', 'POST'])]
public function selectSeason(Request $request, SeasonRepository $seasonRepository): Response
{
$form = $this->createForm(SelectSeasonType::class);
@@ -44,16 +44,16 @@ final class QuizController extends AbstractController
if ([] === $seasonRepository->findBy(['seasonCode' => $seasonCode])) {
$this->addFlash(FlashType::Warning, $this->translator->trans('Invalid season code'));
return $this->redirectToRoute('app_quiz_select_season');
return $this->redirectToRoute('tvdt_quiz_select_season');
}
return $this->redirectToRoute('app_quiz_enter_name', ['seasonCode' => $seasonCode]);
return $this->redirectToRoute('tvdt_quiz_enter_name', ['seasonCode' => $seasonCode]);
}
return $this->render('quiz/select_season.html.twig', ['form' => $form]);
}
#[Route(path: '/{seasonCode:season}', name: 'app_quiz_enter_name', requirements: ['seasonCode' => self::SEASON_CODE_REGEX])]
#[Route(path: '/{seasonCode:season}', name: 'tvdt_quiz_enter_name', requirements: ['seasonCode' => self::SEASON_CODE_REGEX])]
public function enterName(
Request $request,
Season $season,
@@ -65,7 +65,7 @@ final class QuizController extends AbstractController
if ($form->isSubmitted() && $form->isValid()) {
$name = $form->get('name')->getData();
return $this->redirectToRoute('app_quiz_quiz_page', ['seasonCode' => $season->getSeasonCode(), 'nameHash' => Base64::base64UrlEncode($name)]);
return $this->redirectToRoute('tvdt_quiz_quiz_page', ['seasonCode' => $season->getSeasonCode(), 'nameHash' => Base64::base64UrlEncode($name)]);
}
return $this->render('quiz/enter_name.twig', ['season' => $season, 'form' => $form]);
@@ -73,7 +73,7 @@ final class QuizController extends AbstractController
#[Route(
path: '/{seasonCode:season}/{nameHash}',
name: 'app_quiz_quiz_page',
name: 'tvdt_quiz_quiz_page',
requirements: ['seasonCode' => self::SEASON_CODE_REGEX, 'nameHash' => self::CANDIDATE_HASH_REGEX],
)]
public function quizPage(
@@ -91,7 +91,7 @@ final class QuizController extends AbstractController
if (!$candidate instanceof Candidate) {
$this->addFlash(FlashType::Danger, $this->translator->trans('Candidate not found'));
return $this->redirectToRoute('app_quiz_enter_name', ['seasonCode' => $season->getSeasonCode()]);
return $this->redirectToRoute('tvdt_quiz_enter_name', ['seasonCode' => $season->getSeasonCode()]);
}
$quiz = $season->getActiveQuiz();
@@ -99,7 +99,7 @@ final class QuizController extends AbstractController
if (!$quiz instanceof Quiz) {
$this->addFlash(FlashType::Warning, $this->translator->trans('There is no active quiz'));
return $this->redirectToRoute('app_quiz_enter_name', ['seasonCode' => $season->getSeasonCode()]);
return $this->redirectToRoute('tvdt_quiz_enter_name', ['seasonCode' => $season->getSeasonCode()]);
}
if ('POST' === $request->getMethod()) {
@@ -112,7 +112,7 @@ final class QuizController extends AbstractController
$givenAnswer = new GivenAnswer($candidate, $answer->getQuestion()->getQuiz(), $answer);
$givenAnswerRepository->save($givenAnswer);
return $this->redirectToRoute('app_quiz_quiz_page', ['seasonCode' => $season->getSeasonCode(), 'nameHash' => $nameHash]);
return $this->redirectToRoute('tvdt_quiz_quiz_page', ['seasonCode' => $season->getSeasonCode(), 'nameHash' => $nameHash]);
}
$question = $questionRepository->findNextQuestionForCandidate($candidate);
@@ -120,7 +120,7 @@ final class QuizController extends AbstractController
if (!$question instanceof Question) {
$this->addFlash(FlashType::Success, $this->translator->trans('Quiz completed'));
return $this->redirectToRoute('app_quiz_enter_name', ['seasonCode' => $season->getSeasonCode()]);
return $this->redirectToRoute('tvdt_quiz_enter_name', ['seasonCode' => $season->getSeasonCode()]);
}
$quizCandidateRepository->createIfNotExist($quiz, $candidate);

View File

@@ -2,12 +2,8 @@
declare(strict_types=1);
namespace App\Controller;
namespace Tvdt\Controller;
use App\Entity\User;
use App\Form\RegistrationFormType;
use App\Repository\UserRepository;
use App\Security\EmailVerifier;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
@@ -20,12 +16,16 @@ use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
use SymfonyCasts\Bundle\VerifyEmail\Exception\VerifyEmailExceptionInterface;
use Tvdt\Entity\User;
use Tvdt\Form\RegistrationFormType;
use Tvdt\Repository\UserRepository;
use Tvdt\Security\EmailVerifier;
final class RegistrationController extends AbstractController
{
public function __construct(private readonly EmailVerifier $emailVerifier, private readonly TranslatorInterface $translator) {}
#[Route('/register', name: 'app_register')]
#[Route('/register', name: 'tvdt_register')]
public function register(
Request $request,
UserPasswordHasherInterface $userPasswordHasher,
@@ -48,7 +48,7 @@ final class RegistrationController extends AbstractController
try {
// generate a signed url and email it to the user
$this->emailVerifier->sendEmailConfirmation('app_verify_email', $user,
$this->emailVerifier->sendEmailConfirmation('tvdt_verify_email', $user,
new TemplatedEmail()
->to((string) $user->getEmail())
->subject($this->translator->trans('Please Confirm your Email'))
@@ -69,19 +69,19 @@ final class RegistrationController extends AbstractController
]);
}
#[Route('/verify/email', name: 'app_verify_email')]
#[Route('/verify/email', name: 'tvdt_verify_email')]
public function verifyUserEmail(Request $request, TranslatorInterface $translator, UserRepository $userRepository): Response
{
$id = $request->query->get('id');
if (null === $id) {
return $this->redirectToRoute('app_register');
return $this->redirectToRoute('tvdt_register');
}
$user = $userRepository->find($id);
if (null === $user) {
return $this->redirectToRoute('app_register');
return $this->redirectToRoute('tvdt_register');
}
// validate email confirmation link, sets User::isVerified=true and persists
@@ -90,11 +90,11 @@ final class RegistrationController extends AbstractController
} catch (VerifyEmailExceptionInterface $verifyEmailException) {
$this->addFlash('verify_email_error', $translator->trans($verifyEmailException->getReason(), [], 'VerifyEmailBundle'));
return $this->redirectToRoute('app_register');
return $this->redirectToRoute('tvdt_register');
}
$this->addFlash('success', $this->translator->trans('Your email address has been verified.'));
return $this->redirectToRoute('app_backoffice_index');
return $this->redirectToRoute('tvdt_backoffice_index');
}
}