wip 12-03-2025
Some checks failed
CI / Tests (push) Failing after 11s
CI / Docker Lint (push) Successful in 3s

This commit is contained in:
2025-03-12 09:28:36 +01:00
parent f7b4b98da4
commit 448daed6ea
21 changed files with 523 additions and 103 deletions

View File

@@ -138,5 +138,6 @@
<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,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/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>

View File

@@ -17,4 +17,6 @@ tasks:
cmds:
- docker compose run php bin/console doctrine:migrations:migrate
translations:
cmds:
- docker compose exec php bin/console translation:extract --domain=messages --force --format=yaml --sort=asc --clean nl

View File

@@ -1,5 +1,5 @@
{
"name": "MarijnDoeve/TijdVoorDeTest",
"name": "marijndoeve/tijdvoordetest",
"type": "project",
"license": "MIT",
"description": "A minimal Symfony project recommended to create bare bones applications",
@@ -9,11 +9,11 @@
"php": ">=8.3.15",
"ext-ctype": "*",
"ext-iconv": "*",
"doctrine/dbal": "^4.2.2",
"doctrine/dbal": "^4.2.3",
"doctrine/doctrine-bundle": "^2.13.2",
"doctrine/doctrine-migrations-bundle": "^3.4.1",
"doctrine/orm": "^3.3.2",
"easycorp/easyadmin-bundle": "^4.24.4",
"easycorp/easyadmin-bundle": "^4.24.5",
"runtime/frankenphp-symfony": "^0.2.0",
"symfony/asset": "7.2.*",
"symfony/console": "7.2.*",
@@ -31,13 +31,13 @@
"require-dev": {
"roave/security-advisories": "dev-latest",
"doctrine/doctrine-fixtures-bundle": "^4.0",
"friendsofphp/php-cs-fixer": "^3.70.2",
"friendsofphp/php-cs-fixer": "^3.71.0",
"phpstan/extension-installer": "^1.4.3",
"phpstan/phpstan": "^2.1.7",
"phpstan/phpstan": "^2.1.8",
"phpstan/phpstan-doctrine": "^2.0.2",
"phpstan/phpstan-phpunit": "^2.0.4",
"phpstan/phpstan-symfony": "^2.0.2",
"phpunit/phpunit": "^11.5.11",
"phpunit/phpunit": "^11.5.12",
"rector/rector": "^2.0.10",
"symfony/maker-bundle": "^1.62.1",
"symfony/stopwatch": "7.2.*",

106
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5b43ef4edb1211b94fd4f8ec696221cc",
"content-hash": "45bc0712d79d3b5a625b352cbf14afda",
"packages": [
{
"name": "doctrine/cache",
@@ -187,16 +187,16 @@
},
{
"name": "doctrine/dbal",
"version": "4.2.2",
"version": "4.2.3",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "19a2b7deb5fe8c2df0ff817ecea305e50acb62ec"
"reference": "33d2d7fe1269b2301640c44cf2896ea607b30e3e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/19a2b7deb5fe8c2df0ff817ecea305e50acb62ec",
"reference": "19a2b7deb5fe8c2df0ff817ecea305e50acb62ec",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/33d2d7fe1269b2301640c44cf2896ea607b30e3e",
"reference": "33d2d7fe1269b2301640c44cf2896ea607b30e3e",
"shasum": ""
},
"require": {
@@ -273,7 +273,7 @@
],
"support": {
"issues": "https://github.com/doctrine/dbal/issues",
"source": "https://github.com/doctrine/dbal/tree/4.2.2"
"source": "https://github.com/doctrine/dbal/tree/4.2.3"
},
"funding": [
{
@@ -289,7 +289,7 @@
"type": "tidelift"
}
],
"time": "2025-01-16T08:40:56+00:00"
"time": "2025-03-07T18:29:05+00:00"
},
{
"name": "doctrine/deprecations",
@@ -1217,16 +1217,16 @@
},
{
"name": "easycorp/easyadmin-bundle",
"version": "v4.24.4",
"version": "v4.24.5",
"source": {
"type": "git",
"url": "https://github.com/EasyCorp/EasyAdminBundle.git",
"reference": "fd1b0e555655a5d8df67a0a48a28e07a1dd0d6f8"
"reference": "dcc64d06fc142f894667439e72837aa3742b5460"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/EasyCorp/EasyAdminBundle/zipball/fd1b0e555655a5d8df67a0a48a28e07a1dd0d6f8",
"reference": "fd1b0e555655a5d8df67a0a48a28e07a1dd0d6f8",
"url": "https://api.github.com/repos/EasyCorp/EasyAdminBundle/zipball/dcc64d06fc142f894667439e72837aa3742b5460",
"reference": "dcc64d06fc142f894667439e72837aa3742b5460",
"shasum": ""
},
"require": {
@@ -1262,11 +1262,11 @@
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4|3.5.x-dev",
"phpstan/extension-installer": "^1.2",
"phpstan/phpstan": "^1.9",
"phpstan/phpstan-phpunit": "^1.2",
"phpstan/phpstan-strict-rules": "^1.4",
"phpstan/phpstan-symfony": "^1.2",
"phpstan/extension-installer": "^1.4",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-strict-rules": "^2.0",
"phpstan/phpstan-symfony": "^2.0",
"psr/log": "^1.0",
"symfony/browser-kit": "^5.4|^6.0|^7.0",
"symfony/css-selector": "^5.4|^6.0|^7.0",
@@ -1307,7 +1307,7 @@
],
"support": {
"issues": "https://github.com/EasyCorp/EasyAdminBundle/issues",
"source": "https://github.com/EasyCorp/EasyAdminBundle/tree/v4.24.4"
"source": "https://github.com/EasyCorp/EasyAdminBundle/tree/v4.24.5"
},
"funding": [
{
@@ -1315,7 +1315,7 @@
"type": "github"
}
],
"time": "2025-02-19T19:52:22+00:00"
"time": "2025-03-10T19:31:19+00:00"
},
{
"name": "psr/cache",
@@ -6858,16 +6858,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.70.2",
"version": "v3.71.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "1ca468270efbb75ce0c7566a79cca8ea2888584d"
"reference": "3825ffdc69501e1c9230291b79f036a0c0d8749d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/1ca468270efbb75ce0c7566a79cca8ea2888584d",
"reference": "1ca468270efbb75ce0c7566a79cca8ea2888584d",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/3825ffdc69501e1c9230291b79f036a0c0d8749d",
"reference": "3825ffdc69501e1c9230291b79f036a0c0d8749d",
"shasum": ""
},
"require": {
@@ -6949,7 +6949,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.70.2"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.71.0"
},
"funding": [
{
@@ -6957,7 +6957,7 @@
"type": "github"
}
],
"time": "2025-03-03T21:07:23+00:00"
"time": "2025-03-07T23:06:56+00:00"
},
{
"name": "myclabs/deep-copy",
@@ -7245,16 +7245,16 @@
},
{
"name": "phpstan/phpstan",
"version": "2.1.7",
"version": "2.1.8",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "12567f91a74036d56ba0af6d56c8e73ac0e8d850"
"reference": "f9adff3b87c03b12cc7e46a30a524648e497758f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/12567f91a74036d56ba0af6d56c8e73ac0e8d850",
"reference": "12567f91a74036d56ba0af6d56c8e73ac0e8d850",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/f9adff3b87c03b12cc7e46a30a524648e497758f",
"reference": "f9adff3b87c03b12cc7e46a30a524648e497758f",
"shasum": ""
},
"require": {
@@ -7299,7 +7299,7 @@
"type": "github"
}
],
"time": "2025-03-05T13:43:55+00:00"
"time": "2025-03-09T09:30:48+00:00"
},
{
"name": "phpstan/phpstan-doctrine",
@@ -7819,16 +7819,16 @@
},
{
"name": "phpunit/phpunit",
"version": "11.5.11",
"version": "11.5.12",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "3946ac38410be7440186c6e74584f31b15107fc7"
"reference": "d42785840519401ed2113292263795eb4c0f95da"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3946ac38410be7440186c6e74584f31b15107fc7",
"reference": "3946ac38410be7440186c6e74584f31b15107fc7",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d42785840519401ed2113292263795eb4c0f95da",
"reference": "d42785840519401ed2113292263795eb4c0f95da",
"shasum": ""
},
"require": {
@@ -7849,7 +7849,7 @@
"phpunit/php-timer": "^7.0.1",
"sebastian/cli-parser": "^3.0.2",
"sebastian/code-unit": "^3.0.2",
"sebastian/comparator": "^6.3.0",
"sebastian/comparator": "^6.3.1",
"sebastian/diff": "^6.0.2",
"sebastian/environment": "^7.2.0",
"sebastian/exporter": "^6.3.0",
@@ -7900,7 +7900,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.11"
"source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.12"
},
"funding": [
{
@@ -7916,7 +7916,7 @@
"type": "tidelift"
}
],
"time": "2025-03-05T07:36:02+00:00"
"time": "2025-03-07T07:31:03+00:00"
},
{
"name": "react/cache",
@@ -8509,12 +8509,12 @@
"source": {
"type": "git",
"url": "https://github.com/Roave/SecurityAdvisories.git",
"reference": "93d6f477df354be282736a37f732e39382ff9f95"
"reference": "eab95f065c8f07444ff8ea062ae32a2df83e20ea"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/93d6f477df354be282736a37f732e39382ff9f95",
"reference": "93d6f477df354be282736a37f732e39382ff9f95",
"url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/eab95f065c8f07444ff8ea062ae32a2df83e20ea",
"reference": "eab95f065c8f07444ff8ea062ae32a2df83e20ea",
"shasum": ""
},
"conflict": {
@@ -8615,7 +8615,7 @@
"codiad/codiad": "<=2.8.4",
"components/jquery": ">=1.0.3,<3.5",
"composer/composer": "<1.10.27|>=2,<2.2.24|>=2.3,<2.7.7",
"concrete5/concrete5": "<9.3.4",
"concrete5/concrete5": "<9.4.0.0-RC1-dev",
"concrete5/core": "<8.5.8|>=9,<9.1",
"contao-components/mediaelement": ">=2.14.2,<2.21.1",
"contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4",
@@ -8737,7 +8737,7 @@
"friendsoftypo3/mediace": ">=7.6.2,<7.6.5",
"friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6",
"froala/wysiwyg-editor": "<3.2.7|>=4.0.1,<=4.1.3",
"froxlor/froxlor": "<=2.2.0.0-RC3",
"froxlor/froxlor": "<=2.2.5",
"frozennode/administrator": "<=5.0.12",
"fuel/core": "<1.8.1",
"funadmin/funadmin": "<=5.0.2",
@@ -8996,7 +8996,7 @@
"phpmyadmin/phpmyadmin": "<5.2.2",
"phpmyfaq/phpmyfaq": "<3.2.5|==3.2.5|>=3.2.10,<=4.0.1",
"phpoffice/common": "<0.2.9",
"phpoffice/phpexcel": "<1.8.1",
"phpoffice/phpexcel": "<=1.8.2",
"phpoffice/phpspreadsheet": "<1.29.9|>=2,<2.1.8|>=2.2,<2.3.7|>=3,<3.9",
"phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36",
"phpservermon/phpservermon": "<3.6",
@@ -9017,7 +9017,7 @@
"pixelfed/pixelfed": "<0.11.11",
"plotly/plotly.js": "<2.25.2",
"pocketmine/bedrock-protocol": "<8.0.2",
"pocketmine/pocketmine-mp": "<5.11.2",
"pocketmine/pocketmine-mp": "<5.25.2",
"pocketmine/raklib": ">=0.14,<0.14.6|>=0.15,<0.15.1",
"pressbooks/pressbooks": "<5.18",
"prestashop/autoupgrade": ">=4,<4.10.1",
@@ -9098,8 +9098,8 @@
"silverstripe/userforms": "<3|>=5,<5.4.2",
"silverstripe/versioned-admin": ">=1,<1.11.1",
"simple-updates/phpwhois": "<=1",
"simplesamlphp/saml2": "<4.6.14|==5.0.0.0-alpha12",
"simplesamlphp/saml2-legacy": "<4.6.14",
"simplesamlphp/saml2": "<=4.6.15|>=5.0.0.0-alpha1,<=5.0.0.0-alpha19",
"simplesamlphp/saml2-legacy": "<=4.6.15",
"simplesamlphp/simplesamlphp": "<1.18.6",
"simplesamlphp/simplesamlphp-module-infocard": "<1.0.1",
"simplesamlphp/simplesamlphp-module-openid": "<1",
@@ -9378,7 +9378,7 @@
"type": "tidelift"
}
],
"time": "2025-03-05T20:05:33+00:00"
"time": "2025-03-11T21:04:43+00:00"
},
{
"name": "sebastian/cli-parser",
@@ -9552,16 +9552,16 @@
},
{
"name": "sebastian/comparator",
"version": "6.3.0",
"version": "6.3.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
"reference": "d4e47a769525c4dd38cea90e5dcd435ddbbc7115"
"reference": "24b8fbc2c8e201bb1308e7b05148d6ab393b6959"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/d4e47a769525c4dd38cea90e5dcd435ddbbc7115",
"reference": "d4e47a769525c4dd38cea90e5dcd435ddbbc7115",
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/24b8fbc2c8e201bb1308e7b05148d6ab393b6959",
"reference": "24b8fbc2c8e201bb1308e7b05148d6ab393b6959",
"shasum": ""
},
"require": {
@@ -9580,7 +9580,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "6.2-dev"
"dev-main": "6.3-dev"
}
},
"autoload": {
@@ -9620,7 +9620,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/comparator/issues",
"security": "https://github.com/sebastianbergmann/comparator/security/policy",
"source": "https://github.com/sebastianbergmann/comparator/tree/6.3.0"
"source": "https://github.com/sebastianbergmann/comparator/tree/6.3.1"
},
"funding": [
{
@@ -9628,7 +9628,7 @@
"type": "github"
}
],
"time": "2025-01-06T10:28:19+00:00"
"time": "2025-03-07T06:57:01+00:00"
},
{
"name": "sebastian/complexity",

View File

@@ -0,0 +1,119 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20250311213417 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$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 down() migration is auto-generated, please modify it to your needs
$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,49 @@
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Entity\Quiz;
use App\Entity\Season;
use App\Repository\SeasonRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Attribute\Route;
#[AsController]
#[Route('/backoffice', name: 'backoffice_')]
final class BackofficeController extends AbstractController
{
public function __construct(private readonly SeasonRepository $seasonRepository)
{
}
#[Route('/', name: 'index')]
public function index(): Response
{
$seasons = $this->seasonRepository->findAll();
return $this->render('backoffice/index.html.twig', [
'seasons' => $seasons,
]);
}
#[Route('/{seasonCode}', name: 'season')]
public function season(Season $season): Response
{
return $this->render('backoffice/season.html.twig', [
'season' => $season,
]);
}
#[Route('/{seasonCode}/{quiz}', name: 'quiz')]
public function quiz(Season $season, Quiz $quiz): Response
{
return $this->render('backoffice/quiz.html.twig', [
'season' => $season,
'quiz' => $quiz,
]);
}
}

View File

@@ -25,7 +25,7 @@ use Symfony\Component\HttpKernel\Attribute\AsController;
use Symfony\Component\Routing\Attribute\Route;
#[AsController]
class QuizController extends AbstractController
final class QuizController extends AbstractController
{
public const string SEASON_CODE_REGEX = '[A-Za-z\d]{5}';
private const string CANDIDATE_HASH_REGEX = '[\w\-=]+';
@@ -102,7 +102,8 @@ class QuizController extends AbstractController
$givenAnswer = (new GivenAnswer())
->setCandidate($candidate)
->setAnswer($answer);
->setAnswer($answer)
->setQuiz($answer->getQuestion()->getQuiz());
$givenAnswerRepository->save($givenAnswer);
}

View File

@@ -34,7 +34,7 @@ class GivenAnswer
#[ORM\JoinColumn(nullable: true)]
private ?Answer $answer = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: false)]
#[ORM\Column(type: Types::DATETIME_IMMUTABLE, nullable: false)]
private \DateTimeInterface $created;
public function getId(): ?Uuid
@@ -78,7 +78,7 @@ class GivenAnswer
return $this;
}
public function getCreated(): ?\DateTimeInterface
public function getCreated(): \DateTimeInterface
{
return $this->created;
}

