Create Testcoverage and upgrade Symfomy and PHP
Some checks failed
CI / Tests (push) Failing after 1m8s
CI / Build and deploy to ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }} (push) Has been skipped

* Some tests

* More tests!

* Tests 3

* Move getScores from Candidate to Quiz

* Add some suggestions for future refactoring

* - **Add Gedmo doctrine-extensions and Stof bundle integration**
  - Added `stof/doctrine-extensions-bundle` and `gedmo/doctrine-extensions` dependencies.
  - Integrated `Timestampable` behavior for `Created` fields in entities.
  - Updated `bundles.php` to register StofDoctrineExtensionsBundle.
  - Added configuration for the Stof bundle.
  - Simplified `SeasonVoter` with `match` expression and added new tests.
  - Minor fixes and adjustments across various files.

* WIP

* All the tests

* Base64 tests

* Symfomny 7.4.0

* Update

* Update recipe

* PHP 8.5

* Rector changes

* More 8.5

* Things
This commit is contained in:
2025-11-28 22:56:09 +01:00
committed by GitHub
parent fc273638ad
commit bcd6a157a8
56 changed files with 4324 additions and 1424 deletions

View File

@@ -26,6 +26,7 @@ final class BackofficeController extends AbstractController
public function __construct(
private readonly SeasonRepository $seasonRepository,
private readonly Security $security,
private readonly QuizSpreadsheetService $excel,
) {}
#[Route('/backoffice/', name: 'tvdt_backoffice_index')]
@@ -68,9 +69,9 @@ final class BackofficeController extends AbstractController
}
#[Route('/backoffice/template', name: 'tvdt_backoffice_template', priority: 10)]
public function getTemplate(QuizSpreadsheetService $excel): Response
public function getTemplate(): StreamedResponse
{
$response = new StreamedResponse($excel->generateTemplate());
$response = new StreamedResponse($this->excel->generateTemplate());
$response->headers->set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
$response->headers->set('Content-Disposition', 'attachment; filename="template.xlsx"');

View File

@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Tvdt\Controller\Backoffice;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
@@ -17,14 +18,16 @@ use Tvdt\Factory\EliminationFactory;
final class PrepareEliminationController extends AbstractController
{
public function __construct(private readonly EliminationFactory $eliminationFactory) {}
#[Route(
'/backoffice/season/{seasonCode:season}/quiz/{quiz}/elimination/prepare',
name: 'tvdt_prepare_elimination',
requirements: ['seasonCode' => self::SEASON_CODE_REGEX, 'quiz' => Requirement::UUID],
)]
public function index(Season $season, Quiz $quiz, EliminationFactory $eliminationFactory): Response
public function index(Season $season, Quiz $quiz): RedirectResponse
{
$elimination = $eliminationFactory->createEliminationFromQuiz($quiz);
$elimination = $this->eliminationFactory->createEliminationFromQuiz($quiz);
return $this->redirectToRoute('tvdt_prepare_elimination_view', ['elimination' => $elimination->id]);
}

View File

@@ -19,7 +19,6 @@ 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;
@@ -29,8 +28,9 @@ use Tvdt\Security\Voter\SeasonVoter;
class QuizController extends AbstractController
{
public function __construct(
private readonly CandidateRepository $candidateRepository,
private readonly QuizRepository $quizRepository,
private readonly TranslatorInterface $translator,
private readonly QuizCandidateRepository $quizCandidateRepository,
) {}
#[IsGranted(SeasonVoter::EDIT, subject: 'season')]
@@ -44,7 +44,7 @@ class QuizController extends AbstractController
return $this->render('backoffice/quiz.html.twig', [
'season' => $season,
'quiz' => $quiz,
'result' => $this->candidateRepository->getScores($quiz),
'result' => $this->quizRepository->getScores($quiz),
]);
}
@@ -72,10 +72,10 @@ class QuizController extends AbstractController
name: 'tvdt_backoffice_quiz_clear',
requirements: ['quiz' => Requirement::UUID],
)]
public function clearQuiz(Quiz $quiz, QuizRepository $quizRepository): RedirectResponse
public function clearQuiz(Quiz $quiz): RedirectResponse
{
try {
$quizRepository->clearQuiz($quiz);
$this->quizRepository->clearQuiz($quiz);
$this->addFlash('success', $this->translator->trans('Quiz cleared'));
} catch (ErrorClearingQuizException) {
$this->addFlash('error', $this->translator->trans('Error clearing quiz'));
@@ -90,9 +90,9 @@ class QuizController extends AbstractController
name: 'tvdt_backoffice_quiz_delete',
requirements: ['quiz' => Requirement::UUID],
)]
public function deleteQuiz(Quiz $quiz, QuizRepository $quizRepository): RedirectResponse
public function deleteQuiz(Quiz $quiz): RedirectResponse
{
$quizRepository->deleteQuiz($quiz);
$this->quizRepository->deleteQuiz($quiz);
$this->addFlash('success', $this->translator->trans('Quiz deleted'));
@@ -105,7 +105,7 @@ class QuizController extends AbstractController
name: 'tvdt_backoffice_modify_correction',
requirements: ['quiz' => Requirement::UUID, 'candidate' => Requirement::UUID],
)]
public function modifyCorrection(Quiz $quiz, Candidate $candidate, QuizCandidateRepository $quizCandidateRepository, Request $request): RedirectResponse
public function modifyCorrection(Quiz $quiz, Candidate $candidate, Request $request): RedirectResponse
{
if (!$request->isMethod('POST')) {
throw new MethodNotAllowedHttpException(['POST']);
@@ -113,7 +113,7 @@ class QuizController extends AbstractController
$corrections = (float) $request->request->get('corrections');
$quizCandidateRepository->setCorrectionsForCandidate($quiz, $candidate, $corrections);
$this->quizCandidateRepository->setCorrectionsForCandidate($quiz, $candidate, $corrections);
return $this->redirectToRoute('tvdt_backoffice_quiz', ['seasonCode' => $quiz->season->seasonCode, 'quiz' => $quiz->id]);
}

View File

@@ -30,6 +30,7 @@ class SeasonController extends AbstractController
public function __construct(
private readonly TranslatorInterface $translator,
private readonly EntityManagerInterface $em,
private readonly QuizSpreadsheetService $quizSpreadsheet,
) {}
#[IsGranted(SeasonVoter::EDIT, subject: 'season')]
@@ -87,7 +88,7 @@ class SeasonController extends AbstractController
requirements: ['seasonCode' => self::SEASON_CODE_REGEX],
priority: 10,
)]
public function addQuiz(Request $request, Season $season, QuizSpreadsheetService $quizSpreadsheet): Response
public function addQuiz(Request $request, Season $season): Response
{
$quiz = new Quiz();
$form = $this->createForm(UploadQuizFormType::class, $quiz);
@@ -98,7 +99,7 @@ class SeasonController extends AbstractController
/* @var UploadedFile $sheet */
$sheet = $form->get('sheet')->getData();
$quizSpreadsheet->xlsxToQuiz($quiz, $sheet);
$this->quizSpreadsheet->xlsxToQuiz($quiz, $sheet);
$quiz->season = $season;
$this->em->persist($quiz);