mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-03-06 04:44:19 +01:00
- **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.
This commit is contained in:
2
.idea/TijdVoorDeTest.iml
generated
2
.idea/TijdVoorDeTest.iml
generated
@@ -167,6 +167,8 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/martin-georgiev/postgresql-for-doctrine" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/martin-georgiev/postgresql-for-doctrine" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/brianium/paratest" />
|
<excludeFolder url="file://$MODULE_DIR$/vendor/brianium/paratest" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/vendor/dama/doctrine-test-bundle" />
|
<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>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
|||||||
2
.idea/php.xml
generated
2
.idea/php.xml
generated
@@ -198,6 +198,8 @@
|
|||||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php84" />
|
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php84" />
|
||||||
<path value="$PROJECT_DIR$/vendor/brianium/paratest" />
|
<path value="$PROJECT_DIR$/vendor/brianium/paratest" />
|
||||||
<path value="$PROJECT_DIR$/vendor/dama/doctrine-test-bundle" />
|
<path value="$PROJECT_DIR$/vendor/dama/doctrine-test-bundle" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/stof/doctrine-extensions-bundle" />
|
||||||
|
<path value="$PROJECT_DIR$/vendor/gedmo/doctrine-extensions" />
|
||||||
</include_path>
|
</include_path>
|
||||||
</component>
|
</component>
|
||||||
<component name="PhpInterpreters">
|
<component name="PhpInterpreters">
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"phpstan/phpdoc-parser": "^2.3",
|
"phpstan/phpdoc-parser": "^2.3",
|
||||||
"runtime/frankenphp-symfony": "^0.2.0",
|
"runtime/frankenphp-symfony": "^0.2.0",
|
||||||
"sentry/sentry-symfony": "^5.6",
|
"sentry/sentry-symfony": "^5.6",
|
||||||
|
"stof/doctrine-extensions-bundle": "^1.14",
|
||||||
"symfony/asset": "7.3.*",
|
"symfony/asset": "7.3.*",
|
||||||
"symfony/asset-mapper": "7.3.*",
|
"symfony/asset-mapper": "7.3.*",
|
||||||
"symfony/brevo-mailer": "7.3.*",
|
"symfony/brevo-mailer": "7.3.*",
|
||||||
|
|||||||
215
composer.lock
generated
215
composer.lock
generated
@@ -4,7 +4,7 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "0ad053f4679a6b7cb76699c8391a12e5",
|
"content-hash": "944e218741f3c7a1f04072e075255c2c",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "composer/pcre",
|
"name": "composer/pcre",
|
||||||
@@ -1338,6 +1338,138 @@
|
|||||||
],
|
],
|
||||||
"time": "2025-03-06T22:45:56+00:00"
|
"time": "2025-03-06T22:45:56+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "gedmo/doctrine-extensions",
|
||||||
|
"version": "v3.21.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/doctrine-extensions/DoctrineExtensions.git",
|
||||||
|
"reference": "eb53dfcb2b592327b76ac5226fbb003d32aea37e"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/doctrine-extensions/DoctrineExtensions/zipball/eb53dfcb2b592327b76ac5226fbb003d32aea37e",
|
||||||
|
"reference": "eb53dfcb2b592327b76ac5226fbb003d32aea37e",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"doctrine/collections": "^1.2 || ^2.0",
|
||||||
|
"doctrine/deprecations": "^1.0",
|
||||||
|
"doctrine/event-manager": "^1.2 || ^2.0",
|
||||||
|
"doctrine/persistence": "^2.2 || ^3.0 || ^4.0",
|
||||||
|
"php": "^7.4 || ^8.0",
|
||||||
|
"psr/cache": "^1 || ^2 || ^3",
|
||||||
|
"psr/clock": "^1",
|
||||||
|
"symfony/cache": "^5.4 || ^6.0 || ^7.0",
|
||||||
|
"symfony/string": "^5.4 || ^6.0 || ^7.0"
|
||||||
|
},
|
||||||
|
"conflict": {
|
||||||
|
"behat/transliterator": "<1.2 || >=2.0",
|
||||||
|
"doctrine/annotations": "<1.13 || >=3.0",
|
||||||
|
"doctrine/common": "<2.13 || >=4.0",
|
||||||
|
"doctrine/dbal": "<3.7 || >=5.0",
|
||||||
|
"doctrine/mongodb-odm": "<2.3 || >=3.0",
|
||||||
|
"doctrine/orm": "<2.20 || >=3.0 <3.3 || >=4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"behat/transliterator": "^1.2",
|
||||||
|
"doctrine/annotations": "^1.13 || ^2.0",
|
||||||
|
"doctrine/cache": "^1.11 || ^2.0",
|
||||||
|
"doctrine/common": "^2.13 || ^3.0",
|
||||||
|
"doctrine/dbal": "^3.7 || ^4.0",
|
||||||
|
"doctrine/doctrine-bundle": "^2.3",
|
||||||
|
"doctrine/mongodb-odm": "^2.3",
|
||||||
|
"doctrine/orm": "^2.20 || ^3.3",
|
||||||
|
"friendsofphp/php-cs-fixer": "^3.70",
|
||||||
|
"nesbot/carbon": "^2.71 || ^3.0",
|
||||||
|
"phpstan/phpstan": "^2.1.1",
|
||||||
|
"phpstan/phpstan-doctrine": "^2.0.1",
|
||||||
|
"phpstan/phpstan-phpunit": "^2.0.3",
|
||||||
|
"phpunit/phpunit": "^9.6",
|
||||||
|
"rector/rector": "^2.0.6",
|
||||||
|
"symfony/console": "^5.4 || ^6.0 || ^7.0",
|
||||||
|
"symfony/doctrine-bridge": "^5.4 || ^6.0 || ^7.0",
|
||||||
|
"symfony/phpunit-bridge": "^6.4 || ^7.0",
|
||||||
|
"symfony/uid": "^5.4 || ^6.0 || ^7.0",
|
||||||
|
"symfony/yaml": "^5.4 || ^6.0 || ^7.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"doctrine/mongodb-odm": "to use the extensions with the MongoDB ODM",
|
||||||
|
"doctrine/orm": "to use the extensions with the ORM"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "3.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Gedmo\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Gediminas Morkevicius",
|
||||||
|
"email": "gediminas.morkevicius@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gustavo Falco",
|
||||||
|
"email": "comfortablynumb84@gmail.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "David Buchmann",
|
||||||
|
"email": "david@liip.ch"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Doctrine behavioral extensions",
|
||||||
|
"homepage": "http://gediminasm.org/",
|
||||||
|
"keywords": [
|
||||||
|
"Blameable",
|
||||||
|
"behaviors",
|
||||||
|
"doctrine",
|
||||||
|
"extensions",
|
||||||
|
"gedmo",
|
||||||
|
"loggable",
|
||||||
|
"nestedset",
|
||||||
|
"odm",
|
||||||
|
"orm",
|
||||||
|
"sluggable",
|
||||||
|
"sortable",
|
||||||
|
"timestampable",
|
||||||
|
"translatable",
|
||||||
|
"tree",
|
||||||
|
"uploadable"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"docs": "https://github.com/doctrine-extensions/DoctrineExtensions/tree/main/doc",
|
||||||
|
"issues": "https://github.com/doctrine-extensions/DoctrineExtensions/issues",
|
||||||
|
"source": "https://github.com/doctrine-extensions/DoctrineExtensions/tree/v3.21.0"
|
||||||
|
},
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"url": "https://github.com/l3pp4rd",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/mbabker",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/phansys",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://github.com/stof",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"time": "2025-09-22T17:04:34+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "guzzlehttp/psr7",
|
"name": "guzzlehttp/psr7",
|
||||||
"version": "2.8.0",
|
"version": "2.8.0",
|
||||||
@@ -2858,6 +2990,87 @@
|
|||||||
],
|
],
|
||||||
"time": "2025-09-24T13:41:01+00:00"
|
"time": "2025-09-24T13:41:01+00:00"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "stof/doctrine-extensions-bundle",
|
||||||
|
"version": "v1.14.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/stof/StofDoctrineExtensionsBundle.git",
|
||||||
|
"reference": "bdf3eb10baeb497ac5985b8f78a6cf55862c2662"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/stof/StofDoctrineExtensionsBundle/zipball/bdf3eb10baeb497ac5985b8f78a6cf55862c2662",
|
||||||
|
"reference": "bdf3eb10baeb497ac5985b8f78a6cf55862c2662",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"gedmo/doctrine-extensions": "^3.20.0",
|
||||||
|
"php": "^8.1",
|
||||||
|
"symfony/cache": "^6.4 || ^7.0",
|
||||||
|
"symfony/config": "^6.4 || ^7.0",
|
||||||
|
"symfony/dependency-injection": "^6.4 || ^7.0",
|
||||||
|
"symfony/event-dispatcher": "^6.4 || ^7.0",
|
||||||
|
"symfony/http-kernel": "^6.4 || ^7.0",
|
||||||
|
"symfony/translation-contracts": "^2.5 || ^3.5"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpstan/phpstan": "^2.1",
|
||||||
|
"phpstan/phpstan-deprecation-rules": "^2.0",
|
||||||
|
"phpstan/phpstan-phpunit": "^2.0",
|
||||||
|
"phpstan/phpstan-strict-rules": "^2.0",
|
||||||
|
"phpstan/phpstan-symfony": "^2.0",
|
||||||
|
"symfony/mime": "^6.4 || ^7.0",
|
||||||
|
"symfony/phpunit-bridge": "^v6.4.1 || ^7.0.1",
|
||||||
|
"symfony/security-core": "^6.4 || ^7.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"doctrine/doctrine-bundle": "to use the ORM extensions",
|
||||||
|
"doctrine/mongodb-odm-bundle": "to use the MongoDB ODM extensions",
|
||||||
|
"symfony/mime": "To use the Mime component integration for Uploadable"
|
||||||
|
},
|
||||||
|
"type": "symfony-bundle",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-main": "1.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Stof\\DoctrineExtensionsBundle\\": "src"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Christophe Coevoet",
|
||||||
|
"email": "stof@notk.org"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Integration of the gedmo/doctrine-extensions with Symfony",
|
||||||
|
"homepage": "https://github.com/stof/StofDoctrineExtensionsBundle",
|
||||||
|
"keywords": [
|
||||||
|
"behaviors",
|
||||||
|
"doctrine2",
|
||||||
|
"extensions",
|
||||||
|
"gedmo",
|
||||||
|
"loggable",
|
||||||
|
"nestedset",
|
||||||
|
"sluggable",
|
||||||
|
"sortable",
|
||||||
|
"timestampable",
|
||||||
|
"translatable",
|
||||||
|
"tree"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/stof/StofDoctrineExtensionsBundle/issues",
|
||||||
|
"source": "https://github.com/stof/StofDoctrineExtensionsBundle/tree/v1.14.0"
|
||||||
|
},
|
||||||
|
"time": "2025-05-01T08:00:32+00:00"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/asset",
|
"name": "symfony/asset",
|
||||||
"version": "v7.3.0",
|
"version": "v7.3.0",
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
|
|||||||
use Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle;
|
use Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle;
|
||||||
use Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle;
|
use Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle;
|
||||||
use Sentry\SentryBundle\SentryBundle;
|
use Sentry\SentryBundle\SentryBundle;
|
||||||
|
use Stof\DoctrineExtensionsBundle\StofDoctrineExtensionsBundle;
|
||||||
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
|
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
|
||||||
use Symfony\Bundle\MakerBundle\MakerBundle;
|
use Symfony\Bundle\MakerBundle\MakerBundle;
|
||||||
use Symfony\Bundle\SecurityBundle\SecurityBundle;
|
use Symfony\Bundle\SecurityBundle\SecurityBundle;
|
||||||
@@ -34,4 +35,5 @@ return [
|
|||||||
StimulusBundle::class => ['all' => true],
|
StimulusBundle::class => ['all' => true],
|
||||||
TurboBundle::class => ['all' => true],
|
TurboBundle::class => ['all' => true],
|
||||||
DAMADoctrineTestBundle::class => ['test' => true],
|
DAMADoctrineTestBundle::class => ['test' => true],
|
||||||
|
StofDoctrineExtensionsBundle::class => ['all' => true],
|
||||||
];
|
];
|
||||||
|
|||||||
7
config/packages/stof_doctrine_extensions.yaml
Normal file
7
config/packages/stof_doctrine_extensions.yaml
Normal 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
|
||||||
@@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
if (file_exists(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/App_KernelProdContainer.preload.php';
|
require dirname(__DIR__).'/var/cache/prod/Tvdt_KernelProdContainer.preload.php';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ final class QuizController extends AbstractController
|
|||||||
// TODO: Extract getting next question logic to a service
|
// TODO: Extract getting next question logic to a service
|
||||||
$question = $questionRepository->findNextQuestionForCandidate($candidate);
|
$question = $questionRepository->findNextQuestionForCandidate($candidate);
|
||||||
|
|
||||||
// Keep creating flash here based on return type of service call
|
// Keep creating flash here based on the return type of service call
|
||||||
if (!$question instanceof Question) {
|
if (!$question instanceof Question) {
|
||||||
$this->addFlash(FlashType::Success, $this->translator->trans('Quiz completed'));
|
$this->addFlash(FlashType::Success, $this->translator->trans('Quiz completed'));
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Tvdt\Entity;
|
|||||||
|
|
||||||
use Doctrine\DBAL\Types\Types;
|
use Doctrine\DBAL\Types\Types;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Safe\DateTimeImmutable;
|
use Gedmo\Mapping\Annotation as Gedmo;
|
||||||
use Symfony\Bridge\Doctrine\Types\UuidType;
|
use Symfony\Bridge\Doctrine\Types\UuidType;
|
||||||
use Symfony\Component\HttpFoundation\InputBag;
|
use Symfony\Component\HttpFoundation\InputBag;
|
||||||
use Symfony\Component\Uid\Uuid;
|
use Symfony\Component\Uid\Uuid;
|
||||||
@@ -30,6 +30,7 @@ class Elimination
|
|||||||
#[ORM\Column(type: Types::JSONB)]
|
#[ORM\Column(type: Types::JSONB)]
|
||||||
public array $data = [];
|
public array $data = [];
|
||||||
|
|
||||||
|
#[Gedmo\Timestampable(on: 'create')]
|
||||||
#[ORM\Column(type: Types::DATETIMETZ_IMMUTABLE, nullable: false)]
|
#[ORM\Column(type: Types::DATETIMETZ_IMMUTABLE, nullable: false)]
|
||||||
public private(set) \DateTimeImmutable $created;
|
public private(set) \DateTimeImmutable $created;
|
||||||
|
|
||||||
@@ -56,10 +57,4 @@ class Elimination
|
|||||||
{
|
{
|
||||||
return $this->data[$name] ?? null;
|
return $this->data[$name] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[ORM\PrePersist]
|
|
||||||
public function setCreatedAtValue(): void
|
|
||||||
{
|
|
||||||
$this->created = new DateTimeImmutable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,12 @@ namespace Tvdt\Entity;
|
|||||||
|
|
||||||
use Doctrine\DBAL\Types\Types;
|
use Doctrine\DBAL\Types\Types;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Safe\DateTimeImmutable;
|
use Gedmo\Mapping\Annotation as Gedmo;
|
||||||
use Symfony\Bridge\Doctrine\Types\UuidType;
|
use Symfony\Bridge\Doctrine\Types\UuidType;
|
||||||
use Symfony\Component\Uid\Uuid;
|
use Symfony\Component\Uid\Uuid;
|
||||||
use Tvdt\Repository\GivenAnswerRepository;
|
use Tvdt\Repository\GivenAnswerRepository;
|
||||||
|
|
||||||
#[ORM\Entity(repositoryClass: GivenAnswerRepository::class)]
|
#[ORM\Entity(repositoryClass: GivenAnswerRepository::class)]
|
||||||
#[ORM\HasLifecycleCallbacks]
|
|
||||||
class GivenAnswer
|
class GivenAnswer
|
||||||
{
|
{
|
||||||
#[ORM\Column(type: UuidType::NAME, unique: true)]
|
#[ORM\Column(type: UuidType::NAME, unique: true)]
|
||||||
@@ -21,6 +20,7 @@ class GivenAnswer
|
|||||||
#[ORM\Id]
|
#[ORM\Id]
|
||||||
public private(set) Uuid $id;
|
public private(set) Uuid $id;
|
||||||
|
|
||||||
|
#[Gedmo\Timestampable(on: 'create')]
|
||||||
#[ORM\Column(type: Types::DATETIMETZ_IMMUTABLE, nullable: false)]
|
#[ORM\Column(type: Types::DATETIMETZ_IMMUTABLE, nullable: false)]
|
||||||
public private(set) \DateTimeImmutable $created;
|
public private(set) \DateTimeImmutable $created;
|
||||||
|
|
||||||
@@ -37,10 +37,4 @@ class GivenAnswer
|
|||||||
#[ORM\ManyToOne(inversedBy: 'givenAnswers')]
|
#[ORM\ManyToOne(inversedBy: 'givenAnswers')]
|
||||||
private(set) Answer $answer,
|
private(set) Answer $answer,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
#[ORM\PrePersist]
|
|
||||||
public function setCreatedAtValue(): void
|
|
||||||
{
|
|
||||||
$this->created = new DateTimeImmutable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,12 @@ namespace Tvdt\Entity;
|
|||||||
|
|
||||||
use Doctrine\DBAL\Types\Types;
|
use Doctrine\DBAL\Types\Types;
|
||||||
use Doctrine\ORM\Mapping as ORM;
|
use Doctrine\ORM\Mapping as ORM;
|
||||||
use Safe\DateTimeImmutable;
|
use Gedmo\Mapping\Annotation as Gedmo;
|
||||||
use Symfony\Bridge\Doctrine\Types\UuidType;
|
use Symfony\Bridge\Doctrine\Types\UuidType;
|
||||||
use Symfony\Component\Uid\Uuid;
|
use Symfony\Component\Uid\Uuid;
|
||||||
use Tvdt\Repository\QuizCandidateRepository;
|
use Tvdt\Repository\QuizCandidateRepository;
|
||||||
|
|
||||||
#[ORM\Entity(repositoryClass: QuizCandidateRepository::class)]
|
#[ORM\Entity(repositoryClass: QuizCandidateRepository::class)]
|
||||||
#[ORM\HasLifecycleCallbacks]
|
|
||||||
#[ORM\UniqueConstraint(columns: ['candidate_id', 'quiz_id'])]
|
#[ORM\UniqueConstraint(columns: ['candidate_id', 'quiz_id'])]
|
||||||
class QuizCandidate
|
class QuizCandidate
|
||||||
{
|
{
|
||||||
@@ -25,6 +24,7 @@ class QuizCandidate
|
|||||||
#[ORM\Column]
|
#[ORM\Column]
|
||||||
public float $corrections = 0;
|
public float $corrections = 0;
|
||||||
|
|
||||||
|
#[Gedmo\Timestampable(on: 'create')]
|
||||||
#[ORM\Column(type: Types::DATETIMETZ_IMMUTABLE)]
|
#[ORM\Column(type: Types::DATETIMETZ_IMMUTABLE)]
|
||||||
public private(set) \DateTimeImmutable $created;
|
public private(set) \DateTimeImmutable $created;
|
||||||
|
|
||||||
@@ -37,10 +37,4 @@ class QuizCandidate
|
|||||||
#[ORM\ManyToOne(inversedBy: 'quizData')]
|
#[ORM\ManyToOne(inversedBy: 'quizData')]
|
||||||
public Candidate $candidate,
|
public Candidate $candidate,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
#[ORM\PrePersist]
|
|
||||||
public function setCreatedAtValue(): void
|
|
||||||
{
|
|
||||||
$this->created = new DateTimeImmutable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,24 +48,14 @@ final class SeasonVoter extends Voter
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (true) {
|
$season = match (true) {
|
||||||
case $subject instanceof Answer:
|
$subject instanceof Answer => $subject->question->quiz->season,
|
||||||
$season = $subject->question->quiz->season;
|
$subject instanceof Elimination,
|
||||||
break;
|
$subject instanceof Question => $subject->quiz->season,
|
||||||
case $subject instanceof Elimination:
|
$subject instanceof Candidate,
|
||||||
case $subject instanceof Question:
|
$subject instanceof Quiz => $subject->season,
|
||||||
$season = $subject->quiz->season;
|
$subject instanceof Season => $subject,
|
||||||
break;
|
};
|
||||||
case $subject instanceof Candidate:
|
|
||||||
case $subject instanceof Quiz:
|
|
||||||
$season = $subject->season;
|
|
||||||
break;
|
|
||||||
case $subject instanceof Season:
|
|
||||||
$season = $subject;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return match ($attribute) {
|
return match ($attribute) {
|
||||||
self::EDIT, self::DELETE, self::ELIMINATION => $season->isOwner($user),
|
self::EDIT, self::DELETE, self::ELIMINATION => $season->isOwner($user),
|
||||||
|
|||||||
@@ -55,6 +55,10 @@ class QuizSpreadsheetService
|
|||||||
/** @throws SpreadsheetDataException */
|
/** @throws SpreadsheetDataException */
|
||||||
public function xlsxToQuiz(Quiz $quiz, File $file): void
|
public function xlsxToQuiz(Quiz $quiz, File $file): void
|
||||||
{
|
{
|
||||||
|
if (!$this->isSpreadsheetFile($file)) {
|
||||||
|
throw new \InvalidArgumentException('File must be a valid XLSX spreadsheet');
|
||||||
|
}
|
||||||
|
|
||||||
$spreadsheet = $this->readSheet($file);
|
$spreadsheet = $this->readSheet($file);
|
||||||
$sheet = $spreadsheet->getSheet($spreadsheet->getFirstSheetIndex());
|
$sheet = $spreadsheet->getSheet($spreadsheet->getFirstSheetIndex());
|
||||||
|
|
||||||
@@ -112,7 +116,10 @@ class QuizSpreadsheetService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function quizToXlsx(Quiz $quiz): void {}
|
public function quizToXlsx(Quiz $quiz): void
|
||||||
|
{
|
||||||
|
throw new \Exception('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
private function toXlsx(Spreadsheet $spreadsheet): \Closure
|
private function toXlsx(Spreadsheet $spreadsheet): \Closure
|
||||||
{
|
{
|
||||||
@@ -120,4 +127,9 @@ class QuizSpreadsheetService
|
|||||||
|
|
||||||
return static fn () => $writer->save('php://output');
|
return static fn () => $writer->save('php://output');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function isSpreadsheetFile(File $file): bool
|
||||||
|
{
|
||||||
|
return 'xlsx' === $file->getExtension();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
symfony.lock
12
symfony.lock
@@ -109,6 +109,18 @@
|
|||||||
"config/packages/sentry.yaml"
|
"config/packages/sentry.yaml"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"stof/doctrine-extensions-bundle": {
|
||||||
|
"version": "1.14",
|
||||||
|
"recipe": {
|
||||||
|
"repo": "github.com/symfony/recipes-contrib",
|
||||||
|
"branch": "main",
|
||||||
|
"version": "1.2",
|
||||||
|
"ref": "e805aba9eff5372e2d149a9ff56566769e22819d"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"config/packages/stof_doctrine_extensions.yaml"
|
||||||
|
]
|
||||||
|
},
|
||||||
"symfony/asset-mapper": {
|
"symfony/asset-mapper": {
|
||||||
"version": "7.2",
|
"version": "7.2",
|
||||||
"recipe": {
|
"recipe": {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use PHPUnit\Framework\MockObject\Stub;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||||
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
|
||||||
|
use Symfony\Component\Security\Core\User\UserInterface;
|
||||||
use Tvdt\Entity\Answer;
|
use Tvdt\Entity\Answer;
|
||||||
use Tvdt\Entity\Candidate;
|
use Tvdt\Entity\Candidate;
|
||||||
use Tvdt\Entity\Elimination;
|
use Tvdt\Entity\Elimination;
|
||||||
@@ -53,27 +54,57 @@ final class SeasonVoterTest extends TestCase
|
|||||||
{
|
{
|
||||||
$season = self::createStub(Season::class);
|
$season = self::createStub(Season::class);
|
||||||
$season->method('isOwner')->willReturn(true);
|
$season->method('isOwner')->willReturn(true);
|
||||||
|
yield 'Season' => [$season];
|
||||||
$quiz = self::createStub(Quiz::class);
|
|
||||||
$quiz->season = $season;
|
|
||||||
|
|
||||||
$elimination = self::createStub(Elimination::class);
|
|
||||||
$elimination->quiz = $quiz;
|
|
||||||
|
|
||||||
$candidate = self::createStub(Candidate::class);
|
$candidate = self::createStub(Candidate::class);
|
||||||
$candidate->season = $season;
|
$candidate->season = $season;
|
||||||
|
yield 'Candidate' => [$candidate];
|
||||||
|
|
||||||
|
$quiz = self::createStub(Quiz::class);
|
||||||
|
$quiz->season = $season;
|
||||||
|
yield 'Quiz' => [$quiz];
|
||||||
|
|
||||||
|
$elimination = self::createStub(Elimination::class);
|
||||||
|
$elimination->quiz = $quiz;
|
||||||
|
yield 'Elimination' => [$elimination];
|
||||||
|
|
||||||
$question = self::createStub(Question::class);
|
$question = self::createStub(Question::class);
|
||||||
$question->quiz = $quiz;
|
$question->quiz = $quiz;
|
||||||
|
yield 'Question' => [$question];
|
||||||
|
|
||||||
$answer = self::createStub(Answer::class);
|
$answer = self::createStub(Answer::class);
|
||||||
$answer->question = $question;
|
$answer->question = $question;
|
||||||
|
|
||||||
yield 'Season' => [$season];
|
|
||||||
yield 'Elimination' => [$elimination];
|
|
||||||
yield 'Quiz' => [$quiz];
|
|
||||||
yield 'Candidate' => [$candidate];
|
|
||||||
yield 'Question' => [$question];
|
|
||||||
yield 'Answer' => [$answer];
|
yield 'Answer' => [$answer];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testWrongUserTypeReturnFalse(): void
|
||||||
|
{
|
||||||
|
$user = self::createStub(UserInterface::class);
|
||||||
|
$token = $this->createStub(TokenInterface::class);
|
||||||
|
$token->method('getUser')->willReturn($user);
|
||||||
|
|
||||||
|
$this->assertSame(VoterInterface::ACCESS_DENIED, $this->seasonVoter->vote($token, new Season(), ['SEASON_EDIT']));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAdminCanDoAnything(): void
|
||||||
|
{
|
||||||
|
$user = new User();
|
||||||
|
$user->roles = ['ROLE_ADMIN'];
|
||||||
|
$token = $this->createStub(TokenInterface::class);
|
||||||
|
$token->method('getUser')->willReturn($user);
|
||||||
|
|
||||||
|
$this->assertSame(VoterInterface::ACCESS_GRANTED, $this->seasonVoter->vote($token, new Season(), ['SEASON_EDIT']));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRandomClassWillAbstain(): void
|
||||||
|
{
|
||||||
|
$subject = new \stdClass();
|
||||||
|
$this->assertSame(VoterInterface::ACCESS_ABSTAIN, $this->seasonVoter->vote($this->token, $subject, ['SEASON_EDIT']));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRandomSunjectWillAbstain(): void
|
||||||
|
{
|
||||||
|
$subject = new Season();
|
||||||
|
$this->assertSame(VoterInterface::ACCESS_ABSTAIN, $this->seasonVoter->vote($this->token, $subject, ['DO_NOTHING']));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user