diff --git a/migrations/Version20250610210417.php b/migrations/Version20250610210417.php new file mode 100644 index 0000000..83f6260 --- /dev/null +++ b/migrations/Version20250610210417.php @@ -0,0 +1,48 @@ +addSql(<<<'SQL' + CREATE TABLE season_settings (id UUID NOT NULL, show_numbers BOOLEAN DEFAULT false NOT NULL, confirm_answers BOOLEAN DEFAULT false NOT NULL, PRIMARY KEY(id)) + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE season ADD settings_id UUID DEFAULT NULL + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE season ADD CONSTRAINT FK_F0E45BA959949888 FOREIGN KEY (settings_id) REFERENCES season_settings (id) NOT DEFERRABLE INITIALLY IMMEDIATE + SQL); + $this->addSql(<<<'SQL' + CREATE UNIQUE INDEX UNIQ_F0E45BA959949888 ON season (settings_id) + SQL); + } + + public function down(Schema $schema): void + { + $this->addSql(<<<'SQL' + DROP TABLE season_settings + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE season DROP CONSTRAINT FK_F0E45BA959949888 + SQL); + $this->addSql(<<<'SQL' + DROP INDEX UNIQ_F0E45BA959949888 + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE season DROP settings_id + SQL); + } +} diff --git a/src/Command/AddSettingsCommand.php b/src/Command/AddSettingsCommand.php new file mode 100644 index 0000000..e1fece5 --- /dev/null +++ b/src/Command/AddSettingsCommand.php @@ -0,0 +1,40 @@ +seasonRepository->findAll() as $season) { + if (null !== $season->getSettings()) { + continue; + } + $io->text('Adding settings to season : '.$season->getSeasonCode()); + $season->setSettings(new SeasonSettings()); + } + + $this->entityManager->flush(); + + return Command::SUCCESS; + } +} diff --git a/src/Controller/Backoffice/SeasonController.php b/src/Controller/Backoffice/SeasonController.php index 901631e..7b27719 100644 --- a/src/Controller/Backoffice/SeasonController.php +++ b/src/Controller/Backoffice/SeasonController.php @@ -10,6 +10,7 @@ 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; @@ -26,7 +27,9 @@ use Symfony\Contracts\Translation\TranslatorInterface; #[IsGranted('ROLE_USER')] class SeasonController extends AbstractController { - public function __construct(private readonly TranslatorInterface $translator, private readonly EntityManagerInterface $em, + public function __construct( + private readonly TranslatorInterface $translator, + private readonly EntityManagerInterface $em, ) {} #[Route( @@ -35,10 +38,19 @@ class SeasonController extends AbstractController requirements: ['seasonCode' => self::SEASON_CODE_REGEX], )] #[IsGranted(SeasonVoter::EDIT, subject: 'season')] - public function index(Season $season): Response + public function index(Season $season, Request $request): Response { + $form = $this->createForm(SettingsForm::class, $season->getSettings()); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $this->em->flush(); + } + return $this->render('backoffice/season.html.twig', [ 'season' => $season, + 'form' => $form, ]); } diff --git a/src/Controller/QuizController.php b/src/Controller/QuizController.php index d4e6fbb..590ba8d 100644 --- a/src/Controller/QuizController.php +++ b/src/Controller/QuizController.php @@ -125,6 +125,6 @@ final class QuizController extends AbstractController $quizCandidateRepository->createIfNotExist($quiz, $candidate); - return $this->render('quiz/question.twig', ['candidate' => $candidate, 'question' => $question]); + return $this->render('quiz/question.twig', ['candidate' => $candidate, 'question' => $question, 'season' => $season]); } } diff --git a/src/Entity/Season.php b/src/Entity/Season.php index 4d866a4..e135a06 100644 --- a/src/Entity/Season.php +++ b/src/Entity/Season.php @@ -46,8 +46,13 @@ class Season #[ORM\JoinColumn(nullable: true, onDelete: 'SET NULL')] private ?Quiz $ActiveQuiz = null; + #[ORM\OneToOne(cascade: ['persist', 'remove'])] + #[ORM\JoinColumn(nullable: true)] + private ?SeasonSettings $settings = null; + public function __construct() { + $this->settings = new SeasonSettings(); $this->quizzes = new ArrayCollection(); $this->candidates = new ArrayCollection(); $this->owners = new ArrayCollection(); @@ -166,4 +171,16 @@ class Season return $this; } + + public function getSettings(): ?SeasonSettings + { + return $this->settings; + } + + public function setSettings(SeasonSettings $settings): static + { + $this->settings = $settings; + + return $this; + } } diff --git a/src/Entity/SeasonSettings.php b/src/Entity/SeasonSettings.php new file mode 100644 index 0000000..cb1a262 --- /dev/null +++ b/src/Entity/SeasonSettings.php @@ -0,0 +1,57 @@ + false])] + private bool $showNumbers = false; + + #[ORM\Column(type: Types::BOOLEAN, options: ['default' => false])] + private bool $confirmAnswers = false; + + public function getId(): Uuid + { + return $this->id; + } + + public function isShowNumbers(): bool + { + return $this->showNumbers; + } + + public function setShowNumbers(bool $showNumbers): self + { + $this->showNumbers = $showNumbers; + + return $this; + } + + public function isConfirmAnswers(): bool + { + return $this->confirmAnswers; + } + + public function setConfirmAnswers(bool $confirmAnswers): self + { + $this->confirmAnswers = $confirmAnswers; + + return $this; + } +} diff --git a/src/Form/SettingsForm.php b/src/Form/SettingsForm.php new file mode 100644 index 0000000..36acb18 --- /dev/null +++ b/src/Form/SettingsForm.php @@ -0,0 +1,35 @@ + */ +class SettingsForm extends AbstractType +{ + public function buildForm(FormBuilderInterface $builder, array $options): void + { + $builder + ->add('showNumbers', options: [ + 'label_attr' => ['class' => 'checkbox-switch'], + 'attr' => ['role' => 'switch', 'switch' => null]]) + ->add('confirmAnswers', options: [ + 'label_attr' => ['class' => 'checkbox-switch'], + 'attr' => ['role' => 'switch', 'switch' => null]]) + ->add('save', SubmitType::class) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => SeasonSettings::class, + ]); + } +} diff --git a/src/Repository/SeasonSettingsRepository.php b/src/Repository/SeasonSettingsRepository.php new file mode 100644 index 0000000..b0fb073 --- /dev/null +++ b/src/Repository/SeasonSettingsRepository.php @@ -0,0 +1,20 @@ + + */ +class SeasonSettingsRepository extends ServiceEntityRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, SeasonSettings::class); + } +} diff --git a/templates/backoffice/season.html.twig b/templates/backoffice/season.html.twig index eb6a7f4..9e3c3af 100644 --- a/templates/backoffice/season.html.twig +++ b/templates/backoffice/season.html.twig @@ -21,13 +21,18 @@