This commit is contained in:
2025-04-22 23:42:07 +02:00
parent 7b05e52d95
commit 0f07e7eabf
15 changed files with 51 additions and 43 deletions

View File

@@ -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],
];

View File

@@ -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

View File

@@ -1,4 +1,5 @@
parameters:
editorUrl: 'phpstorm://open?file=%%file%%&line=%%line%%'
level: 8
paths:
- bin/

View File

@@ -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

View File

@@ -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)]);
}

View File

@@ -72,7 +72,7 @@ class Answer
return $this;
}
public function isRightAnswer(): ?bool
public function isRightAnswer(): bool
{
return $this->isRightAnswer;
}

View File

@@ -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<string, mixed> */
#[ORM\Column(type: Types::JSON)]
private array $data = [];
public function getId(): ?int
public function getId(): Uuid
{
return $this->id;
}
/** @return array<string, mixed> */
public function getData(): array
{
return $this->data;
}
/** @param array<string, mixed> $data */
public function setData(array $data): static
{
$this->data = $data;

View File

@@ -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;
}

View File

@@ -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';

View File

@@ -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<string>
* @return non-empty-array<int<0, max>, string>
*/
public function getRoles(): array
{

View File

@@ -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<Candidate>
*
* @phpstan-type ResultArray array<string, array{0: Candidate, correct: int, time: DateInterval, corrections?: float, score: float}>
* @phpstan-type Result array{0: Candidate, correct: int, time: \DateInterval, corrections?: float, score: float}
* @phpstan-type ResultList list<Result>
*/
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<string, array{0: Candidate, correct: int, time: \DateInterval, corrections?: float}> $in
*
* @return ResultArray
*/
* @return array<string, Result>
* */
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<string, Result> $results
*
* @return ResultArray
*/
* @return ResultList
* */
private function sortResults(array $results): array
{
usort($results, static fn ($a, $b): int => $b['score'] <=> $a['score']);

View File

@@ -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 {}
}

View File

@@ -17,6 +17,12 @@
href="{{ path('app_backoffice_index') }}">{{ 'Seasons'|trans }}</a>
</li>
</ul>
<ul class="navbar-nav mb-auto me-2 me-lg-0">
<li class="nav-item">
<a class="nav-link"
href="{{ path('app_login_logout') }}">{{ 'Logout'|trans }}</a>
</li>
</ul>
</div>
</div>
</nav>

View File

@@ -1,12 +1,12 @@
<?php
declare(strict_types=1);
use Symfony\Component\Dotenv\Dotenv;
require dirname(__DIR__).'/vendor/autoload.php';
if (method_exists(Dotenv::class, 'bootEnv')) {
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
}
if ($_SERVER['APP_DEBUG']) {
umask(0000);

View File

@@ -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'