diff --git a/config/bundles.php b/config/bundles.php index 2765491..4e50234 100644 --- a/config/bundles.php +++ b/config/bundles.php @@ -17,17 +17,17 @@ use SymfonyCasts\Bundle\VerifyEmail\SymfonyCastsVerifyEmailBundle; use Twig\Extra\TwigExtraBundle\TwigExtraBundle; return [ - DoctrineBundle::class => ['all' => true], - DoctrineFixturesBundle::class => ['dev' => true, 'test' => true], - DoctrineMigrationsBundle::class => ['all' => true], - EasyAdminBundle::class => ['all' => true], FrameworkBundle::class => ['all' => true], + DoctrineBundle::class => ['all' => true], + DoctrineMigrationsBundle::class => ['all' => true], MakerBundle::class => ['dev' => true], - SecurityBundle::class => ['all' => true], - SentryBundle::class => ['prod' => true], - SymfonyCastsVerifyEmailBundle::class => ['all' => true], TwigBundle::class => ['all' => true], - TwigComponentBundle::class => ['all' => true], - TwigExtraBundle::class => ['all' => true], + SecurityBundle::class => ['all' => true], WebProfilerBundle::class => ['dev' => true, 'test' => true], + TwigExtraBundle::class => ['all' => true], + TwigComponentBundle::class => ['all' => true], + EasyAdminBundle::class => ['all' => true], + DoctrineFixturesBundle::class => ['dev' => true, 'test' => true], + SymfonyCastsVerifyEmailBundle::class => ['all' => true], + SentryBundle::class => ['prod' => true], ]; diff --git a/config/packages/framework.yaml b/config/packages/framework.yaml index 4d76e69..b3dd751 100644 --- a/config/packages/framework.yaml +++ b/config/packages/framework.yaml @@ -9,7 +9,7 @@ framework: enabled: true #esi: true #fragments: true - +when@prod: # shortcut for private IP address ranges of your proxy trusted_proxies: 'private_ranges' # or, if your proxy instead uses the "Forwarded" header diff --git a/phpstan.dist.neon b/phpstan.dist.neon index e9bd41c..524626a 100644 --- a/phpstan.dist.neon +++ b/phpstan.dist.neon @@ -1,4 +1,5 @@ parameters: + editorUrl: 'phpstorm://open?file=%%file%%&line=%%line%%' level: 8 paths: - bin/ diff --git a/src/Command/MakeAdminCommand.php b/src/Command/MakeAdminCommand.php index e9034a6..24ad15f 100644 --- a/src/Command/MakeAdminCommand.php +++ b/src/Command/MakeAdminCommand.php @@ -18,15 +18,11 @@ use Symfony\Component\Console\Style\SymfonyStyle; )] class MakeAdminCommand extends Command { - public function __construct(private UserRepository $userRepository) + public function __construct(private readonly UserRepository $userRepository) { parent::__construct(); } - - - - protected function configure(): void { $this diff --git a/src/Controller/QuizController.php b/src/Controller/QuizController.php index 9b6c241..b51aedc 100644 --- a/src/Controller/QuizController.php +++ b/src/Controller/QuizController.php @@ -42,16 +42,15 @@ final class QuizController extends AbstractController $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $data = $form->getData(); - $season_code = $data['season_code']; + $seasonCode = $form->get('season_code')->getData(); - if ([] === $seasonRepository->findBy(['seasonCode' => $season_code])) { + if ([] === $seasonRepository->findBy(['seasonCode' => $seasonCode])) { $this->addFlash(FlashType::Warning, $this->translator->trans('Invalid season code')); return $this->redirectToRoute('app_quiz_selectseason'); } - return $this->redirectToRoute('app_quiz_entername', ['seasonCode' => $season_code]); + return $this->redirectToRoute('app_quiz_entername', ['seasonCode' => $seasonCode]); } return $this->render('quiz/select_season.html.twig', ['form' => $form]); @@ -68,8 +67,7 @@ final class QuizController extends AbstractController $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $data = $form->getData(); - $name = $data['name']; + $name = $form->get('name')->getData(); return $this->redirectToRoute('app_quiz_quizpage', ['seasonCode' => $season->getSeasonCode(), 'nameHash' => Base64::base64UrlEncode($name)]); } diff --git a/src/Entity/Answer.php b/src/Entity/Answer.php index 3e5f13a..bd7247d 100644 --- a/src/Entity/Answer.php +++ b/src/Entity/Answer.php @@ -72,7 +72,7 @@ class Answer return $this; } - public function isRightAnswer(): ?bool + public function isRightAnswer(): bool { return $this->isRightAnswer; } diff --git a/src/Entity/Elimination.php b/src/Entity/Elimination.php index ec47233..8624b74 100644 --- a/src/Entity/Elimination.php +++ b/src/Entity/Elimination.php @@ -18,21 +18,24 @@ class Elimination #[ORM\Column(type: UuidType::NAME, unique: true)] #[ORM\GeneratedValue(strategy: 'CUSTOM')] #[ORM\CustomIdGenerator(class: UuidGenerator::class)] - private ?Uuid $id = null; + private Uuid $id; + /** @var array */ #[ORM\Column(type: Types::JSON)] private array $data = []; - public function getId(): ?int + public function getId(): Uuid { return $this->id; } + /** @return array */ public function getData(): array { return $this->data; } + /** @param array $data */ public function setData(array $data): static { $this->data = $data; diff --git a/src/Entity/GivenAnswer.php b/src/Entity/GivenAnswer.php index 49fd04c..851d311 100644 --- a/src/Entity/GivenAnswer.php +++ b/src/Entity/GivenAnswer.php @@ -20,7 +20,7 @@ class GivenAnswer #[ORM\Column(type: UuidType::NAME, unique: true)] #[ORM\GeneratedValue(strategy: 'CUSTOM')] #[ORM\CustomIdGenerator(class: UuidGenerator::class)] - private ?Uuid $id = null; + private Uuid $id; #[ORM\ManyToOne(inversedBy: 'givenAnswers')] #[ORM\JoinColumn(nullable: false)] @@ -35,7 +35,7 @@ class GivenAnswer private ?Answer $answer = null; #[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: false)] - private \DateTimeInterface $created; + private \DateTimeImmutable $created; public function getId(): ?Uuid { @@ -78,7 +78,7 @@ class GivenAnswer return $this; } - public function getCreated(): \DateTimeInterface + public function getCreated(): \DateTimeImmutable { return $this->created; } diff --git a/src/Entity/Question.php b/src/Entity/Question.php index cddcd36..8177cbd 100644 --- a/src/Entity/Question.php +++ b/src/Entity/Question.php @@ -103,7 +103,7 @@ class Question return 'This question has no answers'; } - $correctAnswers = $this->answers->filter(static fn (Answer $answer): ?bool => $answer->isRightAnswer())->count(); + $correctAnswers = $this->answers->filter(static fn (Answer $answer): bool => $answer->isRightAnswer())->count(); if (0 === $correctAnswers) { return 'This question has no correct answers'; diff --git a/src/Entity/User.php b/src/Entity/User.php index 5f742bd..097edd7 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -76,13 +76,16 @@ class User implements UserInterface, PasswordAuthenticatedUserInterface */ public function getUserIdentifier(): string { - return $this->email; + /** @var non-empty-string $identifier */ + $identifier = $this->email; + + return $identifier; } /** * @see UserInterface * - * @return non-empty-list + * @return non-empty-array, string> */ public function getRoles(): array { diff --git a/src/Repository/CandidateRepository.php b/src/Repository/CandidateRepository.php index c789d35..4b69d52 100644 --- a/src/Repository/CandidateRepository.php +++ b/src/Repository/CandidateRepository.php @@ -9,7 +9,6 @@ use App\Entity\Correction; use App\Entity\Quiz; use App\Entity\Season; use App\Helpers\Base64; -use DateInterval; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\ORM\Query\Expr\Join; use Doctrine\Persistence\ManagerRegistry; @@ -18,7 +17,8 @@ use Safe\Exceptions\UrlException; /** * @extends ServiceEntityRepository * - * @phpstan-type ResultArray array + * @phpstan-type Result array{0: Candidate, correct: int, time: \DateInterval, corrections?: float, score: float} + * @phpstan-type ResultList list */ class CandidateRepository extends ServiceEntityRepository { @@ -52,7 +52,7 @@ class CandidateRepository extends ServiceEntityRepository } } - /** @return ResultArray */ + /** @return ResultList */ public function getScores(Quiz $quiz): array { $scoreTimeQb = $this->createQueryBuilder('c', 'c.id') @@ -76,8 +76,8 @@ class CandidateRepository extends ServiceEntityRepository /** * @param array $in * - * @return ResultArray - */ + * @return array + * */ private function calculateScore(array $in): array { return array_map(static fn ($candidate): array => [ @@ -87,10 +87,10 @@ class CandidateRepository extends ServiceEntityRepository } /** - * @param ResultArray $results + * @param array $results * - * @return ResultArray - */ + * @return ResultList + * */ private function sortResults(array $results): array { usort($results, static fn ($a, $b): int => $b['score'] <=> $a['score']); diff --git a/src/Service/EliminationService.php b/src/Service/EliminationService.php index c23a2c7..d22adbf 100644 --- a/src/Service/EliminationService.php +++ b/src/Service/EliminationService.php @@ -7,10 +7,10 @@ namespace App\Service; use App\Repository\CandidateRepository; /** - * @phpstan-import-type ResultArray from CandidateRepository + * @phpstan-import-type ResultList from CandidateRepository */ class EliminationService { - /** @phpstan-param ResultArray $result */ + /** @phpstan-param ResultList $result */ public function createEliminationFromResult(array $result): void {} } diff --git a/templates/backoffice/nav.html.twig b/templates/backoffice/nav.html.twig index ae63aee..f4c1c95 100644 --- a/templates/backoffice/nav.html.twig +++ b/templates/backoffice/nav.html.twig @@ -17,6 +17,12 @@ href="{{ path('app_backoffice_index') }}">{{ 'Seasons'|trans }} + diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 47a5855..96185bd 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,12 +1,12 @@ bootEnv(dirname(__DIR__).'/.env'); -} +(new Dotenv())->bootEnv(dirname(__DIR__).'/.env'); if ($_SERVER['APP_DEBUG']) { umask(0000); diff --git a/translations/messages+intl-icu.nl.yaml b/translations/messages+intl-icu.nl.yaml index c4c8eb8..2b6522e 100644 --- a/translations/messages+intl-icu.nl.yaml +++ b/translations/messages+intl-icu.nl.yaml @@ -11,6 +11,7 @@ Email: E-mail 'Enter your name': 'Voor je naam in' 'Invalid season code': 'Ongeldige seizoenscode' 'Load Prepared Elimination': 'Laad voorbereide eliminatie' +Logout: Uitloggen Manage: Beheren Name: Naam 'No active quiz': 'Geen actieve test'