Compare commits

..

1 Commits

Author SHA1 Message Date
Marijn 281462fab8 Added Gedmo stuff, fix translations (#117)
* Added Gedmo stuff, fix translations

* Add CSRF token validation across backoffice forms

- Added CSRF validations to candidate correction, penalty, answer saving, and elimination forms.
- Updated corresponding Twig templates to include CSRF token inputs.
- Adjusted column count in `tab_result` template to maintain layout consistency.

* Add unique index constraint for `quiz_candidate` with soft delete support

- Updated migration to include a unique index on `quiz_candidate` table that excludes soft-deleted records.
- Adjusted `QuizCandidate` entity to reflect the new unique constraint with `deleted_at` condition.

* Add CSRF token validation for quiz-related actions

- Added CSRF validation to `enableQuiz`, `clearQuiz`, `deleteQuiz`, `toggleCandidate`, and `prepareElimination` actions.
- Updated Twig templates to replace links with POST forms to include CSRF tokens.
- Set HTTP method restrictions for related endpoints to `POST`.

* Fix unique index condition for `quiz_candidate` with soft deletes

- Updated condition in unique index definition of `quiz_candidate` to add parentheses for clarity.
- Adjusted related migration to reflect the revised condition.

* Remove if for post an use methods in Route instead

* Refactor CSRF token validation in backoffice controllers

- Applied `#[IsCsrfTokenValid]` attribute for CSRF checks to simplify and standardize validation.
- Removed manual `isCsrfTokenValid` calls and associated exception throwing.
- Updated method signatures across affected endpoints to remove unnecessary `Request` dependency.
- Ensured consistency in route HTTP method restrictions where applicable.

* Add rector and phpstan

* Add validation for answering incorrect quiz question

- Added logic to prevent candidates from answering questions out of sequence in `QuizController`.
- Updated Dutch translations to include the new error message.

* Things
2026-05-24 19:43:30 +02:00
6 changed files with 35 additions and 5 deletions
+16 -4
View File
@@ -15,12 +15,15 @@ concurrency:
permissions:
contents: read
packages: write
jobs:
tests:
name: Tests
runs-on: ubuntu-latest
permissions:
checks: write
pull-requests: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v4
@@ -49,9 +52,9 @@ jobs:
- name: Twig Coding Style
run: docker compose exec -T php vendor/bin/twig-cs-fixer check
- name: Static Analysis (PHPStan)
run: docker compose exec -T php vendor/bin/phpstan analyse --no-progress --no-ansi
run: docker compose exec -T php vendor/bin/phpstan analyse --no-progress --no-ansi --error-format=github
- name: Rector
run: docker compose exec -T php vendor/bin/rector process --dry-run
run: docker compose exec -T php vendor/bin/rector process --dry-run --no-progress-bar --output-format=github
- name: Check HTTP reachability
run: curl -v --fail-with-body http://localhost
- name: Check Mercure reachability
@@ -64,12 +67,21 @@ jobs:
- name: Load fixtures
run: docker compose exec -T php bin/console -e test doctrine:fixtures:load --no-interaction --group=test
- name: Run PHPUnit
run: docker compose exec -T php vendor/bin/phpunit
run: docker compose exec -T php vendor/bin/phpunit --log-junit var/phpunit/junit.xml
- name: Publish PHPUnit test results
if: always()
uses: mikepenz/action-junit-report@v5
with:
report_paths: var/phpunit/junit.xml
check_name: PHPUnit
- name: Doctrine Schema Validator
run: docker compose exec -T php bin/console -e test doctrine:schema:validate
build-deploy:
name: Build and deploy to ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }}
permissions:
contents: read
packages: write
environment:
name: ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }}
url: ${{ vars.URL }}
+1 -1
View File
@@ -61,7 +61,7 @@ services:
image: axllent/mailpit
ports:
- "1025"
- "8025"
- "8025:8025"
environment:
MP_SMTP_AUTH_ACCEPT_ANY: 1
MP_SMTP_AUTH_ALLOW_INSECURE: 1
+2
View File
@@ -0,0 +1,2 @@
symfonycasts_verify_email:
lifetime: 604800 # 1 week in seconds
+6
View File
@@ -117,6 +117,12 @@ final class QuizController extends AbstractController
return $this->redirectToRoute('tvdt_quiz_quiz_page', ['seasonCode' => $season->seasonCode, 'nameHash' => $nameHash]);
}
if ($answer->question !== $this->questionRepository->findNextQuestionForCandidate($candidate)) {
$this->addFlash(FlashType::Danger, $this->translator->trans('You cannot answer this question'));
return $this->redirectToRoute('tvdt_quiz_quiz_page', ['seasonCode' => $season->seasonCode, 'nameHash' => $nameHash]);
}
$givenAnswer = new GivenAnswer($candidate, $answer->question->quiz, $answer);
$this->entityManager->persist($givenAnswer);
$this->entityManager->flush();
+6
View File
@@ -12,6 +12,7 @@ use Tvdt\Entity\Candidate;
use Tvdt\Entity\Question;
use Tvdt\Entity\Quiz;
use Tvdt\Entity\Season;
use Tvdt\Entity\SeasonSettings;
final class KrtekFixtures extends Fixture implements FixtureGroupInterface
{
@@ -48,6 +49,11 @@ final class KrtekFixtures extends Fixture implements FixtureGroupInterface
$season->activeQuiz = $quiz1;
$season->addQuiz($this->createQuiz2($season));
\assert($season->settings instanceof SeasonSettings);
$season->settings->confirmAnswers = true;
$season->settings->showNumbers = true;
$manager->flush();
$this->addReference(self::KRTEK_SEASON, $season);
+4
View File
@@ -433,6 +433,10 @@
<source>You are not allowed to answer this quiz</source>
<target>Je mag deze test niet beantwoorden</target>
</trans-unit>
<trans-unit id="78moQnF" resname="You cannot answer this question">
<source>You cannot answer this question</source>
<target>Je kan deze vraag niet beantwoorden</target>
</trans-unit>
<trans-unit id="0afY1NF" resname="You have no seasons yet.">
<source>You have no seasons yet.</source>
<target>Je hebt nog geen seizoenen.</target>