95 Commits

Author SHA1 Message Date
ac46f380cb Remove worker (#71)
Some checks failed
CI / Tests (push) Failing after 39s
CI / Build and deploy to ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }} (push) Has been skipped
* Remove worker config

* Do not copy worker.Caddyfile
2026-02-18 16:50:04 +01:00
b281a199d3 Remove worker config (#70) 2026-02-18 16:39:17 +01:00
e97cb4b034 Symfony 8.0 (#69)
* Pre upgrade

* Symfony 8.0

* Update recipe for sentry

* symfony/framework-bundle
recipe

* symfony/phpunut
recipe

* symfony/routing
recipe

* symfony/security
recipe

* symfony/timulus-bundle
recipe

* doctine recipe
2026-02-18 16:20:14 +01:00
785d5d1165 Dependency upgrades
Some checks failed
CI / Tests (push) Failing after 1m38s
CI / Build and deploy to ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }} (push) Has been skipped
2026-01-25 19:58:39 +01:00
b57faaf431 Update to 7.4.2 (#68)
Some checks failed
CI / Tests (push) Failing after 39s
CI / Build and deploy to ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }} (push) Has been skipped
2025-12-11 16:48:16 +01:00
bcd6a157a8 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
2025-11-28 22:56:09 +01:00
dependabot[bot]
fc273638ad Bump rector/rector from 2.2.3 to 2.2.6
Some checks failed
CI / Tests (push) Failing after 31s
CI / Build and deploy to ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }} (push) Has been skipped
Bumps [rector/rector](https://github.com/rectorphp/rector) from 2.2.3 to 2.2.6.
- [Release notes](https://github.com/rectorphp/rector/releases)
- [Commits](https://github.com/rectorphp/rector/compare/2.2.3...2.2.6)

---
updated-dependencies:
- dependency-name: rector/rector
  dependency-version: 2.2.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-29 15:59:49 +01:00
dependabot[bot]
1ed1d43c54 Bump symfony/ux-turbo from 2.30.0 to 2.31.0
Bumps [symfony/ux-turbo](https://github.com/symfony/ux-turbo) from 2.30.0 to 2.31.0.
- [Changelog](https://github.com/symfony/ux-turbo/blob/2.x/CHANGELOG.md)
- [Commits](https://github.com/symfony/ux-turbo/compare/v2.30.0...v2.31.0)

---
updated-dependencies:
- dependency-name: symfony/ux-turbo
  dependency-version: 2.31.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-29 15:59:39 +01:00
dependabot[bot]
216fabcd4e Bump doctrine/orm from 3.5.2 to 3.5.3
Bumps [doctrine/orm](https://github.com/doctrine/orm) from 3.5.2 to 3.5.3.
- [Release notes](https://github.com/doctrine/orm/releases)
- [Commits](https://github.com/doctrine/orm/compare/3.5.2...3.5.3)

---
updated-dependencies:
- dependency-name: doctrine/orm
  dependency-version: 3.5.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-29 15:59:23 +01:00
dependabot[bot]
a227fb0890 Bump friendsofphp/php-cs-fixer from 3.89.0 to 3.89.1
Bumps [friendsofphp/php-cs-fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer) from 3.89.0 to 3.89.1.
- [Release notes](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/releases)
- [Changelog](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/compare/v3.89.0...v3.89.1)

---
updated-dependencies:
- dependency-name: friendsofphp/php-cs-fixer
  dependency-version: 3.89.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-29 15:59:13 +01:00
dependabot[bot]
354f0140cd Bump phpoffice/phpspreadsheet from 5.1.0 to 5.2.0
Bumps [phpoffice/phpspreadsheet](https://github.com/PHPOffice/PhpSpreadsheet) from 5.1.0 to 5.2.0.
- [Release notes](https://github.com/PHPOffice/PhpSpreadsheet/releases)
- [Changelog](https://github.com/PHPOffice/PhpSpreadsheet/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PHPOffice/PhpSpreadsheet/compare/5.1.0...5.2.0)

---
updated-dependencies:
- dependency-name: phpoffice/phpspreadsheet
  dependency-version: 5.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-29 15:58:58 +01:00
d58d3d7a03 Fix doctrine config
Some checks failed
CI / Tests (push) Failing after 32s
CI / Build and deploy to ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }} (push) Has been skipped
2025-10-22 08:36:05 +02:00
5749f85337 Upgrade dependencies
Some checks failed
CI / Tests (push) Failing after 38s
CI / Build and deploy to ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }} (push) Has been skipped
2025-10-21 22:02:17 +02:00
311fbf607c Change Dependabot schedule to daily and add Docker 2025-10-21 20:51:11 +02:00
dependabot[bot]
9f08209d39 Bump rector/rector from 2.1.7 to 2.2.3
Some checks failed
CI / Tests (push) Failing after 41s
CI / Build and deploy to ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }} (push) Has been skipped
Bumps [rector/rector](https://github.com/rectorphp/rector) from 2.1.7 to 2.2.3.
- [Release notes](https://github.com/rectorphp/rector/releases)
- [Commits](https://github.com/rectorphp/rector/compare/2.1.7...2.2.3)

---
updated-dependencies:
- dependency-name: rector/rector
  dependency-version: 2.2.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-21 08:06:11 +02:00
dependabot[bot]
a1fc86a6a0 Bump doctrine/doctrine-fixtures-bundle from 4.1.0 to 4.3.0
Bumps [doctrine/doctrine-fixtures-bundle](https://github.com/doctrine/DoctrineFixturesBundle) from 4.1.0 to 4.3.0.
- [Release notes](https://github.com/doctrine/DoctrineFixturesBundle/releases)
- [Commits](https://github.com/doctrine/DoctrineFixturesBundle/compare/4.1.0...4.3.0)

---
updated-dependencies:
- dependency-name: doctrine/doctrine-fixtures-bundle
  dependency-version: 4.3.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-21 08:05:35 +02:00
dependabot[bot]
961c7434ac Bump phpstan/phpstan-doctrine from 2.0.6 to 2.0.10
Bumps [phpstan/phpstan-doctrine](https://github.com/phpstan/phpstan-doctrine) from 2.0.6 to 2.0.10.
- [Release notes](https://github.com/phpstan/phpstan-doctrine/releases)
- [Commits](https://github.com/phpstan/phpstan-doctrine/compare/2.0.6...2.0.10)

---
updated-dependencies:
- dependency-name: phpstan/phpstan-doctrine
  dependency-version: 2.0.10
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-21 08:04:57 +02:00
ee1a15ee78 New pipeline
Some checks failed
CI / Tests (push) Failing after 36s
CI / Build and deploy to ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }} (push) Has been skipped
2025-10-21 00:06:23 +02:00
253729abc0 Add completions 2025-10-20 21:41:46 +02:00
b66d2f9e86 Refactor entities and codebase for native property usage
Some checks failed
CI / Tests (push) Failing after 35s
CI / Deploy (push) Has been skipped
- Replaced getters/setters with direct property access across entities and repositories.
- Added and configured `martin-georgiev/postgresql-for-doctrine` for PostgreSQL enhancements.
- Updated Doctrine configuration with types, mappings, and JSONB query functions.
- Removed unused `EliminationService` and related YAML configurations.
2025-10-08 20:50:33 +02:00
ab187a28b9 Add Symfony container support for Rector configuration
- Introduced `tests/symfony-container.php` for bootstrapping Symfony.
  - Updated `rector.php` with new container PHP path and kernel modifications.
  - Registered Symfony routes provider service in Rector.
2025-10-08 20:50:33 +02:00
ca460cca7f - Refactor ORM annotations across entities for consistency.
- Adjusted migrations to align with refactored ORM annotations.
- Added new PHPStan and PHP-CS-Fixer configurations, including stricter rules.
- Introduced `tests/object-manager.php` to improve test environment setup.
2025-10-04 12:40:45 +02:00
3e39550c90 Remove EasyAdmin integration
- Removed EasyAdmin controllers and configurations.
- Uninstalled `easycorp/easyadmin-bundle` and related dependencies.
- Cleaned up all associated routes, bundles, and vendor references.
2025-10-03 22:37:45 +02:00
0319224979 Dependey updates 2025-09-28 21:19:01 +02:00
81e471a760 Change namespace to Tvdt 2025-09-28 18:14:58 +02:00
cfb69c8dab Add Deploy step 2025-09-08 21:51:00 +02:00
35ec71302b Update bake 2025-09-08 19:53:23 +02:00
b7a570928a Update dependencies 2025-09-08 19:50:23 +02:00
d80436534f Update Symfony packages 2025-09-08 19:26:45 +02:00
dependabot[bot]
14e2dd490e Bump phpstan/phpstan-symfony from 2.0.6 to 2.0.7
Bumps [phpstan/phpstan-symfony](https://github.com/phpstan/phpstan-symfony) from 2.0.6 to 2.0.7.
- [Release notes](https://github.com/phpstan/phpstan-symfony/releases)
- [Commits](https://github.com/phpstan/phpstan-symfony/compare/2.0.6...2.0.7)

---
updated-dependencies:
- dependency-name: phpstan/phpstan-symfony
  dependency-version: 2.0.7
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-25 13:30:05 +02:00
dependabot[bot]
68e54b1110 Bump doctrine/doctrine-bundle from 2.14.0 to 2.15.0
Bumps [doctrine/doctrine-bundle](https://github.com/doctrine/DoctrineBundle) from 2.14.0 to 2.15.0.
- [Release notes](https://github.com/doctrine/DoctrineBundle/releases)
- [Commits](https://github.com/doctrine/DoctrineBundle/compare/2.14.0...2.15.0)

---
updated-dependencies:
- dependency-name: doctrine/doctrine-bundle
  dependency-version: 2.15.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-25 13:29:46 +02:00
dependabot[bot]
e615b2cdea Bump symfony/serializer from 7.3.0 to 7.3.1
Bumps [symfony/serializer](https://github.com/symfony/serializer) from 7.3.0 to 7.3.1.
- [Release notes](https://github.com/symfony/serializer/releases)
- [Changelog](https://github.com/symfony/serializer/blob/7.3/CHANGELOG.md)
- [Commits](https://github.com/symfony/serializer/compare/v7.3.0...v7.3.1)

---
updated-dependencies:
- dependency-name: symfony/serializer
  dependency-version: 7.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-25 13:29:34 +02:00
dependabot[bot]
4b45a2c557 Bump symfony/security-bundle from 7.3.0 to 7.3.1
Bumps [symfony/security-bundle](https://github.com/symfony/security-bundle) from 7.3.0 to 7.3.1.
- [Release notes](https://github.com/symfony/security-bundle/releases)
- [Changelog](https://github.com/symfony/security-bundle/blob/7.3/CHANGELOG.md)
- [Commits](https://github.com/symfony/security-bundle/compare/v7.3.0...v7.3.1)

---
updated-dependencies:
- dependency-name: symfony/security-bundle
  dependency-version: 7.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-25 13:29:24 +02:00
c6fe553341 Create dependabot.yml 2025-07-25 13:04:20 +02:00
69a2b9c811 Open db port 2025-06-15 02:18:27 +02:00
f31a7d527d Fix scores? 2025-06-14 21:34:52 +02:00
ed3cf7644f Correct sorting for scores 2025-06-14 12:32:18 +02:00
77d21b004f Update backoffice templates to dynamically include titles and improve candidate handling in SeasonController 2025-06-14 12:32:18 +02:00
379fafcd16 Fix cs 2025-06-12 15:03:01 +02:00
7586d2d8ac Merge branch 'main' of github.com:MarijnDoeve/TijdVoorDeTest 2025-06-11 18:27:04 +02:00
9e41376244 Translations! 2025-06-11 18:26:17 +02:00
2bfef94bbe Add settings management for seasons, update templates, migrations, and commands 2025-06-10 23:06:59 +02:00
a8c4cba968 Disable Turbo for now 2025-06-09 15:52:15 +02:00
d5566d4737 Refactor repositories to use DQL queries, simplify logic, and enhance query efficiency 2025-06-09 14:19:10 +02:00
366bc36520 Fix typo 2025-06-07 23:47:58 +02:00
79b24b0d44 Refine error handling 2025-06-07 23:45:40 +02:00
7f93680987 Allow mail send fail 2025-06-07 23:43:52 +02:00
bdbff32256 Add MAILER_DSN 2025-06-07 23:34:50 +02:00
ebadc24b59 PHP 8.4 2025-06-07 22:24:38 +02:00
e0075fdcdc Rector upgrades 2025-06-07 22:24:38 +02:00
06aafefffc Upgrade to Symfony 7.3 2025-06-07 22:24:38 +02:00
ff6534fa81 Improve links 2025-06-07 22:24:38 +02:00
6a77df402d Add quiz clearing and deletion functionality with UI enhancements
This commit introduces the ability to clear quiz results and delete quizzes directly from the backoffice. It includes new routes, controllers, modals for user confirmation, and updates to translations. The `QuizRepository` now supports dedicated methods for clearing results and deleting quizzes along with error handling. Related database migrations and front-end adjustments are also included.
2025-06-07 20:59:01 +02:00
79236d84e9 Add correction management to backoffice, refactor security voter logic, and enhance candidate scoring
This commit introduces functionality to manage candidate corrections in the backoffice, with updated templates and a new route handler. The SeasonVoter is refactored to support additional entities, and scoring logic is updated to incorporate corrections consistently. Includes test coverage for voter logic and UI improvements for score tables.
2025-06-07 16:09:13 +02:00
beb8d13dde Refactor Candidate and Quiz entities, rename Correction to QuizCandidate, and update related workflows
This commit removes nullable Uuid properties for consistency, transitions the Correction entity to QuizCandidate with associated migrations, refactors queries and repositories, adjusts related routes and controllers to use the new entity, updates front-end assets for elimination workflows, and standardizes route requirements and naming conventions.
2025-06-06 23:06:47 +02:00
3e724ff1fb Add Turbo 2025-06-06 20:12:54 +02:00
e131d3b8d9 Fix cs 2025-06-06 19:33:54 +02:00
f6715de330 Add trailing comma in multi line. 2025-06-05 15:25:03 +02:00
0be29190e6 Fix scss 2025-06-01 21:36:39 +02:00
c6f9b57c60 Refactor translations to XLIFF format, enhance elimination workflows, and update compose configuration
This commit switches translations from YAML to XLIFF format for better standardization, updates the elimination preparation process with UI and functionality improvements, tweaks form structures, adjusts compose.override.yaml for improved asset handling, and optimizes back office usability with refined translation handling.
2025-06-01 21:28:56 +02:00
cd5946bda8 Hotfix Sass build 2025-06-01 15:45:15 +02:00
25aa8b8622 Introduce importmap, enhance elimination workflows, and update assets
This commit adds initial importmap configuration to manage assets, updates the elimination preparation workflow with form enhancements and database changes, introduces new styles and JS assets, refines translations, and improves entity handling with an input bag update method.
2025-06-01 15:40:47 +02:00
d3e5cb0569 Refactor elimination feature and improve backoffice usability
This commit introduces a refactored EliminationFactory for better modularity, updates the elimination preparation process, and adds functionality to view eliminations. Backoffice templates and forms have been reorganized, minor translations were corrected, and additional assets like styles and flashes were included for enhanced user experience.
2025-06-01 15:40:47 +02:00
e0350c8c31 WIP 2025-06-01 15:40:47 +02:00
58bda32f09 Update compose.yaml
Add always to db
2025-05-08 17:08:16 +02:00
0cd23f906e Create devcontainer.json 2025-05-05 12:34:04 +02:00
Marijn Doeve
f1fe827337 Add Sentry Replay 2025-04-30 14:59:41 +02:00
Marijn Doeve
ca08df26b2 Add Sentry config 2025-04-29 08:34:55 +02:00
Marijn Doeve
60723657c2 Add missing env vars 2025-04-29 08:17:50 +02:00
09d74ed327 Add lost file 2025-04-29 07:55:17 +02:00
49b7c0f5d5 Add Sheet upload function 2025-04-28 23:01:37 +02:00
9bae324447 Enhance login and navigation templates with authentication checks 2025-04-23 23:35:08 +02:00
4712c01688 Add quiz management features and improve UI 2025-04-23 23:23:22 +02:00
4e22feb256 Update framework.yaml 2025-04-22 23:49:20 +02:00
0f07e7eabf Phpstan 2025-04-22 23:42:07 +02:00
7b05e52d95 A lot 2025-04-22 22:25:18 +02:00
66b57ea84a Secure admin 2025-04-21 19:12:48 +02:00
daeda4a9b5 Add Sentry integration and configuration 2025-04-21 18:54:43 +02:00
057bc778ed Fixes 2025-04-21 18:03:54 +02:00
f44b63a91f Error code for wrong season code 2025-04-21 15:47:27 +02:00
acd85bfc2b Fix csrf-tokens 2025-04-21 14:09:02 +02:00
4863fad3ba Move fixtures to prod 2025-04-21 13:21:16 +02:00
87104889d1 trailing spaces 2025-04-21 00:33:45 +02:00
2c6eb2ecb7 New caddy 2025-04-21 00:27:19 +02:00
fe00270637 Labels 2025-04-20 21:51:41 +02:00
e967a8da63 add network to db 2025-04-20 21:41:00 +02:00
ffb7df5895 Update postgres version: 2025-04-20 21:39:30 +02:00
4885f746f6 Change ports 2025-04-20 21:37:17 +02:00
4bcab2724a Implement email verification feature, add registration form, and update user entity for verification status 2025-04-20 19:34:27 +02:00
c70f713f7e Refactor Base64 encoding/decoding methods for consistency, update controller routes, and improve CI configuration
Some checks failed
CI / Tests (push) Failing after 9m39s
CI / Docker Lint (push) Successful in 4s
2025-04-14 18:30:18 +02:00
31e6ed406b Refactor routes for consistency, update season codes, and add Justfile for Docker commands 2025-04-02 22:12:55 +02:00
acf5c06fcc Refactor code for improved readability and consistency; add flash message handling and enhance quiz functionality
Some checks failed
CI / Tests (push) Failing after 9s
CI / Docker Lint (push) Successful in 4s
2025-03-12 23:18:13 +01:00
448daed6ea wip 12-03-2025
Some checks failed
CI / Tests (push) Failing after 11s
CI / Docker Lint (push) Successful in 3s
2025-03-12 09:28:36 +01:00
f7b4b98da4 Refactor YAML and Twig files for consistent indentation and formatting
Some checks failed
CI / Tests (push) Failing after 10m32s
CI / Docker Lint (push) Successful in 9s
2025-03-05 22:47:59 +01:00
0ccce51af8 Add AbstractController, implement flash message handling, and refactor repositories 2025-03-05 21:01:57 +01:00
200 changed files with 13912 additions and 4141 deletions

View File

@@ -33,6 +33,10 @@ indent_size = 4
[*.{yaml,yml}]
trim_trailing_whitespace = false
indent_size = 2
[config/**/*.{yaml,yml}]
indent_size = 4
[.github/workflows/*.yml]
indent_size = 2
@@ -50,8 +54,8 @@ indent_size = 4
[{compose,docker-compose}.*.{yaml,yml}]
indent_size = 2
[*.*Dockerfile]
[{*.*Dockerfile,Dockerfile}]
indent_style = tab
[*.*Caddyfile]
[{*.*Caddyfile,Caddyfile}]
indent_style = tab

16
.env
View File

@@ -17,6 +17,7 @@
###> symfony/framework-bundle ###
APP_ENV=dev
APP_SECRET=
APP_SHARE_DIR=var/share
###< symfony/framework-bundle ###
###> doctrine/doctrine-bundle ###
@@ -28,3 +29,18 @@ APP_SECRET=
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=10.11.2-MariaDB&charset=utf8mb4"
DATABASE_URL="postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8"
###< doctrine/doctrine-bundle ###
###> symfony/mailer ###
MAILER_DSN=null://null
###< symfony/mailer ###
###> sentry/sentry-symfony ###
SENTRY_DSN=
###< sentry/sentry-symfony ###
XDEBUG_MODE=coverage
###> symfony/routing ###
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
DEFAULT_URI=http://localhost
###< symfony/routing ###

View File

@@ -2,3 +2,4 @@
###> symfony/framework-bundle ###
APP_SECRET=e26b9552d9e7f969b160373effaa7690
###< symfony/framework-bundle ###
MAILER_SENDER=info@tijdvoordetest.nl

3
.env.test Normal file
View File

@@ -0,0 +1,3 @@
# define your env variables for the test env here
KERNEL_CLASS='Tvdt\Kernel'
APP_SECRET='$ecretf0rt3st'

1
.gitattributes vendored
View File

@@ -15,3 +15,4 @@ composer.lock text eol=lf merge=ours
*.ico binary
*.png binary
config/reference.php linguist-generated

15
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
version: 2
updates:
- package-ecosystem: "composer" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "daily"
- package-ecosystem: "docker"
directtory: "/"
schedule:
interval: "daily"

View File

@@ -4,6 +4,8 @@ on:
push:
branches:
- main
tags:
- '*'
pull_request: ~
workflow_dispatch: ~
@@ -11,20 +13,23 @@ concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
permissions:
contents: read
packages: write
jobs:
tests:
name: Tests
runs-on: ubuntu-latest
steps:
-
name: Checkout
- name: Checkout
uses: actions/checkout@v4
-
name: Set up Docker Buildx
- name: Lint Dockerfile
uses: hadolint/hadolint-action@v3.1.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Build Docker images
uses: docker/bake-action@v4
- name: Build Docker images
uses: docker/bake-action@v5
with:
pull: true
load: true
@@ -35,42 +40,85 @@ jobs:
*.cache-from=type=gha,scope=${{github.ref}}
*.cache-from=type=gha,scope=refs/heads/main
*.cache-to=type=gha,scope=${{github.ref}},mode=max
-
name: Start services
run: docker compose up --wait --no-build
-
name: Check HTTP reachability
- name: Start services
run: docker compose up php database --wait --no-build
- name: Lint Twig templates
run: docker compose exec -T php bin/console lint:twig --format=github templates
- name: Coding Style
run: docker compose exec -T php vendor/bin/php-cs-fixer check --diff --show-progress=none
- name: Twig Coding Style
run: docker compose exec -T php vendor/bin/twig-cs-fixer check
- name: Check HTTP reachability
run: curl -v --fail-with-body http://localhost
-
name: Check HTTPS reachability
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
-
name: Check Mercure reachability
- name: Check Mercure reachability
if: false
run: curl -vkI --fail-with-body https://localhost/.well-known/mercure?topic=test
-
name: Create test database
if: false # Remove this line if Doctrine ORM is installed
- name: Create test database
run: docker compose exec -T php bin/console -e test doctrine:database:create
-
name: Run migrations
if: false # Remove this line if Doctrine Migrations is installed
- name: Run migrations
run: docker compose exec -T php bin/console -e test doctrine:migrations:migrate --no-interaction
-
name: Run PHPUnit
if: false # Remove this line if PHPUnit is installed
run: docker compose exec -T php bin/phpunit
-
name: Doctrine Schema Validator
if: false # Remove this line if Doctrine ORM is installed
- 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
- name: Doctrine Schema Validator
run: docker compose exec -T php bin/console -e test doctrine:schema:validate
lint:
name: Docker Lint
build-deploy:
name: Build and deploy to ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }}
environment:
name: ${{ startsWith(github.ref, 'refs/tags/') && 'production' || (github.ref == 'refs/heads/main' && 'acceptance' || '') }}
url: ${{ vars.URL }}
needs: tests
runs-on: ubuntu-latest
if: (github.ref == 'refs/heads/main' && false) || startsWith(github.ref, 'refs/tags/')
steps:
-
name: Checkout
- name: Checkout
uses: actions/checkout@v4
-
name: Lint Dockerfile
uses: hadolint/hadolint-action@v3.1.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
run: |
REPO_LOWER=$(echo "${{ github.repository }}" | tr '[:upper:]' '[:lower:]')
if [[ "${{ github.ref }}" == refs/tags/* ]]; then
TAG="${GITHUB_REF#refs/tags/}"
{
echo "tag=$TAG"
echo "full_name=ghcr.io/${REPO_LOWER}:$TAG"
} >> "$GITHUB_OUTPUT"
else
SHORT_SHA=$(git rev-parse --short HEAD)
{
echo "tag=$SHORT_SHA"
echo "full_name=ghcr.io/${REPO_LOWER}:$SHORT_SHA"
} >> "$GITHUB_OUTPUT"
fi
- name: Build and Push Docker images
uses: docker/bake-action@v5
with:
pull: true
push: true
files: |
compose.yaml
compose.build.yaml
set: |
*.cache-from=type=gha,scope=${{github.ref}}
*.cache-from=type=gha,scope=refs/heads/main
*.cache-to=type=gha,scope=${{github.ref}},mode=max
*.tags=${{ steps.meta.outputs.full_name }}
- name: Trigger Portainer Deployment
shell: bash
env:
PORTAINER_WEBHOOK: ${{secrets.PORTAINER_WEBHOOK}}
run: |
curl -v -X POST "$PORTAINER_WEBHOOK"?IMAGE_TAG=${{steps.meta.outputs.tag}} --fail-with-body

20
.gitignore vendored
View File

@@ -1,3 +1,5 @@
/frankenphp/data
### Generated by gibo (https://github.com/simonwhitaker/gibo)
### https://raw.github.com/github/gitignore/6eeebe6f49678aacd8311ce079842c971b3ebe96/Symfony.gitignore
@@ -32,7 +34,6 @@
/bin/*
!bin/console
!bin/symfony_requirements
/vendor/
# Assets and user uploads
/web/bundles/
@@ -40,7 +41,6 @@
# PHPUnit
/app/phpunit.xml
/phpunit.xml
# Build data
/build/
@@ -103,5 +103,19 @@ phpstan.neon
###< friendsofphp/php-cs-fixer ###
###> phpunit/phpunit ###
/phpunit.xml
.phpunit.result.cache
/.phpunit.cache/
###< phpunit/phpunit ###
###> vincentlanglet/twig-cs-fixer ###
/.twig-cs-fixer.cache
###< vincentlanglet/twig-cs-fixer ###
###> symfony/phpunit-bridge ###
.phpunit.result.cache
/phpunit.xml
###< symfony/phpunit-bridge ###
###> symfony/asset-mapper ###
/public/assets/
/assets/vendor/
###< symfony/asset-mapper ###

View File

@@ -2,11 +2,10 @@
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="App\" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="App\Tests\" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="Tvdt\" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="Tvdt\Tests\" />
<excludeFolder url="file://$MODULE_DIR$/vendor/clue/ndjson-react" />
<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/dbal" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/deprecations" />
@@ -46,10 +45,7 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/react/socket" />
<excludeFolder url="file://$MODULE_DIR$/vendor/react/stream" />
<excludeFolder url="file://$MODULE_DIR$/vendor/rector/rector" />
<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/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/complexity" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/diff" />
@@ -84,8 +80,6 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/options-resolver" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php83" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/process" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/routing" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/runtime" />
@@ -106,7 +100,6 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/form" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/password-hasher" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-icu" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-uuid" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/property-access" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/property-info" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/security-bundle" />
@@ -122,20 +115,60 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/thecodingmachine/phpstan-safe-rule" />
<excludeFolder url="file://$MODULE_DIR$/vendor/thecodingmachine/safe" />
<excludeFolder url="file://$MODULE_DIR$/vendor/twig/twig" />
<excludeFolder url="file://$MODULE_DIR$/vendor/easycorp/easyadmin-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/intl" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mime" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-idn" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/ux-twig-component" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/validator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/twig/extra-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/twig/html-extra" />
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/data-fixtures" />
<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/webmozart/assert" />
<excludeFolder url="file://$MODULE_DIR$/vendor/egulias/email-validator" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/browser-kit" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/dom-crawler" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mailer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfonycasts/verify-email-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
<excludeFolder url="file://$MODULE_DIR$/vendor/jean85/pretty-package-versions" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-factory" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-message" />
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sentry/sentry" />
<excludeFolder url="file://$MODULE_DIR$/vendor/sentry/sentry-symfony" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/psr-http-message-bridge" />
<excludeFolder url="file://$MODULE_DIR$/.phpunit.cache" />
<excludeFolder url="file://$MODULE_DIR$/var" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-common" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-docblock" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/type-resolver" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpstan/phpdoc-parser" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/css-selector" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/phpunit-bridge" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/serializer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/maennchen/zipstream-php" />
<excludeFolder url="file://$MODULE_DIR$/vendor/markbaker/complex" />
<excludeFolder url="file://$MODULE_DIR$/vendor/markbaker/matrix" />
<excludeFolder url="file://$MODULE_DIR$/vendor/phpoffice/phpspreadsheet" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/simple-cache" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/asset-mapper" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-client" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-client-contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfonycasts/sass-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/twig/intl-extra" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/stimulus-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/ux-turbo" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-uuid" />
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/brevo-mailer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/martin-georgiev/postgresql-for-doctrine" />
<excludeFolder url="file://$MODULE_DIR$/vendor/dama/doctrine-test-bundle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/gedmo/doctrine-extensions" />
<excludeFolder url="file://$MODULE_DIR$/vendor/stof/doctrine-extensions-bundle" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="bootstrap" level="application" />
<orderEntry type="library" name="bootstrap-icons" level="application" />
</component>
</module>

View File

@@ -1,7 +1,133 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="ForgottenDebugOutputInspection" enabled="true" level="ERROR" enabled_by_default="true">
<option name="configuration">
<list>
<option value="\Codeception\Util\Debug::debug" />
<option value="\Codeception\Util\Debug::pause" />
<option value="\Doctrine\Common\Util\Debug::dump" />
<option value="\Doctrine\Common\Util\Debug::export" />
<option value="\Illuminate\Support\Debug\Dumper::dump" />
<option value="\Symfony\Component\Debug\Debug::enable" />
<option value="\Symfony\Component\Debug\DebugClassLoader::enable" />
<option value="\Symfony\Component\Debug\ErrorHandler::register" />
<option value="\Symfony\Component\Debug\ExceptionHandler::register" />
<option value="\TYPO3\CMS\Core\Utility\DebugUtility::debug" />
<option value="\Zend\Debug\Debug::dump" />
<option value="\Zend\Di\Display\Console::export" />
<option value="dd" />
<option value="debug_print_backtrace" />
<option value="debug_zval_dump" />
<option value="dpm" />
<option value="dpq" />
<option value="dsm" />
<option value="dump" />
<option value="dvm" />
<option value="error_log" />
<option value="kpr" />
<option value="phpinfo" />
<option value="print_r" />
<option value="trap" />
<option value="var_dump" />
<option value="var_export" />
<option value="wp_die" />
<option value="xdebug_break" />
<option value="xdebug_call_class" />
<option value="xdebug_call_file" />
<option value="xdebug_call_function" />
<option value="xdebug_call_line" />
<option value="xdebug_code_coverage_started" />
<option value="xdebug_debug_zval" />
<option value="xdebug_debug_zval_stdout" />
<option value="xdebug_dump_superglobals" />
<option value="xdebug_enable" />
<option value="xdebug_get_code_coverage" />
<option value="xdebug_get_collected_errors" />
<option value="xdebug_get_declared_vars" />
<option value="xdebug_get_function_stack" />
<option value="xdebug_get_headers" />
<option value="xdebug_get_monitored_functions" />
<option value="xdebug_get_profiler_filename" />
<option value="xdebug_get_stack_depth" />
<option value="xdebug_get_tracefile_name" />
<option value="xdebug_is_enabled" />
<option value="xdebug_memory_usage" />
<option value="xdebug_peak_memory_usage" />
<option value="xdebug_print_function_stack" />
<option value="xdebug_start_code_coverage" />
<option value="xdebug_start_error_collection" />
<option value="xdebug_start_function_monitor" />
<option value="xdebug_start_trace" />
<option value="xdebug_stop_code_coverage" />
<option value="xdebug_stop_error_collection" />
<option value="xdebug_stop_function_monitor" />
<option value="xdebug_stop_trace" />
<option value="xdebug_time_index" />
<option value="xdebug_var_dump" />
</list>
</option>
<option name="migratedIntoUserSpace" value="true" />
</inspection_tool>
<inspection_tool class="PhpCSFixerValidationInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="PhpFullyQualifiedNameUsageInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="IGNORE_GLOBAL_NAMESPACE" value="true" />
</inspection_tool>
<inspection_tool class="PhpStanGlobal" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="SecurityAdvisoriesInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="optionConfiguration">
<list>
<option value="barryvdh/laravel-debugbar" />
<option value="behat/behat" />
<option value="brianium/paratest" />
<option value="codeception/codeception" />
<option value="codedungeon/phpunit-result-printer" />
<option value="composer/composer" />
<option value="doctrine/coding-standard" />
<option value="filp/whoops" />
<option value="friendsofphp/php-cs-fixer" />
<option value="humbug/humbug" />
<option value="infection/infection" />
<option value="jakub-onderka/php-parallel-lint" />
<option value="johnkary/phpunit-speedtrap" />
<option value="kalessil/production-dependencies-guard" />
<option value="mikey179/vfsStream" />
<option value="mockery/mockery" />
<option value="mybuilder/phpunit-accelerator" />
<option value="orchestra/testbench" />
<option value="pdepend/pdepend" />
<option value="phan/phan" />
<option value="phing/phing" />
<option value="phpcompatibility/php-compatibility" />
<option value="phpmd/phpmd" />
<option value="phpro/grumphp" />
<option value="phpspec/phpspec" />
<option value="phpspec/prophecy" />
<option value="phpstan/phpstan" />
<option value="phpunit/phpunit" />
<option value="povils/phpmnd" />
<option value="roave/security-advisories" />
<option value="satooshi/php-coveralls" />
<option value="sebastian/phpcpd" />
<option value="slevomat/coding-standard" />
<option value="spatie/phpunit-watcher" />
<option value="squizlabs/php_codesniffer" />
<option value="sstalle/php7cc" />
<option value="symfony/debug" />
<option value="symfony/maker-bundle" />
<option value="symfony/phpunit-bridge" />
<option value="symfony/var-dumper" />
<option value="vimeo/psalm" />
<option value="wimg/php-compatibility" />
<option value="wp-coding-standards/wpcs" />
<option value="yiisoft/yii2-coding-standards" />
<option value="yiisoft/yii2-debug" />
<option value="yiisoft/yii2-gii" />
<option value="zendframework/zend-coding-standard" />
<option value="zendframework/zend-debug" />
<option value="zendframework/zend-test" />
</list>
</option>
</inspection_tool>
</profile>
</component>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<file url="PROJECT" libraries="{bootstrap}" />
<file url="PROJECT" libraries="{bootstrap, bootstrap-icons}" />
</component>
</project>

8
.idea/laravel-idea.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="InertiaPackage">
<option name="directoryPaths">
<list />
</option>
</component>
</project>

View File

@@ -5,7 +5,7 @@
<tool tool_name="PHPUnit">
<cache>
<versions>
<info id="interpreter-c1266788-d465-407a-ac5d-1f67a9cf3e8a" version="11.5.2" />
<info id="interpreter-96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" version="12.4.1" />
</versions>
</cache>
</tool>

406
.idea/php.xml generated
View File

@@ -1,8 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="LaravelPint">
<laravel_pint_settings>
<laravel_pint_by_interpreter asDefaultInterpreter="true" interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8">
<option name="timeout" value="30000" />
</laravel_pint_by_interpreter>
</laravel_pint_settings>
</component>
<component name="MessDetector">
<phpmd_settings>
<phpmd_by_interpreter asDefaultInterpreter="true" interpreter_id="c1266788-d465-407a-ac5d-1f67a9cf3e8a" timeout="30000" />
<phpmd_by_interpreter asDefaultInterpreter="true" interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" timeout="30000" />
</phpmd_settings>
</component>
<component name="MessDetectorOptionsConfiguration">
@@ -10,7 +17,7 @@
</component>
<component name="PHPCSFixerOptionsConfiguration">
<option name="codingStandard" value="Custom" />
<option name="rulesetPath" value="/app/.php-cs-fixer.dist.php" />
<option name="rulesetPath" value=".php-cs-fixer.dist.php" />
<option name="transferred" value="true" />
</component>
<component name="PHPCodeSnifferOptionsConfiguration">
@@ -19,14 +26,14 @@
</component>
<component name="PhpCSFixer">
<phpcsfixer_settings>
<phpcs_fixer_by_interpreter interpreter_id="c1266788-d465-407a-ac5d-1f67a9cf3e8a" tool_path="/app/vendor/bin/php-cs-fixer" timeout="30000" />
<phpcs_fixer_by_interpreter asDefaultInterpreter="true" deletedFromTheList="true" interpreter_id="c1266788-d465-407a-ac5d-1f67a9cf3e8a" standards="DoctrineAnnotation;PER;PER-CS;PER-CS1.0;PER-CS2.0;PHP54Migration;PHP56Migration;PHP70Migration;PHP71Migration;PHP73Migration;PHP74Migration;PHP80Migration;PHP81Migration;PHP82Migration;PHP83Migration;PHP84Migration;PHPUnit100Migration;PHPUnit30Migration;PHPUnit32Migration;PHPUnit35Migration;PHPUnit43Migration;PHPUnit48Migration;PHPUnit50Migration;PHPUnit52Migration;PHPUnit54Migration;PHPUnit55Migration;PHPUnit56Migration;PHPUnit57Migration;PHPUnit60Migration;PHPUnit75Migration;PHPUnit84Migration;PHPUnit91Migration;PSR1;PSR12;PSR2;PhpCsFixer;Symfony" tool_path="/app/vendor/bin/php-cs-fixer" timeout="30000" />
<PhpCSFixerConfiguration deletedFromTheList="true" tool_path="$PROJECT_DIR$/vendor/bin/php-cs-fixer" />
<phpcs_fixer_by_interpreter interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" standards="DoctrineAnnotation;PER;PER-CS;PER-CS1.0;PER-CS1x0;PER-CS2.0;PER-CS2x0;PER-CS3.0;PER-CS3x0;PHP54Migration;PHP56Migration;PHP5x4Migration;PHP5x6Migration;PHP70Migration;PHP71Migration;PHP73Migration;PHP74Migration;PHP7x0Migration;PHP7x1Migration;PHP7x3Migration;PHP7x4Migration;PHP80Migration;PHP81Migration;PHP82Migration;PHP83Migration;PHP84Migration;PHP85Migration;PHP8x0Migration;PHP8x1Migration;PHP8x2Migration;PHP8x3Migration;PHP8x4Migration;PHP8x5Migration;PHPUnit100Migration;PHPUnit10x0Migration;PHPUnit11x0Migration;PHPUnit30Migration;PHPUnit32Migration;PHPUnit35Migration;PHPUnit3x0Migration;PHPUnit3x2Migration;PHPUnit3x5Migration;PHPUnit43Migration;PHPUnit48Migration;PHPUnit4x3Migration;PHPUnit4x8Migration;PHPUnit50Migration;PHPUnit52Migration;PHPUnit54Migration;PHPUnit55Migration;PHPUnit56Migration;PHPUnit57Migration;PHPUnit5x0Migration;PHPUnit5x2Migration;PHPUnit5x4Migration;PHPUnit5x5Migration;PHPUnit5x6Migration;PHPUnit5x7Migration;PHPUnit60Migration;PHPUnit6x0Migration;PHPUnit75Migration;PHPUnit7x5Migration;PHPUnit84Migration;PHPUnit8x4Migration;PHPUnit91Migration;PHPUnit9x1Migration;PSR1;PSR12;PSR2;PhpCsFixer;Symfony;auto;autoPHPMigration;autoPHPUnitMigration" tool_path="vendor/bin/php-cs-fixer" timeout="30000" />
<PhpCSFixerConfiguration deletedFromTheList="true" standards="PSR1;PSR2;Symfony;DoctrineAnnotation;PHP70Migration;PHP71Migration" tool_path="$PROJECT_DIR$/vendor/bin/php-cs-fixer" />
<phpcs_fixer_by_interpreter asDefaultInterpreter="true" deletedFromTheList="true" interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" standards="DoctrineAnnotation;PER;PER-CS;PER-CS1.0;PER-CS2.0;PHP54Migration;PHP56Migration;PHP70Migration;PHP71Migration;PHP73Migration;PHP74Migration;PHP80Migration;PHP81Migration;PHP82Migration;PHP83Migration;PHP84Migration;PHPUnit100Migration;PHPUnit30Migration;PHPUnit32Migration;PHPUnit35Migration;PHPUnit43Migration;PHPUnit48Migration;PHPUnit50Migration;PHPUnit52Migration;PHPUnit54Migration;PHPUnit55Migration;PHPUnit56Migration;PHPUnit57Migration;PHPUnit60Migration;PHPUnit75Migration;PHPUnit84Migration;PHPUnit91Migration;PSR1;PSR12;PSR2;PhpCsFixer;Symfony" tool_path="vendor/bin/php-cs-fixer" timeout="30000" />
</phpcsfixer_settings>
</component>
<component name="PhpCodeSniffer">
<phpcs_settings>
<phpcs_by_interpreter asDefaultInterpreter="true" interpreter_id="c1266788-d465-407a-ac5d-1f67a9cf3e8a" timeout="30000" />
<phpcs_by_interpreter asDefaultInterpreter="true" interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" timeout="30000" />
</phpcs_settings>
</component>
<component name="PhpExternalFormatter">
@@ -34,140 +41,172 @@
</component>
<component name="PhpIncludePathManager">
<include_path>
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/string" />
<path value="$PROJECT_DIR$/vendor/symfony/yaml" />
<path value="$PROJECT_DIR$/vendor/symfony/dotenv" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
<path value="$PROJECT_DIR$/vendor/runtime/frankenphp-symfony" />
<path value="$PROJECT_DIR$/vendor/clue/ndjson-react" />
<path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/symfony/cache-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
<path value="$PROJECT_DIR$/vendor/symfony/runtime" />
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php83" />
<path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/symfony/var-exporter" />
<path value="$PROJECT_DIR$/vendor/psr/cache" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<path value="$PROJECT_DIR$/vendor/psr/log" />
<path value="$PROJECT_DIR$/vendor/symfony/cache" />
<path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<path value="$PROJECT_DIR$/vendor/symfony/dependency-injection" />
<path value="$PROJECT_DIR$/vendor/symfony/config" />
<path value="$PROJECT_DIR$/vendor/symfony/filesystem" />
<path value="$PROJECT_DIR$/vendor/symfony/error-handler" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/console" />
<path value="$PROJECT_DIR$/vendor/symfony/flex" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
<path value="$PROJECT_DIR$/vendor/symfony/framework-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
<path value="$PROJECT_DIR$/vendor/symfony/doctrine-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/stopwatch" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-migrations-bundle" />
<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/dbal" />
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
<path value="$PROJECT_DIR$/vendor/doctrine/persistence" />
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/doctrine/orm" />
<path value="$PROJECT_DIR$/vendor/doctrine/event-manager" />
<path value="$PROJECT_DIR$/vendor/dama/doctrine-test-bundle" />
<path value="$PROJECT_DIR$/vendor/doctrine/collections" />
<path value="$PROJECT_DIR$/vendor/doctrine/sql-formatter" />
<path value="$PROJECT_DIR$/vendor/doctrine/data-fixtures" />
<path value="$PROJECT_DIR$/vendor/doctrine/dbal" />
<path value="$PROJECT_DIR$/vendor/doctrine/deprecations" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/process" />
<path value="$PROJECT_DIR$/vendor/symfony/maker-bundle" />
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan" />
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
<path value="$PROJECT_DIR$/vendor/rector/rector" />
<path value="$PROJECT_DIR$/vendor/react/event-loop" />
<path value="$PROJECT_DIR$/vendor/react/cache" />
<path value="$PROJECT_DIR$/vendor/react/stream" />
<path value="$PROJECT_DIR$/vendor/clue/ndjson-react" />
<path value="$PROJECT_DIR$/vendor/react/promise" />
<path value="$PROJECT_DIR$/vendor/react/dns" />
<path value="$PROJECT_DIR$/vendor/friendsofphp/php-cs-fixer" />
<path value="$PROJECT_DIR$/vendor/react/socket" />
<path value="$PROJECT_DIR$/vendor/react/child-process" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-migrations-bundle" />
<path value="$PROJECT_DIR$/vendor/doctrine/event-manager" />
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
<path value="$PROJECT_DIR$/vendor/doctrine/migrations" />
<path value="$PROJECT_DIR$/vendor/doctrine/orm" />
<path value="$PROJECT_DIR$/vendor/doctrine/persistence" />
<path value="$PROJECT_DIR$/vendor/doctrine/sql-formatter" />
<path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
<path value="$PROJECT_DIR$/vendor/evenement/evenement" />
<path value="$PROJECT_DIR$/vendor/symfony/options-resolver" />
<path value="$PROJECT_DIR$/vendor/fidry/cpu-core-counter" />
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
<path value="$PROJECT_DIR$/vendor/sebastian/complexity" />
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
<path value="$PROJECT_DIR$/vendor/sebastian/cli-parser" />
<path value="$PROJECT_DIR$/vendor/sebastian/lines-of-code" />
<path value="$PROJECT_DIR$/vendor/sebastian/type" />
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
<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/friendsofphp/php-cs-fixer" />
<path value="$PROJECT_DIR$/vendor/gedmo/doctrine-extensions" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
<path value="$PROJECT_DIR$/vendor/jean85/pretty-package-versions" />
<path value="$PROJECT_DIR$/vendor/maennchen/zipstream-php" />
<path value="$PROJECT_DIR$/vendor/markbaker/complex" />
<path value="$PROJECT_DIR$/vendor/markbaker/matrix" />
<path value="$PROJECT_DIR$/vendor/martin-georgiev/postgresql-for-doctrine" />
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-invoker" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
<path value="$PROJECT_DIR$/vendor/staabm/side-effects-detector" />
<path value="$PROJECT_DIR$/vendor/symfony/twig-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/twig-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
<path value="$PROJECT_DIR$/vendor/twig/twig" />
<path value="$PROJECT_DIR$/vendor/symfony/uid" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-uuid" />
<path value="$PROJECT_DIR$/vendor/psr/clock" />
<path value="$PROJECT_DIR$/vendor/symfony/security-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/type-info" />
<path value="$PROJECT_DIR$/vendor/symfony/property-access" />
<path value="$PROJECT_DIR$/vendor/symfony/property-info" />
<path value="$PROJECT_DIR$/vendor/symfony/password-hasher" />
<path value="$PROJECT_DIR$/vendor/symfony/clock" />
<path value="$PROJECT_DIR$/vendor/symfony/security-csrf" />
<path value="$PROJECT_DIR$/vendor/symfony/security-core" />
<path value="$PROJECT_DIR$/vendor/symfony/security-http" />
<path value="$PROJECT_DIR$/vendor/symfony/web-profiler-bundle" />
<path value="$PROJECT_DIR$/vendor/thecodingmachine/safe" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
<path value="$PROJECT_DIR$/vendor/phpoffice/phpspreadsheet" />
<path value="$PROJECT_DIR$/vendor/phpstan/extension-installer" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpdoc-parser" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan-doctrine" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan-phpunit" />
<path value="$PROJECT_DIR$/vendor/phpstan/phpstan-symfony" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-invoker" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
<path value="$PROJECT_DIR$/vendor/psr/cache" />
<path value="$PROJECT_DIR$/vendor/psr/clock" />
<path value="$PROJECT_DIR$/vendor/psr/container" />
<path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/psr/http-factory" />
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
<path value="$PROJECT_DIR$/vendor/psr/log" />
<path value="$PROJECT_DIR$/vendor/psr/simple-cache" />
<path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
<path value="$PROJECT_DIR$/vendor/react/cache" />
<path value="$PROJECT_DIR$/vendor/react/child-process" />
<path value="$PROJECT_DIR$/vendor/react/dns" />
<path value="$PROJECT_DIR$/vendor/react/event-loop" />
<path value="$PROJECT_DIR$/vendor/react/promise" />
<path value="$PROJECT_DIR$/vendor/react/socket" />
<path value="$PROJECT_DIR$/vendor/react/stream" />
<path value="$PROJECT_DIR$/vendor/rector/rector" />
<path value="$PROJECT_DIR$/vendor/sebastian/cli-parser" />
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
<path value="$PROJECT_DIR$/vendor/sebastian/complexity" />
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
<path value="$PROJECT_DIR$/vendor/sebastian/lines-of-code" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
<path value="$PROJECT_DIR$/vendor/sebastian/type" />
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
<path value="$PROJECT_DIR$/vendor/sentry/sentry" />
<path value="$PROJECT_DIR$/vendor/sentry/sentry-symfony" />
<path value="$PROJECT_DIR$/vendor/staabm/side-effects-detector" />
<path value="$PROJECT_DIR$/vendor/stof/doctrine-extensions-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/asset" />
<path value="$PROJECT_DIR$/vendor/thecodingmachine/phpstan-safe-rule" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-icu" />
<path value="$PROJECT_DIR$/vendor/symfony/asset-mapper" />
<path value="$PROJECT_DIR$/vendor/symfony/brevo-mailer" />
<path value="$PROJECT_DIR$/vendor/symfony/browser-kit" />
<path value="$PROJECT_DIR$/vendor/symfony/cache" />
<path value="$PROJECT_DIR$/vendor/symfony/cache-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/clock" />
<path value="$PROJECT_DIR$/vendor/symfony/config" />
<path value="$PROJECT_DIR$/vendor/symfony/console" />
<path value="$PROJECT_DIR$/vendor/symfony/css-selector" />
<path value="$PROJECT_DIR$/vendor/symfony/dependency-injection" />
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/doctrine-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/dom-crawler" />
<path value="$PROJECT_DIR$/vendor/symfony/dotenv" />
<path value="$PROJECT_DIR$/vendor/symfony/error-handler" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/filesystem" />
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
<path value="$PROJECT_DIR$/vendor/symfony/flex" />
<path value="$PROJECT_DIR$/vendor/symfony/form" />
<path value="$PROJECT_DIR$/vendor/twig/html-extra" />
<path value="$PROJECT_DIR$/vendor/twig/extra-bundle" />
<path value="$PROJECT_DIR$/vendor/easycorp/easyadmin-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
<path value="$PROJECT_DIR$/vendor/symfony/validator" />
<path value="$PROJECT_DIR$/vendor/symfony/ux-twig-component" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
<path value="$PROJECT_DIR$/vendor/symfony/framework-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/http-client" />
<path value="$PROJECT_DIR$/vendor/symfony/http-client-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
<path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
<path value="$PROJECT_DIR$/vendor/symfony/intl" />
<path value="$PROJECT_DIR$/vendor/symfony/mailer" />
<path value="$PROJECT_DIR$/vendor/symfony/maker-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
<path value="$PROJECT_DIR$/vendor/symfony/options-resolver" />
<path value="$PROJECT_DIR$/vendor/symfony/password-hasher" />
<path value="$PROJECT_DIR$/vendor/symfony/phpunit-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-icu" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php84" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-uuid" />
<path value="$PROJECT_DIR$/vendor/symfony/process" />
<path value="$PROJECT_DIR$/vendor/symfony/property-access" />
<path value="$PROJECT_DIR$/vendor/symfony/property-info" />
<path value="$PROJECT_DIR$/vendor/symfony/psr-http-message-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
<path value="$PROJECT_DIR$/vendor/symfony/runtime" />
<path value="$PROJECT_DIR$/vendor/symfony/security-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/security-core" />
<path value="$PROJECT_DIR$/vendor/symfony/security-csrf" />
<path value="$PROJECT_DIR$/vendor/symfony/security-http" />
<path value="$PROJECT_DIR$/vendor/symfony/serializer" />
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/stimulus-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/stopwatch" />
<path value="$PROJECT_DIR$/vendor/symfony/string" />
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
<path value="$PROJECT_DIR$/vendor/doctrine/data-fixtures" />
<path value="$PROJECT_DIR$/vendor/doctrine/doctrine-fixtures-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
<path value="$PROJECT_DIR$/vendor/symfony/twig-bridge" />
<path value="$PROJECT_DIR$/vendor/symfony/twig-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/type-info" />
<path value="$PROJECT_DIR$/vendor/symfony/uid" />
<path value="$PROJECT_DIR$/vendor/symfony/ux-turbo" />
<path value="$PROJECT_DIR$/vendor/symfony/validator" />
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
<path value="$PROJECT_DIR$/vendor/symfony/var-exporter" />
<path value="$PROJECT_DIR$/vendor/symfony/web-profiler-bundle" />
<path value="$PROJECT_DIR$/vendor/symfony/yaml" />
<path value="$PROJECT_DIR$/vendor/symfonycasts/sass-bundle" />
<path value="$PROJECT_DIR$/vendor/symfonycasts/verify-email-bundle" />
<path value="$PROJECT_DIR$/vendor/thecodingmachine/phpstan-safe-rule" />
<path value="$PROJECT_DIR$/vendor/thecodingmachine/safe" />
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
<path value="$PROJECT_DIR$/vendor/twig/extra-bundle" />
<path value="$PROJECT_DIR$/vendor/twig/intl-extra" />
<path value="$PROJECT_DIR$/vendor/twig/twig" />
<path value="$PROJECT_DIR$/vendor/vincentlanglet/twig-cs-fixer" />
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php85" />
</include_path>
</component>
<component name="PhpInterpreters">
<interpreters>
<interpreter id="c1266788-d465-407a-ac5d-1f67a9cf3e8a" name="php" home="docker-compose://DATA" auto="false" debugger_id="php.debugger.XDebug">
<interpreter id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" name="Compose PHP" home="docker-compose://DATA" auto="false" debugger_id="php.debugger.XDebug">
<remote_data INTERPRETER_PATH="php" HELPERS_PATH="/opt/.phpstorm_helpers" VALID="true" RUN_AS_ROOT_VIA_SUDO="false" DOCKER_ACCOUNT_NAME="Colima" DOCKER_COMPOSE_SERVICE_NAME="php" DOCKER_REMOTE_PROJECT_PATH="/opt/project">
<type_data command="EXEC" />
<dockerComposeConfigurationPaths>
@@ -181,15 +220,15 @@
</component>
<component name="PhpInterpretersPhpInfoCache">
<phpInfoCache>
<interpreter name="php">
<phpinfo binary_type="PHP" php_cgi="/usr/local/bin/php-cgi" php_cli="/usr/local/bin/php" path_separator=":" version="8.3.15">
<additional_php_ini>/usr/local/etc/php/conf.d/docker-php-ext-apcu.ini, /usr/local/etc/php/conf.d/docker-php-ext-intl.ini, /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini, /usr/local/etc/php/conf.d/docker-php-ext-pdo_pgsql.ini, /usr/local/etc/php/conf.d/docker-php-ext-sodium.ini, /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini, /usr/local/etc/php/conf.d/docker-php-ext-zip.ini, /usr/local/etc/php/app.conf.d/10-app.ini, /usr/local/etc/php/app.conf.d/20-app.dev.ini</additional_php_ini>
<interpreter name="Compose PHP">
<phpinfo binary_type="PHP" php_cgi="/usr/local/bin/php-cgi" php_cli="/usr/local/bin/php" path_separator=":" version="8.5.2">
<additional_php_ini>/usr/local/etc/php/conf.d/docker-php-ext-apcu.ini, /usr/local/etc/php/conf.d/docker-php-ext-excimer.ini, /usr/local/etc/php/conf.d/docker-php-ext-gd.ini, /usr/local/etc/php/conf.d/docker-php-ext-intl.ini, /usr/local/etc/php/conf.d/docker-php-ext-pdo_pgsql.ini, /usr/local/etc/php/conf.d/docker-php-ext-sodium.ini, /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini, /usr/local/etc/php/conf.d/docker-php-ext-zip.ini, /usr/local/etc/php/app.conf.d/10-app.ini, /usr/local/etc/php/app.conf.d/20-app.dev.ini</additional_php_ini>
<configuration_file>/usr/local/etc/php/php.ini</configuration_file>
<configuration_options>
<configuration_option name="include_path" value=".:/usr/local/lib/php" />
</configuration_options>
<debuggers>
<debugger_info debugger="xdebug" debugger_version="3.4.0">
<debugger_info debugger="xdebug" debugger_version="3.5.0">
<debug_extensions />
</debugger_info>
</debuggers>
@@ -206,12 +245,15 @@
<extension name="curl" />
<extension name="date" />
<extension name="dom" />
<extension name="excimer" />
<extension name="fileinfo" />
<extension name="filter" />
<extension name="gd" />
<extension name="hash" />
<extension name="iconv" />
<extension name="intl" />
<extension name="json" />
<extension name="lexbor" />
<extension name="libxml" />
<extension name="mbstring" />
<extension name="mysqlnd" />
@@ -227,6 +269,7 @@
<extension name="sqlite3" />
<extension name="standard" />
<extension name="tokenizer" />
<extension name="uri" />
<extension name="xdebug" />
<extension name="xml" />
<extension name="xmlreader" />
@@ -238,28 +281,129 @@
</interpreter>
</phpInfoCache>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="8.3" />
<component name="PhpProjectSharedConfiguration" php_language_level="8.5" />
<component name="PhpRuntimeConfiguration">
<extensions>
<extension name="Ev" enabled="false" />
<extension name="SQLite" enabled="false" />
<extension name="SplType" enabled="false" />
<extension name="ZendDebugger" enabled="false" />
<extension name="ZendUtils" enabled="false" />
<extension name="amqp" enabled="false" />
<extension name="apache" enabled="false" />
<extension name="bcmath" enabled="false" />
<extension name="brotli" enabled="false" />
<extension name="bz2" enabled="false" />
<extension name="calendar" enabled="false" />
<extension name="cassandra" enabled="false" />
<extension name="couchbase" enabled="false" />
<extension name="cubrid" enabled="false" />
<extension name="dba" enabled="false" />
<extension name="decimal" enabled="false" />
<extension name="dio" enabled="false" />
<extension name="elastic_apm" enabled="false" />
<extension name="enchant" enabled="false" />
<extension name="exif" enabled="false" />
<extension name="fann" enabled="false" />
<extension name="ffmpeg" enabled="false" />
<extension name="frankenphp" enabled="false" />
<extension name="ftp" enabled="false" />
<extension name="gearman" enabled="false" />
<extension name="geoip" enabled="false" />
<extension name="geos" enabled="false" />
<extension name="gettext" enabled="false" />
<extension name="gmagick" enabled="false" />
<extension name="gmp" enabled="false" />
<extension name="gnupg" enabled="false" />
<extension name="grpc" enabled="false" />
<extension name="http" enabled="false" />
<extension name="ibm_db2" enabled="false" />
<extension name="igbinary" enabled="false" />
<extension name="imagick" enabled="false" />
<extension name="imap" enabled="false" />
<extension name="inotify" enabled="false" />
<extension name="interbase" enabled="false" />
<extension name="jsonpath" enabled="false" />
<extension name="judy" enabled="false" />
<extension name="ldap" enabled="false" />
<extension name="libevent" enabled="false" />
<extension name="libsodium" enabled="false" />
<extension name="mailparse" enabled="false" />
<extension name="mcrypt" enabled="false" />
<extension name="memcache" enabled="false" />
<extension name="memcached" enabled="false" />
<extension name="ming" enabled="false" />
<extension name="mongo" enabled="false" />
<extension name="mongodb" enabled="false" />
<extension name="mosquitto-php" enabled="false" />
<extension name="mqseries" enabled="false" />
<extension name="mssql" enabled="false" />
<extension name="mysql" enabled="false" />
<extension name="mysql_xdevapi" enabled="false" />
<extension name="mysqli" enabled="false" />
<extension name="ncurses" enabled="false" />
<extension name="newrelic" enabled="false" />
<extension name="oauth" enabled="false" />
<extension name="oci8" enabled="false" />
<extension name="odbc" enabled="false" />
<extension name="opentelemetry" enabled="false" />
<extension name="pcntl" enabled="false" />
<extension name="pdflib" enabled="false" />
<extension name="pgsql" enabled="false" />
<extension name="pspell" enabled="false" />
<extension name="pthreads" enabled="false" />
<extension name="rar" enabled="false" />
<extension name="recode" enabled="false" />
<extension name="redis" enabled="false" />
<extension name="relay" enabled="false" />
<extension name="rrd" enabled="false" />
<extension name="shmop" enabled="false" />
<extension name="snappy" enabled="false" />
<extension name="snmp" enabled="false" />
<extension name="soap" enabled="false" />
<extension name="sockets" enabled="false" />
<extension name="sqlsrv" enabled="false" />
<extension name="ssh2" enabled="false" />
<extension name="suhosin" enabled="false" />
<extension name="svn" enabled="false" />
<extension name="sybase" enabled="false" />
<extension name="sysvmsg" enabled="false" />
<extension name="sysvsem" enabled="false" />
<extension name="sysvshm" enabled="false" />
<extension name="tidy" enabled="false" />
<extension name="v8js" enabled="false" />
<extension name="wddx" enabled="false" />
<extension name="win32service" enabled="false" />
<extension name="wincache" enabled="false" />
<extension name="xhprof" enabled="false" />
<extension name="xlswriter" enabled="false" />
<extension name="xmlrpc" enabled="false" />
<extension name="xsl" enabled="false" />
<extension name="yaml" enabled="false" />
<extension name="zend" enabled="false" />
<extension name="zmq" enabled="false" />
</extensions>
</component>
<component name="PhpStan">
<PhpStan_settings>
<phpstan_by_interpreter interpreter_id="c1266788-d465-407a-ac5d-1f67a9cf3e8a" tool_path="/app/vendor/bin/phpstan" timeout="60000" />
<phpstan_by_interpreter asDefaultInterpreter="true" deletedFromTheList="true" interpreter_id="afbe50d9-a569-498c-8dcc-cf68a5d73813" timeout="60000" />
<phpstan_by_interpreter interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" tool_path="vendor/bin/phpstan" timeout="60000" />
<PhpStanConfiguration deletedFromTheList="true" tool_path="$PROJECT_DIR$/vendor/bin/phpstan" />
<phpstan_by_interpreter asDefaultInterpreter="true" deletedFromTheList="true" interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" tool_path="vendor/bin/phpstan" timeout="60000" />
</PhpStan_settings>
</component>
<component name="PhpStanOptionsConfiguration">
<option name="config" value="$PROJECT_DIR$/phpstan.dist.neon" />
<option name="level" value="8" />
<option name="config" value="phpstan.dist.neon" />
<option name="fullProject" value="true" />
<option name="transferred" value="true" />
</component>
<component name="PhpUnit">
<phpunit_settings>
<phpunit_by_interpreter interpreter_id="c1266788-d465-407a-ac5d-1f67a9cf3e8a" custom_loader_path="/app/vendor/autoload.php" phpunit_phar_path="" />
<PhpUnitSettings custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" />
<phpunit_by_interpreter interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" bootstrap_file_path="./tests/bootstrap.php" configuration_file_path="./phpunit.dist.xml" custom_loader_path="/app/vendor/autoload.php" phpunit_phar_path="" use_bootstrap_file="true" use_configuration_file="true" />
</phpunit_settings>
</component>
<component name="Psalm">
<Psalm_settings>
<psalm_fixer_by_interpreter asDefaultInterpreter="true" interpreter_id="afbe50d9-a569-498c-8dcc-cf68a5d73813" timeout="60000" />
<psalm_fixer_by_interpreter asDefaultInterpreter="true" interpreter_id="96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8" timeout="60000" />
</Psalm_settings>
</component>
<component name="PsalmOptionsConfiguration">

16
.idea/remote-mappings.xml generated Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteMappingsManager">
<list>
<list>
<remote-mappings server-id="php@96512cb2-7b9e-4e1d-bfa2-bf7f3be424c8">
<settings>
<list>
<mapping local-root="$PROJECT_DIR$" remote-root="/app" />
</list>
</settings>
</remote-mappings>
</list>
</list>
</component>
</project>

8
.idea/sonarlint.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SonarLintProjectSettings">
<option name="bindingEnabled" value="true" />
<option name="projectKey" value="MarijnDoeve_TijdVoorDeTest" />
<option name="serverId" value="SonarQube" />
</component>
</project>

6
.idea/sqldialects.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="SqlDialectMappings">
<file url="PROJECT" dialect="PostgreSQL" />
</component>
</project>

1
.idea/symfony2.xml generated
View File

@@ -2,5 +2,6 @@
<project version="4">
<component name="Symfony2PluginSettings">
<option name="pluginEnabled" value="true" />
<option name="profilerCsvPath" value="" />
</component>
</project>

View File

@@ -1,30 +1,40 @@
<?php
declare(strict_types=1);
use PhpCsFixer\Config;
use PhpCsFixer\Finder;
use PhpCsFixer\Runner\Parallel\ParallelConfigFactory;
$finder = (new PhpCsFixer\Finder())
$finder = new Finder()
->in(__DIR__)
->exclude('var')
->exclude('bin')
->notPath(['config/reference.php'])
;
return (new PhpCsFixer\Config())
return new Config()
->setParallelConfig(ParallelConfigFactory::detect())
->setRules([
'@Symfony' => true,
'@Symfony:risky' => true,
'declare_strict_types' => true,
'fully_qualified_strict_types' => ['import_symbols' => true],
'linebreak_after_opening_tag' => true,
'mb_str_functions' => true,
'no_php4_constructor' => true,
'no_unreachable_default_argument_value' => true,
'no_useless_else' => true,
'no_useless_return' => true,
'php_unit_strict' => true,
'phpdoc_line_span' => ['const' => 'single', 'method' => 'single', 'property' => 'single'],
'phpdoc_order' => true,
'single_line_empty_body' => true,
'strict_comparison' => true,
'strict_param' => true,
'blank_line_between_import_groups' => false,
'phpdoc_line_span' => ['const' => 'single', 'method' => 'single', 'property' => 'single'],
'ordered_attributes' => true,
'heredoc_indentation' => ['indentation' => 'start_plus_one'],
'trailing_comma_in_multiline' => ['after_heredoc' => true, 'elements' => ['arguments', 'array_destructuring', 'arrays', 'match', 'parameters']],
])
->setRiskyAllowed(true)
->setFinder($finder)
->setUnsupportedPhpVersionAllowed(true)
;

View File

@@ -1,7 +1,7 @@
#syntax=docker/dockerfile:1
# Versions
FROM dunglas/frankenphp:1-php8.3 AS frankenphp_upstream
FROM dunglas/frankenphp:1-php8.5 AS frankenphp_upstream
# The different stages of this Dockerfile are meant to be built into separate images
# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage
@@ -31,6 +31,8 @@ RUN set -eux; \
intl \
opcache \
zip \
gd \
excimer \
;
# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
@@ -58,27 +60,37 @@ FROM frankenphp_base AS frankenphp_dev
ENV APP_ENV=dev XDEBUG_MODE=off
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends \
bash-completion \
&& rm -rf /var/lib/apt/lists/*
COPY --link frankenphp/console-complete.bash /usr/share/bash-completion/completions/console
COPY --link frankenphp/composer-complete.bash /usr/share/bash-completion/completions/composer
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
RUN set -eux; \
install-php-extensions \
xdebug \
xdebug/xdebug@3.5.0 \
;
COPY --link frankenphp/conf.d/20-app.dev.ini $PHP_INI_DIR/app.conf.d/
RUN git config --global --add safe.directory /app
CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile", "--watch" ]
# Prod FrankenPHP image
FROM frankenphp_base AS frankenphp_prod
RUN rm -rf /var/lib/apt/lists/*
ENV APP_ENV=prod
ENV FRANKENPHP_CONFIG="import worker.Caddyfile"
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
COPY --link frankenphp/conf.d/20-app.prod.ini $PHP_INI_DIR/app.conf.d/
COPY --link frankenphp/worker.Caddyfile /etc/caddy/worker.Caddyfile
# prevent the reinstallation of vendors at every changes in the source code
COPY --link composer.* symfony.* ./
@@ -94,4 +106,7 @@ RUN set -eux; \
composer dump-autoload --classmap-authoritative --no-dev; \
composer dump-env prod; \
composer run-script --no-dev post-install-cmd; \
chmod +x bin/console; sync;
chmod +x bin/console; \
bin/console sass:build; \
bin/console asset-map:compile --no-debug --quiet --no-ansi; \
sync;

53
Justfile Normal file
View File

@@ -0,0 +1,53 @@
up *args:
docker compose up -d {{ args }}
down *args:
docker compose down --remove-orphans {{ args }}
stop:
docker compose stop
exec *args:
docker compose exec php {{ args }}
[no-exit-message]
shell:
@docker compose exec php bash
bash: shell
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 --group=dev
translations:
docker compose exec php bin/console translation:extract --force --format=xliff --sort=asc --clean nl
fix-cs:
docker compose exec php vendor/bin/php-cs-fixer fix
docker compose exec php vendor/bin/twig-cs-fixer fix
rector *args:
docker compose exec php vendor/bin/rector {{ args }}
phpstan *args:
docker compose exec php vendor/bin/phpstan analyse {{ args }}
[confirm]
clean:
docker compose down -v --remove-orphans
rm -rf vendor var assets/vendor public/assets public/bundles .php-cs-fixer.cache .twig-cs-fixer.cache
reload-tests:
@docker compose exec php bin/console --env=test doctrine:database:drop --if-exists --force
@docker compose exec php bin/console --env=test doctrine:database:create
@docker compose exec php bin/console --env=test doctrine:migrations:migrate -n
@docker compose exec php bin/console --env=test doctrine:fixtures:load -n --group=test
trust-cert:
sudo security add-trusted-cer -d \
-r trustRoot \
-k "$HOME/Library/Keychains/login.keychain" \
./frankenphp/data/caddy/pki/authorities/local/root.crt

View File

@@ -6,39 +6,33 @@
- WIDM-tests met een variabel aantal vragen.
- Vragen in een vaste volgorde zijn samen één test (een vraag kan niet bij
meerdere test horen).
- Vragen hebben 2 of meer antwoordmogelijkheden. Slechts één vraag is correct.
meerdere tests horen).
- Vragen hebben 2 of meer antwoordmogelijkheden. Slechts één antwoord is correct.
- Meerdere test samen vormen een seizoen.
- Een seizoen heeft één of geen actieve tests, als er een test actief is kan
Uitsluitend die test gemaakt worden.
- Kandidaten kunnen een test maximaal 1 keer invullen. Indien ingeschakeld
kunnen alleen vooraf ingevoerde namen gebruikt worden in een test.
uitsluitend die test gemaakt worden.
- Kandidaten kunnen een test maximaal 1 keer invullen.
- Vanaf het moment dat de kandidaat op start klikt na het intypen van hun naam
gaat de tijd lopen. Deze stopt na het aanklikken van een antwoord op de laatste
vraag van de test.
- Achtergrondmuziek
### Schermen kijken
- Nadat een speler een test heeft gemaakt (of vooraf als de namen vooraf
ingevoerd zijn) kunnen jokers toegekend worden aan de test van kandidaat. Een
positief getal om antwoorden goed te rekenen, een negatief getal om
antwoorden fout te rekenen. Een vrijstelling kan gegeven worden door evenveel
of meer jokers toe te kennen als dat er vragen in een test zitten.
antwoorden fout te rekenen.
- Vooraf kan gekozen worden hoe veel afvallers er zijn.
- Bij het kijken naam rode en groene schermen wordt een naam ingevoerd. Er
wordt een rood of groen scherm getoond.
- Spelers kunnen geforceerd op groen of rood gezet worden, deze worden dan niet
meegenomen in de berekening van de slechtste speler.
### Statistieken
TBD
## Nice to haves
- Optie voor antwoord geven in twee klikken (selecteren en volgende).

5
assets/backoffice.js Normal file
View File

@@ -0,0 +1,5 @@
import * as bootstrap from 'bootstrap'
import './bootstrap.js';
import 'bootstrap/dist/css/bootstrap.min.css'
import './styles/backoffice.scss';

5
assets/bootstrap.js vendored Normal file
View File

@@ -0,0 +1,5 @@
import { startStimulusApp } from '@symfony/stimulus-bundle';
const app = startStimulusApp();
// register any custom, 3rd party controllers here
// app.register('some_controller_name', SomeImportedController);

15
assets/controllers.json Normal file
View File

@@ -0,0 +1,15 @@
{
"controllers": {
"@symfony/ux-turbo": {
"turbo-core": {
"enabled": false,
"fetch": "eager"
},
"mercure-turbo-stream": {
"enabled": false,
"fetch": "eager"
}
}
},
"entrypoints": []
}

View File

@@ -0,0 +1,17 @@
import {Controller} from '@hotwired/stimulus';
import * as bootstrap from 'bootstrap'
export default class extends Controller {
connect() {
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
}
clearQuiz() {
new bootstrap.Modal('#clearQuizModal').show();
}
deleteQuiz() {
new bootstrap.Modal('#deleteQuizModal').show();
}
}

View File

@@ -0,0 +1,81 @@
const nameCheck = /^[-_a-zA-Z0-9]{4,22}$/;
const tokenCheck = /^[-_/+a-zA-Z0-9]{24,}$/;
// Generate and double-submit a CSRF token in a form field and a cookie, as defined by Symfony's SameOriginCsrfTokenManager
// Use `form.requestSubmit()` to ensure that the submit event is triggered. Using `form.submit()` will not trigger the event
// and thus this event-listener will not be executed.
document.addEventListener('submit', function (event) {
generateCsrfToken(event.target);
}, true);
// When @hotwired/turbo handles form submissions, send the CSRF token in a header in addition to a cookie
// The `framework.csrf_protection.check_header` config option needs to be enabled for the header to be checked
document.addEventListener('turbo:submit-start', function (event) {
const h = generateCsrfHeaders(event.detail.formSubmission.formElement);
Object.keys(h).map(function (k) {
event.detail.formSubmission.fetchRequest.headers[k] = h[k];
});
});
// When @hotwired/turbo handles form submissions, remove the CSRF cookie once a form has been submitted
document.addEventListener('turbo:submit-end', function (event) {
removeCsrfToken(event.detail.formSubmission.formElement);
});
export function generateCsrfToken (formElement) {
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
if (!csrfField) {
return;
}
let csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');
let csrfToken = csrfField.value;
if (!csrfCookie && nameCheck.test(csrfToken)) {
csrfField.setAttribute('data-csrf-protection-cookie-value', csrfCookie = csrfToken);
csrfField.defaultValue = csrfToken = btoa(String.fromCharCode.apply(null, (window.crypto || window.msCrypto).getRandomValues(new Uint8Array(18))));
}
csrfField.dispatchEvent(new Event('change', { bubbles: true }));
if (csrfCookie && tokenCheck.test(csrfToken)) {
const cookie = csrfCookie + '_' + csrfToken + '=' + csrfCookie + '; path=/; samesite=strict';
document.cookie = window.location.protocol === 'https:' ? '__Host-' + cookie + '; secure' : cookie;
}
}
export function generateCsrfHeaders (formElement) {
const headers = {};
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
if (!csrfField) {
return headers;
}
const csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');
if (tokenCheck.test(csrfField.value) && nameCheck.test(csrfCookie)) {
headers[csrfCookie] = csrfField.value;
}
return headers;
}
export function removeCsrfToken (formElement) {
const csrfField = formElement.querySelector('input[data-controller="csrf-protection"], input[name="_csrf_token"]');
if (!csrfField) {
return;
}
const csrfCookie = csrfField.getAttribute('data-csrf-protection-cookie-value');
if (tokenCheck.test(csrfField.value) && nameCheck.test(csrfCookie)) {
const cookie = csrfCookie + '_' + csrfField.value + '=0; path=/; samesite=strict; max-age=0';
document.cookie = window.location.protocol === 'https:' ? '__Host-' + cookie + '; secure' : cookie;
}
}
/* stimulusFetch: 'lazy' */
export default 'csrf-protection-controller';

View File

@@ -0,0 +1,10 @@
import {Controller} from '@hotwired/stimulus';
export default class extends Controller {
next() {
const currentUrl = window.location.href;
const urlParts = currentUrl.split('/');
urlParts.pop();
window.location.href = urlParts.join('/');
}
}

View File

Before

Width:  |  Height:  |  Size: 164 KiB

After

Width:  |  Height:  |  Size: 164 KiB

BIN
assets/img/green.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 KiB

BIN
assets/img/red.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 KiB

6
assets/quiz.js Normal file
View File

@@ -0,0 +1,6 @@
import './bootstrap.js';
import 'bootstrap/dist/css/bootstrap.min.css'
import * as bootstrap from 'bootstrap'
import './styles/app.scss'

View File

@@ -0,0 +1,2 @@
// register any custom, 3rd party controllers here
// app.register('some_controller_name', SomeImportedController);

26
assets/styles/app.scss Normal file
View File

@@ -0,0 +1,26 @@
html, body {
height: 100%;
background-image: url("../img/background.png");
background-position: center center;
background-repeat: no-repeat;
background-color: black;
color: white;
display: grid;
align-items: center;
justify-self: center;
}
.elimination-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100vh;
object-fit: contain;
background-color: white;
z-index: 1000;
display: flex;
justify-content: center;
align-items: center;
}

View File

View File

@@ -1,7 +1,9 @@
#!/usr/bin/env php
<?php
use App\Kernel;
declare(strict_types=1);
use Tvdt\Kernel;
use Symfony\Bundle\FrameworkBundle\Console\Application;
if (!is_dir(dirname(__DIR__).'/vendor')) {

5
compose.build.yaml Normal file
View File

@@ -0,0 +1,5 @@
services:
php:
build:
context: .
target: frankenphp_prod

View File

@@ -8,17 +8,43 @@ services:
- ./:/app
- ./frankenphp/Caddyfile:/etc/caddy/Caddyfile:ro
- ./frankenphp/conf.d/20-app.dev.ini:/usr/local/etc/php/app.conf.d/20-app.dev.ini:ro
# If you develop on Mac or Windows you can remove the vendor/ directory
# from the bind-mount for better performance by enabling the next line:
#- /app/vendor
- ./frankenphp/data:/data
- sass:/app/var/sass
environment:
MERCURE_EXTRA_DIRECTIVES: demo
# See https://xdebug.org/docs/all_settings#mode
XDEBUG_MODE: "${XDEBUG_MODE:-off}"
MAILER_DSN: "smtp://mailer:1025"
extra_hosts:
# Ensure that host.docker.internal is correctly defined on Linux
- host.docker.internal:host-gateway
tty: true
ports:
# HTTP
- target: 80
published: ${HTTP_PORT:-80}
protocol: tcp
# HTTPS
- target: 443
published: ${HTTPS_PORT:-443}
protocol: tcp
# HTTP/3
- target: 443
published: ${HTTP3_PORT:-443}
protocol: udp
sass:
image: ${IMAGES_PREFIX:-}app-php
volumes:
- ./:/app:ro
- sass:/app/var/sass
entrypoint: ''
depends_on:
- php
command:
- bin/console
- sass:build
- --watch
- -v
###> symfony/mercure-bundle ###
###< symfony/mercure-bundle ###
@@ -28,3 +54,17 @@ services:
ports:
- "5432:5432"
###< doctrine/doctrine-bundle ###
###> symfony/mailer ###
mailer:
image: axllent/mailpit
ports:
- "1025"
- "8025"
environment:
MP_SMTP_AUTH_ACCEPT_ANY: 1
MP_SMTP_AUTH_ALLOW_INSECURE: 1
###< symfony/mailer ###
volumes:
sass:

View File

@@ -1,10 +1,31 @@
# Production environment override
services:
php:
build:
context: .
target: frankenphp_prod
image: ghcr.io/marijndoeve/tijdvoordetest:${IMAGE_TAG}
environment:
APP_SECRET: ${APP_SECRET}
MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET}
MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET}
MAILER_DSN: ${MAILER_DSN}
MAILER_SENDER: ${MAILER_SENDER}
SENTRY_DSN: ${SENTRY_DSN}
labels:
- "traefik.enable=true"
- "traefik.http.routers.tvdt.rule=Host(`tijdvoordetest.nl`)"
- "traefik.http.routers.tvdt.entrypoints=websecure"
- "traefik.http.routers.tvdt.tls.certresolver=marijndoeve"
- "traefik.http.routers.tvdt.service=tvdt"
- "traefik.http.services.tvdt.loadbalancer.server.port=80"
networks:
- web
- internal
database:
networks:
- internal
ports:
- "5430:5432"
networks:
web:
external: true
internal:
external: false

View File

@@ -7,30 +7,14 @@ services:
MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
# Run "composer require symfony/orm-pack" to install and configure Doctrine ORM
DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:5432/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8}
DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:5432/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-16}&charset=${POSTGRES_CHARSET:-utf8}
# Run "composer require symfony/mercure-bundle" to install and configure the Mercure integration
MERCURE_URL: ${CADDY_MERCURE_URL:-http://php/.well-known/mercure}
MERCURE_PUBLIC_URL: ${CADDY_MERCURE_PUBLIC_URL:-https://${SERVER_NAME:-localhost}/.well-known/mercure}
MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
# The two next lines can be removed after initial installation
SYMFONY_VERSION: ${SYMFONY_VERSION:-}
STABILITY: ${STABILITY:-stable}
volumes:
- caddy_data:/data
- caddy_config:/config
ports:
# HTTP
- target: 80
published: ${HTTP_PORT:-80}
protocol: tcp
# HTTPS
- target: 443
published: ${HTTPS_PORT:-443}
protocol: tcp
# HTTP/3
- target: 443
published: ${HTTP3_PORT:-443}
protocol: udp
# Mercure is installed as a Caddy module, prevent the Flex recipe from installing another service
###> symfony/mercure-bundle ###
@@ -51,8 +35,7 @@ services:
start_period: 60s
volumes:
- database_data:/var/lib/postgresql/data:rw
# You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data!
# - ./docker/db/data:/var/lib/postgresql/data:rw
restart: always
###< doctrine/doctrine-bundle ###
volumes:

View File

@@ -1,47 +1,72 @@
{
"name": "symfony/skeleton",
"name": "marijndoeve/tijdvoordetest",
"type": "project",
"license": "MIT",
"description": "A minimal Symfony project recommended to create bare bones applications",
"minimum-stability": "stable",
"prefer-stable": true,
"require": {
"php": ">=8.3.15",
"php": ">=8.5",
"ext-ctype": "*",
"ext-iconv": "*",
"doctrine/dbal": "^3",
"doctrine/doctrine-bundle": "^2.13",
"doctrine/doctrine-migrations-bundle": "^3.3",
"doctrine/orm": "^3.3",
"easycorp/easyadmin-bundle": "^4.23",
"runtime/frankenphp-symfony": "^0.2.0",
"symfony/asset": "7.2.*",
"symfony/console": "7.2.*",
"symfony/dotenv": "7.2.*",
"symfony/flex": "^2.4.7",
"symfony/form": "7.2.*",
"symfony/framework-bundle": "7.2.*",
"symfony/runtime": "7.2.*",
"symfony/security-bundle": "7.2.*",
"symfony/twig-bundle": "7.2.*",
"symfony/uid": "7.2.*",
"symfony/yaml": "7.2.*",
"thecodingmachine/safe": "^2.5"
"doctrine/dbal": "^4.4.1",
"doctrine/doctrine-bundle": "^3.2.2",
"doctrine/doctrine-migrations-bundle": "^3.7.0",
"doctrine/orm": "^3.6.2",
"martin-georgiev/postgresql-for-doctrine": "^3.7.0",
"phpdocumentor/reflection-docblock": "^5.6.6",
"phpoffice/phpspreadsheet": "^5.4",
"phpstan/phpdoc-parser": "^2.3.2",
"sentry/sentry-symfony": "^5.8.3",
"stof/doctrine-extensions-bundle": "^1.15.3",
"symfony/asset": "8.0.*",
"symfony/asset-mapper": "8.0.*",
"symfony/brevo-mailer": "8.0.*",
"symfony/console": "8.0.*",
"symfony/dotenv": "8.0.*",
"symfony/flex": "^2.10.0",
"symfony/form": "8.0.*",
"symfony/framework-bundle": "8.0.*",
"symfony/mailer": "8.0.*",
"symfony/property-access": "8.0.*",
"symfony/property-info": "8.0.*",
"symfony/runtime": "8.0.*",
"symfony/security-bundle": "8.0.*",
"symfony/security-csrf": "8.0.*",
"symfony/serializer": "8.0.*",
"symfony/translation": "8.0.*",
"symfony/twig-bundle": "8.0.*",
"symfony/uid": "8.0.*",
"symfony/ux-turbo": "^2.32.0",
"symfony/validator": "8.0.*",
"symfony/yaml": "8.0.*",
"symfonycasts/sass-bundle": "^0.8.3",
"symfonycasts/verify-email-bundle": "^1.18.0",
"thecodingmachine/safe": "^3.3.0",
"twig/extra-bundle": "^3.23.0",
"twig/intl-extra": "^3.23.0",
"twig/twig": "^3.23.0"
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^4.0",
"friendsofphp/php-cs-fixer": "^3.65",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-doctrine": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-symfony": "^2.0",
"phpunit/phpunit": "^11",
"rector/rector": "^2.0",
"symfony/maker-bundle": "^1.62.1",
"symfony/stopwatch": "7.2.*",
"symfony/web-profiler-bundle": "7.2.*",
"thecodingmachine/phpstan-safe-rule": "^1.3"
"dama/doctrine-test-bundle": "^8.6",
"doctrine/doctrine-fixtures-bundle": "^4.3.1",
"friendsofphp/php-cs-fixer": "^3.93.0",
"phpstan/extension-installer": "^1.4.3",
"phpstan/phpstan": "^2.1.37",
"phpstan/phpstan-doctrine": "^2.0.14",
"phpstan/phpstan-phpunit": "^2.0.12",
"phpstan/phpstan-symfony": "^2.0.12",
"phpunit/phpunit": "^12.5.9",
"rector/rector": "^2.3.4",
"roave/security-advisories": "dev-latest",
"symfony/browser-kit": "8.0.*",
"symfony/css-selector": "8.0.*",
"symfony/maker-bundle": "^1.65.1",
"symfony/phpunit-bridge": "8.0.*",
"symfony/stopwatch": "8.0.*",
"symfony/web-profiler-bundle": "8.0.*",
"thecodingmachine/phpstan-safe-rule": "^1.4.3",
"vincentlanglet/twig-cs-fixer": "^3.13.0"
},
"config": {
"allow-plugins": {
@@ -55,28 +80,33 @@
},
"autoload": {
"psr-4": {
"App\\": "src/"
"Tvdt\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
"Tvdt\\Tests\\": "tests/"
}
},
"replace": {
"symfony/polyfill-ctype": "*",
"symfony/polyfill-iconv": "*",
"symfony/polyfill-mbstring": "*",
"symfony/polyfill-php72": "*",
"symfony/polyfill-php73": "*",
"symfony/polyfill-php74": "*",
"symfony/polyfill-php80": "*",
"symfony/polyfill-php81": "*",
"symfony/polyfill-php82": "*"
"symfony/polyfill-php82": "*",
"symfony/polyfill-php83": "*",
"symfony/polyfill-php84": "*",
"symfony/polyfill-php85": "*"
},
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd"
"assets:install %PUBLIC_DIR%": "symfony-cmd",
"importmap:install": "symfony-cmd"
},
"post-install-cmd": [
"@auto-scripts"
@@ -91,7 +121,7 @@
"extra": {
"symfony": {
"allow-contrib": false,
"require": "7.2.*",
"require": "8.0.*",
"docker": true
}
}

7802
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +1,39 @@
<?php
declare(strict_types=1);
use DAMA\DoctrineTestBundle\DAMADoctrineTestBundle;
use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
use Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle;
use Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle;
use Sentry\SentryBundle\SentryBundle;
use Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\MakerBundle\MakerBundle;
use Symfony\Bundle\SecurityBundle\SecurityBundle;
use Symfony\Bundle\TwigBundle\TwigBundle;
use Symfony\Bundle\WebProfilerBundle\WebProfilerBundle;
use Symfony\UX\StimulusBundle\StimulusBundle;
use Symfony\UX\Turbo\TurboBundle;
use SymfonyCasts\Bundle\VerifyEmail\SymfonyCastsVerifyEmailBundle;
use Symfonycasts\SassBundle\SymfonycastsSassBundle;
use Twig\Extra\TwigExtraBundle\TwigExtraBundle;
return [
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true],
EasyCorp\Bundle\EasyAdminBundle\EasyAdminBundle::class => ['all' => true],
Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
FrameworkBundle::class => ['all' => true],
DoctrineBundle::class => ['all' => true],
DoctrineMigrationsBundle::class => ['all' => true],
MakerBundle::class => ['dev' => true],
TwigBundle::class => ['all' => true],
SecurityBundle::class => ['all' => true],
WebProfilerBundle::class => ['dev' => true, 'test' => true],
TwigExtraBundle::class => ['all' => true],
DoctrineFixturesBundle::class => ['dev' => true, 'test' => true],
SymfonyCastsVerifyEmailBundle::class => ['all' => true],
SentryBundle::class => ['prod' => true],
SymfonycastsSassBundle::class => ['all' => true],
StimulusBundle::class => ['all' => true],
TurboBundle::class => ['all' => true],
DAMADoctrineTestBundle::class => ['test' => true],
StofDoctrineExtensionsBundle::class => ['all' => true],
];

View File

@@ -0,0 +1,15 @@
framework:
asset_mapper:
# The paths to make available to the asset mapper.
paths:
- assets/
excluded_patterns:
- '*/assets/styles/_*.scss'
- '*/assets/styles/**/_*.scss'
missing_import_mode: strict
when@prod:
framework:
asset_mapper:
missing_import_mode: warn

View File

@@ -1,11 +0,0 @@
# Enable stateless CSRF protection for forms and logins/logouts
framework:
form:
csrf_protection:
token_id: submit
csrf_protection:
stateless_token_ids:
- submit
- authenticate
- logout

View File

@@ -0,0 +1,5 @@
when@test:
dama_doctrine_test:
enable_static_connection: true
enable_static_meta_data_cache: true
enable_static_query_cache: true

View File

@@ -2,28 +2,33 @@ doctrine:
dbal:
url: '%env(resolve:DATABASE_URL)%'
# IMPORTANT: You MUST configure your server version,
# either here or in the DATABASE_URL env var (see .env file)
#server_version: '16'
profiling_collect_backtrace: '%kernel.debug%'
use_savepoints: true
types:
# JSON types
jsonb: MartinGeorgiev\Doctrine\DBAL\Types\Jsonb
'jsonb[]': MartinGeorgiev\Doctrine\DBAL\Types\JsonbArray
tsrange: MartinGeorgiev\Doctrine\DBAL\Types\TsRange
mapping_types:
# JSON type mappings
jsonb: jsonb
'jsonb[]': 'jsonb[]'
_jsonb: 'jsonb[]'
tsrange: tsrange
orm:
auto_generate_proxy_classes: true
enable_lazy_ghost_objects: true
report_fields_where_declared: true
validate_xml_mapping: true
naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware
identity_generation_preferences:
Doctrine\DBAL\Platforms\PostgreSQLPlatform: identity
auto_mapping: true
mappings:
App:
Tvdt:
type: attribute
is_bundle: false
dir: '%kernel.project_dir%/src/Entity'
prefix: 'App\Entity'
alias: App
prefix: 'Tvdt\Entity'
alias: Tvdt
when@test:
doctrine:
@@ -34,8 +39,6 @@ when@test:
when@prod:
doctrine:
orm:
auto_generate_proxy_classes: false
proxy_dir: '%kernel.build_dir%/doctrine/orm/Proxies'
query_cache_driver:
type: pool
pool: doctrine.system_cache_pool

View File

@@ -1,6 +1,6 @@
doctrine_migrations:
migrations_paths:
# namespace is arbitrary but should be different from App\Migrations
# namespace is arbitrary but should be different from Tvdt\Migrations
# as migrations classes should NOT be autoloaded
'DoctrineMigrations': '%kernel.project_dir%/migrations'
enable_profiler: false

View File

@@ -4,9 +4,17 @@ framework:
# Note that the session will be started ONLY if you read or write from it.
session: true
form:
csrf_protection:
enabled: true
#esi: true
#fragments: true
when@prod:
framework:
# shortcut for private IP address ranges of your proxy
trusted_proxies: 'private_ranges'
# or, if your proxy instead uses the "Forwarded" header
trusted_headers: [ 'forwarded' ]
when@test:
framework:

View File

@@ -0,0 +1,7 @@
framework:
mailer:
dsn: '%env(MAILER_DSN)%'
envelope:
sender: '%env(MAILER_SENDER)%'
headers:
From: 'Tijd voor de test <%env(MAILER_SENDER)%>'

View File

@@ -0,0 +1,3 @@
framework:
property_info:
with_constructor_extractor: true

View File

@@ -2,7 +2,7 @@ framework:
router:
# Configure how to generate URLs in non-HTTP contexts, such as CLI commands.
# See https://symfony.com/doc/current/routing.html#generating-urls-in-commands
#default_uri: http://localhost
default_uri: '%env(DEFAULT_URI)%'
when@prod:
framework:

View File

@@ -2,29 +2,32 @@ security:
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
password_hashers:
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
providers:
# used to reload user from session & other features (e.g. switch_user)
app_user_provider:
tvdt_user_provider:
entity:
class: App\Entity\User
class: Tvdt\Entity\User
property: email
# used to reload user from session & other features (e.g. switch_user)
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
# Ensure dev tools and static assets are always allowed
pattern: ^/(_profiler|_wdt|assets|build)/
security: false
main:
lazy: true
provider: app_user_provider
provider: tvdt_user_provider
form_login:
login_path: app_login
check_path: app_login
login_path: tvdt_login_login
check_path: tvdt_login_login
enable_csrf: true
default_target_path: tvdt_backoffice_index
logout:
path: app_logout
path: tvdt_login_logout
# where to redirect after logout
# target: app_any_route
# target: tvdt_any_route
# activate different ways to authenticate
# https://symfony.com/doc/current/security.html#the-firewall
@@ -32,19 +35,15 @@ security:
# https://symfony.com/doc/current/security/impersonating_user.html
# switch_user: true
# Easy way to control access for large sections of your site
# Note: Only the *first* access control that matches will be used
access_control:
# - { path: ^/admin, roles: ROLE_ADMIN }
# - { path: ^/profile, roles: ROLE_USER }
- { path: ^/admin, roles: ROLE_ADMIN }
- { path: ^/backoffice, roles: ROLE_USER }
when@test:
security:
password_hashers:
# By default, password hashers are resource intensive and take time. This is
# important to generate secure password hashes. In tests however, secure hashes
# are not important, waste resources and increase test times. The following
# reduces the work factor to the lowest possible values.
# Password hashers are resource-intensive by design to ensure security.
# In tests, it's safe to reduce their cost to improve performance.
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
algorithm: auto
cost: 4 # Lowest possible value for bcrypt

View File

@@ -0,0 +1,39 @@
when@prod:
sentry:
dsn: '%env(SENTRY_DSN)%'
options:
# Add request headers, cookies, IP address and the authenticated user
# see https://docs.sentry.io/platforms/php/data-management/data-collected/ for more info
# send_default_pii: true
ignore_exceptions:
- 'Symfony\Component\ErrorHandler\Error\FatalError'
- 'Symfony\Component\Debug\Exception\FatalErrorException'
#
# # If you are using Monolog, you also need this additional configuration to log the errors correctly:
# # https://docs.sentry.io/platforms/php/guides/symfony/integrations/monolog/
# register_error_listener: false
# register_error_handler: false
#
# monolog:
# handlers:
# # Use this only if you don't want to use structured logging and instead receive
# # certain log levels as errors.
# sentry:
# type: service
# id: Sentry\Monolog\Handler
#
# # Use this for structured log integration
# sentry_logs:
# type: service
# id: Sentry\SentryBundle\Monolog\LogsHandler
#
# # Enable one of the two services below, depending on your choice above
# services:
# Sentry\Monolog\Handler:
# arguments:
# $hub: '@Sentry\State\HubInterface'
# $level: !php/const Monolog\Logger::ERROR
# $fillExtraContext: true # Enables sending monolog context to Sentry
# Sentry\SentryBundle\Monolog\LogsHandler:
# arguments:
# - !php/const Monolog\Logger::INFO

View File

@@ -0,0 +1,7 @@
# Read the documentation: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html
# See the official DoctrineExtensions documentation for more details: https://github.com/doctrine-extensions/DoctrineExtensions/tree/main/doc
stof_doctrine_extensions:
default_locale: nl
orm:
default:
timestampable: true

View File

@@ -1,5 +0,0 @@
twig_component:
anonymous_template_directory: 'components/'
defaults:
# Namespace & directory for components
App\Twig\Components\: 'components/'

View File

@@ -1,4 +0,0 @@
framework:
uid:
default_uuid_version: 7
time_based_uuid_version: 7

View File

@@ -3,7 +3,7 @@ framework:
# Enables validator auto-mapping support.
# For instance, basic validation constraints will be inferred from Doctrine's metadata.
#auto_mapping:
# App\Entity\: []
# Tvdt\Entity\: []
when@test:
framework:

View File

@@ -2,6 +2,6 @@
declare(strict_types=1);
if (file_exists(dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php')) {
require dirname(__DIR__).'/var/cache/prod/App_KernelProdContainer.preload.php';
if (file_exists(dirname(__DIR__).'/var/cache/prod/Tvdt_KernelProdContainer.preload.php')) {
require dirname(__DIR__).'/var/cache/prod/Tvdt_KernelProdContainer.preload.php';
}

1632
config/reference.php generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,11 @@
# yaml-language-server: $schema=../vendor/symfony/routing/Loader/schema/routing.schema.json
# This file is the entry point to configure the routes of your app.
# Methods with the #[Route] attribute are automatically imported.
# See also https://symfony.com/doc/current/routing.html
# To list all registered routes, run the following command:
# bin/console debug:router
controllers:
resource:
path: ../src/Controller/
namespace: App\Controller
type: attribute
resource: routing.controllers

View File

@@ -1,9 +1,9 @@
controllers:
resource:
path: ../../src/Controller/
namespace: App\Controller
namespace: Tvdt\Controller
type: attribute
kernel:
resource: App\Kernel
resource: Tvdt\Kernel
type: attribute

View File

@@ -1,3 +0,0 @@
easyadmin:
resource: .
type: easyadmin.routes

View File

@@ -1,4 +1,4 @@
when@dev:
_errors:
resource: '@FrameworkBundle/Resources/config/routing/errors.xml'
resource: '@FrameworkBundle/Resources/config/routing/errors.php'
prefix: /_error

View File

@@ -1,8 +1,8 @@
when@dev:
web_profiler_wdt:
resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
resource: '@WebProfilerBundle/Resources/config/routing/wdt.php'
prefix: /_wdt
web_profiler_profiler:
resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
resource: '@WebProfilerBundle/Resources/config/routing/profiler.php'
prefix: /_profiler

View File

@@ -1,5 +1,8 @@
# yaml-language-server: $schema=../vendor/symfony/dependency-injection/Loader/schema/services.schema.json
# This file is the entry point to configure your own services.
# Files in the packages/ subdirectory configure your dependencies.
# See also https://symfony.com/doc/current/service_container/import.html
# Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
@@ -13,7 +16,7 @@ services:
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
Tvdt\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'

View File

@@ -0,0 +1,84 @@
# This file is part of the Symfony package.
#
# (c) Fabien Potencier <fabien@symfony.com>
#
# For the full copyright and license information, please view
# https://symfony.com/doc/current/contributing/code/license.html
_sf_composer() {
# Use newline as only separator to allow space in completion values
local IFS=$'\n'
local sf_cmd="${COMP_WORDS[0]}"
# for an alias, get the real script behind it
sf_cmd_type=$(type -t $sf_cmd)
if [[ $sf_cmd_type == "alias" ]]; then
sf_cmd=$(alias $sf_cmd | sed -E "s/alias $sf_cmd='(.*)'/\1/")
elif [[ $sf_cmd_type == "file" ]]; then
sf_cmd=$(type -p $sf_cmd)
fi
if [[ $sf_cmd_type != "function" && ! -x $sf_cmd ]]; then
return 1
fi
local cur prev words cword
_get_comp_words_by_ref -n := cur prev words cword
local completecmd=("$sf_cmd" "_complete" "--no-interaction" "-sbash" "-c$cword" "-S2.8.11")
for w in ${words[@]}; do
w=$(printf -- '%b' "$w")
# remove quotes from typed values
quote="${w:0:1}"
if [ "$quote" == \' ]; then
w="${w%\'}"
w="${w#\'}"
elif [ "$quote" == \" ]; then
w="${w%\"}"
w="${w#\"}"
fi
# empty values are ignored
if [ ! -z "$w" ]; then
completecmd+=("-i$w")
fi
done
local sfcomplete
if sfcomplete=$(${completecmd[@]} 2>&1); then
local quote suggestions
quote=${cur:0:1}
# Use single quotes by default if suggestions contains backslash (FQCN)
if [ "$quote" == '' ] && [[ "$sfcomplete" =~ \\ ]]; then
quote=\'
fi
if [ "$quote" == \' ]; then
# single quotes: no additional escaping (does not accept ' in values)
suggestions=$(for s in $sfcomplete; do printf $'%q%q%q\n' "$quote" "$s" "$quote"; done)
elif [ "$quote" == \" ]; then
# double quotes: double escaping for \ $ ` "
suggestions=$(for s in $sfcomplete; do
s=${s//\\/\\\\}
s=${s//\$/\\\$}
s=${s//\`/\\\`}
s=${s//\"/\\\"}
printf $'%q%q%q\n' "$quote" "$s" "$quote";
done)
else
# no quotes: double escaping
suggestions=$(for s in $sfcomplete; do printf $'%q\n' $(printf '%q' "$s"); done)
fi
COMPREPLY=($(IFS=$'\n' compgen -W "$suggestions" -- $(printf -- "%q" "$cur")))
__ltrim_colon_completions "$cur"
else
if [[ "$sfcomplete" != *"Command \"_complete\" is not defined."* ]]; then
>&2 echo
>&2 echo $sfcomplete
fi
return 1
fi
}
complete -F _sf_composer composer

View File

@@ -11,3 +11,6 @@ opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 20000
opcache.memory_consumption = 256
opcache.enable_file_override = 1
; for Sentry
zend.exception_ignore_args = Off

View File

@@ -0,0 +1,94 @@
# This file is part of the Symfony package.
#
# (c) Fabien Potencier <fabien@symfony.com>
#
# For the full copyright and license information, please view
# https://symfony.com/doc/current/contributing/code/license.html
_sf_console() {
# Use the default completion for shell redirect operators.
for w in '>' '>>' '&>' '<'; do
if [[ $w = "${COMP_WORDS[COMP_CWORD-1]}" ]]; then
compopt -o filenames
COMPREPLY=($(compgen -f -- "${COMP_WORDS[COMP_CWORD]}"))
return 0
fi
done
# Use newline as only separator to allow space in completion values
local IFS=$'\n'
local sf_cmd="${COMP_WORDS[0]}"
# for an alias, get the real script behind it
sf_cmd_type=$(type -t $sf_cmd)
if [[ $sf_cmd_type == "alias" ]]; then
sf_cmd=$(alias $sf_cmd | sed -E "s/alias $sf_cmd='(.*)'/\1/")
elif [[ $sf_cmd_type == "file" ]]; then
sf_cmd=$(type -p $sf_cmd)
fi
if [[ $sf_cmd_type != "function" && ! -x $sf_cmd ]]; then
return 1
fi
local cur prev words cword
_get_comp_words_by_ref -n := cur prev words cword
local completecmd=("$sf_cmd" "_complete" "--no-interaction" "-sbash" "-c$cword" "-a1")
for w in ${words[@]}; do
w="${w//\\\\/\\}"
# remove quotes from typed values
quote="${w:0:1}"
if [ "$quote" == \' ]; then
w="${w%\'}"
w="${w#\'}"
elif [ "$quote" == \" ]; then
w="${w%\"}"
w="${w#\"}"
fi
# empty values are ignored
if [ ! -z "$w" ]; then
completecmd+=("-i$w")
fi
done
local sfcomplete
if sfcomplete=$(${completecmd[@]} 2>&1); then
local quote suggestions
quote=${cur:0:1}
# Use single quotes by default if suggestions contains backslash (FQCN)
if [ "$quote" == '' ] && [[ "$sfcomplete" =~ \\ ]]; then
quote=\'
fi
if [ "$quote" == \' ]; then
# single quotes: no additional escaping (does not accept ' in values)
suggestions=$(for s in $sfcomplete; do printf $'%q%q%q\n' "$quote" "$s" "$quote"; done)
elif [ "$quote" == \" ]; then
# double quotes: double escaping for \ $ ` "
suggestions=$(for s in $sfcomplete; do
s=${s//\\/\\\\}
s=${s//\$/\\\$}
s=${s//\`/\\\`}
s=${s//\"/\\\"}
printf $'%q%q%q\n' "$quote" "$s" "$quote";
done)
else
# no quotes: double escaping
suggestions=$(for s in $sfcomplete; do printf $'%q\n' $(printf '%q' "$s"); done)
fi
COMPREPLY=($(IFS=$'\n' compgen -W "$suggestions" -- $(printf -- "%q" "$cur")))
__ltrim_colon_completions "$cur"
else
if [[ "$sfcomplete" != *"Command \"_complete\" is not defined."* ]]; then
>&2 echo
>&2 echo $sfcomplete
fi
return 1
fi
}
complete -F _sf_console console

View File

@@ -1,4 +0,0 @@
worker {
file ./public/index.php
env APP_RUNTIME Runtime\FrankenPhpSymfony\Runtime
}

44
importmap.php Normal file
View File

@@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* Returns the importmap for this application.
*
* - "path" is a path inside the asset mapper system. Use the
* "debug:asset-map" command to see the full list of paths.
*
* - "entrypoint" (JavaScript only) set to true for any module that will
* be used as an "entrypoint" (and passed to the importmap() Twig function).
*
* The "importmap:require" command can be used to add new entries to this file.
*/
return [
'quiz' => [
'path' => './assets/quiz.js',
'entrypoint' => true,
],
'backoffice' => [
'path' => './assets/backoffice.js',
'entrypoint' => true,
],
'bootstrap' => [
'version' => '5.3.6',
],
'@popperjs/core' => [
'version' => '2.11.8',
],
'bootstrap/dist/css/bootstrap.min.css' => [
'version' => '5.3.6',
'type' => 'css',
],
'@hotwired/stimulus' => [
'version' => '3.2.2',
],
'@symfony/stimulus-bundle' => [
'path' => './vendor/symfony/stimulus-bundle/assets/dist/loader.js',
],
'@hotwired/turbo' => [
'version' => '7.3.0',
],
];

View File

@@ -7,9 +7,6 @@ namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20241229195702 extends AbstractMigration
{
public function getDescription(): string
@@ -19,7 +16,6 @@ final class Version20241229195702 extends AbstractMigration
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE answer (id UUID NOT NULL, question_id UUID NOT NULL, text VARCHAR(255) NOT NULL, is_right_answer BOOLEAN NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_DADD4A251E27F6BF ON answer (question_id)');
$this->addSql('COMMENT ON COLUMN answer.id IS \'(DC2Type:uuid)\'');
@@ -67,7 +63,6 @@ final class Version20241229195702 extends AbstractMigration
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('ALTER TABLE answer DROP CONSTRAINT FK_DADD4A251E27F6BF');
$this->addSql('ALTER TABLE answer_candidate DROP CONSTRAINT FK_F54D5192AA334807');

View File

@@ -7,9 +7,6 @@ namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20241229201314 extends AbstractMigration
{
public function getDescription(): string
@@ -19,7 +16,6 @@ final class Version20241229201314 extends AbstractMigration
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE season_user (season_id UUID NOT NULL, user_id UUID NOT NULL, PRIMARY KEY(season_id, user_id))');
$this->addSql('CREATE INDEX IDX_BDA4AD74EC001D1 ON season_user (season_id)');
$this->addSql('CREATE INDEX IDX_BDA4AD7A76ED395 ON season_user (user_id)');
@@ -31,7 +27,6 @@ final class Version20241229201314 extends AbstractMigration
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('ALTER TABLE season_user DROP CONSTRAINT FK_BDA4AD74EC001D1');
$this->addSql('ALTER TABLE season_user DROP CONSTRAINT FK_BDA4AD7A76ED395');

View File

@@ -7,9 +7,6 @@ namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20241229202103 extends AbstractMigration
{
public function getDescription(): string
@@ -19,7 +16,6 @@ final class Version20241229202103 extends AbstractMigration
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE correction (id UUID NOT NULL, candidate_id UUID NOT NULL, quiz_id UUID NOT NULL, amount DOUBLE PRECISION NOT NULL, PRIMARY KEY(id))');
$this->addSql('CREATE INDEX IDX_A29DA1B891BD8781 ON correction (candidate_id)');
$this->addSql('CREATE INDEX IDX_A29DA1B8853CD175 ON correction (quiz_id)');
@@ -32,7 +28,6 @@ final class Version20241229202103 extends AbstractMigration
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('ALTER TABLE correction DROP CONSTRAINT FK_A29DA1B891BD8781');
$this->addSql('ALTER TABLE correction DROP CONSTRAINT FK_A29DA1B8853CD175');

View File

@@ -7,9 +7,6 @@ namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20241229202155 extends AbstractMigration
{
public function getDescription(): string
@@ -19,13 +16,11 @@ final class Version20241229202155 extends AbstractMigration
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE UNIQUE INDEX UNIQ_A29DA1B891BD8781853CD175 ON correction (candidate_id, quiz_id)');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('DROP INDEX UNIQ_A29DA1B891BD8781853CD175');
}

View File

@@ -7,9 +7,6 @@ namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20241229204335 extends AbstractMigration
{
public function getDescription(): string
@@ -19,14 +16,12 @@ final class Version20241229204335 extends AbstractMigration
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE given_answer ALTER answer_id DROP NOT NULL');
$this->addSql('ALTER TABLE given_answer ALTER created DROP NOT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('ALTER TABLE given_answer ALTER answer_id SET NOT NULL');
$this->addSql('ALTER TABLE given_answer ALTER created SET NOT NULL');

View File

@@ -7,9 +7,6 @@ namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250303221227 extends AbstractMigration
{
public function getDescription(): string
@@ -19,7 +16,6 @@ final class Version20250303221227 extends AbstractMigration
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE given_answer ALTER created SET NOT NULL');
$this->addSql('ALTER TABLE season ADD active_quiz_id UUID DEFAULT NULL');
$this->addSql('COMMENT ON COLUMN season.active_quiz_id IS \'(DC2Type:uuid)\'');
@@ -29,7 +25,6 @@ final class Version20250303221227 extends AbstractMigration
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE SCHEMA public');
$this->addSql('ALTER TABLE season DROP CONSTRAINT FK_F0E45BA96706D6B');
$this->addSql('DROP INDEX IDX_F0E45BA96706D6B');

View File

@@ -0,0 +1,114 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20250311213417 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE answer ALTER id TYPE UUID');
$this->addSql('ALTER TABLE answer ALTER question_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN answer.id IS \'\'');
$this->addSql('COMMENT ON COLUMN answer.question_id IS \'\'');
$this->addSql('ALTER TABLE answer_candidate ALTER answer_id TYPE UUID');
$this->addSql('ALTER TABLE answer_candidate ALTER candidate_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN answer_candidate.answer_id IS \'\'');
$this->addSql('COMMENT ON COLUMN answer_candidate.candidate_id IS \'\'');
$this->addSql('ALTER TABLE candidate ALTER id TYPE UUID');
$this->addSql('ALTER TABLE candidate ALTER season_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN candidate.id IS \'\'');
$this->addSql('COMMENT ON COLUMN candidate.season_id IS \'\'');
$this->addSql('ALTER TABLE correction ALTER id TYPE UUID');
$this->addSql('ALTER TABLE correction ALTER candidate_id TYPE UUID');
$this->addSql('ALTER TABLE correction ALTER quiz_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN correction.id IS \'\'');
$this->addSql('COMMENT ON COLUMN correction.candidate_id IS \'\'');
$this->addSql('COMMENT ON COLUMN correction.quiz_id IS \'\'');
$this->addSql('ALTER TABLE given_answer ALTER id TYPE UUID');
$this->addSql('ALTER TABLE given_answer ALTER candidate_id TYPE UUID');
$this->addSql('ALTER TABLE given_answer ALTER quiz_id TYPE UUID');
$this->addSql('ALTER TABLE given_answer ALTER answer_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN given_answer.id IS \'\'');
$this->addSql('COMMENT ON COLUMN given_answer.candidate_id IS \'\'');
$this->addSql('COMMENT ON COLUMN given_answer.quiz_id IS \'\'');
$this->addSql('COMMENT ON COLUMN given_answer.answer_id IS \'\'');
$this->addSql('ALTER TABLE question ALTER id TYPE UUID');
$this->addSql('ALTER TABLE question ALTER quiz_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN question.id IS \'\'');
$this->addSql('COMMENT ON COLUMN question.quiz_id IS \'\'');
$this->addSql('ALTER TABLE quiz ADD dropouts INT DEFAULT NULL');
$this->addSql('ALTER TABLE quiz ALTER id TYPE UUID');
$this->addSql('ALTER TABLE quiz ALTER season_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN quiz.id IS \'\'');
$this->addSql('COMMENT ON COLUMN quiz.season_id IS \'\'');
$this->addSql('ALTER TABLE season ALTER id TYPE UUID');
$this->addSql('ALTER TABLE season ALTER active_quiz_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN season.id IS \'\'');
$this->addSql('COMMENT ON COLUMN season.active_quiz_id IS \'\'');
$this->addSql('ALTER TABLE season_user ALTER season_id TYPE UUID');
$this->addSql('ALTER TABLE season_user ALTER user_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN season_user.season_id IS \'\'');
$this->addSql('COMMENT ON COLUMN season_user.user_id IS \'\'');
$this->addSql('ALTER TABLE "user" ALTER id TYPE UUID');
$this->addSql('COMMENT ON COLUMN "user".id IS \'\'');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE candidate ALTER id TYPE UUID');
$this->addSql('ALTER TABLE candidate ALTER season_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN candidate.id IS \'(DC2Type:uuid)\'');
$this->addSql('COMMENT ON COLUMN candidate.season_id IS \'(DC2Type:uuid)\'');
$this->addSql('ALTER TABLE correction ALTER id TYPE UUID');
$this->addSql('ALTER TABLE correction ALTER candidate_id TYPE UUID');
$this->addSql('ALTER TABLE correction ALTER quiz_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN correction.id IS \'(DC2Type:uuid)\'');
$this->addSql('COMMENT ON COLUMN correction.candidate_id IS \'(DC2Type:uuid)\'');
$this->addSql('COMMENT ON COLUMN correction.quiz_id IS \'(DC2Type:uuid)\'');
$this->addSql('ALTER TABLE given_answer ALTER id TYPE UUID');
$this->addSql('ALTER TABLE given_answer ALTER candidate_id TYPE UUID');
$this->addSql('ALTER TABLE given_answer ALTER quiz_id TYPE UUID');
$this->addSql('ALTER TABLE given_answer ALTER answer_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN given_answer.id IS \'(DC2Type:uuid)\'');
$this->addSql('COMMENT ON COLUMN given_answer.candidate_id IS \'(DC2Type:uuid)\'');
$this->addSql('COMMENT ON COLUMN given_answer.quiz_id IS \'(DC2Type:uuid)\'');
$this->addSql('COMMENT ON COLUMN given_answer.answer_id IS \'(DC2Type:uuid)\'');
$this->addSql('ALTER TABLE answer_candidate ALTER answer_id TYPE UUID');
$this->addSql('ALTER TABLE answer_candidate ALTER candidate_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN answer_candidate.answer_id IS \'(DC2Type:uuid)\'');
$this->addSql('COMMENT ON COLUMN answer_candidate.candidate_id IS \'(DC2Type:uuid)\'');
$this->addSql('ALTER TABLE quiz DROP dropouts');
$this->addSql('ALTER TABLE quiz ALTER id TYPE UUID');
$this->addSql('ALTER TABLE quiz ALTER season_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN quiz.id IS \'(DC2Type:uuid)\'');
$this->addSql('COMMENT ON COLUMN quiz.season_id IS \'(DC2Type:uuid)\'');
$this->addSql('ALTER TABLE season ALTER id TYPE UUID');
$this->addSql('ALTER TABLE season ALTER active_quiz_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN season.id IS \'(DC2Type:uuid)\'');
$this->addSql('COMMENT ON COLUMN season.active_quiz_id IS \'(DC2Type:uuid)\'');
$this->addSql('ALTER TABLE answer ALTER id TYPE UUID');
$this->addSql('ALTER TABLE answer ALTER question_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN answer.id IS \'(DC2Type:uuid)\'');
$this->addSql('COMMENT ON COLUMN answer.question_id IS \'(DC2Type:uuid)\'');
$this->addSql('ALTER TABLE season_user ALTER season_id TYPE UUID');
$this->addSql('ALTER TABLE season_user ALTER user_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN season_user.season_id IS \'(DC2Type:uuid)\'');
$this->addSql('COMMENT ON COLUMN season_user.user_id IS \'(DC2Type:uuid)\'');
$this->addSql('ALTER TABLE question ALTER id TYPE UUID');
$this->addSql('ALTER TABLE question ALTER quiz_id TYPE UUID');
$this->addSql('COMMENT ON COLUMN question.id IS \'(DC2Type:uuid)\'');
$this->addSql('COMMENT ON COLUMN question.quiz_id IS \'(DC2Type:uuid)\'');
$this->addSql('ALTER TABLE "user" ALTER id TYPE UUID');
$this->addSql('COMMENT ON COLUMN "user".id IS \'(DC2Type:uuid)\'');
}
}

View File

@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20250402185128 extends AbstractMigration
{
public function getDescription(): string
{
return 'add elimination table';
}
public function up(Schema $schema): void
{
$this->addSql('CREATE TABLE elimination (id UUID NOT NULL, data JSON NOT NULL, PRIMARY KEY(id))');
}
public function down(Schema $schema): void
{
$this->addSql('DROP TABLE elimination');
}
}

View File

@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20250420111904 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add is_verified column to user table';
}
public function up(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE "user" ADD is_verified BOOLEAN NOT NULL
SQL);
}
public function down(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE "user" DROP is_verified
SQL);
}
}

View File

@@ -0,0 +1,30 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20250420125040 extends AbstractMigration
{
public function getDescription(): string
{
return 'Drop preregister_candidates column from season table';
}
public function up(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE season DROP preregister_candidates
SQL);
}
public function down(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE season ADD preregister_candidates BOOLEAN NOT NULL DEFAULT true
SQL);
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20250427174822 extends AbstractMigration
{
public function getDescription(): string
{
return 'Add ordering to question and answer';
}
public function up(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE answer ADD ordering SMALLINT DEFAULT 0 NOT NULL
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE question ADD ordering SMALLINT DEFAULT 0 NOT NULL
SQL);
}
public function down(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE answer DROP ordering
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE question DROP ordering
SQL);
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20250504101440 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$this->addSql(<<<'SQL'
CREATE UNIQUE INDEX UNIQ_C8B28E445E237E064EC001D1 ON candidate (name, season_id)
SQL);
$this->addSql(<<<'SQL'
CREATE UNIQUE INDEX UNIQ_A412FA925E237E064EC001D1 ON quiz (name, season_id)
SQL);
}
public function down(Schema $schema): void
{
$this->addSql(<<<'SQL'
DROP INDEX UNIQ_A412FA925E237E064EC001D1
SQL);
$this->addSql(<<<'SQL'
DROP INDEX UNIQ_C8B28E445E237E064EC001D1
SQL);
}
}

View File

@@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20250521192752 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE elimination ADD quiz_id UUID NOT NULL
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elimination ADD CONSTRAINT FK_5947284F853CD175 FOREIGN KEY (quiz_id) REFERENCES quiz (id) NOT DEFERRABLE INITIALLY IMMEDIATE
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX IDX_5947284F853CD175 ON elimination (quiz_id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE quiz ALTER dropouts SET DEFAULT 1
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE quiz ALTER dropouts SET NOT NULL
SQL);
}
public function down(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE quiz ALTER dropouts DROP DEFAULT
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE quiz ALTER dropouts DROP NOT NULL
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elimination DROP CONSTRAINT FK_5947284F853CD175
SQL);
$this->addSql(<<<'SQL'
DROP INDEX IDX_5947284F853CD175
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elimination DROP quiz_id
SQL);
}
}

View File

@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20250521194035 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE elimination ADD created TIMESTAMP(0) WITHOUT TIME ZONE
SQL);
$this->addSql(<<<'SQL'
UPDATE elimination SET created = NOW()
SQL
);
$this->addSql(<<<'SQL'
ALTER TABLE elimination ALTER created SET NOT NULL
SQL
);
}
public function down(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE elimination DROP created
SQL);
}
}

View File

@@ -0,0 +1,90 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20250606192337 extends AbstractMigration
{
public function getDescription(): string
{
return 'Ze Big migration';
}
public function up(Schema $schema): void
{
$this->addSql(<<<'SQL'
CREATE TABLE quiz_candidate (id UUID NOT NULL, corrections DOUBLE PRECISION NOT NULL, created TIMESTAMP(0) WITH TIME ZONE NOT NULL, quiz_id UUID NOT NULL, candidate_id UUID NOT NULL, PRIMARY KEY(id))
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX IDX_CED2FFA2853CD175 ON quiz_candidate (quiz_id)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX IDX_CED2FFA291BD8781 ON quiz_candidate (candidate_id)
SQL);
$this->addSql(<<<'SQL'
CREATE UNIQUE INDEX UNIQ_CED2FFA291BD8781853CD175 ON quiz_candidate (candidate_id, quiz_id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE quiz_candidate ADD CONSTRAINT FK_CED2FFA2853CD175 FOREIGN KEY (quiz_id) REFERENCES quiz (id) NOT DEFERRABLE INITIALLY IMMEDIATE
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE quiz_candidate ADD CONSTRAINT FK_CED2FFA291BD8781 FOREIGN KEY (candidate_id) REFERENCES candidate (id) NOT DEFERRABLE INITIALLY IMMEDIATE
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE correction DROP CONSTRAINT fk_a29da1b891bd8781
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE correction DROP CONSTRAINT fk_a29da1b8853cd175
SQL);
$this->addSql(<<<'SQL'
DROP TABLE correction
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elimination ALTER created TYPE TIMESTAMP(0) WITH TIME ZONE
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE given_answer ALTER created TYPE TIMESTAMP(0) WITH TIME ZONE
SQL);
}
public function down(Schema $schema): void
{
$this->addSql(<<<'SQL'
CREATE TABLE correction (id UUID NOT NULL, candidate_id UUID NOT NULL, quiz_id UUID NOT NULL, amount DOUBLE PRECISION NOT NULL, PRIMARY KEY(id))
SQL);
$this->addSql(<<<'SQL'
CREATE UNIQUE INDEX uniq_a29da1b891bd8781853cd175 ON correction (candidate_id, quiz_id)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX idx_a29da1b8853cd175 ON correction (quiz_id)
SQL);
$this->addSql(<<<'SQL'
CREATE INDEX idx_a29da1b891bd8781 ON correction (candidate_id)
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE correction ADD CONSTRAINT fk_a29da1b891bd8781 FOREIGN KEY (candidate_id) REFERENCES candidate (id) NOT DEFERRABLE INITIALLY IMMEDIATE
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE correction ADD CONSTRAINT fk_a29da1b8853cd175 FOREIGN KEY (quiz_id) REFERENCES quiz (id) NOT DEFERRABLE INITIALLY IMMEDIATE
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE quiz_candidate DROP CONSTRAINT FK_CED2FFA2853CD175
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE quiz_candidate DROP CONSTRAINT FK_CED2FFA291BD8781
SQL);
$this->addSql(<<<'SQL'
DROP TABLE quiz_candidate
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE given_answer ALTER created TYPE TIMESTAMP(0) WITHOUT TIME ZONE
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elimination ALTER created TYPE TIMESTAMP(0) WITHOUT TIME ZONE
SQL);
}
}

View File

@@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20250606195952 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$this->addSql(<<<'SQL'
delete from given_answer where answer_id is null
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE given_answer ALTER answer_id TYPE UUID
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE given_answer ALTER answer_id SET NOT NULL
SQL);
}
public function down(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE given_answer ALTER answer_id TYPE UUID
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE given_answer ALTER answer_id DROP NOT NULL
SQL);
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20250607154730 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE season DROP CONSTRAINT FK_F0E45BA96706D6B
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE season ADD CONSTRAINT FK_F0E45BA96706D6B FOREIGN KEY (active_quiz_id) REFERENCES quiz (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE
SQL);
}
public function down(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE season DROP CONSTRAINT fk_f0e45ba96706d6b
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE season ADD CONSTRAINT fk_f0e45ba96706d6b FOREIGN KEY (active_quiz_id) REFERENCES quiz (id) NOT DEFERRABLE INITIALLY IMMEDIATE
SQL);
}
}

View File

@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20250607184525 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE elimination DROP CONSTRAINT FK_5947284F853CD175
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elimination ADD CONSTRAINT FK_5947284F853CD175 FOREIGN KEY (quiz_id) REFERENCES quiz (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE given_answer DROP CONSTRAINT FK_9AC61A30853CD175
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE given_answer ADD CONSTRAINT FK_9AC61A30853CD175 FOREIGN KEY (quiz_id) REFERENCES quiz (id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE
SQL);
}
public function down(Schema $schema): void
{
$this->addSql(<<<'SQL'
ALTER TABLE given_answer DROP CONSTRAINT fk_9ac61a30853cd175
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE given_answer ADD CONSTRAINT fk_9ac61a30853cd175 FOREIGN KEY (quiz_id) REFERENCES quiz (id) NOT DEFERRABLE INITIALLY IMMEDIATE
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elimination DROP CONSTRAINT fk_5947284f853cd175
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE elimination ADD CONSTRAINT fk_5947284f853cd175 FOREIGN KEY (quiz_id) REFERENCES quiz (id) NOT DEFERRABLE INITIALLY IMMEDIATE
SQL);
}
}

View File

@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20250610210417 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
$this->addSql(<<<'SQL'
CREATE TABLE season_settings (id UUID NOT NULL, show_numbers BOOLEAN DEFAULT false NOT NULL, confirm_answers BOOLEAN DEFAULT false NOT NULL, PRIMARY KEY(id))
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE season ADD settings_id UUID DEFAULT NULL
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE season ADD CONSTRAINT FK_F0E45BA959949888 FOREIGN KEY (settings_id) REFERENCES season_settings (id) NOT DEFERRABLE INITIALLY IMMEDIATE
SQL);
$this->addSql(<<<'SQL'
CREATE UNIQUE INDEX UNIQ_F0E45BA959949888 ON season (settings_id)
SQL);
}
public function down(Schema $schema): void
{
$this->addSql(<<<'SQL'
DROP TABLE season_settings
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE season DROP CONSTRAINT FK_F0E45BA959949888
SQL);
$this->addSql(<<<'SQL'
DROP INDEX UNIQ_F0E45BA959949888
SQL);
$this->addSql(<<<'SQL'
ALTER TABLE season DROP settings_id
SQL);
}
}

View File

@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
final class Version20251007194241 extends AbstractMigration
{
public function getDescription(): string
{
return 'Change elimination data type to jsonb';
}
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE elimination ALTER data TYPE JSONB');
}
public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE elimination ALTER data TYPE JSON');
}
}

View File

@@ -1,4 +1,5 @@
parameters:
editorUrl: 'phpstorm://open?file=%%file%%&line=%%line%%'
level: 8
paths:
- bin/
@@ -6,3 +7,8 @@ parameters:
- public/
- src/
- tests/
treatPhpDocTypesAsCertain: false
symfony:
containerXmlPath: var/cache/dev/Tvdt_KernelDevDebugContainer.xml
doctrine:
objectManagerLoader: tests/object-manager.php

38
phpunit.dist.xml Normal file
View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://phpunit.readthedocs.io/en/latest/configuration.html -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
backupGlobals="false"
colors="true"
failOnNotice="true"
failOnWarning="true"
bootstrap="tests/bootstrap.php"
cacheDirectory=".phpunit.cache"
>
<php>
<ini name="display_errors" value="1" />
<ini name="error_reporting" value="-1" />
<server name="APP_ENV" value="test" force="true" />
<server name="SHELL_VERBOSITY" value="-1" />
</php>
<testsuites>
<testsuite name="Project Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<source ignoreSuppressionOfDeprecations="true" restrictNotices="true" restrictWarnings="true">
<include>
<directory>src</directory>
</include>
<exclude>
<directory>src/DataFixtures</directory>
</exclude>
</source>
<extensions>
<bootstrap class="DAMA\DoctrineTestBundle\PHPUnit\PHPUnitExtension" />
</extensions>
</phpunit>

View File

@@ -2,13 +2,13 @@
declare(strict_types=1);
use App\Kernel;
use Tvdt\Kernel;
require_once dirname(__DIR__).'/vendor/autoload_runtime.php';
return static function (array $context): Kernel {
$appEnv = !empty($context['APP_ENV']) ? (string) $context['APP_ENV'] : 'prod';
$appDebug = !empty($context['APP_DEBUG']) ? filter_var($context['APP_DEBUG'], \FILTER_VALIDATE_BOOL) : 'prod' !== $appEnv;
$appEnv = empty($context['APP_ENV']) ? 'prod' : (string) $context['APP_ENV'];
$appDebug = empty($context['APP_DEBUG']) ? 'prod' !== $appEnv : filter_var($context['APP_DEBUG'], \FILTER_VALIDATE_BOOL);
return new Kernel($appEnv, $appDebug);
};

View File

@@ -3,6 +3,8 @@
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\Symfony\Bridge\Symfony\Routing\SymfonyRoutesProvider;
use Rector\Symfony\Contract\Bridge\Symfony\Routing\SymfonyRoutesProviderInterface;
return RectorConfig::configure()
->withPaths([
@@ -11,6 +13,11 @@ return RectorConfig::configure()
__DIR__.'/src',
__DIR__.'/tests',
])
->withSkip([__DIR__.'/config/reference.php'])
->withSymfonyContainerXml(__DIR__.'/var/cache/dev/Tvdt_KernelDevDebugContainer.xml')
->withSymfonyContainerPhp(__DIR__.'/tests/symfony-container.php')
->registerService(SymfonyRoutesProvider::class, SymfonyRoutesProviderInterface::class)
->withParallel()
->withPhpSets()
->withPreparedSets(
deadCode: true,
@@ -20,12 +27,11 @@ return RectorConfig::configure()
privatization: true,
instanceOf: true,
earlyReturn: true,
strictBooleans: true,
rectorPreset: true,
phpunitCodeQuality: true,
doctrineCodeQuality: true,
symfonyCodeQuality: true,
)
->withComposerBased(twig: true, doctrine: true, phpunit: true)
->withAttributesSets()
->withAttributesSets(all: true)
->withComposerBased(twig: true, doctrine: true, phpunit: true, symfony: true)
;

View File

@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace Tvdt\Command;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\Argument;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Style\SymfonyStyle;
use Tvdt\Entity\Season;
use Tvdt\Repository\SeasonRepository;
use Tvdt\Repository\UserRepository;
#[AsCommand(
name: 'tvdt:claim-season',
description: 'Give a user owner rights on a season',
)]
final readonly class ClaimSeasonCommand
{
public function __construct(private UserRepository $userRepository, private SeasonRepository $seasonRepository, private EntityManagerInterface $entityManager) {}
public function __invoke(
#[Argument]
string $seasonCode,
#[Argument]
string $email,
SymfonyStyle $io,
): int {
try {
$season = $this->seasonRepository->findOneBySeasonCode($seasonCode);
if (!$season instanceof Season) {
throw new \InvalidArgumentException('Season not found');
}
$user = $this->userRepository->findOneBy(['email' => $email]);
if (null === $user) {
throw new \InvalidArgumentException('User not found');
}
$season->addOwner($user);
$this->entityManager->flush();
} catch (\InvalidArgumentException $invalidArgumentException) {
$io->error($invalidArgumentException->getMessage());
return Command::FAILURE;
}
return Command::SUCCESS;
}
}

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace Tvdt\Command;
use Symfony\Component\Console\Attribute\Argument;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Style\SymfonyStyle;
use Tvdt\Repository\UserRepository;
#[AsCommand(
name: 'tvdt:make-admin',
description: 'Give a user the role admin',
)]
final readonly class MakeAdminCommand
{
public function __construct(private UserRepository $userRepository) {}
public function __invoke(
#[Argument]
string $email,
SymfonyStyle $io,
): int {
try {
$this->userRepository->makeAdmin($email);
} catch (\InvalidArgumentException) {
$io->error('User not found');
return Command::FAILURE;
}
return Command::SUCCESS;
}
}

View File

@@ -0,0 +1,25 @@
<?php
declare(strict_types=1);
namespace Tvdt\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as AbstractBaseController;
use Tvdt\Enum\FlashType;
abstract class AbstractController extends AbstractBaseController
{
protected const string SEASON_CODE_REGEX = '[A-Za-z\d]{5}';
protected const string CANDIDATE_HASH_REGEX = '[\w\-=]+';
#[\Override]
protected function addFlash(FlashType|string $type, mixed $message): void
{
if ($type instanceof FlashType) {
$type = $type->value;
}
parent::addFlash($type, $message);
}
}

View File

@@ -1,28 +0,0 @@
<?php
namespace App\Controller\Admin;
use App\Entity\Answer;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
class AnswerCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Answer::class;
}
/*
public function configureFields(string $pageName): iterable
{
return [
IdField::new('id'),
TextField::new('title'),
TextEditorField::new('description'),
];
}
*/
}

View File

@@ -1,28 +0,0 @@
<?php
namespace App\Controller\Admin;
use App\Entity\Candidate;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
class CandidateCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Candidate::class;
}
/*
public function configureFields(string $pageName): iterable
{
return [
IdField::new('id'),
TextField::new('title'),
TextEditorField::new('description'),
];
}
*/
}

Some files were not shown because too many files have changed in this diff Show More