View File

@@ -36,6 +36,9 @@ class Quiz
#[ORM\OneToMany(targetEntity: Correction::class, mappedBy: 'quiz', orphanRemoval: true)]
private Collection $corrections;
#[ORM\Column(nullable: true)]
private ?int $dropouts = null;
public function __construct()
{
$this->questions = new ArrayCollection();
@@ -102,4 +105,16 @@ class Quiz
return $this;
}
public function getDropouts(): ?int
{
return $this->dropouts;
}
public function setDropouts(?int $dropouts): static
{
$this->dropouts = $dropouts;
return $this;
}
}

View File

@@ -17,4 +17,8 @@ class QuizRepository extends ServiceEntityRepository
{
parent::__construct($registry, Quiz::class);
}
public function quizReault(Quiz $quiz): array
{
}
}

View File

@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en" data-bs-theme="dark">
<head>
<meta charset="UTF-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz"
crossorigin="anonymous"></script>
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="icon"
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
<title>
{% block title %}Tijd voor de test{% endblock title %}
</title>
{% block stylesheets %}
{% endblock %}
{% block javascripts %}
{% endblock %}
</head>
<body>
{% block nav %}
{{ include('backoffice/nav.html.twig') }}
{% endblock nav %}
<main>
<div class="container">
{# {% include "messages.html" %} #}
{% block body %}
{% endblock body %}
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,48 @@
{% extends 'backoffice/base.html.twig' %}
{% block title %}Hello BackofficeController!{% endblock %}
{% block body %}
<h2>{% trans %}Your Seasons{% endtrans %}</h2>
<table class="table table-hover">
<thead>
<tr>
<th scope="col">{% trans %}Name{% endtrans %}</th>
<th scope="col">{% trans %}Active Quiz{% endtrans %}</th>
<th scope="col">{% trans %}Season Code{% endtrans %}</th>
<th scope="col">{% trans %}Preregister?{% endtrans %}</th>
<th scope="col">{% trans %}Manage{% endtrans %}</th>
</tr>
</thead>
<tbody>
{% for season in seasons %}
<tr class="align-middle">
<td>{{ season.name }}</td>
<td>
{% if season.activeQuiz %}
{{ season.activeQuiz.name }}
{% else %}
{% trans %} No active quiz {% endtrans %}
{% endif %}
</td>
<td>
<a {% if season.activeQuiz %}href="{{ path('enter_name', {seasonCode: season.seasonCode}) }}"
{% else %}class="disabled" {% endif %}>{{ season.seasonCode }}</a>
</td>
<td>
<input class="form-check-input"
type="checkbox"
disabled
{% if season.preregisterCandidates %}checked{% endif %}
aria-label="Preregister Enabled">
</td>
<td>
<a href="{{ path('backoffice_season', {seasonCode: season.seasonCode}) }}">{% trans %}Manage{% endtrans %}</a>
</td>
</tr>
{% else %}
EMPTY
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@@ -0,0 +1,22 @@
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid">
<a class="navbar-brand" href="#">Tijd voor de test</a>
<button class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link{% if 'backoffice_index' == app.current_route() %} active{% endif %}"
href="{{ path('backoffice_index') }}">{{ t('Seasons') }}</a>
</li>
</ul>
</div>
</div>
</nav>

View File

@@ -0,0 +1,95 @@
{% extends 'backoffice/base.html.twig' %}
{% block body %}
<p>
<h2>{{ t('Quiz') }}: {{ quiz.season.name }} - {{ quiz.name }}</h2>
</p>
<div id="questions">
<p>
<h4>{{ t('Questions') }}</h4>
</p>
<div class="accordion">
{% for question in quiz.questions %}
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed"
type="button"
data-bs-toggle="collapse"
data-bs-target="#question-{{ loop.index0 }}"
aria-controls="question-{{ loop.index0 }}">
{# {% with question_error = question.errors %} #}
{# {% if question_error %} #}
{# <span data-bs-toggle="tooltip" #}
{# title="{{ question_error }}" #}
{# class="badge text-bg-danger rounded-pill me-2">!</span> #}
{# {% endif %} #}
{# {% endwith %} #}
{{ loop.index }}. {{ question.question }}
</button>
</h2>
<div id="question-{{ loop.index0 }}"
class="accordion-collapse collapse">
<div class="accordion-body">
{% for answer in question.answers %}
<li {% if answer.isRightAnswer %}class="text-decoration-underline"{% endif %}>{{ answer.text }}</li>
{% else %}
{{ t('There are no answers for this question') }}
{% endfor %}
</div>
</div>
</div>
{% else %}
EMPTY
{% endfor %}
</div>
</div>
<div class="scores">
<p>
<h4>{{ t('Score') }}</h4>
</p>
<div class="btn-toolbar" role="toolbar">
<div class="btn-group btn-group-lg me-2">
<a class="btn btn-primary">{{ t('Start Elimination') }}</a>
</div>
<div class="btn-group btn-group-lg">
<a class="btn btn-secondary">{{ t('Prepare Custom Elimination') }}</a>
<a class="btn btn-secondary">{{ t('Load Prepared Elimination') }}</a>
</div>
</div>
<p>{{ t('Number of dropouts:') }} {{ quiz.dropouts }} </p>
<table class="table table-hover">
<thead>
<tr>
<th scope="col">{{ t('Candidate') }}</th>
<th scope="col">{{ t('Correct Answers') }}</th>
<th scope="col">{{ t('Corrections') }}</th>
<th scope="col">{{ t('Score') }}</th>
<th scope="col">{{ t('Time') }}</th>
</tr>
</thead>
<tbody>
{# {% with result = quiz.get_score %} #}
{# {% for candidate in result %} #}
{# <tr class="table-{% if forloop.revcounter > quiz.dropouts %}success{% else %}danger{% endif %}"> #}
{# <td>{{ candidate.name }}</td> #}
{# <td>{{ candidate.correct }}</td> #}
{# <td>{{ candidate.corrections }}</td> #}
{# <td>{{ candidate.score }}</td> #}
{# <td>{{ candidate.time }}</td> #}
{# </tr> #}
{# {% empty %} #}
{# {% endfor %} #}
</tbody>
</table>
{# {% endwith %} #}
</div>
{% endblock %}
{% block script %}
<script>
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
</script>
{% endblock script %}
{% block title %}
{% endblock %}

View File

@@ -0,0 +1,26 @@
{% extends 'backoffice/base.html.twig' %}
{% block body %}
<p>
<h2>{{ t('Season') }}: {{ season.name }}</h2>
</p>
<div class="row">
<div class="col-md-6 col-12">
<h4>{{ t('Quizzes') }}</h4>
<div class="list-group">
{% for quiz in season.quizzes %}
<a class="list-group-item list-group-item-action{% if season.activeQuiz == quiz %} active{% endif %}"
href="{{ path('backoffice_quiz', {seasonCode: season.seasonCode, quiz: quiz.id}) }}">{{ quiz.name }}</a>
{% else %}
No quizzes
{% endfor %}
</div>
</div>
<div class="col-md-6 col-12">
<h4>{{ t('Candidates') }}</h4>
<ul>
{% for candidate in season.candidates %}
<li>{{ candidate.name }}</li>{% endfor %}
</ul>
</div>
</div>
{% endblock body %}

View File

@@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
<link rel="icon"
href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫️</text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
{% block stylesheets %}
{% endblock %}
{% block javascripts %}
{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file source-language="nl" target-language="nl" datatype="plaintext" original="file.ext">
<header>
<tool tool-id="symfony" tool-name="Symfony"/>
</header>
<body>
<trans-unit id="RnI7jJT" resname="Enter your name">
<source>Enter your name</source>
<target>Voor je naam in</target>
</trans-unit>
</body>
</file>
</xliff>

View File

@@ -0,0 +1,24 @@
'Active Quiz': 'Actieve test'
Candidate: Kandidaat
Candidates: Kandidaten
'Correct Answers': 'Goede antwoorden'
Corrections: Jokers
'Enter your name': 'Voor je naam in'
'Load Prepared Elimination': 'Laad voorbereide eliminatie'
Manage: Beheren
Name: Naam
'No active quiz': 'Geen actieve test'
'Number of dropouts:': 'Aantal afvallers:'
'Prepare Custom Elimination': 'Bereid aangepaste eliminatie voor'
'Preregister?': 'Voorregistreren?'
Questions: Vragen
Quiz: Test
Quizzes: Tests
Score: Score
Season: Seizoen
'Season Code': Seizoenscode
Seasons: Seizoenen
'Start Elimination': 'Start eliminatie'
'There are no answers for this question': 'Er zijn geen antwoorden voor deze vraag'
Time: Tijd
'Your Seasons': 'Jouw seizoenen'