mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-03-07 13:14:20 +01:00
Compare commits
2 Commits
acf5c06fcc
...
c70f713f7e
| Author | SHA1 | Date | |
|---|---|---|---|
|
c70f713f7e
|
|||
|
31e6ed406b
|
47
.github/workflows/ci.yml
vendored
47
.github/workflows/ci.yml
vendored
@@ -16,14 +16,11 @@ jobs:
|
|||||||
name: Tests
|
name: Tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
-
|
- name: Set up Docker Buildx
|
||||||
name: Set up Docker Buildx
|
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
-
|
- name: Build Docker images
|
||||||
name: Build Docker images
|
|
||||||
uses: docker/bake-action@v4
|
uses: docker/bake-action@v4
|
||||||
with:
|
with:
|
||||||
pull: true
|
pull: true
|
||||||
@@ -35,42 +32,30 @@ jobs:
|
|||||||
*.cache-from=type=gha,scope=${{github.ref}}
|
*.cache-from=type=gha,scope=${{github.ref}}
|
||||||
*.cache-from=type=gha,scope=refs/heads/main
|
*.cache-from=type=gha,scope=refs/heads/main
|
||||||
*.cache-to=type=gha,scope=${{github.ref}},mode=max
|
*.cache-to=type=gha,scope=${{github.ref}},mode=max
|
||||||
-
|
- name: Start services
|
||||||
name: Start services
|
|
||||||
run: docker compose up --wait --no-build
|
run: docker compose up --wait --no-build
|
||||||
-
|
- name: Check HTTP reachability
|
||||||
name: Check HTTP reachability
|
|
||||||
run: curl -v --fail-with-body http://localhost
|
run: curl -v --fail-with-body http://localhost
|
||||||
-
|
- name: Check HTTPS reachability
|
||||||
name: Check HTTPS reachability
|
|
||||||
if: false # Remove this line when the homepage will be configured, or change the path to check
|
if: false # Remove this line when the homepage will be configured, or change the path to check
|
||||||
run: curl -vk --fail-with-body https://localhost
|
run: curl -vk --fail-with-body https://localhost
|
||||||
-
|
- name: Check Mercure reachability
|
||||||
name: Check Mercure reachability
|
|
||||||
run: curl -vkI --fail-with-body https://localhost/.well-known/mercure?topic=test
|
run: curl -vkI --fail-with-body https://localhost/.well-known/mercure?topic=test
|
||||||
-
|
- name: Create test database
|
||||||
name: Create test database
|
|
||||||
if: false # Remove this line if Doctrine ORM is installed
|
|
||||||
run: docker compose exec -T php bin/console -e test doctrine:database:create
|
run: docker compose exec -T php bin/console -e test doctrine:database:create
|
||||||
-
|
- name: Run migrations
|
||||||
name: Run migrations
|
|
||||||
if: false # Remove this line if Doctrine Migrations is installed
|
|
||||||
run: docker compose exec -T php bin/console -e test doctrine:migrations:migrate --no-interaction
|
run: docker compose exec -T php bin/console -e test doctrine:migrations:migrate --no-interaction
|
||||||
-
|
- name: Run PHPUnit
|
||||||
name: Run PHPUnit
|
if: false # Remove this line when the tests are ready
|
||||||
if: false # Remove this line if PHPUnit is installed
|
run: docker compose exec -T php vendor/bin/phpunit
|
||||||
run: docker compose exec -T php bin/phpunit
|
- name: Doctrine Schema Validator
|
||||||
-
|
|
||||||
name: Doctrine Schema Validator
|
|
||||||
if: false # Remove this line if Doctrine ORM is installed
|
|
||||||
run: docker compose exec -T php bin/console -e test doctrine:schema:validate
|
run: docker compose exec -T php bin/console -e test doctrine:schema:validate
|
||||||
lint:
|
lint:
|
||||||
name: Docker Lint
|
name: Docker Lint
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
-
|
- name: Checkout
|
||||||
name: Checkout
|
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
-
|
- name: Lint Dockerfile
|
||||||
name: Lint Dockerfile
|
|
||||||
uses: hadolint/hadolint-action@v3.1.0
|
uses: hadolint/hadolint-action@v3.1.0
|
||||||
|
|
||||||
|
|||||||
4
.idea/TijdVoorDeTest.iml
generated
4
.idea/TijdVoorDeTest.iml
generated
@@ -6,7 +6,6 @@
|
|||||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="App\Tests\" />
|
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="App\Tests\" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/clue/ndjson-react" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/clue/ndjson-react" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/cache" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/collections" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/collections" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/dbal" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/dbal" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/deprecations" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/deprecations" />
|
||||||
@@ -48,8 +47,6 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/rector/rector" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/rector/rector" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/runtime/frankenphp-symfony" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/runtime/frankenphp-symfony" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/cli-parser" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/cli-parser" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/complexity" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/complexity" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/diff" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/diff" />
|
||||||
@@ -134,6 +131,7 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/vincentlanglet/twig-cs-fixer" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/vincentlanglet/twig-cs-fixer" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/webmozart/assert" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/webmozart/assert" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php84" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
|||||||
4
.idea/php.xml
generated
4
.idea/php.xml
generated
@@ -70,7 +70,6 @@
|
|||||||
<path value="$PROJECT_DIR$/vendor/symfony/stopwatch" />
|
<path value="$PROJECT_DIR$/vendor/symfony/stopwatch" />
|
||||||
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-migrations-bundle" />
|
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-migrations-bundle" />
|
||||||
<path value="$PROJECT_DIR$/vendor/doctrine/migrations" />
|
<path value="$PROJECT_DIR$/vendor/doctrine/migrations" />
|
||||||
<path value="$PROJECT_DIR$/vendor/doctrine/cache" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
|
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
|
||||||
<path value="$PROJECT_DIR$/vendor/doctrine/dbal" />
|
<path value="$PROJECT_DIR$/vendor/doctrine/dbal" />
|
||||||
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
|
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
|
||||||
@@ -112,8 +111,6 @@
|
|||||||
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
|
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
|
||||||
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
|
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
|
||||||
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
|
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
|
||||||
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
|
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
|
||||||
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
|
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
|
||||||
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
|
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
|
||||||
@@ -164,6 +161,7 @@
|
|||||||
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
|
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
|
||||||
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
|
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
|
||||||
<path value="$PROJECT_DIR$/vendor/vincentlanglet/twig-cs-fixer" />
|
<path value="$PROJECT_DIR$/vendor/vincentlanglet/twig-cs-fixer" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php84" />
|
||||||
</include_path>
|
</include_path>
|
||||||
</component>
|
</component>
|
||||||
<component name="PhpInterpreters">
|
<component name="PhpInterpreters">
|
||||||
|
|||||||
27
Justfile
Normal file
27
Justfile
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
up:
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
down *args:
|
||||||
|
docker compose down {{ args }} --remove-orphans
|
||||||
|
|
||||||
|
stop:
|
||||||
|
docker compose stop
|
||||||
|
|
||||||
|
exec *args:
|
||||||
|
docker compose exec php {{ args }}
|
||||||
|
|
||||||
|
[no-exit-message]
|
||||||
|
shell:
|
||||||
|
@docker compose exec php bash
|
||||||
|
|
||||||
|
migrate: up
|
||||||
|
docker compose run --rm php bin/console doctrine:migrations:migrate --no-interaction
|
||||||
|
|
||||||
|
fixtures:
|
||||||
|
docker compose exec php bin/console doctrine:fixtures:load --purge-with-truncate --no-interaction
|
||||||
|
|
||||||
|
translations:
|
||||||
|
docker compose exec php bin/console translation:extract --domain=messages --force --format=yaml --sort=asc --clean nl
|
||||||
|
|
||||||
|
fix-cs:
|
||||||
|
docker compose exec php vendor/bin/php-cs-fixer fix
|
||||||
22
Taskfile.yml
22
Taskfile.yml
@@ -1,22 +0,0 @@
|
|||||||
version: '3'
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
up:
|
|
||||||
cmds:
|
|
||||||
- docker compose up -d
|
|
||||||
down:
|
|
||||||
cmds:
|
|
||||||
- docker compose down
|
|
||||||
stop:
|
|
||||||
cmds:
|
|
||||||
- docker compose stop
|
|
||||||
shell:
|
|
||||||
cmds:
|
|
||||||
- docker compose exec app bash
|
|
||||||
migrate:
|
|
||||||
cmds:
|
|
||||||
- docker compose run php bin/console doctrine:migrations:migrate
|
|
||||||
|
|
||||||
translations:
|
|
||||||
cmds:
|
|
||||||
- docker compose exec php bin/console translation:extract --domain=messages --force --format=yaml --sort=asc --clean nl
|
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/env php
|
#!/usr/bin/env php
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
use App\Kernel;
|
use App\Kernel;
|
||||||
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
use Symfony\Bundle\FrameworkBundle\Console\Application;
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
"ext-iconv": "*",
|
"ext-iconv": "*",
|
||||||
"doctrine/dbal": "^4.2.3",
|
"doctrine/dbal": "^4.2.3",
|
||||||
"doctrine/doctrine-bundle": "^2.13.2",
|
"doctrine/doctrine-bundle": "^2.14.0",
|
||||||
"doctrine/doctrine-migrations-bundle": "^3.4.1",
|
"doctrine/doctrine-migrations-bundle": "^3.4.1",
|
||||||
"doctrine/orm": "^3.3.2",
|
"doctrine/orm": "^3.3.2",
|
||||||
"easycorp/easyadmin-bundle": "^4.24.5",
|
"easycorp/easyadmin-bundle": "^4.24.5",
|
||||||
@@ -26,19 +26,19 @@
|
|||||||
"symfony/twig-bundle": "7.2.*",
|
"symfony/twig-bundle": "7.2.*",
|
||||||
"symfony/uid": "7.2.*",
|
"symfony/uid": "7.2.*",
|
||||||
"symfony/yaml": "7.2.*",
|
"symfony/yaml": "7.2.*",
|
||||||
"thecodingmachine/safe": "^2.5"
|
"thecodingmachine/safe": "^3.0.2"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"roave/security-advisories": "dev-latest",
|
"doctrine/doctrine-fixtures-bundle": "^4.1",
|
||||||
"doctrine/doctrine-fixtures-bundle": "^4.0",
|
"friendsofphp/php-cs-fixer": "^3.75.0",
|
||||||
"friendsofphp/php-cs-fixer": "^3.71.0",
|
|
||||||
"phpstan/extension-installer": "^1.4.3",
|
"phpstan/extension-installer": "^1.4.3",
|
||||||
"phpstan/phpstan": "^2.1.8",
|
"phpstan/phpstan": "^2.1.11",
|
||||||
"phpstan/phpstan-doctrine": "^2.0.2",
|
"phpstan/phpstan-doctrine": "^2.0.2",
|
||||||
"phpstan/phpstan-phpunit": "^2.0.4",
|
"phpstan/phpstan-phpunit": "^2.0.6",
|
||||||
"phpstan/phpstan-symfony": "^2.0.2",
|
"phpstan/phpstan-symfony": "^2.0.4",
|
||||||
"phpunit/phpunit": "^11.5.12",
|
"phpunit/phpunit": "^12.0.10",
|
||||||
"rector/rector": "^2.0.10",
|
"rector/rector": "^2.0.11",
|
||||||
|
"roave/security-advisories": "dev-latest",
|
||||||
"symfony/maker-bundle": "^1.62.1",
|
"symfony/maker-bundle": "^1.62.1",
|
||||||
"symfony/stopwatch": "7.2.*",
|
"symfony/stopwatch": "7.2.*",
|
||||||
"symfony/web-profiler-bundle": "7.2.*",
|
"symfony/web-profiler-bundle": "7.2.*",
|
||||||
|
|||||||
1220
composer.lock
generated
1220
composer.lock
generated
File diff suppressed because it is too large
Load Diff
31
migrations/Version20250402185128.php
Normal file
31
migrations/Version20250402185128.php
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace DoctrineMigrations;
|
||||||
|
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated Migration: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
final class Version20250402185128 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'add elimination table';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this up() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('CREATE TABLE elimination (id UUID NOT NULL, data JSON NOT NULL, PRIMARY KEY(id))');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
// this down() migration is auto-generated, please modify it to your needs
|
||||||
|
$this->addSql('DROP TABLE elimination');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,7 +27,7 @@ class TestCommand extends Command
|
|||||||
{
|
{
|
||||||
new SymfonyStyle($input, $output);
|
new SymfonyStyle($input, $output);
|
||||||
|
|
||||||
dd($this->candidateRepository->getScores($this->quizRepository->find('1effa06a-8aca-6c52-b52b-3974eda7eed7')));
|
dd($this->candidateRepository->getScores($this->quizRepository->find('1f00ff44-6f12-630e-9b87-67e78e97c05e')));
|
||||||
|
|
||||||
return Command::SUCCESS;
|
return Command::SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ use App\Entity\Quiz;
|
|||||||
use App\Entity\Season;
|
use App\Entity\Season;
|
||||||
use App\Repository\CandidateRepository;
|
use App\Repository\CandidateRepository;
|
||||||
use App\Repository\SeasonRepository;
|
use App\Repository\SeasonRepository;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
use Symfony\Component\HttpKernel\Attribute\AsController;
|
use Symfony\Component\HttpKernel\Attribute\AsController;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
@@ -21,7 +20,7 @@ final class BackofficeController extends AbstractController
|
|||||||
private readonly CandidateRepository $candidateRepository,
|
private readonly CandidateRepository $candidateRepository,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
#[Route('/backoffice/', name: 'index')]
|
#[Route('/backoffice/', name: 'app_backoffice_index')]
|
||||||
public function index(): Response
|
public function index(): Response
|
||||||
{
|
{
|
||||||
$seasons = $this->seasonRepository->findAll();
|
$seasons = $this->seasonRepository->findAll();
|
||||||
@@ -31,7 +30,7 @@ final class BackofficeController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/backoffice/{seasonCode}', name: 'season')]
|
#[Route('/backoffice/{seasonCode}', name: 'app_backoffice_season')]
|
||||||
public function season(Season $season): Response
|
public function season(Season $season): Response
|
||||||
{
|
{
|
||||||
return $this->render('backoffice/season.html.twig', [
|
return $this->render('backoffice/season.html.twig', [
|
||||||
@@ -39,7 +38,7 @@ final class BackofficeController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/backoffice/{seasonCode}/{quiz}', name: 'quiz')]
|
#[Route('/backoffice/{seasonCode}/{quiz}', name: 'app_backoffice_quiz')]
|
||||||
public function quiz(Season $season, Quiz $quiz): Response
|
public function quiz(Season $season, Quiz $quiz): Response
|
||||||
{
|
{
|
||||||
return $this->render('backoffice/quiz.html.twig', [
|
return $this->render('backoffice/quiz.html.twig', [
|
||||||
|
|||||||
@@ -6,12 +6,14 @@ namespace App\Controller;
|
|||||||
|
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\HttpKernel\Attribute\AsController;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
|
||||||
|
|
||||||
|
#[AsController]
|
||||||
class LoginController extends AbstractController
|
class LoginController extends AbstractController
|
||||||
{
|
{
|
||||||
#[Route(path: '/login', name: 'app_login')]
|
#[Route(path: '/login', name: 'app_login_login')]
|
||||||
public function login(AuthenticationUtils $authenticationUtils): Response
|
public function login(AuthenticationUtils $authenticationUtils): Response
|
||||||
{
|
{
|
||||||
// get the login error if there is one
|
// get the login error if there is one
|
||||||
@@ -26,7 +28,7 @@ class LoginController extends AbstractController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route(path: '/logout', name: 'app_logout')]
|
#[Route(path: '/logout', name: 'app_login_logout')]
|
||||||
public function logout(): void
|
public function logout(): void
|
||||||
{
|
{
|
||||||
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
|
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
|
||||||
|
|||||||
21
src/Controller/PrepareEliminationController.php
Normal file
21
src/Controller/PrepareEliminationController.php
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Controller;
|
||||||
|
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
#[Route(path: '/backoffice/elimination')]
|
||||||
|
final class PrepareEliminationController extends AbstractController
|
||||||
|
{
|
||||||
|
#[Route('/prepare', name: 'app_prepare_elimination')]
|
||||||
|
public function index(): Response
|
||||||
|
{
|
||||||
|
return $this->render('prepare_elimination/index.html.twig', [
|
||||||
|
'controller_name' => 'PrepareEliminationController',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,7 +31,7 @@ final class QuizController extends AbstractController
|
|||||||
|
|
||||||
private const string CANDIDATE_HASH_REGEX = '[\w\-=]+';
|
private const string CANDIDATE_HASH_REGEX = '[\w\-=]+';
|
||||||
|
|
||||||
#[Route(path: '/', name: 'select_season', methods: ['GET', 'POST'])]
|
#[Route(path: '/', name: 'app_quiz_selectseason', methods: ['GET', 'POST'])]
|
||||||
public function selectSeason(Request $request): Response
|
public function selectSeason(Request $request): Response
|
||||||
{
|
{
|
||||||
$form = $this->createForm(SelectSeasonType::class);
|
$form = $this->createForm(SelectSeasonType::class);
|
||||||
@@ -40,13 +40,13 @@ final class QuizController extends AbstractController
|
|||||||
if ($form->isSubmitted() && $form->isValid()) {
|
if ($form->isSubmitted() && $form->isValid()) {
|
||||||
$data = $form->getData();
|
$data = $form->getData();
|
||||||
|
|
||||||
return $this->redirectToRoute('enter_name', ['seasonCode' => $data['season_code']]);
|
return $this->redirectToRoute('app_quiz_entername', ['seasonCode' => $data['season_code']]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('quiz/select_season.html.twig', ['form' => $form]);
|
return $this->render('quiz/select_season.html.twig', ['form' => $form]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route(path: '/{seasonCode}', name: 'enter_name', requirements: ['seasonCode' => self::SEASON_CODE_REGEX])]
|
#[Route(path: '/{seasonCode}', name: 'app_quiz_entername', requirements: ['seasonCode' => self::SEASON_CODE_REGEX])]
|
||||||
public function enterName(
|
public function enterName(
|
||||||
Request $request,
|
Request $request,
|
||||||
#[MapEntity(mapping: ['seasonCode' => 'seasonCode'])]
|
#[MapEntity(mapping: ['seasonCode' => 'seasonCode'])]
|
||||||
@@ -60,7 +60,7 @@ final class QuizController extends AbstractController
|
|||||||
$data = $form->getData();
|
$data = $form->getData();
|
||||||
$name = $data['name'];
|
$name = $data['name'];
|
||||||
|
|
||||||
return $this->redirectToRoute('quiz_page', ['seasonCode' => $season->getSeasonCode(), 'nameHash' => Base64::base64_url_encode($name)]);
|
return $this->redirectToRoute('app_quiz_quizpage', ['seasonCode' => $season->getSeasonCode(), 'nameHash' => Base64::base64UrlEncode($name)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render('quiz/enter_name.twig', ['season' => $season, 'form' => $form]);
|
return $this->render('quiz/enter_name.twig', ['season' => $season, 'form' => $form]);
|
||||||
@@ -68,7 +68,7 @@ final class QuizController extends AbstractController
|
|||||||
|
|
||||||
#[Route(
|
#[Route(
|
||||||
path: '/{seasonCode}/{nameHash}',
|
path: '/{seasonCode}/{nameHash}',
|
||||||
name: 'quiz_page',
|
name: 'app_quiz_quizpage',
|
||||||
requirements: ['seasonCode' => self::SEASON_CODE_REGEX, 'nameHash' => self::CANDIDATE_HASH_REGEX],
|
requirements: ['seasonCode' => self::SEASON_CODE_REGEX, 'nameHash' => self::CANDIDATE_HASH_REGEX],
|
||||||
)]
|
)]
|
||||||
public function quizPage(
|
public function quizPage(
|
||||||
@@ -87,10 +87,10 @@ final class QuizController extends AbstractController
|
|||||||
if ($season->isPreregisterCandidates()) {
|
if ($season->isPreregisterCandidates()) {
|
||||||
$this->addFlash(FlashType::Danger, 'Candidate not found');
|
$this->addFlash(FlashType::Danger, 'Candidate not found');
|
||||||
|
|
||||||
return $this->redirectToRoute('enter_name', ['seasonCode' => $season->getSeasonCode()]);
|
return $this->redirectToRoute('app_quiz_entername', ['seasonCode' => $season->getSeasonCode()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$candidate = new Candidate(Base64::base64_url_decode($nameHash));
|
$candidate = new Candidate(Base64::base64UrlDecode($nameHash));
|
||||||
$candidateRepository->save($candidate);
|
$candidateRepository->save($candidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +113,7 @@ final class QuizController extends AbstractController
|
|||||||
if (!$question instanceof Question) {
|
if (!$question instanceof Question) {
|
||||||
$this->addFlash(FlashType::Success, 'Quiz completed');
|
$this->addFlash(FlashType::Success, 'Quiz completed');
|
||||||
|
|
||||||
return $this->redirectToRoute('enter_name', ['seasonCode' => $season->getSeasonCode()]);
|
return $this->redirectToRoute('app_quiz_entername', ['seasonCode' => $season->getSeasonCode()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO One first question record time
|
// TODO One first question record time
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class KrtekFixtures extends Fixture
|
|||||||
$manager->persist($season);
|
$manager->persist($season);
|
||||||
|
|
||||||
$season->setName('Krtek Weekend')
|
$season->setName('Krtek Weekend')
|
||||||
->setSeasonCode('12345')
|
->setSeasonCode('krtek')
|
||||||
->setPreregisterCandidates(true)
|
->setPreregisterCandidates(true)
|
||||||
->addCandidate(new Candidate('Claudia'))
|
->addCandidate(new Candidate('Claudia'))
|
||||||
->addCandidate(new Candidate('Eelco'))
|
->addCandidate(new Candidate('Eelco'))
|
||||||
|
|||||||
@@ -135,6 +135,6 @@ class Candidate
|
|||||||
|
|
||||||
public function getNameHash(): string
|
public function getNameHash(): string
|
||||||
{
|
{
|
||||||
return Base64::base64_url_encode($this->name);
|
return Base64::base64UrlEncode($this->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,15 +8,13 @@ use Safe\Exceptions\UrlException;
|
|||||||
|
|
||||||
class Base64
|
class Base64
|
||||||
{
|
{
|
||||||
private function __construct() {}
|
public static function base64UrlEncode(string $input): string
|
||||||
|
|
||||||
public static function base64_url_encode(string $input): string
|
|
||||||
{
|
{
|
||||||
return rtrim(strtr(base64_encode($input), '+/', '-_'), '=');
|
return rtrim(strtr(base64_encode($input), '+/', '-_'), '=');
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @throws UrlException */
|
/** @throws UrlException */
|
||||||
public static function base64_url_decode(string $input): string
|
public static function base64UrlDecode(string $input): string
|
||||||
{
|
{
|
||||||
return \Safe\base64_decode(strtr($input, '-_', '+/'), true);
|
return \Safe\base64_decode(strtr($input, '-_', '+/'), true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class CandidateRepository extends ServiceEntityRepository
|
|||||||
public function getCandidateByHash(Season $season, string $hash): ?Candidate
|
public function getCandidateByHash(Season $season, string $hash): ?Candidate
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$name = Base64::base64_url_decode($hash);
|
$name = Base64::base64UrlDecode($hash);
|
||||||
} catch (UrlException) {
|
} catch (UrlException) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a {% if season.activeQuiz %}href="{{ path('enter_name', {seasonCode: season.seasonCode}) }}"
|
<a {% if season.activeQuiz %}href="{{ path('app_quiz_entername', {seasonCode: season.seasonCode}) }}"
|
||||||
{% else %}class="disabled" {% endif %}>{{ season.seasonCode }}</a>
|
{% else %}class="disabled" {% endif %}>{{ season.seasonCode }}</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
aria-label="Preregister Enabled">
|
aria-label="Preregister Enabled">
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a href="{{ path('backoffice_season', {seasonCode: season.seasonCode}) }}">{% trans %}Manage{% endtrans %}</a>
|
<a href="{{ path('app_backoffice_season', {seasonCode: season.seasonCode}) }}">{% trans %}Manage{% endtrans %}</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link{% if 'backoffice_index' == app.current_route() %} active{% endif %}"
|
<a class="nav-link{% if 'app_backoffice_index' == app.current_route() %} active{% endif %}"
|
||||||
href="{{ path('backoffice_index') }}">{{ 'Seasons'|trans }}</a>
|
href="{{ path('app_backoffice_index') }}">{{ 'Seasons'|trans }}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
3
templates/backoffice/prepare_elimination/index.html.twig
Normal file
3
templates/backoffice/prepare_elimination/index.html.twig
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{% extends 'backoffice/base.html.twig' %}
|
||||||
|
{% block body %}
|
||||||
|
{% endblock %}
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
{% for quiz in season.quizzes %}
|
{% for quiz in season.quizzes %}
|
||||||
<a class="list-group-item list-group-item-action{% if season.activeQuiz == quiz %} active{% endif %}"
|
<a class="list-group-item list-group-item-action{% if season.activeQuiz == quiz %} active{% endif %}"
|
||||||
href="{{ path('backoffice_quiz', {seasonCode: season.seasonCode, quiz: quiz.id}) }}">{{ quiz.name }}</a>
|
href="{{ path('app_backoffice_quiz', {seasonCode: season.seasonCode, quiz: quiz.id}) }}">{{ quiz.name }}</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
No quizzes
|
No quizzes
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
|
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
|
||||||
<label for="username">Email</label>
|
<label for="username">Email</label>
|
||||||
<input type="email" value="{{ last_username }}" name="_username" id="username" class="form-control" autocomplete="email" required autofocus>
|
<input type="email" value="{{ last_username }}" name="_username" id="username" class="form-control"
|
||||||
|
autocomplete="email" required autofocus>
|
||||||
<label for="password">Password</label>
|
<label for="password">Password</label>
|
||||||
<input type="password" name="_password" id="password" class="form-control" autocomplete="current-password" required>
|
<input type="password" name="_password" id="password" class="form-control" autocomplete="current-password"
|
||||||
|
required>
|
||||||
|
|
||||||
<input type="hidden" name="_csrf_token"
|
<input type="hidden" name="_csrf_token"
|
||||||
value="{{ csrf_token('authenticate') }}"
|
value="{{ csrf_token('authenticate') }}"
|
||||||
|
|||||||
Reference in New Issue
Block a user