diff --git a/.env b/.env
index 08f2977..f8efe0f 100644
--- a/.env
+++ b/.env
@@ -36,3 +36,4 @@ MAILER_DSN=null://null
###> sentry/sentry-symfony ###
SENTRY_DSN=
###< sentry/sentry-symfony ###
+XDEBUG_MODE=coverage
diff --git a/.env.test b/.env.test
index 52a25f1..e2b1fb1 100644
--- a/.env.test
+++ b/.env.test
@@ -1,4 +1,3 @@
# define your env variables for the test env here
KERNEL_CLASS='Tvdt\Kernel'
APP_SECRET='$ecretf0rt3st'
-SYMFONY_DEPRECATIONS_HELPER=999999
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0034028..25bd701 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -57,6 +57,8 @@ jobs:
run: docker compose exec -T php bin/console -e test doctrine:database:create
- name: Run migrations
run: docker compose exec -T php bin/console -e test doctrine:migrations:migrate --no-interaction
+ - 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
diff --git a/.idea/TijdVoorDeTest.iml b/.idea/TijdVoorDeTest.iml
index 19e2f78..b6ef210 100644
--- a/.idea/TijdVoorDeTest.iml
+++ b/.idea/TijdVoorDeTest.iml
@@ -165,6 +165,9 @@
+
+
+
diff --git a/.idea/php-test-framework.xml b/.idea/php-test-framework.xml
index 527878e..6a33060 100644
--- a/.idea/php-test-framework.xml
+++ b/.idea/php-test-framework.xml
@@ -5,7 +5,7 @@
-
+
diff --git a/.idea/php.xml b/.idea/php.xml
index 697eb1b..2230a34 100644
--- a/.idea/php.xml
+++ b/.idea/php.xml
@@ -36,165 +36,169 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
@@ -273,7 +277,7 @@
-
+
@@ -288,8 +292,7 @@
-
-
+
diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php
index 0b5a012..4de2e7d 100644
--- a/.php-cs-fixer.dist.php
+++ b/.php-cs-fixer.dist.php
@@ -9,6 +9,7 @@ $finder = new Finder()
->in(__DIR__)
->exclude('var')
->exclude('bin')
+ ->notPath(['config/reference.php'])
;
return new Config()
@@ -24,7 +25,6 @@ return new Config()
'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,
@@ -36,4 +36,5 @@ return new Config()
])
->setRiskyAllowed(true)
->setFinder($finder)
+ ->setUnsupportedPhpVersionAllowed(true)
;
diff --git a/Dockerfile b/Dockerfile
index c45d53b..58539a8 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,7 +1,7 @@
#syntax=docker/dockerfile:1
# Versions
-FROM dunglas/frankenphp:1-php8.4 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
@@ -72,7 +72,7 @@ RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
RUN set -eux; \
install-php-extensions \
- xdebug \
+ xdebug/xdebug@3.5.0alpha3 \
;
COPY --link frankenphp/conf.d/20-app.dev.ini $PHP_INI_DIR/app.conf.d/
diff --git a/Justfile b/Justfile
index e261941..750a6a6 100644
--- a/Justfile
+++ b/Justfile
@@ -20,7 +20,7 @@ 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
+ 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
@@ -39,3 +39,9 @@ phpstan *args:
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
diff --git a/composer.json b/composer.json
index 9db9615..bcafdc2 100644
--- a/composer.json
+++ b/composer.json
@@ -6,66 +6,68 @@
"minimum-stability": "stable",
"prefer-stable": true,
"require": {
- "php": ">=8.4",
+ "php": ">=8.5",
"ext-ctype": "*",
"ext-iconv": "*",
"doctrine/dbal": "^4.3.4",
"doctrine/doctrine-bundle": "^3.0",
- "doctrine/doctrine-migrations-bundle": "^3.5.0",
- "doctrine/orm": "^3.5.2",
- "martin-georgiev/postgresql-for-doctrine": "^3.5.1",
- "phpdocumentor/reflection-docblock": "^5.6.3",
- "phpoffice/phpspreadsheet": "^5.1",
+ "doctrine/doctrine-migrations-bundle": "^3.7.0",
+ "doctrine/orm": "^3.5.7",
+ "martin-georgiev/postgresql-for-doctrine": "^3.6.2",
+ "phpdocumentor/reflection-docblock": "^5.6.4",
+ "phpoffice/phpspreadsheet": "^5.3",
"phpstan/phpdoc-parser": "^2.3",
"runtime/frankenphp-symfony": "^0.2.0",
"sentry/sentry-symfony": "^5.6",
- "symfony/asset": "7.3.*",
- "symfony/asset-mapper": "7.3.*",
- "symfony/brevo-mailer": "7.3.*",
- "symfony/console": "7.3.*",
- "symfony/dotenv": "7.3.*",
- "symfony/flex": "^2.8.2",
- "symfony/form": "7.3.*",
- "symfony/framework-bundle": "7.3.*",
- "symfony/mailer": "7.3.*",
- "symfony/property-access": "7.3.*",
- "symfony/property-info": "7.3.*",
- "symfony/runtime": "7.3.*",
- "symfony/security-bundle": "7.3.*",
- "symfony/security-csrf": "7.3.*",
- "symfony/serializer": "7.3.*",
- "symfony/translation": "7.3.*",
- "symfony/twig-bundle": "7.3.*",
- "symfony/uid": "7.3.*",
- "symfony/ux-turbo": "^2.30.0",
- "symfony/validator": "7.3.*",
- "symfony/yaml": "7.3.*",
+ "stof/doctrine-extensions-bundle": "^1.14",
+ "symfony/asset": "7.4.*",
+ "symfony/asset-mapper": "7.4.*",
+ "symfony/brevo-mailer": "7.4.*",
+ "symfony/console": "7.4.*",
+ "symfony/dotenv": "7.4.*",
+ "symfony/flex": "^2.10.0",
+ "symfony/form": "7.4.*",
+ "symfony/framework-bundle": "7.4.*",
+ "symfony/mailer": "7.4.*",
+ "symfony/property-access": "7.4.*",
+ "symfony/property-info": "7.4.*",
+ "symfony/runtime": "7.4.*",
+ "symfony/security-bundle": "7.4.*",
+ "symfony/security-csrf": "7.4.*",
+ "symfony/serializer": "7.4.*",
+ "symfony/translation": "7.4.*",
+ "symfony/twig-bundle": "7.4.*",
+ "symfony/uid": "7.4.*",
+ "symfony/ux-turbo": "^2.31.0",
+ "symfony/validator": "7.4.*",
+ "symfony/yaml": "7.4.*",
"symfonycasts/sass-bundle": "^0.8.3",
"symfonycasts/verify-email-bundle": "^1.17.4",
"thecodingmachine/safe": "^3.3.0",
- "twig/extra-bundle": "^3.21",
- "twig/intl-extra": "^3.21",
- "twig/twig": "^3.21.1"
+ "twig/extra-bundle": "^3.22.1",
+ "twig/intl-extra": "^3.22.1",
+ "twig/twig": "^3.22.0"
},
"require-dev": {
+ "dama/doctrine-test-bundle": "^8.4",
"doctrine/doctrine-fixtures-bundle": "^4.3",
- "friendsofphp/php-cs-fixer": "^3.89.0",
+ "friendsofphp/php-cs-fixer": "^3.90.0",
"phpstan/extension-installer": "^1.4.3",
- "phpstan/phpstan": "^2.1.31",
- "phpstan/phpstan-doctrine": "^2.0.10",
- "phpstan/phpstan-phpunit": "^2.0.7",
+ "phpstan/phpstan": "^2.1.32",
+ "phpstan/phpstan-doctrine": "^2.0.11",
+ "phpstan/phpstan-phpunit": "^2.0.8",
"phpstan/phpstan-symfony": "^2.0.8",
- "phpunit/phpunit": "^12.4.1",
- "rector/rector": "^2.2.3",
+ "phpunit/phpunit": "^12.4.4",
+ "rector/rector": "^2.2.9",
"roave/security-advisories": "dev-latest",
- "symfony/browser-kit": "7.3.*",
- "symfony/css-selector": "7.3.*",
- "symfony/maker-bundle": "^1.64.0",
- "symfony/phpunit-bridge": "7.3.*",
- "symfony/stopwatch": "7.3.*",
- "symfony/web-profiler-bundle": "7.3.*",
- "thecodingmachine/phpstan-safe-rule": "^1.4.1",
- "vincentlanglet/twig-cs-fixer": "^3.10.0"
+ "symfony/browser-kit": "7.4.*",
+ "symfony/css-selector": "7.4.*",
+ "symfony/maker-bundle": "^1.65.0",
+ "symfony/phpunit-bridge": "7.4.*",
+ "symfony/stopwatch": "7.4.*",
+ "symfony/web-profiler-bundle": "7.4.*",
+ "thecodingmachine/phpstan-safe-rule": "^1.4.3",
+ "vincentlanglet/twig-cs-fixer": "^3.11.0"
},
"config": {
"allow-plugins": {
@@ -98,7 +100,8 @@
"symfony/polyfill-php81": "*",
"symfony/polyfill-php82": "*",
"symfony/polyfill-php83": "*",
- "symfony/polyfill-php84": "*"
+ "symfony/polyfill-php84": "*",
+ "symfony/polyfill-php85": "*"
},
"scripts": {
"auto-scripts": {
@@ -119,7 +122,7 @@
"extra": {
"symfony": {
"allow-contrib": false,
- "require": "7.3.*",
+ "require": "7.4.*",
"docker": true
}
}
diff --git a/composer.lock b/composer.lock
index 7e9a55a..6dbd27d 100644
--- a/composer.lock
+++ b/composer.lock
@@ -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": "a87c0ab4f169484014962048bb246199",
+ "content-hash": "8cc636185a72a4be33cb8005bb2ec45d",
"packages": [
{
"name": "composer/pcre",
@@ -520,16 +520,16 @@
},
{
"name": "doctrine/doctrine-migrations-bundle",
- "version": "3.5.0",
+ "version": "3.7.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/DoctrineMigrationsBundle.git",
- "reference": "71c81279ca0e907c3edc718418b93fd63074856c"
+ "reference": "1e380c6dd8ac8488217f39cff6b77e367f1a644b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/71c81279ca0e907c3edc718418b93fd63074856c",
- "reference": "71c81279ca0e907c3edc718418b93fd63074856c",
+ "url": "https://api.github.com/repos/doctrine/DoctrineMigrationsBundle/zipball/1e380c6dd8ac8488217f39cff6b77e367f1a644b",
+ "reference": "1e380c6dd8ac8488217f39cff6b77e367f1a644b",
"shasum": ""
},
"require": {
@@ -537,7 +537,7 @@
"doctrine/migrations": "^3.2",
"php": "^7.2 || ^8.0",
"symfony/deprecation-contracts": "^2.1 || ^3",
- "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0"
+ "symfony/framework-bundle": "^5.4 || ^6.0 || ^7.0 || ^8.0"
},
"require-dev": {
"composer/semver": "^3.0",
@@ -549,8 +549,8 @@
"phpstan/phpstan-strict-rules": "^1.1 || ^2",
"phpstan/phpstan-symfony": "^1.3 || ^2",
"phpunit/phpunit": "^8.5 || ^9.5",
- "symfony/phpunit-bridge": "^6.3 || ^7",
- "symfony/var-exporter": "^5.4 || ^6 || ^7"
+ "symfony/phpunit-bridge": "^6.3 || ^7 || ^8",
+ "symfony/var-exporter": "^5.4 || ^6 || ^7 || ^8"
},
"type": "symfony-bundle",
"autoload": {
@@ -585,7 +585,7 @@
],
"support": {
"issues": "https://github.com/doctrine/DoctrineMigrationsBundle/issues",
- "source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/3.5.0"
+ "source": "https://github.com/doctrine/DoctrineMigrationsBundle/tree/3.7.0"
},
"funding": [
{
@@ -601,7 +601,7 @@
"type": "tidelift"
}
],
- "time": "2025-10-12T17:06:40+00:00"
+ "time": "2025-11-15T19:02:59+00:00"
},
{
"name": "doctrine/event-manager",
@@ -933,16 +933,16 @@
},
{
"name": "doctrine/migrations",
- "version": "3.9.4",
+ "version": "3.9.5",
"source": {
"type": "git",
"url": "https://github.com/doctrine/migrations.git",
- "reference": "1b88fcb812f2cd6e77c83d16db60e3cf1e35c66c"
+ "reference": "1b823afbc40f932dae8272574faee53f2755eac5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/migrations/zipball/1b88fcb812f2cd6e77c83d16db60e3cf1e35c66c",
- "reference": "1b88fcb812f2cd6e77c83d16db60e3cf1e35c66c",
+ "url": "https://api.github.com/repos/doctrine/migrations/zipball/1b823afbc40f932dae8272574faee53f2755eac5",
+ "reference": "1b823afbc40f932dae8272574faee53f2755eac5",
"shasum": ""
},
"require": {
@@ -952,15 +952,15 @@
"doctrine/event-manager": "^1.2 || ^2.0",
"php": "^8.1",
"psr/log": "^1.1.3 || ^2 || ^3",
- "symfony/console": "^5.4 || ^6.0 || ^7.0",
- "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0",
- "symfony/var-exporter": "^6.2 || ^7.0"
+ "symfony/console": "^5.4 || ^6.0 || ^7.0 || ^8.0",
+ "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0 || ^8.0",
+ "symfony/var-exporter": "^6.2 || ^7.0 || ^8.0"
},
"conflict": {
"doctrine/orm": "<2.12 || >=4"
},
"require-dev": {
- "doctrine/coding-standard": "^13",
+ "doctrine/coding-standard": "^14",
"doctrine/orm": "^2.13 || ^3",
"doctrine/persistence": "^2 || ^3 || ^4",
"doctrine/sql-formatter": "^1.0",
@@ -972,9 +972,9 @@
"phpstan/phpstan-strict-rules": "^2",
"phpstan/phpstan-symfony": "^2",
"phpunit/phpunit": "^10.3 || ^11.0 || ^12.0",
- "symfony/cache": "^5.4 || ^6.0 || ^7.0",
- "symfony/process": "^5.4 || ^6.0 || ^7.0",
- "symfony/yaml": "^5.4 || ^6.0 || ^7.0"
+ "symfony/cache": "^5.4 || ^6.0 || ^7.0 || ^8.0",
+ "symfony/process": "^5.4 || ^6.0 || ^7.0 || ^8.0",
+ "symfony/yaml": "^5.4 || ^6.0 || ^7.0 || ^8.0"
},
"suggest": {
"doctrine/sql-formatter": "Allows to generate formatted SQL with the diff command.",
@@ -1016,7 +1016,7 @@
],
"support": {
"issues": "https://github.com/doctrine/migrations/issues",
- "source": "https://github.com/doctrine/migrations/tree/3.9.4"
+ "source": "https://github.com/doctrine/migrations/tree/3.9.5"
},
"funding": [
{
@@ -1032,20 +1032,20 @@
"type": "tidelift"
}
],
- "time": "2025-08-19T06:41:07+00:00"
+ "time": "2025-11-20T11:15:36+00:00"
},
{
"name": "doctrine/orm",
- "version": "3.5.3",
+ "version": "3.5.7",
"source": {
"type": "git",
"url": "https://github.com/doctrine/orm.git",
- "reference": "1220edf9535303feb6dbfcf171beeef842fc9e1c"
+ "reference": "f18de9d569f00ed6eb9dac4b33c7844d705d17da"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/orm/zipball/1220edf9535303feb6dbfcf171beeef842fc9e1c",
- "reference": "1220edf9535303feb6dbfcf171beeef842fc9e1c",
+ "url": "https://api.github.com/repos/doctrine/orm/zipball/f18de9d569f00ed6eb9dac4b33c7844d705d17da",
+ "reference": "f18de9d569f00ed6eb9dac4b33c7844d705d17da",
"shasum": ""
},
"require": {
@@ -1069,7 +1069,7 @@
"phpbench/phpbench": "^1.0",
"phpdocumentor/guides-cli": "^1.4",
"phpstan/extension-installer": "^1.4",
- "phpstan/phpstan": "2.1.22",
+ "phpstan/phpstan": "2.1.23",
"phpstan/phpstan-deprecation-rules": "^2",
"phpunit/phpunit": "^10.5.0 || ^11.5",
"psr/log": "^1 || ^2 || ^3",
@@ -1119,9 +1119,9 @@
],
"support": {
"issues": "https://github.com/doctrine/orm/issues",
- "source": "https://github.com/doctrine/orm/tree/3.5.3"
+ "source": "https://github.com/doctrine/orm/tree/3.5.7"
},
- "time": "2025-10-27T22:06:52+00:00"
+ "time": "2025-11-11T18:27:40+00:00"
},
{
"name": "doctrine/persistence",
@@ -1218,26 +1218,26 @@
},
{
"name": "doctrine/sql-formatter",
- "version": "1.5.2",
+ "version": "1.5.3",
"source": {
"type": "git",
"url": "https://github.com/doctrine/sql-formatter.git",
- "reference": "d6d00aba6fd2957fe5216fe2b7673e9985db20c8"
+ "reference": "a8af23a8e9d622505baa2997465782cbe8bb7fc7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/d6d00aba6fd2957fe5216fe2b7673e9985db20c8",
- "reference": "d6d00aba6fd2957fe5216fe2b7673e9985db20c8",
+ "url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/a8af23a8e9d622505baa2997465782cbe8bb7fc7",
+ "reference": "a8af23a8e9d622505baa2997465782cbe8bb7fc7",
"shasum": ""
},
"require": {
"php": "^8.1"
},
"require-dev": {
- "doctrine/coding-standard": "^12",
- "ergebnis/phpunit-slow-test-detector": "^2.14",
- "phpstan/phpstan": "^1.10",
- "phpunit/phpunit": "^10.5"
+ "doctrine/coding-standard": "^14",
+ "ergebnis/phpunit-slow-test-detector": "^2.20",
+ "phpstan/phpstan": "^2.1.31",
+ "phpunit/phpunit": "^10.5.58"
},
"bin": [
"bin/sql-formatter"
@@ -1267,9 +1267,9 @@
],
"support": {
"issues": "https://github.com/doctrine/sql-formatter/issues",
- "source": "https://github.com/doctrine/sql-formatter/tree/1.5.2"
+ "source": "https://github.com/doctrine/sql-formatter/tree/1.5.3"
},
- "time": "2025-01-24T11:45:48+00:00"
+ "time": "2025-10-26T09:35:14+00:00"
},
{
"name": "egulias/email-validator",
@@ -1338,6 +1338,138 @@
],
"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",
"version": "2.8.0",
@@ -1701,16 +1833,16 @@
},
{
"name": "martin-georgiev/postgresql-for-doctrine",
- "version": "v3.5.1",
+ "version": "v3.6.2",
"source": {
"type": "git",
"url": "https://github.com/martin-georgiev/postgresql-for-doctrine.git",
- "reference": "5d1621e48edd7c7306cf2b9e73e374727867d6af"
+ "reference": "266820d371bd6e407ea68ff7e88f436269292cc0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/martin-georgiev/postgresql-for-doctrine/zipball/5d1621e48edd7c7306cf2b9e73e374727867d6af",
- "reference": "5d1621e48edd7c7306cf2b9e73e374727867d6af",
+ "url": "https://api.github.com/repos/martin-georgiev/postgresql-for-doctrine/zipball/266820d371bd6e407ea68ff7e88f436269292cc0",
+ "reference": "266820d371bd6e407ea68ff7e88f436269292cc0",
"shasum": ""
},
"require": {
@@ -1718,24 +1850,24 @@
"ext-ctype": "*",
"ext-json": "*",
"ext-mbstring": "*",
- "php": "^8.1"
+ "php": "^8.1 <8.6"
},
"require-dev": {
"deptrac/deptrac": "^4.0",
"doctrine/orm": "~2.14||~3.0",
"ekino/phpstan-banned-code": "^3.0",
- "friendsofphp/php-cs-fixer": "^3.87.1",
- "phpstan/phpstan": "^2.1.22",
+ "friendsofphp/php-cs-fixer": "^3.90.0",
+ "phpstan/phpstan": "^2.1.32",
"phpstan/phpstan-deprecation-rules": "^2.0.3",
- "phpstan/phpstan-doctrine": "^2.0.4",
- "phpstan/phpstan-phpunit": "^2.0.7",
- "phpunit/phpunit": "^10.5.53",
- "rector/rector": "^2.1.5",
+ "phpstan/phpstan-doctrine": "^2.0.11",
+ "phpstan/phpstan-phpunit": "^2.0.8",
+ "phpunit/phpunit": "^10.5.58",
+ "rector/rector": "^2.2.8",
"symfony/cache": "^6.4||^7.0"
},
"suggest": {
"doctrine/orm": "~2.14||~3.0",
- "php": "^8.3"
+ "php": "^8.4"
},
"type": "library",
"autoload": {
@@ -1769,7 +1901,7 @@
],
"support": {
"issues": "https://github.com/martin-georgiev/postgresql-for-doctrine/issues",
- "source": "https://github.com/martin-georgiev/postgresql-for-doctrine/tree/v3.5.1"
+ "source": "https://github.com/martin-georgiev/postgresql-for-doctrine/tree/v3.6.2"
},
"funding": [
{
@@ -1781,7 +1913,7 @@
"type": "github"
}
],
- "time": "2025-09-12T10:54:26+00:00"
+ "time": "2025-11-25T23:53:36+00:00"
},
{
"name": "phpdocumentor/reflection-common",
@@ -1838,16 +1970,16 @@
},
{
"name": "phpdocumentor/reflection-docblock",
- "version": "5.6.3",
+ "version": "5.6.4",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
- "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9"
+ "reference": "90a04bcbf03784066f16038e87e23a0a83cee3c2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94f8051919d1b0369a6bcc7931d679a511c03fe9",
- "reference": "94f8051919d1b0369a6bcc7931d679a511c03fe9",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/90a04bcbf03784066f16038e87e23a0a83cee3c2",
+ "reference": "90a04bcbf03784066f16038e87e23a0a83cee3c2",
"shasum": ""
},
"require": {
@@ -1896,22 +2028,22 @@
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
"support": {
"issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
- "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.3"
+ "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.4"
},
- "time": "2025-08-01T19:43:32+00:00"
+ "time": "2025-11-17T21:13:10+00:00"
},
{
"name": "phpdocumentor/type-resolver",
- "version": "1.10.0",
+ "version": "1.12.0",
"source": {
"type": "git",
"url": "https://github.com/phpDocumentor/TypeResolver.git",
- "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a"
+ "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a",
- "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a",
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/92a98ada2b93d9b201a613cb5a33584dde25f195",
+ "reference": "92a98ada2b93d9b201a613cb5a33584dde25f195",
"shasum": ""
},
"require": {
@@ -1954,22 +2086,22 @@
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
"support": {
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
- "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0"
+ "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.12.0"
},
- "time": "2024-11-09T15:12:26+00:00"
+ "time": "2025-11-21T15:09:14+00:00"
},
{
"name": "phpoffice/phpspreadsheet",
- "version": "5.2.0",
+ "version": "5.3.0",
"source": {
"type": "git",
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
- "reference": "3b8994b3aac4b61018bc04fc8c441f4fd68c18eb"
+ "reference": "4d597c1aacdde1805a33c525b9758113ea0d90df"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/3b8994b3aac4b61018bc04fc8c441f4fd68c18eb",
- "reference": "3b8994b3aac4b61018bc04fc8c441f4fd68c18eb",
+ "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/4d597c1aacdde1805a33c525b9758113ea0d90df",
+ "reference": "4d597c1aacdde1805a33c525b9758113ea0d90df",
"shasum": ""
},
"require": {
@@ -2011,7 +2143,7 @@
},
"suggest": {
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
- "ext-intl": "PHP Internationalization Functions, regquired for NumberFormat Wizard",
+ "ext-intl": "PHP Internationalization Functions, required for NumberFormat Wizard",
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
@@ -2060,9 +2192,9 @@
],
"support": {
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
- "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/5.2.0"
+ "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/5.3.0"
},
- "time": "2025-10-26T15:54:22+00:00"
+ "time": "2025-11-24T15:47:10+00:00"
},
{
"name": "phpstan/phpdoc-parser",
@@ -2670,16 +2802,16 @@
},
{
"name": "sentry/sentry",
- "version": "4.17.0",
+ "version": "4.19.0",
"source": {
"type": "git",
"url": "https://github.com/getsentry/sentry-php.git",
- "reference": "62927369a572efc27ddbd89e466e17788329224b"
+ "reference": "1d29a07c8fb68ae9ad9bb8c3fecfaad3cbc23053"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/62927369a572efc27ddbd89e466e17788329224b",
- "reference": "62927369a572efc27ddbd89e466e17788329224b",
+ "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/1d29a07c8fb68ae9ad9bb8c3fecfaad3cbc23053",
+ "reference": "1d29a07c8fb68ae9ad9bb8c3fecfaad3cbc23053",
"shasum": ""
},
"require": {
@@ -2690,7 +2822,7 @@
"jean85/pretty-package-versions": "^1.5|^2.0.4",
"php": "^7.2|^8.0",
"psr/log": "^1.0|^2.0|^3.0",
- "symfony/options-resolver": "^4.4.30|^5.0.11|^6.0|^7.0"
+ "symfony/options-resolver": "^4.4.30|^5.0.11|^6.0|^7.0|^8.0"
},
"conflict": {
"raven/raven": "*"
@@ -2742,7 +2874,7 @@
],
"support": {
"issues": "https://github.com/getsentry/sentry-php/issues",
- "source": "https://github.com/getsentry/sentry-php/tree/4.17.0"
+ "source": "https://github.com/getsentry/sentry-php/tree/4.19.0"
},
"funding": [
{
@@ -2754,7 +2886,7 @@
"type": "custom"
}
],
- "time": "2025-10-20T12:57:02+00:00"
+ "time": "2025-11-27T14:53:55+00:00"
},
{
"name": "sentry/sentry-symfony",
@@ -2859,17 +2991,98 @@
"time": "2025-09-24T13:41:01+00:00"
},
{
- "name": "symfony/asset",
- "version": "v7.3.0",
+ "name": "stof/doctrine-extensions-bundle",
+ "version": "v1.14.0",
"source": {
"type": "git",
- "url": "https://github.com/symfony/asset.git",
- "reference": "56c4d9f759247c4e07d8549e3baf7493cb9c3e4b"
+ "url": "https://github.com/stof/StofDoctrineExtensionsBundle.git",
+ "reference": "bdf3eb10baeb497ac5985b8f78a6cf55862c2662"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/asset/zipball/56c4d9f759247c4e07d8549e3baf7493cb9c3e4b",
- "reference": "56c4d9f759247c4e07d8549e3baf7493cb9c3e4b",
+ "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",
+ "version": "v7.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/asset.git",
+ "reference": "0f7bccb9ffa1f373cbd659774d90629b2773464f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/asset/zipball/0f7bccb9ffa1f373cbd659774d90629b2773464f",
+ "reference": "0f7bccb9ffa1f373cbd659774d90629b2773464f",
"shasum": ""
},
"require": {
@@ -2879,9 +3092,9 @@
"symfony/http-foundation": "<6.4"
},
"require-dev": {
- "symfony/http-client": "^6.4|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0"
+ "symfony/http-client": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -2909,7 +3122,7 @@
"description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/asset/tree/v7.3.0"
+ "source": "https://github.com/symfony/asset/tree/v7.4.0"
},
"funding": [
{
@@ -2920,48 +3133,53 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2025-03-05T10:15:41+00:00"
+ "time": "2025-08-04T07:05:15+00:00"
},
{
"name": "symfony/asset-mapper",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/asset-mapper.git",
- "reference": "0c40c579e27244616cf0fe4d1759aab2ceb99a9a"
+ "reference": "90beb7ededfcfcf0ea2f58cac3c0340ee504f596"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/asset-mapper/zipball/0c40c579e27244616cf0fe4d1759aab2ceb99a9a",
- "reference": "0c40c579e27244616cf0fe4d1759aab2ceb99a9a",
+ "url": "https://api.github.com/repos/symfony/asset-mapper/zipball/90beb7ededfcfcf0ea2f58cac3c0340ee504f596",
+ "reference": "90beb7ededfcfcf0ea2f58cac3c0340ee504f596",
"shasum": ""
},
"require": {
"composer/semver": "^3.0",
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.1|^3",
- "symfony/filesystem": "^7.1",
- "symfony/http-client": "^6.4|^7.0"
+ "symfony/filesystem": "^7.1|^8.0",
+ "symfony/http-client": "^6.4|^7.0|^8.0"
},
"conflict": {
"symfony/framework-bundle": "<6.4"
},
"require-dev": {
- "symfony/asset": "^6.4|^7.0",
- "symfony/browser-kit": "^6.4|^7.0",
- "symfony/console": "^6.4|^7.0",
+ "symfony/asset": "^6.4|^7.0|^8.0",
+ "symfony/browser-kit": "^6.4|^7.0|^8.0",
+ "symfony/console": "^6.4.13|^7.1.6|^8.0",
"symfony/event-dispatcher-contracts": "^3.0",
- "symfony/finder": "^6.4|^7.0",
- "symfony/framework-bundle": "^6.4|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/process": "^6.4|^7.0",
- "symfony/web-link": "^6.4|^7.0"
+ "symfony/finder": "^6.4|^7.0|^8.0",
+ "symfony/framework-bundle": "^6.4.13|^7.1.6|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4.13|^7.1.6|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0",
+ "symfony/runtime": "^6.4.13|^7.1.6|^8.0",
+ "symfony/web-link": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -2989,7 +3207,7 @@
"description": "Maps directories of assets & makes them available in a public directory with versioned filenames.",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/asset-mapper/tree/v7.3.4"
+ "source": "https://github.com/symfony/asset-mapper/tree/v7.4.0"
},
"funding": [
{
@@ -3009,32 +3227,32 @@
"type": "tidelift"
}
],
- "time": "2025-09-22T15:31:00+00:00"
+ "time": "2025-11-21T13:17:08+00:00"
},
{
"name": "symfony/brevo-mailer",
- "version": "v7.3.2",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/brevo-mailer.git",
- "reference": "e3efdac57c76eb0a504c2000aaa53abf370ea4ef"
+ "reference": "f1ef26ffe147e9185531030fc1503ed7b63fa0ef"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/brevo-mailer/zipball/e3efdac57c76eb0a504c2000aaa53abf370ea4ef",
- "reference": "e3efdac57c76eb0a504c2000aaa53abf370ea4ef",
+ "url": "https://api.github.com/repos/symfony/brevo-mailer/zipball/f1ef26ffe147e9185531030fc1503ed7b63fa0ef",
+ "reference": "f1ef26ffe147e9185531030fc1503ed7b63fa0ef",
"shasum": ""
},
"require": {
- "php": ">=8.1",
- "symfony/mailer": "^7.2"
+ "php": ">=8.2",
+ "symfony/mailer": "^7.2|^8.0"
},
"conflict": {
"symfony/mime": "<6.2"
},
"require-dev": {
- "symfony/http-client": "^6.3|^7.0",
- "symfony/webhook": "^6.3|^7.0"
+ "symfony/http-client": "^6.3|^7.0|^8.0",
+ "symfony/webhook": "^6.3|^7.0|^8.0"
},
"type": "symfony-mailer-bridge",
"autoload": {
@@ -3062,7 +3280,7 @@
"description": "Symfony Brevo Mailer Bridge",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/brevo-mailer/tree/v7.3.2"
+ "source": "https://github.com/symfony/brevo-mailer/tree/v7.4.0"
},
"funding": [
{
@@ -3082,20 +3300,20 @@
"type": "tidelift"
}
],
- "time": "2025-07-24T11:52:02+00:00"
+ "time": "2025-08-04T08:00:56+00:00"
},
{
"name": "symfony/cache",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/cache.git",
- "reference": "bf8afc8ffd4bfd3d9c373e417f041d9f1e5b863f"
+ "reference": "a7a1325a5de2e54ddb45fda002ff528162e48293"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/cache/zipball/bf8afc8ffd4bfd3d9c373e417f041d9f1e5b863f",
- "reference": "bf8afc8ffd4bfd3d9c373e417f041d9f1e5b863f",
+ "url": "https://api.github.com/repos/symfony/cache/zipball/a7a1325a5de2e54ddb45fda002ff528162e48293",
+ "reference": "a7a1325a5de2e54ddb45fda002ff528162e48293",
"shasum": ""
},
"require": {
@@ -3103,12 +3321,14 @@
"psr/cache": "^2.0|^3.0",
"psr/log": "^1.1|^2|^3",
"symfony/cache-contracts": "^3.6",
- "symfony/deprecation-contracts": "^2.5|^3.0",
+ "symfony/deprecation-contracts": "^2.5|^3",
"symfony/service-contracts": "^2.5|^3",
- "symfony/var-exporter": "^6.4|^7.0"
+ "symfony/var-exporter": "^6.4|^7.0|^8.0"
},
"conflict": {
"doctrine/dbal": "<3.6",
+ "ext-redis": "<6.1",
+ "ext-relay": "<0.12.1",
"symfony/dependency-injection": "<6.4",
"symfony/http-kernel": "<6.4",
"symfony/var-dumper": "<6.4"
@@ -3123,13 +3343,13 @@
"doctrine/dbal": "^3.6|^4",
"predis/predis": "^1.1|^2.0",
"psr/simple-cache": "^1.0|^2.0|^3.0",
- "symfony/clock": "^6.4|^7.0",
- "symfony/config": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/filesystem": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/messenger": "^6.4|^7.0",
- "symfony/var-dumper": "^6.4|^7.0"
+ "symfony/clock": "^6.4|^7.0|^8.0",
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/filesystem": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/messenger": "^6.4|^7.0|^8.0",
+ "symfony/var-dumper": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -3164,7 +3384,7 @@
"psr6"
],
"support": {
- "source": "https://github.com/symfony/cache/tree/v7.3.4"
+ "source": "https://github.com/symfony/cache/tree/v7.4.0"
},
"funding": [
{
@@ -3184,7 +3404,7 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T10:12:26+00:00"
+ "time": "2025-11-16T10:14:42+00:00"
},
{
"name": "symfony/cache-contracts",
@@ -3264,16 +3484,16 @@
},
{
"name": "symfony/clock",
- "version": "v7.3.0",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/clock.git",
- "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24"
+ "reference": "9169f24776edde469914c1e7a1442a50f7a4e110"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/clock/zipball/b81435fbd6648ea425d1ee96a2d8e68f4ceacd24",
- "reference": "b81435fbd6648ea425d1ee96a2d8e68f4ceacd24",
+ "url": "https://api.github.com/repos/symfony/clock/zipball/9169f24776edde469914c1e7a1442a50f7a4e110",
+ "reference": "9169f24776edde469914c1e7a1442a50f7a4e110",
"shasum": ""
},
"require": {
@@ -3318,7 +3538,7 @@
"time"
],
"support": {
- "source": "https://github.com/symfony/clock/tree/v7.3.0"
+ "source": "https://github.com/symfony/clock/tree/v7.4.0"
},
"funding": [
{
@@ -3329,31 +3549,35 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2024-09-25T14:21:43+00:00"
+ "time": "2025-11-12T15:39:26+00:00"
},
{
"name": "symfony/config",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
- "reference": "8a09223170046d2cfda3d2e11af01df2c641e961"
+ "reference": "f76c74e93bce2b9285f2dad7fbd06fa8182a7a41"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/8a09223170046d2cfda3d2e11af01df2c641e961",
- "reference": "8a09223170046d2cfda3d2e11af01df2c641e961",
+ "url": "https://api.github.com/repos/symfony/config/zipball/f76c74e93bce2b9285f2dad7fbd06fa8182a7a41",
+ "reference": "f76c74e93bce2b9285f2dad7fbd06fa8182a7a41",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/filesystem": "^7.1",
+ "symfony/filesystem": "^7.1|^8.0",
"symfony/polyfill-ctype": "~1.8"
},
"conflict": {
@@ -3361,11 +3585,11 @@
"symfony/service-contracts": "<2.5"
},
"require-dev": {
- "symfony/event-dispatcher": "^6.4|^7.0",
- "symfony/finder": "^6.4|^7.0",
- "symfony/messenger": "^6.4|^7.0",
+ "symfony/event-dispatcher": "^6.4|^7.0|^8.0",
+ "symfony/finder": "^6.4|^7.0|^8.0",
+ "symfony/messenger": "^6.4|^7.0|^8.0",
"symfony/service-contracts": "^2.5|^3",
- "symfony/yaml": "^6.4|^7.0"
+ "symfony/yaml": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -3393,7 +3617,7 @@
"description": "Helps you find, load, combine, autofill and validate configuration values of any kind",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/config/tree/v7.3.4"
+ "source": "https://github.com/symfony/config/tree/v7.4.0"
},
"funding": [
{
@@ -3413,20 +3637,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-22T12:46:16+00:00"
+ "time": "2025-11-27T13:27:24+00:00"
},
{
"name": "symfony/console",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db"
+ "reference": "0bc0f45254b99c58d45a8fbf9fb955d46cbd1bb8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/2b9c5fafbac0399a20a2e82429e2bd735dcfb7db",
- "reference": "2b9c5fafbac0399a20a2e82429e2bd735dcfb7db",
+ "url": "https://api.github.com/repos/symfony/console/zipball/0bc0f45254b99c58d45a8fbf9fb955d46cbd1bb8",
+ "reference": "0bc0f45254b99c58d45a8fbf9fb955d46cbd1bb8",
"shasum": ""
},
"require": {
@@ -3434,7 +3658,7 @@
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-mbstring": "~1.0",
"symfony/service-contracts": "^2.5|^3",
- "symfony/string": "^7.2"
+ "symfony/string": "^7.2|^8.0"
},
"conflict": {
"symfony/dependency-injection": "<6.4",
@@ -3448,16 +3672,16 @@
},
"require-dev": {
"psr/log": "^1|^2|^3",
- "symfony/config": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/event-dispatcher": "^6.4|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/lock": "^6.4|^7.0",
- "symfony/messenger": "^6.4|^7.0",
- "symfony/process": "^6.4|^7.0",
- "symfony/stopwatch": "^6.4|^7.0",
- "symfony/var-dumper": "^6.4|^7.0"
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/event-dispatcher": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/lock": "^6.4|^7.0|^8.0",
+ "symfony/messenger": "^6.4|^7.0|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0",
+ "symfony/stopwatch": "^6.4|^7.0|^8.0",
+ "symfony/var-dumper": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -3491,7 +3715,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v7.3.4"
+ "source": "https://github.com/symfony/console/tree/v7.4.0"
},
"funding": [
{
@@ -3511,28 +3735,28 @@
"type": "tidelift"
}
],
- "time": "2025-09-22T15:31:00+00:00"
+ "time": "2025-11-27T13:27:24+00:00"
},
{
"name": "symfony/dependency-injection",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/dependency-injection.git",
- "reference": "82119812ab0bf3425c1234d413efd1b19bb92ae4"
+ "reference": "3972ca7bbd649467b21a54870721b9e9f3652f9b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/82119812ab0bf3425c1234d413efd1b19bb92ae4",
- "reference": "82119812ab0bf3425c1234d413efd1b19bb92ae4",
+ "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/3972ca7bbd649467b21a54870721b9e9f3652f9b",
+ "reference": "3972ca7bbd649467b21a54870721b9e9f3652f9b",
"shasum": ""
},
"require": {
"php": ">=8.2",
"psr/container": "^1.1|^2.0",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/service-contracts": "^3.5",
- "symfony/var-exporter": "^6.4.20|^7.2.5"
+ "symfony/service-contracts": "^3.6",
+ "symfony/var-exporter": "^6.4.20|^7.2.5|^8.0"
},
"conflict": {
"ext-psr": "<1.1|>=2",
@@ -3545,9 +3769,9 @@
"symfony/service-implementation": "1.1|2.0|3.0"
},
"require-dev": {
- "symfony/config": "^6.4|^7.0",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/yaml": "^6.4|^7.0"
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/yaml": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -3575,7 +3799,7 @@
"description": "Allows you to standardize and centralize the way objects are constructed in your application",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/dependency-injection/tree/v7.3.4"
+ "source": "https://github.com/symfony/dependency-injection/tree/v7.4.0"
},
"funding": [
{
@@ -3595,7 +3819,7 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T10:12:26+00:00"
+ "time": "2025-11-27T13:27:24+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -3666,16 +3890,16 @@
},
{
"name": "symfony/doctrine-bridge",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/doctrine-bridge.git",
- "reference": "21cd48c34a47a0d0e303a590a67c3450fde55888"
+ "reference": "7b511891a81ca14e993b6c88fd35d6bf656085f7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/21cd48c34a47a0d0e303a590a67c3450fde55888",
- "reference": "21cd48c34a47a0d0e303a590a67c3450fde55888",
+ "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/7b511891a81ca14e993b6c88fd35d6bf656085f7",
+ "reference": "7b511891a81ca14e993b6c88fd35d6bf656085f7",
"shasum": ""
},
"require": {
@@ -3702,7 +3926,7 @@
"symfony/property-info": "<6.4",
"symfony/security-bundle": "<6.4",
"symfony/security-core": "<6.4",
- "symfony/validator": "<6.4"
+ "symfony/validator": "<7.4"
},
"require-dev": {
"doctrine/collections": "^1.8|^2.0",
@@ -3710,24 +3934,24 @@
"doctrine/dbal": "^3.6|^4",
"doctrine/orm": "^2.15|^3",
"psr/log": "^1|^2|^3",
- "symfony/cache": "^6.4|^7.0",
- "symfony/config": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/doctrine-messenger": "^6.4|^7.0",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/form": "^6.4.6|^7.0.6",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/lock": "^6.4|^7.0",
- "symfony/messenger": "^6.4|^7.0",
- "symfony/property-access": "^6.4|^7.0",
- "symfony/property-info": "^6.4|^7.0",
- "symfony/security-core": "^6.4|^7.0",
- "symfony/stopwatch": "^6.4|^7.0",
- "symfony/translation": "^6.4|^7.0",
- "symfony/type-info": "^7.1.8",
- "symfony/uid": "^6.4|^7.0",
- "symfony/validator": "^6.4|^7.0",
- "symfony/var-dumper": "^6.4|^7.0"
+ "symfony/cache": "^6.4|^7.0|^8.0",
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/doctrine-messenger": "^6.4|^7.0|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/form": "^7.2|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/lock": "^6.4|^7.0|^8.0",
+ "symfony/messenger": "^6.4|^7.0|^8.0",
+ "symfony/property-access": "^6.4|^7.0|^8.0",
+ "symfony/property-info": "^6.4|^7.0|^8.0",
+ "symfony/security-core": "^6.4|^7.0|^8.0",
+ "symfony/stopwatch": "^6.4|^7.0|^8.0",
+ "symfony/translation": "^6.4|^7.0|^8.0",
+ "symfony/type-info": "^7.1.8|^8.0",
+ "symfony/uid": "^6.4|^7.0|^8.0",
+ "symfony/validator": "^7.4|^8.0",
+ "symfony/var-dumper": "^6.4|^7.0|^8.0"
},
"type": "symfony-bridge",
"autoload": {
@@ -3755,7 +3979,7 @@
"description": "Provides integration for Doctrine with various Symfony components",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/doctrine-bridge/tree/v7.3.4"
+ "source": "https://github.com/symfony/doctrine-bridge/tree/v7.4.0"
},
"funding": [
{
@@ -3775,20 +3999,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-24T09:56:23+00:00"
+ "time": "2025-11-04T03:05:49+00:00"
},
{
"name": "symfony/dotenv",
- "version": "v7.3.2",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/dotenv.git",
- "reference": "2192790a11f9e22cbcf9dc705a3ff22a5503923a"
+ "reference": "1658a4d34df028f3d93bcdd8e81f04423925a364"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dotenv/zipball/2192790a11f9e22cbcf9dc705a3ff22a5503923a",
- "reference": "2192790a11f9e22cbcf9dc705a3ff22a5503923a",
+ "url": "https://api.github.com/repos/symfony/dotenv/zipball/1658a4d34df028f3d93bcdd8e81f04423925a364",
+ "reference": "1658a4d34df028f3d93bcdd8e81f04423925a364",
"shasum": ""
},
"require": {
@@ -3799,8 +4023,8 @@
"symfony/process": "<6.4"
},
"require-dev": {
- "symfony/console": "^6.4|^7.0",
- "symfony/process": "^6.4|^7.0"
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -3833,7 +4057,7 @@
"environment"
],
"support": {
- "source": "https://github.com/symfony/dotenv/tree/v7.3.2"
+ "source": "https://github.com/symfony/dotenv/tree/v7.4.0"
},
"funding": [
{
@@ -3853,36 +4077,37 @@
"type": "tidelift"
}
],
- "time": "2025-07-10T08:29:33+00:00"
+ "time": "2025-11-16T10:14:42+00:00"
},
{
"name": "symfony/error-handler",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/error-handler.git",
- "reference": "99f81bc944ab8e5dae4f21b4ca9972698bbad0e4"
+ "reference": "48be2b0653594eea32dcef130cca1c811dcf25c2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/error-handler/zipball/99f81bc944ab8e5dae4f21b4ca9972698bbad0e4",
- "reference": "99f81bc944ab8e5dae4f21b4ca9972698bbad0e4",
+ "url": "https://api.github.com/repos/symfony/error-handler/zipball/48be2b0653594eea32dcef130cca1c811dcf25c2",
+ "reference": "48be2b0653594eea32dcef130cca1c811dcf25c2",
"shasum": ""
},
"require": {
"php": ">=8.2",
"psr/log": "^1|^2|^3",
- "symfony/var-dumper": "^6.4|^7.0"
+ "symfony/polyfill-php85": "^1.32",
+ "symfony/var-dumper": "^6.4|^7.0|^8.0"
},
"conflict": {
"symfony/deprecation-contracts": "<2.5",
"symfony/http-kernel": "<6.4"
},
"require-dev": {
- "symfony/console": "^6.4|^7.0",
+ "symfony/console": "^6.4|^7.0|^8.0",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/serializer": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/serializer": "^6.4|^7.0|^8.0",
"symfony/webpack-encore-bundle": "^1.0|^2.0"
},
"bin": [
@@ -3914,7 +4139,7 @@
"description": "Provides tools to manage errors and ease debugging PHP code",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/error-handler/tree/v7.3.4"
+ "source": "https://github.com/symfony/error-handler/tree/v7.4.0"
},
"funding": [
{
@@ -3934,20 +4159,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T10:12:26+00:00"
+ "time": "2025-11-05T14:29:59+00:00"
},
{
"name": "symfony/event-dispatcher",
- "version": "v7.3.3",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191"
+ "reference": "9dddcddff1ef974ad87b3708e4b442dc38b2261d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191",
- "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9dddcddff1ef974ad87b3708e4b442dc38b2261d",
+ "reference": "9dddcddff1ef974ad87b3708e4b442dc38b2261d",
"shasum": ""
},
"require": {
@@ -3964,13 +4189,14 @@
},
"require-dev": {
"psr/log": "^1|^2|^3",
- "symfony/config": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/error-handler": "^6.4|^7.0",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/error-handler": "^6.4|^7.0|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/framework-bundle": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
"symfony/service-contracts": "^2.5|^3",
- "symfony/stopwatch": "^6.4|^7.0"
+ "symfony/stopwatch": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -3998,7 +4224,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.3"
+ "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.0"
},
"funding": [
{
@@ -4018,7 +4244,7 @@
"type": "tidelift"
}
],
- "time": "2025-08-13T11:49:31+00:00"
+ "time": "2025-10-28T09:38:46+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
@@ -4098,16 +4324,16 @@
},
{
"name": "symfony/filesystem",
- "version": "v7.3.2",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd"
+ "reference": "d551b38811096d0be9c4691d406991b47c0c630a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/edcbb768a186b5c3f25d0643159a787d3e63b7fd",
- "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/d551b38811096d0be9c4691d406991b47c0c630a",
+ "reference": "d551b38811096d0be9c4691d406991b47c0c630a",
"shasum": ""
},
"require": {
@@ -4116,7 +4342,7 @@
"symfony/polyfill-mbstring": "~1.8"
},
"require-dev": {
- "symfony/process": "^6.4|^7.0"
+ "symfony/process": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -4144,7 +4370,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/filesystem/tree/v7.3.2"
+ "source": "https://github.com/symfony/filesystem/tree/v7.4.0"
},
"funding": [
{
@@ -4164,27 +4390,27 @@
"type": "tidelift"
}
],
- "time": "2025-07-07T08:17:47+00:00"
+ "time": "2025-11-27T13:27:24+00:00"
},
{
"name": "symfony/finder",
- "version": "v7.3.2",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe"
+ "reference": "340b9ed7320570f319028a2cbec46d40535e94bd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/2a6614966ba1074fa93dae0bc804227422df4dfe",
- "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/340b9ed7320570f319028a2cbec46d40535e94bd",
+ "reference": "340b9ed7320570f319028a2cbec46d40535e94bd",
"shasum": ""
},
"require": {
"php": ">=8.2"
},
"require-dev": {
- "symfony/filesystem": "^6.4|^7.0"
+ "symfony/filesystem": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -4212,7 +4438,7 @@
"description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/finder/tree/v7.3.2"
+ "source": "https://github.com/symfony/finder/tree/v7.4.0"
},
"funding": [
{
@@ -4232,35 +4458,36 @@
"type": "tidelift"
}
],
- "time": "2025-07-15T13:41:35+00:00"
+ "time": "2025-11-05T05:42:40+00:00"
},
{
"name": "symfony/flex",
- "version": "v2.8.2",
+ "version": "v2.10.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/flex.git",
- "reference": "f356aa35f3cf3d2f46c31d344c1098eb2d260426"
+ "reference": "9cd384775973eabbf6e8b05784dda279fc67c28d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/flex/zipball/f356aa35f3cf3d2f46c31d344c1098eb2d260426",
- "reference": "f356aa35f3cf3d2f46c31d344c1098eb2d260426",
+ "url": "https://api.github.com/repos/symfony/flex/zipball/9cd384775973eabbf6e8b05784dda279fc67c28d",
+ "reference": "9cd384775973eabbf6e8b05784dda279fc67c28d",
"shasum": ""
},
"require": {
"composer-plugin-api": "^2.1",
- "php": ">=8.0"
+ "php": ">=8.1"
},
"conflict": {
- "composer/semver": "<1.7.2"
+ "composer/semver": "<1.7.2",
+ "symfony/dotenv": "<5.4"
},
"require-dev": {
"composer/composer": "^2.1",
- "symfony/dotenv": "^5.4|^6.0",
- "symfony/filesystem": "^5.4|^6.0",
- "symfony/phpunit-bridge": "^5.4|^6.0",
- "symfony/process": "^5.4|^6.0"
+ "symfony/dotenv": "^6.4|^7.4|^8.0",
+ "symfony/filesystem": "^6.4|^7.4|^8.0",
+ "symfony/phpunit-bridge": "^6.4|^7.4|^8.0",
+ "symfony/process": "^6.4|^7.4|^8.0"
},
"type": "composer-plugin",
"extra": {
@@ -4284,7 +4511,7 @@
"description": "Composer plugin for Symfony",
"support": {
"issues": "https://github.com/symfony/flex/issues",
- "source": "https://github.com/symfony/flex/tree/v2.8.2"
+ "source": "https://github.com/symfony/flex/tree/v2.10.0"
},
"funding": [
{
@@ -4304,31 +4531,31 @@
"type": "tidelift"
}
],
- "time": "2025-08-22T07:17:23+00:00"
+ "time": "2025-11-16T09:38:19+00:00"
},
{
"name": "symfony/form",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/form.git",
- "reference": "7b3eee0f4d4dfd1ff1be70a27474197330c61736"
+ "reference": "00b8d61709b323749aef317950abd276f309597b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/form/zipball/7b3eee0f4d4dfd1ff1be70a27474197330c61736",
- "reference": "7b3eee0f4d4dfd1ff1be70a27474197330c61736",
+ "url": "https://api.github.com/repos/symfony/form/zipball/00b8d61709b323749aef317950abd276f309597b",
+ "reference": "00b8d61709b323749aef317950abd276f309597b",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/event-dispatcher": "^6.4|^7.0",
- "symfony/options-resolver": "^7.3",
+ "symfony/event-dispatcher": "^6.4|^7.0|^8.0",
+ "symfony/options-resolver": "^7.3|^8.0",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-intl-icu": "^1.21",
"symfony/polyfill-mbstring": "~1.0",
- "symfony/property-access": "^6.4|^7.0",
+ "symfony/property-access": "^6.4|^7.0|^8.0",
"symfony/service-contracts": "^2.5|^3"
},
"conflict": {
@@ -4338,26 +4565,28 @@
"symfony/error-handler": "<6.4",
"symfony/framework-bundle": "<6.4",
"symfony/http-kernel": "<6.4",
+ "symfony/intl": "<7.4",
"symfony/translation": "<6.4.3|>=7.0,<7.0.3",
"symfony/translation-contracts": "<2.5",
"symfony/twig-bridge": "<6.4"
},
"require-dev": {
"doctrine/collections": "^1.0|^2.0",
- "symfony/config": "^6.4|^7.0",
- "symfony/console": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/html-sanitizer": "^6.4|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/intl": "^6.4|^7.0",
- "symfony/security-core": "^6.4|^7.0",
- "symfony/security-csrf": "^6.4|^7.0",
- "symfony/translation": "^6.4.3|^7.0.3",
- "symfony/uid": "^6.4|^7.0",
- "symfony/validator": "^6.4|^7.0",
- "symfony/var-dumper": "^6.4|^7.0"
+ "symfony/clock": "^6.4|^7.0|^8.0",
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/html-sanitizer": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/intl": "^7.4|^8.0",
+ "symfony/security-core": "^6.4|^7.0|^8.0",
+ "symfony/security-csrf": "^6.4|^7.0|^8.0",
+ "symfony/translation": "^6.4.3|^7.0.3|^8.0",
+ "symfony/uid": "^6.4|^7.0|^8.0",
+ "symfony/validator": "^6.4.12|^7.1.5|^8.0",
+ "symfony/var-dumper": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -4385,7 +4614,7 @@
"description": "Allows to easily create, process and reuse HTML forms",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/form/tree/v7.3.4"
+ "source": "https://github.com/symfony/form/tree/v7.4.0"
},
"funding": [
{
@@ -4405,38 +4634,39 @@
"type": "tidelift"
}
],
- "time": "2025-09-22T15:31:00+00:00"
+ "time": "2025-11-20T12:20:24+00:00"
},
{
"name": "symfony/framework-bundle",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/framework-bundle.git",
- "reference": "b13e7cec5a144c8dba6f4233a2c53c00bc29e140"
+ "reference": "3c62a3437267ac55bcd40175689c74772250e943"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/b13e7cec5a144c8dba6f4233a2c53c00bc29e140",
- "reference": "b13e7cec5a144c8dba6f4233a2c53c00bc29e140",
+ "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/3c62a3437267ac55bcd40175689c74772250e943",
+ "reference": "3c62a3437267ac55bcd40175689c74772250e943",
"shasum": ""
},
"require": {
"composer-runtime-api": ">=2.1",
"ext-xml": "*",
"php": ">=8.2",
- "symfony/cache": "^6.4|^7.0",
- "symfony/config": "^7.3",
- "symfony/dependency-injection": "^7.2",
+ "symfony/cache": "^6.4.12|^7.0|^8.0",
+ "symfony/config": "^7.4|^8.0",
+ "symfony/dependency-injection": "^7.4|^8.0",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/error-handler": "^7.3",
- "symfony/event-dispatcher": "^6.4|^7.0",
- "symfony/filesystem": "^7.1",
- "symfony/finder": "^6.4|^7.0",
- "symfony/http-foundation": "^7.3",
- "symfony/http-kernel": "^7.2",
+ "symfony/error-handler": "^7.3|^8.0",
+ "symfony/event-dispatcher": "^6.4|^7.0|^8.0",
+ "symfony/filesystem": "^7.1|^8.0",
+ "symfony/finder": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^7.4|^8.0",
+ "symfony/http-kernel": "^7.4|^8.0",
"symfony/polyfill-mbstring": "~1.0",
- "symfony/routing": "^6.4|^7.0"
+ "symfony/polyfill-php85": "^1.32",
+ "symfony/routing": "^7.4|^8.0"
},
"conflict": {
"doctrine/persistence": "<1.3",
@@ -4448,14 +4678,12 @@
"symfony/console": "<6.4",
"symfony/dom-crawler": "<6.4",
"symfony/dotenv": "<6.4",
- "symfony/form": "<6.4",
+ "symfony/form": "<7.4",
"symfony/http-client": "<6.4",
- "symfony/json-streamer": ">=7.4",
"symfony/lock": "<6.4",
"symfony/mailer": "<6.4",
- "symfony/messenger": "<6.4",
+ "symfony/messenger": "<7.4",
"symfony/mime": "<6.4",
- "symfony/object-mapper": ">=7.4",
"symfony/property-access": "<6.4",
"symfony/property-info": "<6.4",
"symfony/runtime": "<6.4.13|>=7.0,<7.1.6",
@@ -4470,51 +4698,52 @@
"symfony/validator": "<6.4",
"symfony/web-profiler-bundle": "<6.4",
"symfony/webhook": "<7.2",
- "symfony/workflow": "<7.3.0-beta2"
+ "symfony/workflow": "<7.4"
},
"require-dev": {
"doctrine/persistence": "^1.3|^2|^3",
"dragonmantank/cron-expression": "^3.1",
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
"seld/jsonlint": "^1.10",
- "symfony/asset": "^6.4|^7.0",
- "symfony/asset-mapper": "^6.4|^7.0",
- "symfony/browser-kit": "^6.4|^7.0",
- "symfony/clock": "^6.4|^7.0",
- "symfony/console": "^6.4|^7.0",
- "symfony/css-selector": "^6.4|^7.0",
- "symfony/dom-crawler": "^6.4|^7.0",
- "symfony/dotenv": "^6.4|^7.0",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/form": "^6.4|^7.0",
- "symfony/html-sanitizer": "^6.4|^7.0",
- "symfony/http-client": "^6.4|^7.0",
- "symfony/json-streamer": "7.3.*",
- "symfony/lock": "^6.4|^7.0",
- "symfony/mailer": "^6.4|^7.0",
- "symfony/messenger": "^6.4|^7.0",
- "symfony/mime": "^6.4|^7.0",
- "symfony/notifier": "^6.4|^7.0",
- "symfony/object-mapper": "^v7.3.0-beta2",
+ "symfony/asset": "^6.4|^7.0|^8.0",
+ "symfony/asset-mapper": "^6.4|^7.0|^8.0",
+ "symfony/browser-kit": "^6.4|^7.0|^8.0",
+ "symfony/clock": "^6.4|^7.0|^8.0",
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/css-selector": "^6.4|^7.0|^8.0",
+ "symfony/dom-crawler": "^6.4|^7.0|^8.0",
+ "symfony/dotenv": "^6.4|^7.0|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/form": "^7.4|^8.0",
+ "symfony/html-sanitizer": "^6.4|^7.0|^8.0",
+ "symfony/http-client": "^6.4|^7.0|^8.0",
+ "symfony/json-streamer": "^7.3|^8.0",
+ "symfony/lock": "^6.4|^7.0|^8.0",
+ "symfony/mailer": "^6.4|^7.0|^8.0",
+ "symfony/messenger": "^7.4|^8.0",
+ "symfony/mime": "^6.4|^7.0|^8.0",
+ "symfony/notifier": "^6.4|^7.0|^8.0",
+ "symfony/object-mapper": "^7.3|^8.0",
"symfony/polyfill-intl-icu": "~1.0",
- "symfony/process": "^6.4|^7.0",
- "symfony/property-info": "^6.4|^7.0",
- "symfony/rate-limiter": "^6.4|^7.0",
- "symfony/scheduler": "^6.4.4|^7.0.4",
- "symfony/security-bundle": "^6.4|^7.0",
- "symfony/semaphore": "^6.4|^7.0",
- "symfony/serializer": "^7.2.5",
- "symfony/stopwatch": "^6.4|^7.0",
- "symfony/string": "^6.4|^7.0",
- "symfony/translation": "^7.3",
- "symfony/twig-bundle": "^6.4|^7.0",
- "symfony/type-info": "^7.1.8",
- "symfony/uid": "^6.4|^7.0",
- "symfony/validator": "^6.4|^7.0",
- "symfony/web-link": "^6.4|^7.0",
- "symfony/webhook": "^7.2",
- "symfony/workflow": "^7.3",
- "symfony/yaml": "^6.4|^7.0",
+ "symfony/process": "^6.4|^7.0|^8.0",
+ "symfony/property-info": "^6.4|^7.0|^8.0",
+ "symfony/rate-limiter": "^6.4|^7.0|^8.0",
+ "symfony/runtime": "^6.4.13|^7.1.6|^8.0",
+ "symfony/scheduler": "^6.4.4|^7.0.4|^8.0",
+ "symfony/security-bundle": "^6.4|^7.0|^8.0",
+ "symfony/semaphore": "^6.4|^7.0|^8.0",
+ "symfony/serializer": "^7.2.5|^8.0",
+ "symfony/stopwatch": "^6.4|^7.0|^8.0",
+ "symfony/string": "^6.4|^7.0|^8.0",
+ "symfony/translation": "^7.3|^8.0",
+ "symfony/twig-bundle": "^6.4|^7.0|^8.0",
+ "symfony/type-info": "^7.1.8|^8.0",
+ "symfony/uid": "^6.4|^7.0|^8.0",
+ "symfony/validator": "^7.4|^8.0",
+ "symfony/web-link": "^6.4|^7.0|^8.0",
+ "symfony/webhook": "^7.2|^8.0",
+ "symfony/workflow": "^7.4|^8.0",
+ "symfony/yaml": "^7.3|^8.0",
"twig/twig": "^3.12"
},
"type": "symfony-bundle",
@@ -4543,7 +4772,7 @@
"description": "Provides a tight integration between Symfony components and the Symfony full-stack framework",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/framework-bundle/tree/v7.3.4"
+ "source": "https://github.com/symfony/framework-bundle/tree/v7.4.0"
},
"funding": [
{
@@ -4563,20 +4792,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-17T05:51:54+00:00"
+ "time": "2025-11-27T13:27:24+00:00"
},
{
"name": "symfony/http-client",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-client.git",
- "reference": "4b62871a01c49457cf2a8e560af7ee8a94b87a62"
+ "reference": "ee5e0e0139ab506f6063a230e631bed677c650a4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-client/zipball/4b62871a01c49457cf2a8e560af7ee8a94b87a62",
- "reference": "4b62871a01c49457cf2a8e560af7ee8a94b87a62",
+ "url": "https://api.github.com/repos/symfony/http-client/zipball/ee5e0e0139ab506f6063a230e631bed677c650a4",
+ "reference": "ee5e0e0139ab506f6063a230e631bed677c650a4",
"shasum": ""
},
"require": {
@@ -4607,12 +4836,13 @@
"php-http/httplug": "^1.0|^2.0",
"psr/http-client": "^1.0",
"symfony/amphp-http-client-meta": "^1.0|^2.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/messenger": "^6.4|^7.0",
- "symfony/process": "^6.4|^7.0",
- "symfony/rate-limiter": "^6.4|^7.0",
- "symfony/stopwatch": "^6.4|^7.0"
+ "symfony/cache": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/messenger": "^6.4|^7.0|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0",
+ "symfony/rate-limiter": "^6.4|^7.0|^8.0",
+ "symfony/stopwatch": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -4643,7 +4873,7 @@
"http"
],
"support": {
- "source": "https://github.com/symfony/http-client/tree/v7.3.4"
+ "source": "https://github.com/symfony/http-client/tree/v7.4.0"
},
"funding": [
{
@@ -4663,7 +4893,7 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T10:12:26+00:00"
+ "time": "2025-11-20T12:32:50+00:00"
},
{
"name": "symfony/http-client-contracts",
@@ -4745,23 +4975,22 @@
},
{
"name": "symfony/http-foundation",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "c061c7c18918b1b64268771aad04b40be41dd2e6"
+ "reference": "769c1720b68e964b13b58529c17d4a385c62167b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/c061c7c18918b1b64268771aad04b40be41dd2e6",
- "reference": "c061c7c18918b1b64268771aad04b40be41dd2e6",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/769c1720b68e964b13b58529c17d4a385c62167b",
+ "reference": "769c1720b68e964b13b58529c17d4a385c62167b",
"shasum": ""
},
"require": {
"php": ">=8.2",
- "symfony/deprecation-contracts": "^2.5|^3.0",
- "symfony/polyfill-mbstring": "~1.1",
- "symfony/polyfill-php83": "^1.27"
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-mbstring": "^1.1"
},
"conflict": {
"doctrine/dbal": "<3.6",
@@ -4770,13 +4999,13 @@
"require-dev": {
"doctrine/dbal": "^3.6|^4",
"predis/predis": "^1.1|^2.0",
- "symfony/cache": "^6.4.12|^7.1.5",
- "symfony/clock": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/mime": "^6.4|^7.0",
- "symfony/rate-limiter": "^6.4|^7.0"
+ "symfony/cache": "^6.4.12|^7.1.5|^8.0",
+ "symfony/clock": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/mime": "^6.4|^7.0|^8.0",
+ "symfony/rate-limiter": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -4804,7 +5033,7 @@
"description": "Defines an object-oriented layer for the HTTP specification",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-foundation/tree/v7.3.4"
+ "source": "https://github.com/symfony/http-foundation/tree/v7.4.0"
},
"funding": [
{
@@ -4824,29 +5053,29 @@
"type": "tidelift"
}
],
- "time": "2025-09-16T08:38:17+00:00"
+ "time": "2025-11-13T08:49:24+00:00"
},
{
"name": "symfony/http-kernel",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "b796dffea7821f035047235e076b60ca2446e3cf"
+ "reference": "7348193cd384495a755554382e4526f27c456085"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/b796dffea7821f035047235e076b60ca2446e3cf",
- "reference": "b796dffea7821f035047235e076b60ca2446e3cf",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/7348193cd384495a755554382e4526f27c456085",
+ "reference": "7348193cd384495a755554382e4526f27c456085",
"shasum": ""
},
"require": {
"php": ">=8.2",
"psr/log": "^1|^2|^3",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/error-handler": "^6.4|^7.0",
- "symfony/event-dispatcher": "^7.3",
- "symfony/http-foundation": "^7.3",
+ "symfony/error-handler": "^6.4|^7.0|^8.0",
+ "symfony/event-dispatcher": "^7.3|^8.0",
+ "symfony/http-foundation": "^7.4|^8.0",
"symfony/polyfill-ctype": "^1.8"
},
"conflict": {
@@ -4856,6 +5085,7 @@
"symfony/console": "<6.4",
"symfony/dependency-injection": "<6.4",
"symfony/doctrine-bridge": "<6.4",
+ "symfony/flex": "<2.10",
"symfony/form": "<6.4",
"symfony/http-client": "<6.4",
"symfony/http-client-contracts": "<2.5",
@@ -4873,27 +5103,27 @@
},
"require-dev": {
"psr/cache": "^1.0|^2.0|^3.0",
- "symfony/browser-kit": "^6.4|^7.0",
- "symfony/clock": "^6.4|^7.0",
- "symfony/config": "^6.4|^7.0",
- "symfony/console": "^6.4|^7.0",
- "symfony/css-selector": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/dom-crawler": "^6.4|^7.0",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/finder": "^6.4|^7.0",
+ "symfony/browser-kit": "^6.4|^7.0|^8.0",
+ "symfony/clock": "^6.4|^7.0|^8.0",
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/css-selector": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/dom-crawler": "^6.4|^7.0|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/finder": "^6.4|^7.0|^8.0",
"symfony/http-client-contracts": "^2.5|^3",
- "symfony/process": "^6.4|^7.0",
- "symfony/property-access": "^7.1",
- "symfony/routing": "^6.4|^7.0",
- "symfony/serializer": "^7.1",
- "symfony/stopwatch": "^6.4|^7.0",
- "symfony/translation": "^6.4|^7.0",
+ "symfony/process": "^6.4|^7.0|^8.0",
+ "symfony/property-access": "^7.1|^8.0",
+ "symfony/routing": "^6.4|^7.0|^8.0",
+ "symfony/serializer": "^7.1|^8.0",
+ "symfony/stopwatch": "^6.4|^7.0|^8.0",
+ "symfony/translation": "^6.4|^7.0|^8.0",
"symfony/translation-contracts": "^2.5|^3",
- "symfony/uid": "^6.4|^7.0",
- "symfony/validator": "^6.4|^7.0",
- "symfony/var-dumper": "^6.4|^7.0",
- "symfony/var-exporter": "^6.4|^7.0",
+ "symfony/uid": "^6.4|^7.0|^8.0",
+ "symfony/validator": "^6.4|^7.0|^8.0",
+ "symfony/var-dumper": "^6.4|^7.0|^8.0",
+ "symfony/var-exporter": "^6.4|^7.0|^8.0",
"twig/twig": "^3.12"
},
"type": "library",
@@ -4922,7 +5152,7 @@
"description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/http-kernel/tree/v7.3.4"
+ "source": "https://github.com/symfony/http-kernel/tree/v7.4.0"
},
"funding": [
{
@@ -4942,20 +5172,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-27T12:32:17+00:00"
+ "time": "2025-11-27T13:38:24+00:00"
},
{
"name": "symfony/intl",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/intl.git",
- "reference": "e6db84864655885d9dac676a9d7dde0d904fda54"
+ "reference": "2fa074de6c7faa6b54f2891fc22708f42245ed5c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/intl/zipball/e6db84864655885d9dac676a9d7dde0d904fda54",
- "reference": "e6db84864655885d9dac676a9d7dde0d904fda54",
+ "url": "https://api.github.com/repos/symfony/intl/zipball/2fa074de6c7faa6b54f2891fc22708f42245ed5c",
+ "reference": "2fa074de6c7faa6b54f2891fc22708f42245ed5c",
"shasum": ""
},
"require": {
@@ -4966,8 +5196,8 @@
"symfony/string": "<7.1"
},
"require-dev": {
- "symfony/filesystem": "^6.4|^7.0",
- "symfony/var-exporter": "^6.4|^7.0"
+ "symfony/filesystem": "^6.4|^7.0|^8.0",
+ "symfony/var-exporter": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -5012,7 +5242,7 @@
"localization"
],
"support": {
- "source": "https://github.com/symfony/intl/tree/v7.3.4"
+ "source": "https://github.com/symfony/intl/tree/v7.4.0"
},
"funding": [
{
@@ -5032,20 +5262,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-08T14:11:30+00:00"
+ "time": "2025-11-27T13:27:24+00:00"
},
{
"name": "symfony/mailer",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/mailer.git",
- "reference": "ab97ef2f7acf0216955f5845484235113047a31d"
+ "reference": "a3d9eea8cfa467ece41f0f54ba28185d74bd53fd"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mailer/zipball/ab97ef2f7acf0216955f5845484235113047a31d",
- "reference": "ab97ef2f7acf0216955f5845484235113047a31d",
+ "url": "https://api.github.com/repos/symfony/mailer/zipball/a3d9eea8cfa467ece41f0f54ba28185d74bd53fd",
+ "reference": "a3d9eea8cfa467ece41f0f54ba28185d74bd53fd",
"shasum": ""
},
"require": {
@@ -5053,8 +5283,8 @@
"php": ">=8.2",
"psr/event-dispatcher": "^1",
"psr/log": "^1|^2|^3",
- "symfony/event-dispatcher": "^6.4|^7.0",
- "symfony/mime": "^7.2",
+ "symfony/event-dispatcher": "^6.4|^7.0|^8.0",
+ "symfony/mime": "^7.2|^8.0",
"symfony/service-contracts": "^2.5|^3"
},
"conflict": {
@@ -5065,10 +5295,10 @@
"symfony/twig-bridge": "<6.4"
},
"require-dev": {
- "symfony/console": "^6.4|^7.0",
- "symfony/http-client": "^6.4|^7.0",
- "symfony/messenger": "^6.4|^7.0",
- "symfony/twig-bridge": "^6.4|^7.0"
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/http-client": "^6.4|^7.0|^8.0",
+ "symfony/messenger": "^6.4|^7.0|^8.0",
+ "symfony/twig-bridge": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -5096,7 +5326,7 @@
"description": "Helps sending emails",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/mailer/tree/v7.3.4"
+ "source": "https://github.com/symfony/mailer/tree/v7.4.0"
},
"funding": [
{
@@ -5116,24 +5346,25 @@
"type": "tidelift"
}
],
- "time": "2025-09-17T05:51:54+00:00"
+ "time": "2025-11-21T15:26:00+00:00"
},
{
"name": "symfony/mime",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
- "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35"
+ "reference": "bdb02729471be5d047a3ac4a69068748f1a6be7a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/mime/zipball/b1b828f69cbaf887fa835a091869e55df91d0e35",
- "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35",
+ "url": "https://api.github.com/repos/symfony/mime/zipball/bdb02729471be5d047a3ac4a69068748f1a6be7a",
+ "reference": "bdb02729471be5d047a3ac4a69068748f1a6be7a",
"shasum": ""
},
"require": {
"php": ">=8.2",
+ "symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-intl-idn": "^1.10",
"symfony/polyfill-mbstring": "^1.0"
},
@@ -5148,11 +5379,11 @@
"egulias/email-validator": "^2.1.10|^3.1|^4",
"league/html-to-markdown": "^5.0",
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/process": "^6.4|^7.0",
- "symfony/property-access": "^6.4|^7.0",
- "symfony/property-info": "^6.4|^7.0",
- "symfony/serializer": "^6.4.3|^7.0.3"
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0",
+ "symfony/property-access": "^6.4|^7.0|^8.0",
+ "symfony/property-info": "^6.4|^7.0|^8.0",
+ "symfony/serializer": "^6.4.3|^7.0.3|^8.0"
},
"type": "library",
"autoload": {
@@ -5184,7 +5415,7 @@
"mime-type"
],
"support": {
- "source": "https://github.com/symfony/mime/tree/v7.3.4"
+ "source": "https://github.com/symfony/mime/tree/v7.4.0"
},
"funding": [
{
@@ -5204,20 +5435,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-16T08:38:17+00:00"
+ "time": "2025-11-16T10:14:42+00:00"
},
{
"name": "symfony/options-resolver",
- "version": "v7.3.3",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
- "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d"
+ "reference": "b38026df55197f9e39a44f3215788edf83187b80"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/options-resolver/zipball/0ff2f5c3df08a395232bbc3c2eb7e84912df911d",
- "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d",
+ "url": "https://api.github.com/repos/symfony/options-resolver/zipball/b38026df55197f9e39a44f3215788edf83187b80",
+ "reference": "b38026df55197f9e39a44f3215788edf83187b80",
"shasum": ""
},
"require": {
@@ -5255,7 +5486,7 @@
"options"
],
"support": {
- "source": "https://github.com/symfony/options-resolver/tree/v7.3.3"
+ "source": "https://github.com/symfony/options-resolver/tree/v7.4.0"
},
"funding": [
{
@@ -5275,20 +5506,20 @@
"type": "tidelift"
}
],
- "time": "2025-08-05T10:16:07+00:00"
+ "time": "2025-11-12T15:39:26+00:00"
},
{
"name": "symfony/password-hasher",
- "version": "v7.3.0",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/password-hasher.git",
- "reference": "31fbe66af859582a20b803f38be96be8accdf2c3"
+ "reference": "aa075ce6f54fe931f03c1e382597912f4fd94e1e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/password-hasher/zipball/31fbe66af859582a20b803f38be96be8accdf2c3",
- "reference": "31fbe66af859582a20b803f38be96be8accdf2c3",
+ "url": "https://api.github.com/repos/symfony/password-hasher/zipball/aa075ce6f54fe931f03c1e382597912f4fd94e1e",
+ "reference": "aa075ce6f54fe931f03c1e382597912f4fd94e1e",
"shasum": ""
},
"require": {
@@ -5298,8 +5529,8 @@
"symfony/security-core": "<6.4"
},
"require-dev": {
- "symfony/console": "^6.4|^7.0",
- "symfony/security-core": "^6.4|^7.0"
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/security-core": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -5331,7 +5562,7 @@
"password"
],
"support": {
- "source": "https://github.com/symfony/password-hasher/tree/v7.3.0"
+ "source": "https://github.com/symfony/password-hasher/tree/v7.4.0"
},
"funding": [
{
@@ -5342,12 +5573,16 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2025-02-04T08:22:58+00:00"
+ "time": "2025-08-13T16:46:49+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
@@ -5776,16 +6011,16 @@
},
{
"name": "symfony/process",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b"
+ "reference": "7ca8dc2d0dcf4882658313aba8be5d9fd01026c8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/f24f8f316367b30810810d4eb30c543d7003ff3b",
- "reference": "f24f8f316367b30810810d4eb30c543d7003ff3b",
+ "url": "https://api.github.com/repos/symfony/process/zipball/7ca8dc2d0dcf4882658313aba8be5d9fd01026c8",
+ "reference": "7ca8dc2d0dcf4882658313aba8be5d9fd01026c8",
"shasum": ""
},
"require": {
@@ -5817,7 +6052,7 @@
"description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/process/tree/v7.3.4"
+ "source": "https://github.com/symfony/process/tree/v7.4.0"
},
"funding": [
{
@@ -5837,28 +6072,29 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T10:12:26+00:00"
+ "time": "2025-10-16T11:21:06+00:00"
},
{
"name": "symfony/property-access",
- "version": "v7.3.3",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/property-access.git",
- "reference": "4a4389e5c8bd1d0320d80a23caa6a1ac71cb81a7"
+ "reference": "537626149d2910ca43eb9ce465654366bf4442f4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/property-access/zipball/4a4389e5c8bd1d0320d80a23caa6a1ac71cb81a7",
- "reference": "4a4389e5c8bd1d0320d80a23caa6a1ac71cb81a7",
+ "url": "https://api.github.com/repos/symfony/property-access/zipball/537626149d2910ca43eb9ce465654366bf4442f4",
+ "reference": "537626149d2910ca43eb9ce465654366bf4442f4",
"shasum": ""
},
"require": {
"php": ">=8.2",
- "symfony/property-info": "^6.4|^7.0"
+ "symfony/property-info": "^6.4|^7.0|^8.0"
},
"require-dev": {
- "symfony/cache": "^6.4|^7.0"
+ "symfony/cache": "^6.4|^7.0|^8.0",
+ "symfony/var-exporter": "^6.4.1|^7.0.1|^8.0"
},
"type": "library",
"autoload": {
@@ -5897,7 +6133,7 @@
"reflection"
],
"support": {
- "source": "https://github.com/symfony/property-access/tree/v7.3.3"
+ "source": "https://github.com/symfony/property-access/tree/v7.4.0"
},
"funding": [
{
@@ -5917,27 +6153,27 @@
"type": "tidelift"
}
],
- "time": "2025-08-04T15:15:28+00:00"
+ "time": "2025-09-08T21:14:32+00:00"
},
{
"name": "symfony/property-info",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/property-info.git",
- "reference": "7b6db23f23d13ada41e1cb484748a8ec028fbace"
+ "reference": "c3c686e3d3a33a99f6967e69d6d5832acb7c25a1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/property-info/zipball/7b6db23f23d13ada41e1cb484748a8ec028fbace",
- "reference": "7b6db23f23d13ada41e1cb484748a8ec028fbace",
+ "url": "https://api.github.com/repos/symfony/property-info/zipball/c3c686e3d3a33a99f6967e69d6d5832acb7c25a1",
+ "reference": "c3c686e3d3a33a99f6967e69d6d5832acb7c25a1",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/string": "^6.4|^7.0",
- "symfony/type-info": "~7.2.8|^7.3.1"
+ "symfony/string": "^6.4|^7.0|^8.0",
+ "symfony/type-info": "^7.3.5|^8.0"
},
"conflict": {
"phpdocumentor/reflection-docblock": "<5.2",
@@ -5949,9 +6185,9 @@
"require-dev": {
"phpdocumentor/reflection-docblock": "^5.2",
"phpstan/phpdoc-parser": "^1.0|^2.0",
- "symfony/cache": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/serializer": "^6.4|^7.0"
+ "symfony/cache": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/serializer": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -5987,7 +6223,7 @@
"validator"
],
"support": {
- "source": "https://github.com/symfony/property-info/tree/v7.3.4"
+ "source": "https://github.com/symfony/property-info/tree/v7.4.0"
},
"funding": [
{
@@ -6007,26 +6243,26 @@
"type": "tidelift"
}
],
- "time": "2025-09-15T13:55:54+00:00"
+ "time": "2025-11-13T08:38:49+00:00"
},
{
"name": "symfony/psr-http-message-bridge",
- "version": "v7.3.0",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/psr-http-message-bridge.git",
- "reference": "03f2f72319e7acaf2a9f6fcbe30ef17eec51594f"
+ "reference": "0101ff8bd0506703b045b1670960302d302a726c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/03f2f72319e7acaf2a9f6fcbe30ef17eec51594f",
- "reference": "03f2f72319e7acaf2a9f6fcbe30ef17eec51594f",
+ "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/0101ff8bd0506703b045b1670960302d302a726c",
+ "reference": "0101ff8bd0506703b045b1670960302d302a726c",
"shasum": ""
},
"require": {
"php": ">=8.2",
"psr/http-message": "^1.0|^2.0",
- "symfony/http-foundation": "^6.4|^7.0"
+ "symfony/http-foundation": "^6.4|^7.0|^8.0"
},
"conflict": {
"php-http/discovery": "<1.15",
@@ -6036,11 +6272,12 @@
"nyholm/psr7": "^1.1",
"php-http/discovery": "^1.15",
"psr/log": "^1.1.4|^2|^3",
- "symfony/browser-kit": "^6.4|^7.0",
- "symfony/config": "^6.4|^7.0",
- "symfony/event-dispatcher": "^6.4|^7.0",
- "symfony/framework-bundle": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0"
+ "symfony/browser-kit": "^6.4|^7.0|^8.0",
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/event-dispatcher": "^6.4|^7.0|^8.0",
+ "symfony/framework-bundle": "^6.4.13|^7.1.6|^8.0",
+ "symfony/http-kernel": "^6.4.13|^7.1.6|^8.0",
+ "symfony/runtime": "^6.4.13|^7.1.6|^8.0"
},
"type": "symfony-bridge",
"autoload": {
@@ -6074,7 +6311,7 @@
"psr-7"
],
"support": {
- "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.3.0"
+ "source": "https://github.com/symfony/psr-http-message-bridge/tree/v7.4.0"
},
"funding": [
{
@@ -6085,25 +6322,29 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2024-09-26T08:57:56+00:00"
+ "time": "2025-11-13T08:38:49+00:00"
},
{
"name": "symfony/routing",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
- "reference": "8dc648e159e9bac02b703b9fbd937f19ba13d07c"
+ "reference": "4720254cb2644a0b876233d258a32bf017330db7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/8dc648e159e9bac02b703b9fbd937f19ba13d07c",
- "reference": "8dc648e159e9bac02b703b9fbd937f19ba13d07c",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/4720254cb2644a0b876233d258a32bf017330db7",
+ "reference": "4720254cb2644a0b876233d258a32bf017330db7",
"shasum": ""
},
"require": {
@@ -6117,11 +6358,11 @@
},
"require-dev": {
"psr/log": "^1|^2|^3",
- "symfony/config": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/yaml": "^6.4|^7.0"
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/yaml": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -6155,7 +6396,7 @@
"url"
],
"support": {
- "source": "https://github.com/symfony/routing/tree/v7.3.4"
+ "source": "https://github.com/symfony/routing/tree/v7.4.0"
},
"funding": [
{
@@ -6175,20 +6416,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T10:12:26+00:00"
+ "time": "2025-11-27T13:27:24+00:00"
},
{
"name": "symfony/runtime",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/runtime.git",
- "reference": "3550e2711e30bfa5d808514781cd52d1cc1d9e9f"
+ "reference": "e3dd6c0f46a6810b3245726e8452cee45754e628"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/runtime/zipball/3550e2711e30bfa5d808514781cd52d1cc1d9e9f",
- "reference": "3550e2711e30bfa5d808514781cd52d1cc1d9e9f",
+ "url": "https://api.github.com/repos/symfony/runtime/zipball/e3dd6c0f46a6810b3245726e8452cee45754e628",
+ "reference": "e3dd6c0f46a6810b3245726e8452cee45754e628",
"shasum": ""
},
"require": {
@@ -6200,10 +6441,10 @@
},
"require-dev": {
"composer/composer": "^2.6",
- "symfony/console": "^6.4|^7.0",
- "symfony/dotenv": "^6.4|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0"
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/dotenv": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0"
},
"type": "composer-plugin",
"extra": {
@@ -6238,7 +6479,7 @@
"runtime"
],
"support": {
- "source": "https://github.com/symfony/runtime/tree/v7.3.4"
+ "source": "https://github.com/symfony/runtime/tree/v7.4.0"
},
"funding": [
{
@@ -6258,36 +6499,37 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T15:31:28+00:00"
+ "time": "2025-11-04T03:05:49+00:00"
},
{
"name": "symfony/security-bundle",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/security-bundle.git",
- "reference": "f750d9abccbeaa433c56f6a4eb2073166476a75a"
+ "reference": "48a64e746857464a5e8fd7bab84b31c9ba967eb9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/security-bundle/zipball/f750d9abccbeaa433c56f6a4eb2073166476a75a",
- "reference": "f750d9abccbeaa433c56f6a4eb2073166476a75a",
+ "url": "https://api.github.com/repos/symfony/security-bundle/zipball/48a64e746857464a5e8fd7bab84b31c9ba967eb9",
+ "reference": "48a64e746857464a5e8fd7bab84b31c9ba967eb9",
"shasum": ""
},
"require": {
"composer-runtime-api": ">=2.1",
"ext-xml": "*",
"php": ">=8.2",
- "symfony/clock": "^6.4|^7.0",
- "symfony/config": "^7.3",
- "symfony/dependency-injection": "^6.4.11|^7.1.4",
- "symfony/event-dispatcher": "^6.4|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/password-hasher": "^6.4|^7.0",
- "symfony/security-core": "^7.3",
- "symfony/security-csrf": "^6.4|^7.0",
- "symfony/security-http": "^7.3",
+ "symfony/clock": "^6.4|^7.0|^8.0",
+ "symfony/config": "^7.4|^8.0",
+ "symfony/dependency-injection": "^6.4.11|^7.1.4|^8.0",
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/event-dispatcher": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4.13|^7.1.6|^8.0",
+ "symfony/password-hasher": "^6.4|^7.0|^8.0",
+ "symfony/security-core": "^7.4|^8.0",
+ "symfony/security-csrf": "^6.4|^7.0|^8.0",
+ "symfony/security-http": "^7.4|^8.0",
"symfony/service-contracts": "^2.5|^3"
},
"conflict": {
@@ -6301,25 +6543,26 @@
"symfony/validator": "<6.4"
},
"require-dev": {
- "symfony/asset": "^6.4|^7.0",
- "symfony/browser-kit": "^6.4|^7.0",
- "symfony/console": "^6.4|^7.0",
- "symfony/css-selector": "^6.4|^7.0",
- "symfony/dom-crawler": "^6.4|^7.0",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/form": "^6.4|^7.0",
- "symfony/framework-bundle": "^6.4|^7.0",
- "symfony/http-client": "^6.4|^7.0",
- "symfony/ldap": "^6.4|^7.0",
- "symfony/process": "^6.4|^7.0",
- "symfony/rate-limiter": "^6.4|^7.0",
- "symfony/serializer": "^6.4|^7.0",
- "symfony/translation": "^6.4|^7.0",
- "symfony/twig-bridge": "^6.4|^7.0",
- "symfony/twig-bundle": "^6.4|^7.0",
- "symfony/validator": "^6.4|^7.0",
- "symfony/yaml": "^6.4|^7.0",
- "twig/twig": "^3.12",
+ "symfony/asset": "^6.4|^7.0|^8.0",
+ "symfony/browser-kit": "^6.4|^7.0|^8.0",
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/css-selector": "^6.4|^7.0|^8.0",
+ "symfony/dom-crawler": "^6.4|^7.0|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/form": "^6.4|^7.0|^8.0",
+ "symfony/framework-bundle": "^6.4.13|^7.1.6|^8.0",
+ "symfony/http-client": "^6.4|^7.0|^8.0",
+ "symfony/ldap": "^6.4|^7.0|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0",
+ "symfony/rate-limiter": "^6.4|^7.0|^8.0",
+ "symfony/runtime": "^6.4.13|^7.1.6|^8.0",
+ "symfony/serializer": "^6.4|^7.0|^8.0",
+ "symfony/translation": "^6.4|^7.0|^8.0",
+ "symfony/twig-bridge": "^6.4|^7.0|^8.0",
+ "symfony/twig-bundle": "^6.4|^7.0|^8.0",
+ "symfony/validator": "^6.4|^7.0|^8.0",
+ "symfony/yaml": "^6.4|^7.0|^8.0",
+ "twig/twig": "^3.15",
"web-token/jwt-library": "^3.3.2|^4.0"
},
"type": "symfony-bundle",
@@ -6348,7 +6591,7 @@
"description": "Provides a tight integration of the Security component into the Symfony full-stack framework",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/security-bundle/tree/v7.3.4"
+ "source": "https://github.com/symfony/security-bundle/tree/v7.4.0"
},
"funding": [
{
@@ -6368,27 +6611,27 @@
"type": "tidelift"
}
],
- "time": "2025-09-22T15:31:00+00:00"
+ "time": "2025-11-14T09:57:20+00:00"
},
{
"name": "symfony/security-core",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/security-core.git",
- "reference": "68b9d3ca57615afde6152a1e1441fa035bea43f8"
+ "reference": "fe4d25e5700a2f3b605bf23f520be57504ae5c51"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/security-core/zipball/68b9d3ca57615afde6152a1e1441fa035bea43f8",
- "reference": "68b9d3ca57615afde6152a1e1441fa035bea43f8",
+ "url": "https://api.github.com/repos/symfony/security-core/zipball/fe4d25e5700a2f3b605bf23f520be57504ae5c51",
+ "reference": "fe4d25e5700a2f3b605bf23f520be57504ae5c51",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/event-dispatcher-contracts": "^2.5|^3",
- "symfony/password-hasher": "^6.4|^7.0",
+ "symfony/password-hasher": "^6.4|^7.0|^8.0",
"symfony/service-contracts": "^2.5|^3"
},
"conflict": {
@@ -6403,15 +6646,15 @@
"psr/cache": "^1.0|^2.0|^3.0",
"psr/container": "^1.1|^2.0",
"psr/log": "^1|^2|^3",
- "symfony/cache": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/event-dispatcher": "^6.4|^7.0",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/ldap": "^6.4|^7.0",
- "symfony/string": "^6.4|^7.0",
- "symfony/translation": "^6.4.3|^7.0.3",
- "symfony/validator": "^6.4|^7.0"
+ "symfony/cache": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/event-dispatcher": "^6.4|^7.0|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/ldap": "^6.4|^7.0|^8.0",
+ "symfony/string": "^6.4|^7.0|^8.0",
+ "symfony/translation": "^6.4.3|^7.0.3|^8.0",
+ "symfony/validator": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -6439,7 +6682,7 @@
"description": "Symfony Security Component - Core Library",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/security-core/tree/v7.3.4"
+ "source": "https://github.com/symfony/security-core/tree/v7.4.0"
},
"funding": [
{
@@ -6459,33 +6702,33 @@
"type": "tidelift"
}
],
- "time": "2025-09-24T14:32:13+00:00"
+ "time": "2025-11-21T15:26:00+00:00"
},
{
"name": "symfony/security-csrf",
- "version": "v7.3.0",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/security-csrf.git",
- "reference": "2b4b0c46c901729e4e90719eacd980381f53e0a3"
+ "reference": "ec41009e83589d0b3d86bd131d07e6fc8ecf35ab"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/security-csrf/zipball/2b4b0c46c901729e4e90719eacd980381f53e0a3",
- "reference": "2b4b0c46c901729e4e90719eacd980381f53e0a3",
+ "url": "https://api.github.com/repos/symfony/security-csrf/zipball/ec41009e83589d0b3d86bd131d07e6fc8ecf35ab",
+ "reference": "ec41009e83589d0b3d86bd131d07e6fc8ecf35ab",
"shasum": ""
},
"require": {
"php": ">=8.2",
- "symfony/security-core": "^6.4|^7.0"
+ "symfony/security-core": "^6.4|^7.0|^8.0"
},
"conflict": {
"symfony/http-foundation": "<6.4"
},
"require-dev": {
"psr/log": "^1|^2|^3",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0"
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -6513,7 +6756,7 @@
"description": "Symfony Security Component - CSRF Library",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/security-csrf/tree/v7.3.0"
+ "source": "https://github.com/symfony/security-csrf/tree/v7.4.0"
},
"funding": [
{
@@ -6524,55 +6767,59 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2025-01-02T18:42:10+00:00"
+ "time": "2025-11-21T15:26:00+00:00"
},
{
"name": "symfony/security-http",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/security-http.git",
- "reference": "1cf54d0648ebab23bf9b8972617b79f1995e13a9"
+ "reference": "92f9cc6494f3d29042ac35c2ee5209191bbbb781"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/security-http/zipball/1cf54d0648ebab23bf9b8972617b79f1995e13a9",
- "reference": "1cf54d0648ebab23bf9b8972617b79f1995e13a9",
+ "url": "https://api.github.com/repos/symfony/security-http/zipball/92f9cc6494f3d29042ac35c2ee5209191bbbb781",
+ "reference": "92f9cc6494f3d29042ac35c2ee5209191bbbb781",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
+ "symfony/event-dispatcher": "^6.4|^7.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
"symfony/polyfill-mbstring": "~1.0",
- "symfony/property-access": "^6.4|^7.0",
- "symfony/security-core": "^7.3",
+ "symfony/property-access": "^6.4|^7.0|^8.0",
+ "symfony/security-core": "^7.3|^8.0",
"symfony/service-contracts": "^2.5|^3"
},
"conflict": {
"symfony/clock": "<6.4",
- "symfony/event-dispatcher": "<6.4",
"symfony/http-client-contracts": "<3.0",
"symfony/security-bundle": "<6.4",
"symfony/security-csrf": "<6.4"
},
"require-dev": {
"psr/log": "^1|^2|^3",
- "symfony/cache": "^6.4|^7.0",
- "symfony/clock": "^6.4|^7.0",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/http-client": "^6.4|^7.0",
+ "symfony/cache": "^6.4|^7.0|^8.0",
+ "symfony/clock": "^6.4|^7.0|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/http-client": "^6.4|^7.0|^8.0",
"symfony/http-client-contracts": "^3.0",
- "symfony/rate-limiter": "^6.4|^7.0",
- "symfony/routing": "^6.4|^7.0",
- "symfony/security-csrf": "^6.4|^7.0",
- "symfony/translation": "^6.4|^7.0",
+ "symfony/rate-limiter": "^6.4|^7.0|^8.0",
+ "symfony/routing": "^6.4|^7.0|^8.0",
+ "symfony/security-csrf": "^6.4|^7.0|^8.0",
+ "symfony/translation": "^6.4|^7.0|^8.0",
"web-token/jwt-library": "^3.3.2|^4.0"
},
"type": "library",
@@ -6601,7 +6848,7 @@
"description": "Symfony Security Component - HTTP Integration",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/security-http/tree/v7.3.4"
+ "source": "https://github.com/symfony/security-http/tree/v7.4.0"
},
"funding": [
{
@@ -6621,20 +6868,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-09T17:06:44+00:00"
+ "time": "2025-11-27T13:27:24+00:00"
},
{
"name": "symfony/serializer",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/serializer.git",
- "reference": "0df5af266c6fe9a855af7db4fea86e13b9ca3ab1"
+ "reference": "5a3bbf317b3f1025126b6d9debce53515601ab43"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/serializer/zipball/0df5af266c6fe9a855af7db4fea86e13b9ca3ab1",
- "reference": "0df5af266c6fe9a855af7db4fea86e13b9ca3ab1",
+ "url": "https://api.github.com/repos/symfony/serializer/zipball/5a3bbf317b3f1025126b6d9debce53515601ab43",
+ "reference": "5a3bbf317b3f1025126b6d9debce53515601ab43",
"shasum": ""
},
"require": {
@@ -6657,26 +6904,26 @@
"phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0",
"phpstan/phpdoc-parser": "^1.0|^2.0",
"seld/jsonlint": "^1.10",
- "symfony/cache": "^6.4|^7.0",
- "symfony/config": "^6.4|^7.0",
- "symfony/console": "^6.4|^7.0",
- "symfony/dependency-injection": "^7.2",
- "symfony/error-handler": "^6.4|^7.0",
- "symfony/filesystem": "^6.4|^7.0",
- "symfony/form": "^6.4|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/messenger": "^6.4|^7.0",
- "symfony/mime": "^6.4|^7.0",
- "symfony/property-access": "^6.4|^7.0",
- "symfony/property-info": "^6.4|^7.0",
+ "symfony/cache": "^6.4|^7.0|^8.0",
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^7.2|^8.0",
+ "symfony/error-handler": "^6.4|^7.0|^8.0",
+ "symfony/filesystem": "^6.4|^7.0|^8.0",
+ "symfony/form": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/messenger": "^6.4|^7.0|^8.0",
+ "symfony/mime": "^6.4|^7.0|^8.0",
+ "symfony/property-access": "^6.4|^7.0|^8.0",
+ "symfony/property-info": "^6.4|^7.0|^8.0",
"symfony/translation-contracts": "^2.5|^3",
- "symfony/type-info": "^7.1.8",
- "symfony/uid": "^6.4|^7.0",
- "symfony/validator": "^6.4|^7.0",
- "symfony/var-dumper": "^6.4|^7.0",
- "symfony/var-exporter": "^6.4|^7.0",
- "symfony/yaml": "^6.4|^7.0"
+ "symfony/type-info": "^7.1.8|^8.0",
+ "symfony/uid": "^6.4|^7.0|^8.0",
+ "symfony/validator": "^6.4|^7.0|^8.0",
+ "symfony/var-dumper": "^6.4|^7.0|^8.0",
+ "symfony/var-exporter": "^6.4|^7.0|^8.0",
+ "symfony/yaml": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -6704,7 +6951,7 @@
"description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/serializer/tree/v7.3.4"
+ "source": "https://github.com/symfony/serializer/tree/v7.4.0"
},
"funding": [
{
@@ -6724,20 +6971,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-15T13:39:02+00:00"
+ "time": "2025-11-18T13:23:20+00:00"
},
{
"name": "symfony/service-contracts",
- "version": "v3.6.0",
+ "version": "v3.6.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
- "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4"
+ "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4",
- "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/45112560a3ba2d715666a509a0bc9521d10b6c43",
+ "reference": "45112560a3ba2d715666a509a0bc9521d10b6c43",
"shasum": ""
},
"require": {
@@ -6791,7 +7038,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/service-contracts/tree/v3.6.0"
+ "source": "https://github.com/symfony/service-contracts/tree/v3.6.1"
},
"funding": [
{
@@ -6802,12 +7049,16 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2025-04-25T09:37:31+00:00"
+ "time": "2025-07-15T11:30:57+00:00"
},
{
"name": "symfony/stimulus-bundle",
@@ -6884,16 +7135,16 @@
},
{
"name": "symfony/stopwatch",
- "version": "v7.3.0",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/stopwatch.git",
- "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd"
+ "reference": "8a24af0a2e8a872fb745047180649b8418303084"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd",
- "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd",
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/8a24af0a2e8a872fb745047180649b8418303084",
+ "reference": "8a24af0a2e8a872fb745047180649b8418303084",
"shasum": ""
},
"require": {
@@ -6926,7 +7177,7 @@
"description": "Provides a way to profile code",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/stopwatch/tree/v7.3.0"
+ "source": "https://github.com/symfony/stopwatch/tree/v7.4.0"
},
"funding": [
{
@@ -6937,31 +7188,36 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2025-02-24T10:49:57+00:00"
+ "time": "2025-08-04T07:05:15+00:00"
},
{
"name": "symfony/string",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "f96476035142921000338bad71e5247fbc138872"
+ "reference": "d50e862cb0a0e0886f73ca1f31b865efbb795003"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/f96476035142921000338bad71e5247fbc138872",
- "reference": "f96476035142921000338bad71e5247fbc138872",
+ "url": "https://api.github.com/repos/symfony/string/zipball/d50e862cb0a0e0886f73ca1f31b865efbb795003",
+ "reference": "d50e862cb0a0e0886f73ca1f31b865efbb795003",
"shasum": ""
},
"require": {
"php": ">=8.2",
+ "symfony/deprecation-contracts": "^2.5|^3.0",
"symfony/polyfill-ctype": "~1.8",
- "symfony/polyfill-intl-grapheme": "~1.0",
+ "symfony/polyfill-intl-grapheme": "~1.33",
"symfony/polyfill-intl-normalizer": "~1.0",
"symfony/polyfill-mbstring": "~1.0"
},
@@ -6969,11 +7225,11 @@
"symfony/translation-contracts": "<2.5"
},
"require-dev": {
- "symfony/emoji": "^7.1",
- "symfony/http-client": "^6.4|^7.0",
- "symfony/intl": "^6.4|^7.0",
+ "symfony/emoji": "^7.1|^8.0",
+ "symfony/http-client": "^6.4|^7.0|^8.0",
+ "symfony/intl": "^6.4|^7.0|^8.0",
"symfony/translation-contracts": "^2.5|^3.0",
- "symfony/var-exporter": "^6.4|^7.0"
+ "symfony/var-exporter": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -7012,7 +7268,7 @@
"utf8"
],
"support": {
- "source": "https://github.com/symfony/string/tree/v7.3.4"
+ "source": "https://github.com/symfony/string/tree/v7.4.0"
},
"funding": [
{
@@ -7032,27 +7288,27 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T14:36:48+00:00"
+ "time": "2025-11-27T13:27:24+00:00"
},
{
"name": "symfony/translation",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
- "reference": "ec25870502d0c7072d086e8ffba1420c85965174"
+ "reference": "2d01ca0da3f092f91eeedb46f24aa30d2fca8f68"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation/zipball/ec25870502d0c7072d086e8ffba1420c85965174",
- "reference": "ec25870502d0c7072d086e8ffba1420c85965174",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/2d01ca0da3f092f91eeedb46f24aa30d2fca8f68",
+ "reference": "2d01ca0da3f092f91eeedb46f24aa30d2fca8f68",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-mbstring": "~1.0",
- "symfony/translation-contracts": "^2.5|^3.0"
+ "symfony/translation-contracts": "^2.5.3|^3.3"
},
"conflict": {
"nikic/php-parser": "<5.0",
@@ -7071,17 +7327,17 @@
"require-dev": {
"nikic/php-parser": "^5.0",
"psr/log": "^1|^2|^3",
- "symfony/config": "^6.4|^7.0",
- "symfony/console": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/finder": "^6.4|^7.0",
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/finder": "^6.4|^7.0|^8.0",
"symfony/http-client-contracts": "^2.5|^3.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/intl": "^6.4|^7.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/intl": "^6.4|^7.0|^8.0",
"symfony/polyfill-intl-icu": "^1.21",
- "symfony/routing": "^6.4|^7.0",
+ "symfony/routing": "^6.4|^7.0|^8.0",
"symfony/service-contracts": "^2.5|^3",
- "symfony/yaml": "^6.4|^7.0"
+ "symfony/yaml": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -7112,7 +7368,7 @@
"description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/translation/tree/v7.3.4"
+ "source": "https://github.com/symfony/translation/tree/v7.4.0"
},
"funding": [
{
@@ -7132,20 +7388,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-07T11:39:36+00:00"
+ "time": "2025-11-27T13:27:24+00:00"
},
{
"name": "symfony/translation-contracts",
- "version": "v3.6.0",
+ "version": "v3.6.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation-contracts.git",
- "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d"
+ "reference": "65a8bc82080447fae78373aa10f8d13b38338977"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/df210c7a2573f1913b2d17cc95f90f53a73d8f7d",
- "reference": "df210c7a2573f1913b2d17cc95f90f53a73d8f7d",
+ "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/65a8bc82080447fae78373aa10f8d13b38338977",
+ "reference": "65a8bc82080447fae78373aa10f8d13b38338977",
"shasum": ""
},
"require": {
@@ -7194,7 +7450,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/translation-contracts/tree/v3.6.0"
+ "source": "https://github.com/symfony/translation-contracts/tree/v3.6.1"
},
"funding": [
{
@@ -7205,25 +7461,29 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2024-09-27T08:32:26+00:00"
+ "time": "2025-07-15T13:41:35+00:00"
},
{
"name": "symfony/twig-bridge",
- "version": "v7.3.3",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/twig-bridge.git",
- "reference": "33558f013b7f6ed72805527c8405cae0062e47c5"
+ "reference": "e96998da928007554b8b8c02e677861877daced9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/33558f013b7f6ed72805527c8405cae0062e47c5",
- "reference": "33558f013b7f6ed72805527c8405cae0062e47c5",
+ "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/e96998da928007554b8b8c02e677861877daced9",
+ "reference": "e96998da928007554b8b8c02e677861877daced9",
"shasum": ""
},
"require": {
@@ -7248,33 +7508,33 @@
"egulias/email-validator": "^2.1.10|^3|^4",
"league/html-to-markdown": "^5.0",
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
- "symfony/asset": "^6.4|^7.0",
- "symfony/asset-mapper": "^6.4|^7.0",
- "symfony/console": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/emoji": "^7.1",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/finder": "^6.4|^7.0",
- "symfony/form": "^6.4.20|^7.2.5",
- "symfony/html-sanitizer": "^6.4|^7.0",
- "symfony/http-foundation": "^7.3",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/intl": "^6.4|^7.0",
- "symfony/mime": "^6.4|^7.0",
+ "symfony/asset": "^6.4|^7.0|^8.0",
+ "symfony/asset-mapper": "^6.4|^7.0|^8.0",
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/emoji": "^7.1|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/finder": "^6.4|^7.0|^8.0",
+ "symfony/form": "^6.4.20|^7.2.5|^8.0",
+ "symfony/html-sanitizer": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^7.3|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/intl": "^6.4|^7.0|^8.0",
+ "symfony/mime": "^6.4|^7.0|^8.0",
"symfony/polyfill-intl-icu": "~1.0",
- "symfony/property-info": "^6.4|^7.0",
- "symfony/routing": "^6.4|^7.0",
+ "symfony/property-info": "^6.4|^7.0|^8.0",
+ "symfony/routing": "^6.4|^7.0|^8.0",
"symfony/security-acl": "^2.8|^3.0",
- "symfony/security-core": "^6.4|^7.0",
- "symfony/security-csrf": "^6.4|^7.0",
- "symfony/security-http": "^6.4|^7.0",
- "symfony/serializer": "^6.4.3|^7.0.3",
- "symfony/stopwatch": "^6.4|^7.0",
- "symfony/translation": "^6.4|^7.0",
- "symfony/validator": "^6.4|^7.0",
- "symfony/web-link": "^6.4|^7.0",
- "symfony/workflow": "^6.4|^7.0",
- "symfony/yaml": "^6.4|^7.0",
+ "symfony/security-core": "^6.4|^7.0|^8.0",
+ "symfony/security-csrf": "^6.4|^7.0|^8.0",
+ "symfony/security-http": "^6.4|^7.0|^8.0",
+ "symfony/serializer": "^6.4.3|^7.0.3|^8.0",
+ "symfony/stopwatch": "^6.4|^7.0|^8.0",
+ "symfony/translation": "^6.4|^7.0|^8.0",
+ "symfony/validator": "^6.4|^7.0|^8.0",
+ "symfony/web-link": "^6.4|^7.0|^8.0",
+ "symfony/workflow": "^6.4|^7.0|^8.0",
+ "symfony/yaml": "^6.4|^7.0|^8.0",
"twig/cssinliner-extra": "^3",
"twig/inky-extra": "^3",
"twig/markdown-extra": "^3"
@@ -7305,7 +7565,7 @@
"description": "Provides integration for Twig with various Symfony components",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/twig-bridge/tree/v7.3.3"
+ "source": "https://github.com/symfony/twig-bridge/tree/v7.4.0"
},
"funding": [
{
@@ -7325,30 +7585,30 @@
"type": "tidelift"
}
],
- "time": "2025-08-18T13:10:53+00:00"
+ "time": "2025-11-05T14:29:59+00:00"
},
{
"name": "symfony/twig-bundle",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/twig-bundle.git",
- "reference": "da5c778a8416fcce5318737c4d944f6fa2bb3f81"
+ "reference": "f83f530d00d1bbc6f7fafeb433077887c83326ef"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/da5c778a8416fcce5318737c4d944f6fa2bb3f81",
- "reference": "da5c778a8416fcce5318737c4d944f6fa2bb3f81",
+ "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/f83f530d00d1bbc6f7fafeb433077887c83326ef",
+ "reference": "f83f530d00d1bbc6f7fafeb433077887c83326ef",
"shasum": ""
},
"require": {
"composer-runtime-api": ">=2.1",
"php": ">=8.2",
- "symfony/config": "^7.3",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/twig-bridge": "^7.3",
+ "symfony/config": "^7.4|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4.13|^7.1.6|^8.0",
+ "symfony/twig-bridge": "^7.3|^8.0",
"twig/twig": "^3.12"
},
"conflict": {
@@ -7356,16 +7616,17 @@
"symfony/translation": "<6.4"
},
"require-dev": {
- "symfony/asset": "^6.4|^7.0",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/finder": "^6.4|^7.0",
- "symfony/form": "^6.4|^7.0",
- "symfony/framework-bundle": "^6.4|^7.0",
- "symfony/routing": "^6.4|^7.0",
- "symfony/stopwatch": "^6.4|^7.0",
- "symfony/translation": "^6.4|^7.0",
- "symfony/web-link": "^6.4|^7.0",
- "symfony/yaml": "^6.4|^7.0"
+ "symfony/asset": "^6.4|^7.0|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/finder": "^6.4|^7.0|^8.0",
+ "symfony/form": "^6.4|^7.0|^8.0",
+ "symfony/framework-bundle": "^6.4.13|^7.1.6|^8.0",
+ "symfony/routing": "^6.4|^7.0|^8.0",
+ "symfony/runtime": "^6.4.13|^7.1.6",
+ "symfony/stopwatch": "^6.4|^7.0|^8.0",
+ "symfony/translation": "^6.4|^7.0|^8.0",
+ "symfony/web-link": "^6.4|^7.0|^8.0",
+ "symfony/yaml": "^6.4|^7.0|^8.0"
},
"type": "symfony-bundle",
"autoload": {
@@ -7393,7 +7654,7 @@
"description": "Provides a tight integration of Twig into the Symfony full-stack framework",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/twig-bundle/tree/v7.3.4"
+ "source": "https://github.com/symfony/twig-bundle/tree/v7.4.0"
},
"funding": [
{
@@ -7413,20 +7674,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-10T12:00:31+00:00"
+ "time": "2025-10-02T07:41:02+00:00"
},
{
"name": "symfony/type-info",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/type-info.git",
- "reference": "d34eaeb57f39c8a9c97eb72a977c423207dfa35b"
+ "reference": "7f9743e921abcce92a03fc693530209c59e73076"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/type-info/zipball/d34eaeb57f39c8a9c97eb72a977c423207dfa35b",
- "reference": "d34eaeb57f39c8a9c97eb72a977c423207dfa35b",
+ "url": "https://api.github.com/repos/symfony/type-info/zipball/7f9743e921abcce92a03fc693530209c59e73076",
+ "reference": "7f9743e921abcce92a03fc693530209c59e73076",
"shasum": ""
},
"require": {
@@ -7476,7 +7737,7 @@
"type"
],
"support": {
- "source": "https://github.com/symfony/type-info/tree/v7.3.4"
+ "source": "https://github.com/symfony/type-info/tree/v7.4.0"
},
"funding": [
{
@@ -7496,20 +7757,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T15:33:27+00:00"
+ "time": "2025-11-07T09:36:46+00:00"
},
{
"name": "symfony/uid",
- "version": "v7.3.1",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/uid.git",
- "reference": "a69f69f3159b852651a6bf45a9fdd149520525bb"
+ "reference": "2498e9f81b7baa206f44de583f2f48350b90142c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/uid/zipball/a69f69f3159b852651a6bf45a9fdd149520525bb",
- "reference": "a69f69f3159b852651a6bf45a9fdd149520525bb",
+ "url": "https://api.github.com/repos/symfony/uid/zipball/2498e9f81b7baa206f44de583f2f48350b90142c",
+ "reference": "2498e9f81b7baa206f44de583f2f48350b90142c",
"shasum": ""
},
"require": {
@@ -7517,7 +7778,7 @@
"symfony/polyfill-uuid": "^1.15"
},
"require-dev": {
- "symfony/console": "^6.4|^7.0"
+ "symfony/console": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -7554,7 +7815,7 @@
"uuid"
],
"support": {
- "source": "https://github.com/symfony/uid/tree/v7.3.1"
+ "source": "https://github.com/symfony/uid/tree/v7.4.0"
},
"funding": [
{
@@ -7565,12 +7826,16 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2025-06-27T19:55:54+00:00"
+ "time": "2025-09-25T11:02:55+00:00"
},
{
"name": "symfony/ux-turbo",
@@ -7677,16 +7942,16 @@
},
{
"name": "symfony/validator",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/validator.git",
- "reference": "5e29a348b5fac2227b6938a54db006d673bb813a"
+ "reference": "829d4acbecc6a9c097ca9cb118d7f96f46d33da9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/validator/zipball/5e29a348b5fac2227b6938a54db006d673bb813a",
- "reference": "5e29a348b5fac2227b6938a54db006d673bb813a",
+ "url": "https://api.github.com/repos/symfony/validator/zipball/829d4acbecc6a9c097ca9cb118d7f96f46d33da9",
+ "reference": "829d4acbecc6a9c097ca9cb118d7f96f46d33da9",
"shasum": ""
},
"require": {
@@ -7706,27 +7971,29 @@
"symfony/intl": "<6.4",
"symfony/property-info": "<6.4",
"symfony/translation": "<6.4.3|>=7.0,<7.0.3",
+ "symfony/var-exporter": "<6.4.25|>=7.0,<7.3.3",
"symfony/yaml": "<6.4"
},
"require-dev": {
"egulias/email-validator": "^2.1.10|^3|^4",
- "symfony/cache": "^6.4|^7.0",
- "symfony/config": "^6.4|^7.0",
- "symfony/console": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
- "symfony/expression-language": "^6.4|^7.0",
- "symfony/finder": "^6.4|^7.0",
- "symfony/http-client": "^6.4|^7.0",
- "symfony/http-foundation": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/intl": "^6.4|^7.0",
- "symfony/mime": "^6.4|^7.0",
- "symfony/property-access": "^6.4|^7.0",
- "symfony/property-info": "^6.4|^7.0",
- "symfony/string": "^6.4|^7.0",
- "symfony/translation": "^6.4.3|^7.0.3",
+ "symfony/cache": "^6.4|^7.0|^8.0",
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
+ "symfony/expression-language": "^6.4|^7.0|^8.0",
+ "symfony/finder": "^6.4|^7.0|^8.0",
+ "symfony/http-client": "^6.4|^7.0|^8.0",
+ "symfony/http-foundation": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/intl": "^6.4|^7.0|^8.0",
+ "symfony/mime": "^6.4|^7.0|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0",
+ "symfony/property-access": "^6.4|^7.0|^8.0",
+ "symfony/property-info": "^6.4|^7.0|^8.0",
+ "symfony/string": "^6.4|^7.0|^8.0",
+ "symfony/translation": "^6.4.3|^7.0.3|^8.0",
"symfony/type-info": "^7.1.8",
- "symfony/yaml": "^6.4|^7.0"
+ "symfony/yaml": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -7755,7 +8022,7 @@
"description": "Provides tools to validate values",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/validator/tree/v7.3.4"
+ "source": "https://github.com/symfony/validator/tree/v7.4.0"
},
"funding": [
{
@@ -7775,20 +8042,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-24T06:32:27+00:00"
+ "time": "2025-11-18T13:23:20+00:00"
},
{
"name": "symfony/var-dumper",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "b8abe7daf2730d07dfd4b2ee1cecbf0dd2fbdabb"
+ "reference": "41fd6c4ae28c38b294b42af6db61446594a0dece"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b8abe7daf2730d07dfd4b2ee1cecbf0dd2fbdabb",
- "reference": "b8abe7daf2730d07dfd4b2ee1cecbf0dd2fbdabb",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/41fd6c4ae28c38b294b42af6db61446594a0dece",
+ "reference": "41fd6c4ae28c38b294b42af6db61446594a0dece",
"shasum": ""
},
"require": {
@@ -7800,10 +8067,10 @@
"symfony/console": "<6.4"
},
"require-dev": {
- "symfony/console": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/process": "^6.4|^7.0",
- "symfony/uid": "^6.4|^7.0",
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0",
+ "symfony/uid": "^6.4|^7.0|^8.0",
"twig/twig": "^3.12"
},
"bin": [
@@ -7842,7 +8109,7 @@
"dump"
],
"support": {
- "source": "https://github.com/symfony/var-dumper/tree/v7.3.4"
+ "source": "https://github.com/symfony/var-dumper/tree/v7.4.0"
},
"funding": [
{
@@ -7862,20 +8129,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T10:12:26+00:00"
+ "time": "2025-10-27T20:36:44+00:00"
},
{
"name": "symfony/var-exporter",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-exporter.git",
- "reference": "0f020b544a30a7fe8ba972e53ee48a74c0bc87f4"
+ "reference": "03a60f169c79a28513a78c967316fbc8bf17816f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-exporter/zipball/0f020b544a30a7fe8ba972e53ee48a74c0bc87f4",
- "reference": "0f020b544a30a7fe8ba972e53ee48a74c0bc87f4",
+ "url": "https://api.github.com/repos/symfony/var-exporter/zipball/03a60f169c79a28513a78c967316fbc8bf17816f",
+ "reference": "03a60f169c79a28513a78c967316fbc8bf17816f",
"shasum": ""
},
"require": {
@@ -7883,9 +8150,9 @@
"symfony/deprecation-contracts": "^2.5|^3"
},
"require-dev": {
- "symfony/property-access": "^6.4|^7.0",
- "symfony/serializer": "^6.4|^7.0",
- "symfony/var-dumper": "^6.4|^7.0"
+ "symfony/property-access": "^6.4|^7.0|^8.0",
+ "symfony/serializer": "^6.4|^7.0|^8.0",
+ "symfony/var-dumper": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -7923,7 +8190,7 @@
"serialize"
],
"support": {
- "source": "https://github.com/symfony/var-exporter/tree/v7.3.4"
+ "source": "https://github.com/symfony/var-exporter/tree/v7.4.0"
},
"funding": [
{
@@ -7943,32 +8210,32 @@
"type": "tidelift"
}
],
- "time": "2025-09-11T10:12:26+00:00"
+ "time": "2025-09-11T10:15:23+00:00"
},
{
"name": "symfony/yaml",
- "version": "v7.3.3",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "d4f4a66866fe2451f61296924767280ab5732d9d"
+ "reference": "6c84a4b55aee4cd02034d1c528e83f69ddf63810"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/d4f4a66866fe2451f61296924767280ab5732d9d",
- "reference": "d4f4a66866fe2451f61296924767280ab5732d9d",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/6c84a4b55aee4cd02034d1c528e83f69ddf63810",
+ "reference": "6c84a4b55aee4cd02034d1c528e83f69ddf63810",
"shasum": ""
},
"require": {
"php": ">=8.2",
- "symfony/deprecation-contracts": "^2.5|^3.0",
+ "symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-ctype": "^1.8"
},
"conflict": {
"symfony/console": "<6.4"
},
"require-dev": {
- "symfony/console": "^6.4|^7.0"
+ "symfony/console": "^6.4|^7.0|^8.0"
},
"bin": [
"Resources/bin/yaml-lint"
@@ -7999,7 +8266,7 @@
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/yaml/tree/v7.3.3"
+ "source": "https://github.com/symfony/yaml/tree/v7.4.0"
},
"funding": [
{
@@ -8019,7 +8286,7 @@
"type": "tidelift"
}
],
- "time": "2025-08-27T11:34:33+00:00"
+ "time": "2025-11-16T10:14:42+00:00"
},
{
"name": "symfonycasts/sass-bundle",
@@ -8262,26 +8529,26 @@
},
{
"name": "twig/extra-bundle",
- "version": "v3.21.0",
+ "version": "v3.22.1",
"source": {
"type": "git",
"url": "https://github.com/twigphp/twig-extra-bundle.git",
- "reference": "62d1cf47a1aa009cbd07b21045b97d3d5cb79896"
+ "reference": "b6534bc925bec930004facca92fccebd0c809247"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/62d1cf47a1aa009cbd07b21045b97d3d5cb79896",
- "reference": "62d1cf47a1aa009cbd07b21045b97d3d5cb79896",
+ "url": "https://api.github.com/repos/twigphp/twig-extra-bundle/zipball/b6534bc925bec930004facca92fccebd0c809247",
+ "reference": "b6534bc925bec930004facca92fccebd0c809247",
"shasum": ""
},
"require": {
"php": ">=8.1.0",
- "symfony/framework-bundle": "^5.4|^6.4|^7.0",
- "symfony/twig-bundle": "^5.4|^6.4|^7.0",
+ "symfony/framework-bundle": "^5.4|^6.4|^7.0|^8.0",
+ "symfony/twig-bundle": "^5.4|^6.4|^7.0|^8.0",
"twig/twig": "^3.2|^4.0"
},
"require-dev": {
- "league/commonmark": "^1.0|^2.0",
+ "league/commonmark": "^2.7",
"symfony/phpunit-bridge": "^6.4|^7.0",
"twig/cache-extra": "^3.0",
"twig/cssinliner-extra": "^3.0",
@@ -8320,7 +8587,7 @@
"twig"
],
"support": {
- "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.21.0"
+ "source": "https://github.com/twigphp/twig-extra-bundle/tree/v3.22.1"
},
"funding": [
{
@@ -8332,25 +8599,25 @@
"type": "tidelift"
}
],
- "time": "2025-02-19T14:29:33+00:00"
+ "time": "2025-11-02T11:00:49+00:00"
},
{
"name": "twig/intl-extra",
- "version": "v3.21.0",
+ "version": "v3.22.1",
"source": {
"type": "git",
"url": "https://github.com/twigphp/intl-extra.git",
- "reference": "05bc5d46b9df9e62399eae53e7c0b0633298b146"
+ "reference": "93ac31e53cdd3f2e541f42690cd0c54ca8138ab1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/05bc5d46b9df9e62399eae53e7c0b0633298b146",
- "reference": "05bc5d46b9df9e62399eae53e7c0b0633298b146",
+ "url": "https://api.github.com/repos/twigphp/intl-extra/zipball/93ac31e53cdd3f2e541f42690cd0c54ca8138ab1",
+ "reference": "93ac31e53cdd3f2e541f42690cd0c54ca8138ab1",
"shasum": ""
},
"require": {
"php": ">=8.1.0",
- "symfony/intl": "^5.4|^6.4|^7.0",
+ "symfony/intl": "^5.4|^6.4|^7.0|^8.0",
"twig/twig": "^3.13|^4.0"
},
"require-dev": {
@@ -8384,7 +8651,7 @@
"twig"
],
"support": {
- "source": "https://github.com/twigphp/intl-extra/tree/v3.21.0"
+ "source": "https://github.com/twigphp/intl-extra/tree/v3.22.1"
},
"funding": [
{
@@ -8396,20 +8663,20 @@
"type": "tidelift"
}
],
- "time": "2025-01-31T20:45:36+00:00"
+ "time": "2025-11-02T11:00:49+00:00"
},
{
"name": "twig/twig",
- "version": "v3.21.1",
+ "version": "v3.22.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "285123877d4dd97dd7c11842ac5fb7e86e60d81d"
+ "reference": "4509984193026de413baf4ba80f68590a7f2c51d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/285123877d4dd97dd7c11842ac5fb7e86e60d81d",
- "reference": "285123877d4dd97dd7c11842ac5fb7e86e60d81d",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/4509984193026de413baf4ba80f68590a7f2c51d",
+ "reference": "4509984193026de413baf4ba80f68590a7f2c51d",
"shasum": ""
},
"require": {
@@ -8463,7 +8730,7 @@
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
- "source": "https://github.com/twigphp/Twig/tree/v3.21.1"
+ "source": "https://github.com/twigphp/Twig/tree/v3.22.0"
},
"funding": [
{
@@ -8475,20 +8742,20 @@
"type": "tidelift"
}
],
- "time": "2025-05-03T07:21:55+00:00"
+ "time": "2025-10-29T15:56:47+00:00"
},
{
"name": "webmozart/assert",
- "version": "1.12.0",
+ "version": "1.12.1",
"source": {
"type": "git",
"url": "https://github.com/webmozarts/assert.git",
- "reference": "541057574806f942c94662b817a50f63f7345360"
+ "reference": "9be6926d8b485f55b9229203f962b51ed377ba68"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozarts/assert/zipball/541057574806f942c94662b817a50f63f7345360",
- "reference": "541057574806f942c94662b817a50f63f7345360",
+ "url": "https://api.github.com/repos/webmozarts/assert/zipball/9be6926d8b485f55b9229203f962b51ed377ba68",
+ "reference": "9be6926d8b485f55b9229203f962b51ed377ba68",
"shasum": ""
},
"require": {
@@ -8531,9 +8798,9 @@
],
"support": {
"issues": "https://github.com/webmozarts/assert/issues",
- "source": "https://github.com/webmozarts/assert/tree/1.12.0"
+ "source": "https://github.com/webmozarts/assert/tree/1.12.1"
},
- "time": "2025-10-20T12:43:39+00:00"
+ "time": "2025-10-29T15:56:20+00:00"
}
],
"packages-dev": [
@@ -8667,6 +8934,75 @@
],
"time": "2024-05-06T16:37:16+00:00"
},
+ {
+ "name": "dama/doctrine-test-bundle",
+ "version": "v8.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/dmaicher/doctrine-test-bundle.git",
+ "reference": "ce7cd44126c36694e2f2d92c4aedd4fc5b0874f2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/dmaicher/doctrine-test-bundle/zipball/ce7cd44126c36694e2f2d92c4aedd4fc5b0874f2",
+ "reference": "ce7cd44126c36694e2f2d92c4aedd4fc5b0874f2",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/dbal": "^3.3 || ^4.0",
+ "doctrine/doctrine-bundle": "^2.11.0 || ^3.0",
+ "php": ">= 8.1",
+ "psr/cache": "^2.0 || ^3.0",
+ "symfony/cache": "^6.4 || ^7.3 || ^8.0",
+ "symfony/framework-bundle": "^6.4 || ^7.3 || ^8.0"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<10.0"
+ },
+ "require-dev": {
+ "behat/behat": "^3.0",
+ "friendsofphp/php-cs-fixer": "^3.27",
+ "phpstan/phpstan": "^2.0",
+ "phpunit/phpunit": "^10.5.57 || ^11.5.41|| ^12.3.14",
+ "symfony/dotenv": "^6.4 || ^7.3 || ^8.0",
+ "symfony/process": "^6.4 || ^7.3 || ^8.0"
+ },
+ "type": "symfony-bundle",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "8.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "DAMA\\DoctrineTestBundle\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "David Maicher",
+ "email": "mail@dmaicher.de"
+ }
+ ],
+ "description": "Symfony bundle to isolate doctrine database tests and improve test performance",
+ "keywords": [
+ "doctrine",
+ "isolation",
+ "performance",
+ "symfony",
+ "testing",
+ "tests"
+ ],
+ "support": {
+ "issues": "https://github.com/dmaicher/doctrine-test-bundle/issues",
+ "source": "https://github.com/dmaicher/doctrine-test-bundle/tree/v8.4.0"
+ },
+ "time": "2025-10-11T15:24:02+00:00"
+ },
{
"name": "doctrine/data-fixtures",
"version": "2.2.0",
@@ -8946,16 +9282,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
- "version": "v3.89.1",
+ "version": "v3.90.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
- "reference": "f34967da2866ace090a2b447de1f357356474573"
+ "reference": "ad732c2e9299c9743f9c55ae53cc0e7642ab1155"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/f34967da2866ace090a2b447de1f357356474573",
- "reference": "f34967da2866ace090a2b447de1f357356474573",
+ "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/ad732c2e9299c9743f9c55ae53cc0e7642ab1155",
+ "reference": "ad732c2e9299c9743f9c55ae53cc0e7642ab1155",
"shasum": ""
},
"require": {
@@ -8973,17 +9309,17 @@
"react/socket": "^1.16",
"react/stream": "^1.4",
"sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0",
- "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0",
- "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0",
- "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0",
- "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0",
- "symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0",
+ "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0 || ^8.0",
+ "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0",
+ "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0",
+ "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0",
+ "symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0",
"symfony/polyfill-mbstring": "^1.33",
"symfony/polyfill-php80": "^1.33",
"symfony/polyfill-php81": "^1.33",
"symfony/polyfill-php84": "^1.33",
- "symfony/process": "^5.4.47 || ^6.4.24 || ^7.2",
- "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0"
+ "symfony/process": "^5.4.47 || ^6.4.24 || ^7.2 || ^8.0",
+ "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0"
},
"require-dev": {
"facile-it/paraunit": "^1.3.1 || ^2.7",
@@ -8991,12 +9327,12 @@
"justinrainbow/json-schema": "^6.5",
"keradus/cli-executor": "^2.2",
"mikey179/vfsstream": "^1.6.12",
- "php-coveralls/php-coveralls": "^2.8",
+ "php-coveralls/php-coveralls": "^2.9",
"php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6",
"php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6",
"phpunit/phpunit": "^9.6.25 || ^10.5.53 || ^11.5.34",
- "symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2",
- "symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2"
+ "symfony/var-dumper": "^5.4.48 || ^6.4.24 || ^7.3.2 || ^8.0",
+ "symfony/yaml": "^5.4.45 || ^6.4.24 || ^7.3.2 || ^8.0"
},
"suggest": {
"ext-dom": "For handling output formats in XML",
@@ -9037,7 +9373,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.89.1"
+ "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.90.0"
},
"funding": [
{
@@ -9045,7 +9381,7 @@
"type": "github"
}
],
- "time": "2025-10-24T12:05:10+00:00"
+ "time": "2025-11-20T15:15:16+00:00"
},
{
"name": "masterminds/html5",
@@ -9400,11 +9736,11 @@
},
{
"name": "phpstan/phpstan",
- "version": "2.1.31",
+ "version": "2.1.32",
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ead89849d879fe203ce9292c6ef5e7e76f867b96",
- "reference": "ead89849d879fe203ce9292c6ef5e7e76f867b96",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e126cad1e30a99b137b8ed75a85a676450ebb227",
+ "reference": "e126cad1e30a99b137b8ed75a85a676450ebb227",
"shasum": ""
},
"require": {
@@ -9449,20 +9785,20 @@
"type": "github"
}
],
- "time": "2025-10-10T14:14:11+00:00"
+ "time": "2025-11-11T15:18:17+00:00"
},
{
"name": "phpstan/phpstan-doctrine",
- "version": "2.0.10",
+ "version": "2.0.11",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-doctrine.git",
- "reference": "5eaf37b87288474051469aee9f937fc9d862f330"
+ "reference": "368ad1c713a6d95763890bc2292694a603ece7c8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/5eaf37b87288474051469aee9f937fc9d862f330",
- "reference": "5eaf37b87288474051469aee9f937fc9d862f330",
+ "url": "https://api.github.com/repos/phpstan/phpstan-doctrine/zipball/368ad1c713a6d95763890bc2292694a603ece7c8",
+ "reference": "368ad1c713a6d95763890bc2292694a603ece7c8",
"shasum": ""
},
"require": {
@@ -9492,7 +9828,7 @@
"nesbot/carbon": "^2.49",
"php-parallel-lint/php-parallel-lint": "^1.2",
"phpstan/phpstan-deprecation-rules": "^2.0.2",
- "phpstan/phpstan-phpunit": "^2.0",
+ "phpstan/phpstan-phpunit": "^2.0.8",
"phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^9.6.20",
"ramsey/uuid": "^4.2",
@@ -9520,27 +9856,27 @@
"description": "Doctrine extensions for PHPStan",
"support": {
"issues": "https://github.com/phpstan/phpstan-doctrine/issues",
- "source": "https://github.com/phpstan/phpstan-doctrine/tree/2.0.10"
+ "source": "https://github.com/phpstan/phpstan-doctrine/tree/2.0.11"
},
- "time": "2025-10-06T10:01:02+00:00"
+ "time": "2025-11-04T09:55:35+00:00"
},
{
"name": "phpstan/phpstan-phpunit",
- "version": "2.0.7",
+ "version": "2.0.8",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan-phpunit.git",
- "reference": "9a9b161baee88a5f5c58d816943cff354ff233dc"
+ "reference": "2fe9fbeceaf76dd1ebaa7bbbb25e2fb5e59db2fe"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/9a9b161baee88a5f5c58d816943cff354ff233dc",
- "reference": "9a9b161baee88a5f5c58d816943cff354ff233dc",
+ "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/2fe9fbeceaf76dd1ebaa7bbbb25e2fb5e59db2fe",
+ "reference": "2fe9fbeceaf76dd1ebaa7bbbb25e2fb5e59db2fe",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0",
- "phpstan/phpstan": "^2.1.18"
+ "phpstan/phpstan": "^2.1.32"
},
"conflict": {
"phpunit/phpunit": "<7.0"
@@ -9573,9 +9909,9 @@
"description": "PHPUnit extensions and rules for PHPStan",
"support": {
"issues": "https://github.com/phpstan/phpstan-phpunit/issues",
- "source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.7"
+ "source": "https://github.com/phpstan/phpstan-phpunit/tree/2.0.8"
},
- "time": "2025-07-13T11:31:46+00:00"
+ "time": "2025-11-11T07:55:22+00:00"
},
{
"name": "phpstan/phpstan-symfony",
@@ -9984,16 +10320,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "12.4.1",
+ "version": "12.4.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "fc5413a2e6d240d2f6d9317bdf7f0a24e73de194"
+ "reference": "9253ec75a672e39fcc9d85bdb61448215b8162c7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fc5413a2e6d240d2f6d9317bdf7f0a24e73de194",
- "reference": "fc5413a2e6d240d2f6d9317bdf7f0a24e73de194",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9253ec75a672e39fcc9d85bdb61448215b8162c7",
+ "reference": "9253ec75a672e39fcc9d85bdb61448215b8162c7",
"shasum": ""
},
"require": {
@@ -10061,7 +10397,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
- "source": "https://github.com/sebastianbergmann/phpunit/tree/12.4.1"
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/12.4.4"
},
"funding": [
{
@@ -10085,7 +10421,7 @@
"type": "tidelift"
}
],
- "time": "2025-10-09T14:08:29+00:00"
+ "time": "2025-11-21T07:39:11+00:00"
},
{
"name": "react/cache",
@@ -10236,16 +10572,16 @@
},
{
"name": "react/dns",
- "version": "v1.13.0",
+ "version": "v1.14.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/dns.git",
- "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5"
+ "reference": "7562c05391f42701c1fccf189c8225fece1cd7c3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5",
- "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5",
+ "url": "https://api.github.com/repos/reactphp/dns/zipball/7562c05391f42701c1fccf189c8225fece1cd7c3",
+ "reference": "7562c05391f42701c1fccf189c8225fece1cd7c3",
"shasum": ""
},
"require": {
@@ -10300,7 +10636,7 @@
],
"support": {
"issues": "https://github.com/reactphp/dns/issues",
- "source": "https://github.com/reactphp/dns/tree/v1.13.0"
+ "source": "https://github.com/reactphp/dns/tree/v1.14.0"
},
"funding": [
{
@@ -10308,20 +10644,20 @@
"type": "open_collective"
}
],
- "time": "2024-06-13T14:18:03+00:00"
+ "time": "2025-11-18T19:34:28+00:00"
},
{
"name": "react/event-loop",
- "version": "v1.5.0",
+ "version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/event-loop.git",
- "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354"
+ "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354",
- "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354",
+ "url": "https://api.github.com/repos/reactphp/event-loop/zipball/ba276bda6083df7e0050fd9b33f66ad7a4ac747a",
+ "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a",
"shasum": ""
},
"require": {
@@ -10372,7 +10708,7 @@
],
"support": {
"issues": "https://github.com/reactphp/event-loop/issues",
- "source": "https://github.com/reactphp/event-loop/tree/v1.5.0"
+ "source": "https://github.com/reactphp/event-loop/tree/v1.6.0"
},
"funding": [
{
@@ -10380,7 +10716,7 @@
"type": "open_collective"
}
],
- "time": "2023-11-13T13:48:05+00:00"
+ "time": "2025-11-17T20:46:25+00:00"
},
{
"name": "react/promise",
@@ -10457,16 +10793,16 @@
},
{
"name": "react/socket",
- "version": "v1.16.0",
+ "version": "v1.17.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/socket.git",
- "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1"
+ "reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1",
- "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1",
+ "url": "https://api.github.com/repos/reactphp/socket/zipball/ef5b17b81f6f60504c539313f94f2d826c5faa08",
+ "reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08",
"shasum": ""
},
"require": {
@@ -10525,7 +10861,7 @@
],
"support": {
"issues": "https://github.com/reactphp/socket/issues",
- "source": "https://github.com/reactphp/socket/tree/v1.16.0"
+ "source": "https://github.com/reactphp/socket/tree/v1.17.0"
},
"funding": [
{
@@ -10533,7 +10869,7 @@
"type": "open_collective"
}
],
- "time": "2024-07-26T10:38:09+00:00"
+ "time": "2025-11-19T20:47:34+00:00"
},
{
"name": "react/stream",
@@ -10615,21 +10951,21 @@
},
{
"name": "rector/rector",
- "version": "2.2.6",
+ "version": "2.2.9",
"source": {
"type": "git",
"url": "https://github.com/rectorphp/rector.git",
- "reference": "5c5bbc956b9a056a26cb593379253104b7ed9c2d"
+ "reference": "0b8e49ec234877b83244d2ecd0df7a4c16471f05"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/rectorphp/rector/zipball/5c5bbc956b9a056a26cb593379253104b7ed9c2d",
- "reference": "5c5bbc956b9a056a26cb593379253104b7ed9c2d",
+ "url": "https://api.github.com/repos/rectorphp/rector/zipball/0b8e49ec234877b83244d2ecd0df7a4c16471f05",
+ "reference": "0b8e49ec234877b83244d2ecd0df7a4c16471f05",
"shasum": ""
},
"require": {
"php": "^7.4|^8.0",
- "phpstan/phpstan": "^2.1.26"
+ "phpstan/phpstan": "^2.1.32"
},
"conflict": {
"rector/rector-doctrine": "*",
@@ -10663,7 +10999,7 @@
],
"support": {
"issues": "https://github.com/rectorphp/rector/issues",
- "source": "https://github.com/rectorphp/rector/tree/2.2.6"
+ "source": "https://github.com/rectorphp/rector/tree/2.2.9"
},
"funding": [
{
@@ -10671,7 +11007,7 @@
"type": "github"
}
],
- "time": "2025-10-27T11:35:56+00:00"
+ "time": "2025-11-28T14:21:22+00:00"
},
{
"name": "roave/security-advisories",
@@ -10679,18 +11015,18 @@
"source": {
"type": "git",
"url": "https://github.com/Roave/SecurityAdvisories.git",
- "reference": "960ccb49b6f273fa566a23fd2e8968f81ad207dd"
+ "reference": "3f393e137e490ecb2ac77989a692129c31192de7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/960ccb49b6f273fa566a23fd2e8968f81ad207dd",
- "reference": "960ccb49b6f273fa566a23fd2e8968f81ad207dd",
+ "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/3f393e137e490ecb2ac77989a692129c31192de7",
+ "reference": "3f393e137e490ecb2ac77989a692129c31192de7",
"shasum": ""
},
"conflict": {
"3f/pygmentize": "<1.2",
"adaptcms/adaptcms": "<=1.3",
- "admidio/admidio": "<4.3.12",
+ "admidio/admidio": "<=4.3.16",
"adodb/adodb-php": "<=5.22.9",
"aheinze/cockpit": "<2.2",
"aimeos/ai-admin-graphql": ">=2022.04.1,<2022.10.10|>=2023.04.1,<2023.10.6|>=2024.04.1,<2024.07.2",
@@ -10737,7 +11073,7 @@
"aws/aws-sdk-php": "<3.288.1",
"azuracast/azuracast": "<0.18.3",
"b13/seo_basics": "<0.8.2",
- "backdrop/backdrop": "<1.27.3|>=1.28,<1.28.2",
+ "backdrop/backdrop": "<=1.32",
"backpack/crud": "<3.4.9",
"backpack/filemanager": "<2.0.2|>=3,<3.0.9",
"bacula-web/bacula-web": "<9.7.1",
@@ -10793,12 +11129,14 @@
"clickstorm/cs-seo": ">=6,<6.8|>=7,<7.5|>=8,<8.4|>=9,<9.3",
"co-stack/fal_sftp": "<0.2.6",
"cockpit-hq/cockpit": "<2.11.4",
+ "code16/sharp": "<9.11.1",
"codeception/codeception": "<3.1.3|>=4,<4.1.22",
"codeigniter/framework": "<3.1.10",
"codeigniter4/framework": "<4.6.2",
"codeigniter4/shield": "<1.0.0.0-beta8",
"codiad/codiad": "<=2.8.4",
"codingms/additional-tca": ">=1.7,<1.15.17|>=1.16,<1.16.9",
+ "codingms/modules": "<4.3.11|>=5,<5.7.4|>=6,<6.4.2|>=7,<7.5.5",
"commerceteam/commerce": ">=0.9.6,<0.9.9",
"components/jquery": ">=1.0.3,<3.5",
"composer/composer": "<1.10.27|>=2,<2.2.24|>=2.3,<2.7.7",
@@ -10808,7 +11146,7 @@
"contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4",
"contao/contao": ">=3,<3.5.37|>=4,<4.4.56|>=4.5,<4.13.56|>=5,<5.3.38|>=5.4.0.0-RC1-dev,<5.6.1",
"contao/core": "<3.5.39",
- "contao/core-bundle": "<4.13.56|>=5,<5.3.38|>=5.4,<5.6.1",
+ "contao/core-bundle": "<4.13.57|>=5,<5.3.42|>=5.4,<5.6.5",
"contao/listing-bundle": ">=3,<=3.5.30|>=4,<4.4.8",
"contao/managed-edition": "<=1.5",
"corveda/phpsandbox": "<1.3.5",
@@ -10832,6 +11170,7 @@
"derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1|>=7,<7.4",
"desperado/xml-bundle": "<=0.1.7",
"dev-lancer/minecraft-motd-parser": "<=1.0.5",
+ "devcode-it/openstamanager": "<=2.9.4",
"devgroup/dotplant": "<2020.09.14-dev",
"digimix/wp-svg-upload": "<=1",
"directmailteam/direct-mail": "<6.0.3|>=7,<7.0.3|>=8,<9.5.2",
@@ -10851,30 +11190,41 @@
"dompdf/dompdf": "<2.0.4",
"doublethreedigital/guest-entries": "<3.1.2",
"drupal-pattern-lab/unified-twig-extensions": "<=0.1",
+ "drupal/access_code": "<2.0.5",
+ "drupal/acquia_dam": "<1.1.5",
"drupal/admin_audit_trail": "<1.0.5",
"drupal/ai": "<1.0.5",
"drupal/alogin": "<2.0.6",
"drupal/cache_utility": "<1.2.1",
+ "drupal/civictheme": "<1.12",
"drupal/commerce_alphabank_redirect": "<1.0.3",
"drupal/commerce_eurobank_redirect": "<2.1.1",
"drupal/config_split": "<1.10|>=2,<2.0.2",
- "drupal/core": ">=6,<6.38|>=7,<7.102|>=8,<10.3.14|>=10.4,<10.4.5|>=11,<11.0.13|>=11.1,<11.1.5",
+ "drupal/core": ">=6,<6.38|>=7,<7.102|>=8,<10.4.9|>=10.5,<10.5.6|>=11,<11.1.9|>=11.2,<11.2.8",
"drupal/core-recommended": ">=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8",
+ "drupal/currency": "<3.5",
"drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8",
+ "drupal/email_tfa": "<2.0.6",
"drupal/formatter_suite": "<2.1",
"drupal/gdpr": "<3.0.1|>=3.1,<3.1.2",
"drupal/google_tag": "<1.8|>=2,<2.0.8",
"drupal/ignition": "<1.0.4",
+ "drupal/json_field": "<1.5",
"drupal/lightgallery": "<1.6",
"drupal/link_field_display_mode_formatter": "<1.6",
"drupal/matomo": "<1.24",
"drupal/oauth2_client": "<4.1.3",
"drupal/oauth2_server": "<2.1",
"drupal/obfuscate": "<2.0.1",
+ "drupal/plausible_tracking": "<1.0.2",
"drupal/quick_node_block": "<2",
"drupal/rapidoc_elements_field_formatter": "<1.0.1",
+ "drupal/reverse_proxy_header": "<1.1.2",
+ "drupal/simple_multistep": "<2",
+ "drupal/simple_oauth": ">=6,<6.0.7",
"drupal/spamspan": "<3.2.1",
"drupal/tfa": "<1.10",
+ "drupal/umami_analytics": "<1.0.1",
"duncanmcclean/guest-entries": "<3.1.2",
"dweeves/magmi": "<=0.7.24",
"ec-cube/ec-cube": "<2.4.4|>=2.11,<=2.17.1|>=3,<=3.0.18.0-patch4|>=4,<=4.1.2",
@@ -10961,9 +11311,9 @@
"genix/cms": "<=1.1.11",
"georgringer/news": "<1.3.3",
"geshi/geshi": "<=1.0.9.1",
- "getformwork/formwork": "<1.13.1|>=2.0.0.0-beta1,<2.0.0.0-beta4",
+ "getformwork/formwork": "<2.2",
"getgrav/grav": "<1.7.46",
- "getkirby/cms": "<3.9.8.3-dev|>=3.10,<3.10.1.2-dev|>=4,<4.7.1",
+ "getkirby/cms": "<3.9.8.3-dev|>=3.10,<3.10.1.2-dev|>=4,<4.7.1|>=5,<5.1.4",
"getkirby/kirby": "<3.9.8.3-dev|>=3.10,<3.10.1.2-dev|>=4,<4.7.1",
"getkirby/panel": "<2.5.14",
"getkirby/starterkit": "<=3.7.0.2",
@@ -11109,7 +11459,7 @@
"maikuolan/phpmussel": ">=1,<1.6",
"mainwp/mainwp": "<=4.4.3.3",
"manogi/nova-tiptap": "<=3.2.6",
- "mantisbt/mantisbt": "<=2.26.3",
+ "mantisbt/mantisbt": "<2.27.2",
"marcwillmann/turn": "<0.3.3",
"marshmallow/nova-tiptap": "<5.7",
"matomo/matomo": "<1.11",
@@ -11143,17 +11493,17 @@
"modx/revolution": "<=3.1",
"mojo42/jirafeau": "<4.4",
"mongodb/mongodb": ">=1,<1.9.2",
+ "mongodb/mongodb-extension": "<1.21.2",
"monolog/monolog": ">=1.8,<1.12",
- "moodle/moodle": "<4.3.12|>=4.4,<4.4.8|>=4.5.0.0-beta,<4.5.4",
+ "moodle/moodle": "<4.4.11|>=4.5.0.0-beta,<4.5.7|>=5.0.0.0-beta,<5.0.3",
"moonshine/moonshine": "<=3.12.5",
"mos/cimage": "<0.7.19",
"movim/moxl": ">=0.8,<=0.10",
"movingbytes/social-network": "<=1.2.1",
"mpdf/mpdf": "<=7.1.7",
- "munkireport/comment": "<4.1",
+ "munkireport/comment": "<4",
"munkireport/managedinstalls": "<2.6",
"munkireport/munki_facts": "<1.5",
- "munkireport/munkireport": ">=2.5.3,<5.6.3",
"munkireport/reportdata": "<3.5",
"munkireport/softwareupdate": "<1.6",
"mustache/mustache": ">=2,<2.14.1",
@@ -11197,7 +11547,7 @@
"open-web-analytics/open-web-analytics": "<1.8.1",
"opencart/opencart": ">=0",
"openid/php-openid": "<2.3",
- "openmage/magento-lts": "<20.12.3",
+ "openmage/magento-lts": "<20.16",
"opensolutions/vimbadmin": "<=3.0.15",
"opensource-workshop/connect-cms": "<1.8.7|>=2,<2.4.7",
"orchid/platform": ">=8,<14.43",
@@ -11238,11 +11588,12 @@
"phpmailer/phpmailer": "<6.5",
"phpmussel/phpmussel": ">=1,<1.6",
"phpmyadmin/phpmyadmin": "<5.2.2",
- "phpmyfaq/phpmyfaq": "<3.2.5|==3.2.5|>=3.2.10,<=4.0.1",
+ "phpmyfaq/phpmyfaq": "<=4.0.13",
"phpoffice/common": "<0.2.9",
"phpoffice/math": "<=0.2",
"phpoffice/phpexcel": "<=1.8.2",
"phpoffice/phpspreadsheet": "<1.30|>=2,<2.1.12|>=2.2,<2.4|>=3,<3.10|>=4,<5",
+ "phppgadmin/phppgadmin": "<=7.13",
"phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36",
"phpservermon/phpservermon": "<3.6",
"phpsysinfo/phpsysinfo": "<3.4.3",
@@ -11278,8 +11629,8 @@
"prestashop/ps_emailsubscription": "<2.6.1",
"prestashop/ps_facetedsearch": "<3.4.1",
"prestashop/ps_linklist": "<3.1",
- "privatebin/privatebin": "<1.4|>=1.5,<1.7.4",
- "processwire/processwire": "<=3.0.229",
+ "privatebin/privatebin": "<1.4|>=1.5,<1.7.4|>=1.7.7,<2.0.3",
+ "processwire/processwire": "<=3.0.246",
"propel/propel": ">=2.0.0.0-alpha1,<=2.0.0.0-alpha7",
"propel/propel1": ">=1,<=1.7.1",
"pterodactyl/panel": "<=1.11.10",
@@ -11300,7 +11651,7 @@
"rap2hpoutre/laravel-log-viewer": "<0.13",
"react/http": ">=0.7,<1.9",
"really-simple-plugins/complianz-gdpr": "<6.4.2",
- "redaxo/source": "<5.18.3",
+ "redaxo/source": "<5.20.1",
"remdex/livehelperchat": "<4.29",
"renolit/reint-downloadmanager": "<4.0.2|>=5,<5.0.1",
"reportico-web/reportico": "<=8.1",
@@ -11322,7 +11673,7 @@
"setasign/fpdi": "<2.6.4",
"sfroemken/url_redirect": "<=1.2.1",
"sheng/yiicms": "<1.2.1",
- "shopware/core": "<6.6.10.7-dev|>=6.7,<6.7.3.1-dev",
+ "shopware/core": "<6.6.10.9-dev|>=6.7,<6.7.4.1-dev",
"shopware/platform": "<6.6.10.7-dev|>=6.7,<6.7.3.1-dev",
"shopware/production": "<=6.3.5.2",
"shopware/shopware": "<=5.7.17|>=6.7,<6.7.2.1-dev",
@@ -11367,7 +11718,7 @@
"slim/slim": "<2.6",
"slub/slub-events": "<3.0.3",
"smarty/smarty": "<4.5.3|>=5,<5.1.1",
- "snipe/snipe-it": "<8.1.18",
+ "snipe/snipe-it": "<=8.3.4",
"socalnick/scn-social-auth": "<1.15.2",
"socialiteproviders/steam": "<1.1",
"solspace/craft-freeform": ">=5,<5.10.16",
@@ -11376,6 +11727,7 @@
"spatie/image-optimizer": "<1.7.3",
"spencer14420/sp-php-email-handler": "<1",
"spipu/html2pdf": "<5.2.8",
+ "spiral/roadrunner": "<2025.1",
"spoon/library": "<1.4.1",
"spoonity/tcpdf": "<6.2.22",
"squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1",
@@ -11384,7 +11736,7 @@
"starcitizentools/short-description": ">=4,<4.0.1",
"starcitizentools/tabber-neue": ">=1.9.1,<2.7.2|>=3,<3.1.1",
"starcitizenwiki/embedvideo": "<=4",
- "statamic/cms": "<=5.16",
+ "statamic/cms": "<=5.22",
"stormpath/sdk": "<9.9.99",
"studio-42/elfinder": "<=2.1.64",
"studiomitte/friendlycaptcha": "<0.1.4",
@@ -11415,7 +11767,7 @@
"symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1",
"symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<5.3.15|>=5.4.3,<5.4.4|>=6.0.3,<6.0.4",
"symfony/http-client": ">=4.3,<5.4.47|>=6,<6.4.15|>=7,<7.1.8",
- "symfony/http-foundation": "<5.4.46|>=6,<6.4.14|>=7,<7.1.7",
+ "symfony/http-foundation": "<5.4.50|>=6,<6.4.29|>=7,<7.3.7",
"symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6",
"symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13",
"symfony/maker-bundle": ">=1.27,<1.29.2|>=1.30,<1.31.1",
@@ -11434,7 +11786,7 @@
"symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8",
"symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.4.47|>=6,<6.4.15|>=7,<7.1.8",
"symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12",
- "symfony/symfony": "<5.4.47|>=6,<6.4.15|>=7,<7.1.8",
+ "symfony/symfony": "<5.4.50|>=6,<6.4.29|>=7,<7.3.7",
"symfony/translation": ">=2,<2.0.17",
"symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8",
"symfony/ux-autocomplete": "<2.11.2",
@@ -11458,7 +11810,7 @@
"thelia/thelia": ">=2.1,<2.1.3",
"theonedemon/phpwhois": "<=4.2.5",
"thinkcmf/thinkcmf": "<6.0.8",
- "thorsten/phpmyfaq": "<=4.0.1|>=4.0.7,<4.0.13",
+ "thorsten/phpmyfaq": "<=4.0.13",
"tikiwiki/tiki-manager": "<=17.1",
"timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1",
"tinymce/tinymce": "<7.2",
@@ -11469,7 +11821,7 @@
"topthink/framework": "<6.0.17|>=6.1,<=8.0.4",
"topthink/think": "<=6.1.1",
"topthink/thinkphp": "<=3.2.3|>=6.1.3,<=8.0.4",
- "torrentpier/torrentpier": "<=2.4.3",
+ "torrentpier/torrentpier": "<=2.8.8",
"tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2",
"tribalsystems/zenario": "<=9.7.61188",
"truckersmp/phpwhois": "<=4.3.1",
@@ -11651,7 +12003,7 @@
"type": "tidelift"
}
],
- "time": "2025-10-21T18:07:19+00:00"
+ "time": "2025-11-26T00:22:38+00:00"
},
{
"name": "sebastian/cli-parser",
@@ -12604,27 +12956,28 @@
},
{
"name": "symfony/browser-kit",
- "version": "v7.3.2",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/browser-kit.git",
- "reference": "f0b889b73a845cddef1d25fe207b37fd04cb5419"
+ "reference": "3bb26dafce31633b1f699894c86379eefc8af5bb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/browser-kit/zipball/f0b889b73a845cddef1d25fe207b37fd04cb5419",
- "reference": "f0b889b73a845cddef1d25fe207b37fd04cb5419",
+ "url": "https://api.github.com/repos/symfony/browser-kit/zipball/3bb26dafce31633b1f699894c86379eefc8af5bb",
+ "reference": "3bb26dafce31633b1f699894c86379eefc8af5bb",
"shasum": ""
},
"require": {
"php": ">=8.2",
- "symfony/dom-crawler": "^6.4|^7.0"
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/dom-crawler": "^6.4|^7.0|^8.0"
},
"require-dev": {
- "symfony/css-selector": "^6.4|^7.0",
- "symfony/http-client": "^6.4|^7.0",
- "symfony/mime": "^6.4|^7.0",
- "symfony/process": "^6.4|^7.0"
+ "symfony/css-selector": "^6.4|^7.0|^8.0",
+ "symfony/http-client": "^6.4|^7.0|^8.0",
+ "symfony/mime": "^6.4|^7.0|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -12652,7 +13005,7 @@
"description": "Simulates the behavior of a web browser, allowing you to make requests, click on links and submit forms programmatically",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/browser-kit/tree/v7.3.2"
+ "source": "https://github.com/symfony/browser-kit/tree/v7.4.0"
},
"funding": [
{
@@ -12672,20 +13025,20 @@
"type": "tidelift"
}
],
- "time": "2025-07-10T08:47:49+00:00"
+ "time": "2025-11-05T14:29:59+00:00"
},
{
"name": "symfony/css-selector",
- "version": "v7.3.0",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2"
+ "reference": "ab862f478513e7ca2fe9ec117a6f01a8da6e1135"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2",
- "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/ab862f478513e7ca2fe9ec117a6f01a8da6e1135",
+ "reference": "ab862f478513e7ca2fe9ec117a6f01a8da6e1135",
"shasum": ""
},
"require": {
@@ -12721,7 +13074,7 @@
"description": "Converts CSS selectors to XPath expressions",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/css-selector/tree/v7.3.0"
+ "source": "https://github.com/symfony/css-selector/tree/v7.4.0"
},
"funding": [
{
@@ -12732,35 +13085,40 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2024-09-25T14:21:43+00:00"
+ "time": "2025-10-30T13:39:42+00:00"
},
{
"name": "symfony/dom-crawler",
- "version": "v7.3.3",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
- "reference": "efa076ea0eeff504383ff0dcf827ea5ce15690ba"
+ "reference": "8f3e7464fe7e77294686e935956a6a8ccf7442c4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/efa076ea0eeff504383ff0dcf827ea5ce15690ba",
- "reference": "efa076ea0eeff504383ff0dcf827ea5ce15690ba",
+ "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/8f3e7464fe7e77294686e935956a6a8ccf7442c4",
+ "reference": "8f3e7464fe7e77294686e935956a6a8ccf7442c4",
"shasum": ""
},
"require": {
"masterminds/html5": "^2.6",
"php": ">=8.2",
+ "symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.0"
},
"require-dev": {
- "symfony/css-selector": "^6.4|^7.0"
+ "symfony/css-selector": "^6.4|^7.0|^8.0"
},
"type": "library",
"autoload": {
@@ -12788,7 +13146,7 @@
"description": "Eases DOM navigation for HTML and XML documents",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/dom-crawler/tree/v7.3.3"
+ "source": "https://github.com/symfony/dom-crawler/tree/v7.4.0"
},
"funding": [
{
@@ -12808,35 +13166,35 @@
"type": "tidelift"
}
],
- "time": "2025-08-06T20:13:54+00:00"
+ "time": "2025-10-31T09:30:03+00:00"
},
{
"name": "symfony/maker-bundle",
- "version": "v1.64.0",
+ "version": "v1.65.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/maker-bundle.git",
- "reference": "c86da84640b0586e92aee2b276ee3638ef2f425a"
+ "reference": "9a0276d7486b29cae641b4a0a85d5e5cc149bff2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/c86da84640b0586e92aee2b276ee3638ef2f425a",
- "reference": "c86da84640b0586e92aee2b276ee3638ef2f425a",
+ "url": "https://api.github.com/repos/symfony/maker-bundle/zipball/9a0276d7486b29cae641b4a0a85d5e5cc149bff2",
+ "reference": "9a0276d7486b29cae641b4a0a85d5e5cc149bff2",
"shasum": ""
},
"require": {
"doctrine/inflector": "^2.0",
"nikic/php-parser": "^5.0",
"php": ">=8.1",
- "symfony/config": "^6.4|^7.0",
- "symfony/console": "^6.4|^7.0",
- "symfony/dependency-injection": "^6.4|^7.0",
+ "symfony/config": "^6.4|^7.0|^8.0",
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/dependency-injection": "^6.4|^7.0|^8.0",
"symfony/deprecation-contracts": "^2.2|^3",
- "symfony/filesystem": "^6.4|^7.0",
- "symfony/finder": "^6.4|^7.0",
- "symfony/framework-bundle": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/process": "^6.4|^7.0"
+ "symfony/filesystem": "^6.4|^7.0|^8.0",
+ "symfony/finder": "^6.4|^7.0|^8.0",
+ "symfony/framework-bundle": "^6.4|^7.0|^8.0",
+ "symfony/http-kernel": "^6.4|^7.0|^8.0",
+ "symfony/process": "^6.4|^7.0|^8.0"
},
"conflict": {
"doctrine/doctrine-bundle": "<2.10",
@@ -12844,13 +13202,14 @@
},
"require-dev": {
"composer/semver": "^3.0",
- "doctrine/doctrine-bundle": "^2.5.0",
+ "doctrine/doctrine-bundle": "^2.5.0|^3.0.0",
"doctrine/orm": "^2.15|^3",
- "symfony/http-client": "^6.4|^7.0",
- "symfony/phpunit-bridge": "^6.4.1|^7.0",
- "symfony/security-core": "^6.4|^7.0",
- "symfony/security-http": "^6.4|^7.0",
- "symfony/yaml": "^6.4|^7.0",
+ "doctrine/persistence": "^3.1|^4.0",
+ "symfony/http-client": "^6.4|^7.0|^8.0",
+ "symfony/phpunit-bridge": "^6.4.1|^7.0|^8.0",
+ "symfony/security-core": "^6.4|^7.0|^8.0",
+ "symfony/security-http": "^6.4|^7.0|^8.0",
+ "symfony/yaml": "^6.4|^7.0|^8.0",
"twig/twig": "^3.0|^4.x-dev"
},
"type": "symfony-bundle",
@@ -12885,7 +13244,7 @@
],
"support": {
"issues": "https://github.com/symfony/maker-bundle/issues",
- "source": "https://github.com/symfony/maker-bundle/tree/v1.64.0"
+ "source": "https://github.com/symfony/maker-bundle/tree/v1.65.0"
},
"funding": [
{
@@ -12896,37 +13255,37 @@
"url": "https://github.com/fabpot",
"type": "github"
},
+ {
+ "url": "https://github.com/nicolas-grekas",
+ "type": "github"
+ },
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
- "time": "2025-06-23T16:12:08+00:00"
+ "time": "2025-11-24T15:41:51+00:00"
},
{
"name": "symfony/phpunit-bridge",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/phpunit-bridge.git",
- "reference": "ed77a629c13979e051b7000a317966474d566398"
+ "reference": "059b051b38f2138ef104dd848fa48f0cbbb7d78b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/ed77a629c13979e051b7000a317966474d566398",
- "reference": "ed77a629c13979e051b7000a317966474d566398",
+ "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/059b051b38f2138ef104dd848fa48f0cbbb7d78b",
+ "reference": "059b051b38f2138ef104dd848fa48f0cbbb7d78b",
"shasum": ""
},
"require": {
- "php": ">=7.2.5"
- },
- "conflict": {
- "phpunit/phpunit": "<7.5|9.1.2"
+ "php": ">=8.1.0"
},
"require-dev": {
- "symfony/deprecation-contracts": "^2.5|^3.0",
- "symfony/error-handler": "^5.4|^6.4|^7.0",
- "symfony/polyfill-php81": "^1.27"
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/error-handler": "^6.4.3|^7.0.3|^8.0"
},
"bin": [
"bin/simple-phpunit"
@@ -12970,7 +13329,7 @@
"testing"
],
"support": {
- "source": "https://github.com/symfony/phpunit-bridge/tree/v7.3.4"
+ "source": "https://github.com/symfony/phpunit-bridge/tree/v7.4.0"
},
"funding": [
{
@@ -12990,32 +13349,32 @@
"type": "tidelift"
}
],
- "time": "2025-09-12T12:18:52+00:00"
+ "time": "2025-10-28T22:44:23+00:00"
},
{
"name": "symfony/web-profiler-bundle",
- "version": "v7.3.4",
+ "version": "v7.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/web-profiler-bundle.git",
- "reference": "f305fa4add690bb7d6b14ab61f37c3bd061a3dd7"
+ "reference": "dcd955ca9c60f2942194854518049f8ae4dbd696"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/f305fa4add690bb7d6b14ab61f37c3bd061a3dd7",
- "reference": "f305fa4add690bb7d6b14ab61f37c3bd061a3dd7",
+ "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/dcd955ca9c60f2942194854518049f8ae4dbd696",
+ "reference": "dcd955ca9c60f2942194854518049f8ae4dbd696",
"shasum": ""
},
"require": {
"composer-runtime-api": ">=2.1",
"php": ">=8.2",
- "symfony/config": "^7.3",
+ "symfony/config": "^7.3|^8.0",
"symfony/deprecation-contracts": "^2.5|^3",
- "symfony/framework-bundle": "^6.4|^7.0",
- "symfony/http-kernel": "^6.4|^7.0",
- "symfony/routing": "^6.4|^7.0",
- "symfony/twig-bundle": "^6.4|^7.0",
- "twig/twig": "^3.12"
+ "symfony/framework-bundle": "^6.4.13|^7.1.6|^8.0",
+ "symfony/http-kernel": "^6.4.13|^7.1.6|^8.0",
+ "symfony/routing": "^6.4|^7.0|^8.0",
+ "symfony/twig-bundle": "^6.4|^7.0|^8.0",
+ "twig/twig": "^3.15"
},
"conflict": {
"symfony/form": "<6.4",
@@ -13025,10 +13384,11 @@
"symfony/workflow": "<7.3"
},
"require-dev": {
- "symfony/browser-kit": "^6.4|^7.0",
- "symfony/console": "^6.4|^7.0",
- "symfony/css-selector": "^6.4|^7.0",
- "symfony/stopwatch": "^6.4|^7.0"
+ "symfony/browser-kit": "^6.4|^7.0|^8.0",
+ "symfony/console": "^6.4|^7.0|^8.0",
+ "symfony/css-selector": "^6.4|^7.0|^8.0",
+ "symfony/runtime": "^6.4.13|^7.1.6|^8.0",
+ "symfony/stopwatch": "^6.4|^7.0|^8.0"
},
"type": "symfony-bundle",
"autoload": {
@@ -13059,7 +13419,7 @@
"dev"
],
"support": {
- "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.3.4"
+ "source": "https://github.com/symfony/web-profiler-bundle/tree/v7.4.0"
},
"funding": [
{
@@ -13079,20 +13439,20 @@
"type": "tidelift"
}
],
- "time": "2025-09-25T08:03:55+00:00"
+ "time": "2025-11-19T14:48:01+00:00"
},
{
"name": "thecodingmachine/phpstan-safe-rule",
- "version": "v1.4.1",
+ "version": "v1.4.3",
"source": {
"type": "git",
"url": "https://github.com/thecodingmachine/phpstan-safe-rule.git",
- "reference": "5f9795eae8891dffa475965463a4281633651768"
+ "reference": "5c804889253ce9498ef185e108e9f94b6023208e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/thecodingmachine/phpstan-safe-rule/zipball/5f9795eae8891dffa475965463a4281633651768",
- "reference": "5f9795eae8891dffa475965463a4281633651768",
+ "url": "https://api.github.com/repos/thecodingmachine/phpstan-safe-rule/zipball/5c804889253ce9498ef185e108e9f94b6023208e",
+ "reference": "5c804889253ce9498ef185e108e9f94b6023208e",
"shasum": ""
},
"require": {
@@ -13135,22 +13495,22 @@
"description": "A PHPStan rule to detect safety issues. Must be used in conjunction with thecodingmachine/safe",
"support": {
"issues": "https://github.com/thecodingmachine/phpstan-safe-rule/issues",
- "source": "https://github.com/thecodingmachine/phpstan-safe-rule/tree/v1.4.1"
+ "source": "https://github.com/thecodingmachine/phpstan-safe-rule/tree/v1.4.3"
},
- "time": "2025-04-09T20:30:35+00:00"
+ "time": "2025-11-21T09:41:49+00:00"
},
{
"name": "theseer/tokenizer",
- "version": "1.2.3",
+ "version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/theseer/tokenizer.git",
- "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2"
+ "reference": "b7489ce515e168639d17feec34b8847c326b0b3c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
- "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2",
+ "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c",
+ "reference": "b7489ce515e168639d17feec34b8847c326b0b3c",
"shasum": ""
},
"require": {
@@ -13179,7 +13539,7 @@
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
"support": {
"issues": "https://github.com/theseer/tokenizer/issues",
- "source": "https://github.com/theseer/tokenizer/tree/1.2.3"
+ "source": "https://github.com/theseer/tokenizer/tree/1.3.1"
},
"funding": [
{
@@ -13187,20 +13547,20 @@
"type": "github"
}
],
- "time": "2024-03-03T12:36:25+00:00"
+ "time": "2025-11-17T20:03:58+00:00"
},
{
"name": "vincentlanglet/twig-cs-fixer",
- "version": "3.10.0",
+ "version": "3.11.0",
"source": {
"type": "git",
"url": "https://github.com/VincentLanglet/Twig-CS-Fixer.git",
- "reference": "ee9b6a31d2c2522b2773ecf31f5d29c2e26311a6"
+ "reference": "866af065fd09980b6390ee5c69e45b08053101e8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/VincentLanglet/Twig-CS-Fixer/zipball/ee9b6a31d2c2522b2773ecf31f5d29c2e26311a6",
- "reference": "ee9b6a31d2c2522b2773ecf31f5d29c2e26311a6",
+ "url": "https://api.github.com/repos/VincentLanglet/Twig-CS-Fixer/zipball/866af065fd09980b6390ee5c69e45b08053101e8",
+ "reference": "866af065fd09980b6390ee5c69e45b08053101e8",
"shasum": ""
},
"require": {
@@ -13256,7 +13616,7 @@
"homepage": "https://github.com/VincentLanglet/Twig-CS-Fixer",
"support": {
"issues": "https://github.com/VincentLanglet/Twig-CS-Fixer/issues",
- "source": "https://github.com/VincentLanglet/Twig-CS-Fixer/tree/3.10.0"
+ "source": "https://github.com/VincentLanglet/Twig-CS-Fixer/tree/3.11.0"
},
"funding": [
{
@@ -13264,7 +13624,7 @@
"type": "github"
}
],
- "time": "2025-09-15T11:28:55+00:00"
+ "time": "2025-11-24T18:13:18+00:00"
}
],
"aliases": [],
@@ -13275,10 +13635,10 @@
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
- "php": ">=8.4",
+ "php": ">=8.5",
"ext-ctype": "*",
"ext-iconv": "*"
},
"platform-dev": {},
- "plugin-api-version": "2.6.0"
+ "plugin-api-version": "2.9.0"
}
diff --git a/config/bundles.php b/config/bundles.php
index 31046bc..0cf9639 100644
--- a/config/bundles.php
+++ b/config/bundles.php
@@ -2,10 +2,12 @@
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;
@@ -32,4 +34,6 @@ return [
SymfonycastsSassBundle::class => ['all' => true],
StimulusBundle::class => ['all' => true],
TurboBundle::class => ['all' => true],
+ DAMADoctrineTestBundle::class => ['test' => true],
+ StofDoctrineExtensionsBundle::class => ['all' => true],
];
diff --git a/config/packages/dama_doctrine_test_bundle.yaml b/config/packages/dama_doctrine_test_bundle.yaml
new file mode 100644
index 0000000..3482cba
--- /dev/null
+++ b/config/packages/dama_doctrine_test_bundle.yaml
@@ -0,0 +1,5 @@
+when@test:
+ dama_doctrine_test:
+ enable_static_connection: true
+ enable_static_meta_data_cache: true
+ enable_static_query_cache: true
diff --git a/config/packages/sentry.yaml b/config/packages/sentry.yaml
index 5d398b7..d6165de 100644
--- a/config/packages/sentry.yaml
+++ b/config/packages/sentry.yaml
@@ -1,31 +1,36 @@
when@prod:
sentry:
dsn: '%env(SENTRY_DSN)%'
- # 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
-
options:
- traces_sample_rate: 1.0
- profiles_sample_rate: 1.0
+ # 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/#monolog-integration
+#
+# # If you are using Monolog, you also need this additional configuration to log the errors correctly:
+# # https://docs.sentry.io/platforms/php/guides/symfony/#monolog-integration
# 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: sentry
# level: !php/const Monolog\Logger::ERROR
# hub_id: Sentry\State\HubInterface
-
-# Uncomment these lines to register a log message processor that resolves PSR-3 placeholders
-# https://docs.sentry.io/platforms/php/guides/symfony/#monolog-integration
+# fill_extra_context: true # Enables sending monolog context to Sentry
+# process_psr_3_messages: false # Disables the resolution of PSR-3 placeholders
+#
+# # Use this for structured log integration
+# sentry_logs:
+# type: service
+# id: Sentry\SentryBundle\Monolog\LogsHandler
+#
# services:
-# Monolog\Processor\PsrLogMessageProcessor:
-# tags: { name: monolog.processor, handler: sentry }
+# Sentry\SentryBundle\Monolog\LogsHandler:
+# arguments:
+# - !php/const Monolog\Logger::INFO
diff --git a/config/packages/stof_doctrine_extensions.yaml b/config/packages/stof_doctrine_extensions.yaml
new file mode 100644
index 0000000..9718713
--- /dev/null
+++ b/config/packages/stof_doctrine_extensions.yaml
@@ -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
diff --git a/config/preload.php b/config/preload.php
index 7cbe578..b5e3bb0 100644
--- a/config/preload.php
+++ b/config/preload.php
@@ -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';
}
diff --git a/config/reference.php b/config/reference.php
new file mode 100644
index 0000000..14cfbd1
--- /dev/null
+++ b/config/reference.php
@@ -0,0 +1,1636 @@
+ [
+ * 'App\\' => [
+ * 'resource' => '../src/',
+ * ],
+ * ],
+ * ]);
+ * ```
+ *
+ * @psalm-type ImportsConfig = list
+ * @psalm-type ParametersConfig = array|null>|null>
+ * @psalm-type ArgumentsType = list|array
+ * @psalm-type CallType = array|array{0:string, 1?:ArgumentsType, 2?:bool}|array{method:string, arguments?:ArgumentsType, returns_clone?:bool}
+ * @psalm-type TagsType = list>> // arrays inside the list must have only one element, with the tag name as the key
+ * @psalm-type CallbackType = string|array{0:string|ReferenceConfigurator,1:string}|\Closure|ReferenceConfigurator|ExpressionConfigurator
+ * @psalm-type DeprecationType = array{package: string, version: string, message?: string}
+ * @psalm-type DefaultsType = array{
+ * public?: bool,
+ * tags?: TagsType,
+ * resource_tags?: TagsType,
+ * autowire?: bool,
+ * autoconfigure?: bool,
+ * bind?: array,
+ * }
+ * @psalm-type InstanceofType = array{
+ * shared?: bool,
+ * lazy?: bool|string,
+ * public?: bool,
+ * properties?: array,
+ * configurator?: CallbackType,
+ * calls?: list,
+ * tags?: TagsType,
+ * resource_tags?: TagsType,
+ * autowire?: bool,
+ * bind?: array,
+ * constructor?: string,
+ * }
+ * @psalm-type DefinitionType = array{
+ * class?: string,
+ * file?: string,
+ * parent?: string,
+ * shared?: bool,
+ * synthetic?: bool,
+ * lazy?: bool|string,
+ * public?: bool,
+ * abstract?: bool,
+ * deprecated?: DeprecationType,
+ * factory?: CallbackType,
+ * configurator?: CallbackType,
+ * arguments?: ArgumentsType,
+ * properties?: array,
+ * calls?: list,
+ * tags?: TagsType,
+ * resource_tags?: TagsType,
+ * decorates?: string,
+ * decoration_inner_name?: string,
+ * decoration_priority?: int,
+ * decoration_on_invalid?: 'exception'|'ignore'|null,
+ * autowire?: bool,
+ * autoconfigure?: bool,
+ * bind?: array,
+ * constructor?: string,
+ * from_callable?: CallbackType,
+ * }
+ * @psalm-type AliasType = string|array{
+ * alias: string,
+ * public?: bool,
+ * deprecated?: DeprecationType,
+ * }
+ * @psalm-type PrototypeType = array{
+ * resource: string,
+ * namespace?: string,
+ * exclude?: string|list,
+ * parent?: string,
+ * shared?: bool,
+ * lazy?: bool|string,
+ * public?: bool,
+ * abstract?: bool,
+ * deprecated?: DeprecationType,
+ * factory?: CallbackType,
+ * arguments?: ArgumentsType,
+ * properties?: array,
+ * configurator?: CallbackType,
+ * calls?: list,
+ * tags?: TagsType,
+ * resource_tags?: TagsType,
+ * autowire?: bool,
+ * autoconfigure?: bool,
+ * bind?: array,
+ * constructor?: string,
+ * }
+ * @psalm-type StackType = array{
+ * stack: list>,
+ * public?: bool,
+ * deprecated?: DeprecationType,
+ * }
+ * @psalm-type ServicesConfig = array{
+ * _defaults?: DefaultsType,
+ * _instanceof?: InstanceofType,
+ * ...
+ * }
+ * @psalm-type ExtensionType = array
+ * @psalm-type FrameworkConfig = array{
+ * secret?: scalar|null,
+ * http_method_override?: bool, // Set true to enable support for the '_method' request parameter to determine the intended HTTP method on POST requests. // Default: false
+ * allowed_http_method_override?: list|null,
+ * trust_x_sendfile_type_header?: scalar|null, // Set true to enable support for xsendfile in binary file responses. // Default: "%env(bool:default::SYMFONY_TRUST_X_SENDFILE_TYPE_HEADER)%"
+ * ide?: scalar|null, // Default: "%env(default::SYMFONY_IDE)%"
+ * test?: bool,
+ * default_locale?: scalar|null, // Default: "en"
+ * set_locale_from_accept_language?: bool, // Whether to use the Accept-Language HTTP header to set the Request locale (only when the "_locale" request attribute is not passed). // Default: false
+ * set_content_language_from_locale?: bool, // Whether to set the Content-Language HTTP header on the Response using the Request locale. // Default: false
+ * enabled_locales?: list,
+ * trusted_hosts?: list,
+ * trusted_proxies?: mixed, // Default: ["%env(default::SYMFONY_TRUSTED_PROXIES)%"]
+ * trusted_headers?: list,
+ * error_controller?: scalar|null, // Default: "error_controller"
+ * handle_all_throwables?: bool, // HttpKernel will handle all kinds of \Throwable. // Default: true
+ * csrf_protection?: bool|array{
+ * enabled?: scalar|null, // Default: null
+ * stateless_token_ids?: list,
+ * check_header?: scalar|null, // Whether to check the CSRF token in a header in addition to a cookie when using stateless protection. // Default: false
+ * cookie_name?: scalar|null, // The name of the cookie to use when using stateless protection. // Default: "csrf-token"
+ * },
+ * form?: bool|array{ // Form configuration
+ * enabled?: bool, // Default: true
+ * csrf_protection?: array{
+ * enabled?: scalar|null, // Default: null
+ * token_id?: scalar|null, // Default: null
+ * field_name?: scalar|null, // Default: "_token"
+ * field_attr?: array,
+ * },
+ * },
+ * http_cache?: bool|array{ // HTTP cache configuration
+ * enabled?: bool, // Default: false
+ * debug?: bool, // Default: "%kernel.debug%"
+ * trace_level?: "none"|"short"|"full",
+ * trace_header?: scalar|null,
+ * default_ttl?: int,
+ * private_headers?: list,
+ * skip_response_headers?: list,
+ * allow_reload?: bool,
+ * allow_revalidate?: bool,
+ * stale_while_revalidate?: int,
+ * stale_if_error?: int,
+ * terminate_on_cache_hit?: bool,
+ * },
+ * esi?: bool|array{ // ESI configuration
+ * enabled?: bool, // Default: false
+ * },
+ * ssi?: bool|array{ // SSI configuration
+ * enabled?: bool, // Default: false
+ * },
+ * fragments?: bool|array{ // Fragments configuration
+ * enabled?: bool, // Default: false
+ * hinclude_default_template?: scalar|null, // Default: null
+ * path?: scalar|null, // Default: "/_fragment"
+ * },
+ * profiler?: bool|array{ // Profiler configuration
+ * enabled?: bool, // Default: false
+ * collect?: bool, // Default: true
+ * collect_parameter?: scalar|null, // The name of the parameter to use to enable or disable collection on a per request basis. // Default: null
+ * only_exceptions?: bool, // Default: false
+ * only_main_requests?: bool, // Default: false
+ * dsn?: scalar|null, // Default: "file:%kernel.cache_dir%/profiler"
+ * collect_serializer_data?: bool, // Enables the serializer data collector and profiler panel. // Default: false
+ * },
+ * workflows?: bool|array{
+ * enabled?: bool, // Default: false
+ * workflows?: array,
+ * definition_validators?: list,
+ * support_strategy?: scalar|null,
+ * initial_marking?: list,
+ * events_to_dispatch?: list|null,
+ * places?: list,
+ * }>,
+ * transitions: list,
+ * to?: list,
+ * weight?: int, // Default: 1
+ * metadata?: list,
+ * }>,
+ * metadata?: list,
+ * }>,
+ * },
+ * router?: bool|array{ // Router configuration
+ * enabled?: bool, // Default: false
+ * resource: scalar|null,
+ * type?: scalar|null,
+ * cache_dir?: scalar|null, // Deprecated: Setting the "framework.router.cache_dir.cache_dir" configuration option is deprecated. It will be removed in version 8.0. // Default: "%kernel.build_dir%"
+ * default_uri?: scalar|null, // The default URI used to generate URLs in a non-HTTP context. // Default: null
+ * http_port?: scalar|null, // Default: 80
+ * https_port?: scalar|null, // Default: 443
+ * strict_requirements?: scalar|null, // set to true to throw an exception when a parameter does not match the requirements set to false to disable exceptions when a parameter does not match the requirements (and return null instead) set to null to disable parameter checks against requirements 'true' is the preferred configuration in development mode, while 'false' or 'null' might be preferred in production // Default: true
+ * utf8?: bool, // Default: true
+ * },
+ * session?: bool|array{ // Session configuration
+ * enabled?: bool, // Default: false
+ * storage_factory_id?: scalar|null, // Default: "session.storage.factory.native"
+ * handler_id?: scalar|null, // Defaults to using the native session handler, or to the native *file* session handler if "save_path" is not null.
+ * name?: scalar|null,
+ * cookie_lifetime?: scalar|null,
+ * cookie_path?: scalar|null,
+ * cookie_domain?: scalar|null,
+ * cookie_secure?: true|false|"auto", // Default: "auto"
+ * cookie_httponly?: bool, // Default: true
+ * cookie_samesite?: null|"lax"|"strict"|"none", // Default: "lax"
+ * use_cookies?: bool,
+ * gc_divisor?: scalar|null,
+ * gc_probability?: scalar|null,
+ * gc_maxlifetime?: scalar|null,
+ * save_path?: scalar|null, // Defaults to "%kernel.cache_dir%/sessions" if the "handler_id" option is not null.
+ * metadata_update_threshold?: int, // Seconds to wait between 2 session metadata updates. // Default: 0
+ * sid_length?: int, // Deprecated: Setting the "framework.session.sid_length.sid_length" configuration option is deprecated. It will be removed in version 8.0. No alternative is provided as PHP 8.4 has deprecated the related option.
+ * sid_bits_per_character?: int, // Deprecated: Setting the "framework.session.sid_bits_per_character.sid_bits_per_character" configuration option is deprecated. It will be removed in version 8.0. No alternative is provided as PHP 8.4 has deprecated the related option.
+ * },
+ * request?: bool|array{ // Request configuration
+ * enabled?: bool, // Default: false
+ * formats?: array>,
+ * },
+ * assets?: bool|array{ // Assets configuration
+ * enabled?: bool, // Default: true
+ * strict_mode?: bool, // Throw an exception if an entry is missing from the manifest.json. // Default: false
+ * version_strategy?: scalar|null, // Default: null
+ * version?: scalar|null, // Default: null
+ * version_format?: scalar|null, // Default: "%%s?%%s"
+ * json_manifest_path?: scalar|null, // Default: null
+ * base_path?: scalar|null, // Default: ""
+ * base_urls?: list,
+ * packages?: array,
+ * }>,
+ * },
+ * asset_mapper?: bool|array{ // Asset Mapper configuration
+ * enabled?: bool, // Default: true
+ * paths?: array,
+ * excluded_patterns?: list,
+ * exclude_dotfiles?: bool, // If true, any files starting with "." will be excluded from the asset mapper. // Default: true
+ * server?: bool, // If true, a "dev server" will return the assets from the public directory (true in "debug" mode only by default). // Default: true
+ * public_prefix?: scalar|null, // The public path where the assets will be written to (and served from when "server" is true). // Default: "/assets/"
+ * missing_import_mode?: "strict"|"warn"|"ignore", // Behavior if an asset cannot be found when imported from JavaScript or CSS files - e.g. "import './non-existent.js'". "strict" means an exception is thrown, "warn" means a warning is logged, "ignore" means the import is left as-is. // Default: "warn"
+ * extensions?: array,
+ * importmap_path?: scalar|null, // The path of the importmap.php file. // Default: "%kernel.project_dir%/importmap.php"
+ * importmap_polyfill?: scalar|null, // The importmap name that will be used to load the polyfill. Set to false to disable. // Default: "es-module-shims"
+ * importmap_script_attributes?: array,
+ * vendor_dir?: scalar|null, // The directory to store JavaScript vendors. // Default: "%kernel.project_dir%/assets/vendor"
+ * precompress?: bool|array{ // Precompress assets with Brotli, Zstandard and gzip.
+ * enabled?: bool, // Default: false
+ * formats?: list,
+ * extensions?: list,
+ * },
+ * },
+ * translator?: bool|array{ // Translator configuration
+ * enabled?: bool, // Default: true
+ * fallbacks?: list,
+ * logging?: bool, // Default: false
+ * formatter?: scalar|null, // Default: "translator.formatter.default"
+ * cache_dir?: scalar|null, // Default: "%kernel.cache_dir%/translations"
+ * default_path?: scalar|null, // The default path used to load translations. // Default: "%kernel.project_dir%/translations"
+ * paths?: list,
+ * pseudo_localization?: bool|array{
+ * enabled?: bool, // Default: false
+ * accents?: bool, // Default: true
+ * expansion_factor?: float, // Default: 1.0
+ * brackets?: bool, // Default: true
+ * parse_html?: bool, // Default: false
+ * localizable_html_attributes?: list,
+ * },
+ * providers?: array,
+ * locales?: list,
+ * }>,
+ * globals?: array,
+ * domain?: string,
+ * }>,
+ * },
+ * validation?: bool|array{ // Validation configuration
+ * enabled?: bool, // Default: true
+ * cache?: scalar|null, // Deprecated: Setting the "framework.validation.cache.cache" configuration option is deprecated. It will be removed in version 8.0.
+ * enable_attributes?: bool, // Default: true
+ * static_method?: list,
+ * translation_domain?: scalar|null, // Default: "validators"
+ * email_validation_mode?: "html5"|"html5-allow-no-tld"|"strict"|"loose", // Default: "html5"
+ * mapping?: array{
+ * paths?: list,
+ * },
+ * not_compromised_password?: bool|array{
+ * enabled?: bool, // When disabled, compromised passwords will be accepted as valid. // Default: true
+ * endpoint?: scalar|null, // API endpoint for the NotCompromisedPassword Validator. // Default: null
+ * },
+ * disable_translation?: bool, // Default: false
+ * auto_mapping?: array,
+ * }>,
+ * },
+ * annotations?: bool|array{
+ * enabled?: bool, // Default: false
+ * },
+ * serializer?: bool|array{ // Serializer configuration
+ * enabled?: bool, // Default: true
+ * enable_attributes?: bool, // Default: true
+ * name_converter?: scalar|null,
+ * circular_reference_handler?: scalar|null,
+ * max_depth_handler?: scalar|null,
+ * mapping?: array{
+ * paths?: list,
+ * },
+ * default_context?: list,
+ * named_serializers?: array,
+ * include_built_in_normalizers?: bool, // Whether to include the built-in normalizers // Default: true
+ * include_built_in_encoders?: bool, // Whether to include the built-in encoders // Default: true
+ * }>,
+ * },
+ * property_access?: bool|array{ // Property access configuration
+ * enabled?: bool, // Default: true
+ * magic_call?: bool, // Default: false
+ * magic_get?: bool, // Default: true
+ * magic_set?: bool, // Default: true
+ * throw_exception_on_invalid_index?: bool, // Default: false
+ * throw_exception_on_invalid_property_path?: bool, // Default: true
+ * },
+ * type_info?: bool|array{ // Type info configuration
+ * enabled?: bool, // Default: true
+ * aliases?: array,
+ * },
+ * property_info?: bool|array{ // Property info configuration
+ * enabled?: bool, // Default: true
+ * with_constructor_extractor?: bool, // Registers the constructor extractor.
+ * },
+ * cache?: array{ // Cache configuration
+ * prefix_seed?: scalar|null, // Used to namespace cache keys when using several apps with the same shared backend. // Default: "_%kernel.project_dir%.%kernel.container_class%"
+ * app?: scalar|null, // App related cache pools configuration. // Default: "cache.adapter.filesystem"
+ * system?: scalar|null, // System related cache pools configuration. // Default: "cache.adapter.system"
+ * directory?: scalar|null, // Default: "%kernel.share_dir%/pools/app"
+ * default_psr6_provider?: scalar|null,
+ * default_redis_provider?: scalar|null, // Default: "redis://localhost"
+ * default_valkey_provider?: scalar|null, // Default: "valkey://localhost"
+ * default_memcached_provider?: scalar|null, // Default: "memcached://localhost"
+ * default_doctrine_dbal_provider?: scalar|null, // Default: "database_connection"
+ * default_pdo_provider?: scalar|null, // Default: null
+ * pools?: array,
+ * tags?: scalar|null, // Default: null
+ * public?: bool, // Default: false
+ * default_lifetime?: scalar|null, // Default lifetime of the pool.
+ * provider?: scalar|null, // Overwrite the setting from the default provider for this adapter.
+ * early_expiration_message_bus?: scalar|null,
+ * clearer?: scalar|null,
+ * }>,
+ * },
+ * php_errors?: array{ // PHP errors handling configuration
+ * log?: mixed, // Use the application logger instead of the PHP logger for logging PHP errors. // Default: true
+ * throw?: bool, // Throw PHP errors as \ErrorException instances. // Default: true
+ * },
+ * exceptions?: array,
+ * web_link?: bool|array{ // Web links configuration
+ * enabled?: bool, // Default: false
+ * },
+ * lock?: bool|string|array{ // Lock configuration
+ * enabled?: bool, // Default: false
+ * resources?: array>,
+ * },
+ * semaphore?: bool|string|array{ // Semaphore configuration
+ * enabled?: bool, // Default: false
+ * resources?: array,
+ * },
+ * messenger?: bool|array{ // Messenger configuration
+ * enabled?: bool, // Default: false
+ * routing?: array,
+ * }>,
+ * serializer?: array{
+ * default_serializer?: scalar|null, // Service id to use as the default serializer for the transports. // Default: "messenger.transport.native_php_serializer"
+ * symfony_serializer?: array{
+ * format?: scalar|null, // Serialization format for the messenger.transport.symfony_serializer service (which is not the serializer used by default). // Default: "json"
+ * context?: array,
+ * },
+ * },
+ * transports?: array,
+ * failure_transport?: scalar|null, // Transport name to send failed messages to (after all retries have failed). // Default: null
+ * retry_strategy?: string|array{
+ * service?: scalar|null, // Service id to override the retry strategy entirely. // Default: null
+ * max_retries?: int, // Default: 3
+ * delay?: int, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000
+ * multiplier?: float, // If greater than 1, delay will grow exponentially for each retry: this delay = (delay * (multiple ^ retries)). // Default: 2
+ * max_delay?: int, // Max time in ms that a retry should ever be delayed (0 = infinite). // Default: 0
+ * jitter?: float, // Randomness to apply to the delay (between 0 and 1). // Default: 0.1
+ * },
+ * rate_limiter?: scalar|null, // Rate limiter name to use when processing messages. // Default: null
+ * }>,
+ * failure_transport?: scalar|null, // Transport name to send failed messages to (after all retries have failed). // Default: null
+ * stop_worker_on_signals?: list,
+ * default_bus?: scalar|null, // Default: null
+ * buses?: array,
+ * }>,
+ * }>,
+ * },
+ * scheduler?: bool|array{ // Scheduler configuration
+ * enabled?: bool, // Default: false
+ * },
+ * disallow_search_engine_index?: bool, // Enabled by default when debug is enabled. // Default: true
+ * http_client?: bool|array{ // HTTP Client configuration
+ * enabled?: bool, // Default: true
+ * max_host_connections?: int, // The maximum number of connections to a single host.
+ * default_options?: array{
+ * headers?: array,
+ * vars?: list,
+ * max_redirects?: int, // The maximum number of redirects to follow.
+ * http_version?: scalar|null, // The default HTTP version, typically 1.1 or 2.0, leave to null for the best version.
+ * resolve?: array,
+ * proxy?: scalar|null, // The URL of the proxy to pass requests through or null for automatic detection.
+ * no_proxy?: scalar|null, // A comma separated list of hosts that do not require a proxy to be reached.
+ * timeout?: float, // The idle timeout, defaults to the "default_socket_timeout" ini parameter.
+ * max_duration?: float, // The maximum execution time for the request+response as a whole.
+ * bindto?: scalar|null, // A network interface name, IP address, a host name or a UNIX socket to bind to.
+ * verify_peer?: bool, // Indicates if the peer should be verified in a TLS context.
+ * verify_host?: bool, // Indicates if the host should exist as a certificate common name.
+ * cafile?: scalar|null, // A certificate authority file.
+ * capath?: scalar|null, // A directory that contains multiple certificate authority files.
+ * local_cert?: scalar|null, // A PEM formatted certificate file.
+ * local_pk?: scalar|null, // A private key file.
+ * passphrase?: scalar|null, // The passphrase used to encrypt the "local_pk" file.
+ * ciphers?: scalar|null, // A list of TLS ciphers separated by colons, commas or spaces (e.g. "RC3-SHA:TLS13-AES-128-GCM-SHA256"...)
+ * peer_fingerprint?: array{ // Associative array: hashing algorithm => hash(es).
+ * sha1?: mixed,
+ * pin-sha256?: mixed,
+ * md5?: mixed,
+ * },
+ * crypto_method?: scalar|null, // The minimum version of TLS to accept; must be one of STREAM_CRYPTO_METHOD_TLSv*_CLIENT constants.
+ * extra?: list,
+ * rate_limiter?: scalar|null, // Rate limiter name to use for throttling requests. // Default: null
+ * caching?: bool|array{ // Caching configuration.
+ * enabled?: bool, // Default: false
+ * cache_pool?: string, // The taggable cache pool to use for storing the responses. // Default: "cache.http_client"
+ * shared?: bool, // Indicates whether the cache is shared (public) or private. // Default: true
+ * max_ttl?: int, // The maximum TTL (in seconds) allowed for cached responses. Null means no cap. // Default: null
+ * },
+ * retry_failed?: bool|array{
+ * enabled?: bool, // Default: false
+ * retry_strategy?: scalar|null, // service id to override the retry strategy. // Default: null
+ * http_codes?: array,
+ * }>,
+ * max_retries?: int, // Default: 3
+ * delay?: int, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000
+ * multiplier?: float, // If greater than 1, delay will grow exponentially for each retry: delay * (multiple ^ retries). // Default: 2
+ * max_delay?: int, // Max time in ms that a retry should ever be delayed (0 = infinite). // Default: 0
+ * jitter?: float, // Randomness in percent (between 0 and 1) to apply to the delay. // Default: 0.1
+ * },
+ * },
+ * mock_response_factory?: scalar|null, // The id of the service that should generate mock responses. It should be either an invokable or an iterable.
+ * scoped_clients?: array,
+ * headers?: array,
+ * max_redirects?: int, // The maximum number of redirects to follow.
+ * http_version?: scalar|null, // The default HTTP version, typically 1.1 or 2.0, leave to null for the best version.
+ * resolve?: array,
+ * proxy?: scalar|null, // The URL of the proxy to pass requests through or null for automatic detection.
+ * no_proxy?: scalar|null, // A comma separated list of hosts that do not require a proxy to be reached.
+ * timeout?: float, // The idle timeout, defaults to the "default_socket_timeout" ini parameter.
+ * max_duration?: float, // The maximum execution time for the request+response as a whole.
+ * bindto?: scalar|null, // A network interface name, IP address, a host name or a UNIX socket to bind to.
+ * verify_peer?: bool, // Indicates if the peer should be verified in a TLS context.
+ * verify_host?: bool, // Indicates if the host should exist as a certificate common name.
+ * cafile?: scalar|null, // A certificate authority file.
+ * capath?: scalar|null, // A directory that contains multiple certificate authority files.
+ * local_cert?: scalar|null, // A PEM formatted certificate file.
+ * local_pk?: scalar|null, // A private key file.
+ * passphrase?: scalar|null, // The passphrase used to encrypt the "local_pk" file.
+ * ciphers?: scalar|null, // A list of TLS ciphers separated by colons, commas or spaces (e.g. "RC3-SHA:TLS13-AES-128-GCM-SHA256"...).
+ * peer_fingerprint?: array{ // Associative array: hashing algorithm => hash(es).
+ * sha1?: mixed,
+ * pin-sha256?: mixed,
+ * md5?: mixed,
+ * },
+ * crypto_method?: scalar|null, // The minimum version of TLS to accept; must be one of STREAM_CRYPTO_METHOD_TLSv*_CLIENT constants.
+ * extra?: list,
+ * rate_limiter?: scalar|null, // Rate limiter name to use for throttling requests. // Default: null
+ * caching?: bool|array{ // Caching configuration.
+ * enabled?: bool, // Default: false
+ * cache_pool?: string, // The taggable cache pool to use for storing the responses. // Default: "cache.http_client"
+ * shared?: bool, // Indicates whether the cache is shared (public) or private. // Default: true
+ * max_ttl?: int, // The maximum TTL (in seconds) allowed for cached responses. Null means no cap. // Default: null
+ * },
+ * retry_failed?: bool|array{
+ * enabled?: bool, // Default: false
+ * retry_strategy?: scalar|null, // service id to override the retry strategy. // Default: null
+ * http_codes?: array,
+ * }>,
+ * max_retries?: int, // Default: 3
+ * delay?: int, // Time in ms to delay (or the initial value when multiplier is used). // Default: 1000
+ * multiplier?: float, // If greater than 1, delay will grow exponentially for each retry: delay * (multiple ^ retries). // Default: 2
+ * max_delay?: int, // Max time in ms that a retry should ever be delayed (0 = infinite). // Default: 0
+ * jitter?: float, // Randomness in percent (between 0 and 1) to apply to the delay. // Default: 0.1
+ * },
+ * }>,
+ * },
+ * mailer?: bool|array{ // Mailer configuration
+ * enabled?: bool, // Default: true
+ * message_bus?: scalar|null, // The message bus to use. Defaults to the default bus if the Messenger component is installed. // Default: null
+ * dsn?: scalar|null, // Default: null
+ * transports?: array,
+ * envelope?: array{ // Mailer Envelope configuration
+ * sender?: scalar|null,
+ * recipients?: list,
+ * allowed_recipients?: list,
+ * },
+ * headers?: array,
+ * dkim_signer?: bool|array{ // DKIM signer configuration
+ * enabled?: bool, // Default: false
+ * key?: scalar|null, // Key content, or path to key (in PEM format with the `file://` prefix) // Default: ""
+ * domain?: scalar|null, // Default: ""
+ * select?: scalar|null, // Default: ""
+ * passphrase?: scalar|null, // The private key passphrase // Default: ""
+ * options?: array,
+ * },
+ * smime_signer?: bool|array{ // S/MIME signer configuration
+ * enabled?: bool, // Default: false
+ * key?: scalar|null, // Path to key (in PEM format) // Default: ""
+ * certificate?: scalar|null, // Path to certificate (in PEM format without the `file://` prefix) // Default: ""
+ * passphrase?: scalar|null, // The private key passphrase // Default: null
+ * extra_certificates?: scalar|null, // Default: null
+ * sign_options?: int, // Default: null
+ * },
+ * smime_encrypter?: bool|array{ // S/MIME encrypter configuration
+ * enabled?: bool, // Default: false
+ * repository?: scalar|null, // S/MIME certificate repository service. This service shall implement the `Symfony\Component\Mailer\EventListener\SmimeCertificateRepositoryInterface`. // Default: ""
+ * cipher?: int, // A set of algorithms used to encrypt the message // Default: null
+ * },
+ * },
+ * secrets?: bool|array{
+ * enabled?: bool, // Default: true
+ * vault_directory?: scalar|null, // Default: "%kernel.project_dir%/config/secrets/%kernel.runtime_environment%"
+ * local_dotenv_file?: scalar|null, // Default: "%kernel.project_dir%/.env.%kernel.runtime_environment%.local"
+ * decryption_env_var?: scalar|null, // Default: "base64:default::SYMFONY_DECRYPTION_SECRET"
+ * },
+ * notifier?: bool|array{ // Notifier configuration
+ * enabled?: bool, // Default: false
+ * message_bus?: scalar|null, // The message bus to use. Defaults to the default bus if the Messenger component is installed. // Default: null
+ * chatter_transports?: array,
+ * texter_transports?: array,
+ * notification_on_failed_messages?: bool, // Default: false
+ * channel_policy?: array>,
+ * admin_recipients?: list,
+ * },
+ * rate_limiter?: bool|array{ // Rate limiter configuration
+ * enabled?: bool, // Default: false
+ * limiters?: array,
+ * limit?: int, // The maximum allowed hits in a fixed interval or burst.
+ * interval?: scalar|null, // Configures the fixed interval if "policy" is set to "fixed_window" or "sliding_window". The value must be a number followed by "second", "minute", "hour", "day", "week" or "month" (or their plural equivalent).
+ * rate?: array{ // Configures the fill rate if "policy" is set to "token_bucket".
+ * interval?: scalar|null, // Configures the rate interval. The value must be a number followed by "second", "minute", "hour", "day", "week" or "month" (or their plural equivalent).
+ * amount?: int, // Amount of tokens to add each interval. // Default: 1
+ * },
+ * }>,
+ * },
+ * uid?: bool|array{ // Uid configuration
+ * enabled?: bool, // Default: true
+ * default_uuid_version?: 7|6|4|1, // Default: 7
+ * name_based_uuid_version?: 5|3, // Default: 5
+ * name_based_uuid_namespace?: scalar|null,
+ * time_based_uuid_version?: 7|6|1, // Default: 7
+ * time_based_uuid_node?: scalar|null,
+ * },
+ * html_sanitizer?: bool|array{ // HtmlSanitizer configuration
+ * enabled?: bool, // Default: false
+ * sanitizers?: array,
+ * block_elements?: list,
+ * drop_elements?: list,
+ * allow_attributes?: array,
+ * drop_attributes?: array,
+ * force_attributes?: array>,
+ * force_https_urls?: bool, // Transforms URLs using the HTTP scheme to use the HTTPS scheme instead. // Default: false
+ * allowed_link_schemes?: list,
+ * allowed_link_hosts?: list|null,
+ * allow_relative_links?: bool, // Allows relative URLs to be used in links href attributes. // Default: false
+ * allowed_media_schemes?: list,
+ * allowed_media_hosts?: list|null,
+ * allow_relative_medias?: bool, // Allows relative URLs to be used in media source attributes (img, audio, video, ...). // Default: false
+ * with_attribute_sanitizers?: list,
+ * without_attribute_sanitizers?: list,
+ * max_input_length?: int, // The maximum length allowed for the sanitized input. // Default: 0
+ * }>,
+ * },
+ * webhook?: bool|array{ // Webhook configuration
+ * enabled?: bool, // Default: false
+ * message_bus?: scalar|null, // The message bus to use. // Default: "messenger.default_bus"
+ * routing?: array,
+ * },
+ * remote-event?: bool|array{ // RemoteEvent configuration
+ * enabled?: bool, // Default: false
+ * },
+ * json_streamer?: bool|array{ // JSON streamer configuration
+ * enabled?: bool, // Default: false
+ * },
+ * }
+ * @psalm-type DoctrineConfig = array{
+ * dbal?: array{
+ * default_connection?: scalar|null,
+ * types?: array,
+ * driver_schemes?: array,
+ * connections?: array,
+ * mapping_types?: array,
+ * default_table_options?: array,
+ * schema_manager_factory?: scalar|null, // Default: "doctrine.dbal.default_schema_manager_factory"
+ * result_cache?: scalar|null,
+ * replicas?: array,
+ * }>,
+ * },
+ * orm?: array{
+ * default_entity_manager?: scalar|null,
+ * enable_native_lazy_objects?: bool, // no-op, will be deprecated and removed in the future // Default: true
+ * controller_resolver?: bool|array{
+ * enabled?: bool, // Default: true
+ * auto_mapping?: bool, // Set to true to enable using route placeholders as lookup criteria when the primary key doesn't match the argument name // Default: false
+ * evict_cache?: bool, // Set to true to fetch the entity from the database instead of using the cache, if any // Default: false
+ * },
+ * entity_managers?: array,
+ * }>,
+ * }>,
+ * },
+ * connection?: scalar|null,
+ * class_metadata_factory_name?: scalar|null, // Default: "Doctrine\\ORM\\Mapping\\ClassMetadataFactory"
+ * default_repository_class?: scalar|null, // Default: "Doctrine\\ORM\\EntityRepository"
+ * auto_mapping?: scalar|null, // Default: false
+ * naming_strategy?: scalar|null, // Default: "doctrine.orm.naming_strategy.default"
+ * quote_strategy?: scalar|null, // Default: "doctrine.orm.quote_strategy.default"
+ * typed_field_mapper?: scalar|null, // Default: "doctrine.orm.typed_field_mapper.default"
+ * entity_listener_resolver?: scalar|null, // Default: null
+ * fetch_mode_subselect_batch_size?: scalar|null,
+ * repository_factory?: scalar|null, // Default: "doctrine.orm.container_repository_factory"
+ * schema_ignore_classes?: list,
+ * validate_xml_mapping?: bool, // Set to "true" to opt-in to the new mapping driver mode that was added in Doctrine ORM 2.14 and will be mandatory in ORM 3.0. See https://github.com/doctrine/orm/pull/6728. // Default: false
+ * second_level_cache?: array{
+ * region_cache_driver?: string|array{
+ * type?: scalar|null, // Default: null
+ * id?: scalar|null,
+ * pool?: scalar|null,
+ * },
+ * region_lock_lifetime?: scalar|null, // Default: 60
+ * log_enabled?: bool, // Default: true
+ * region_lifetime?: scalar|null, // Default: 3600
+ * enabled?: bool, // Default: true
+ * factory?: scalar|null,
+ * regions?: array,
+ * loggers?: array,
+ * },
+ * hydrators?: array,
+ * mappings?: array,
+ * dql?: array{
+ * string_functions?: array,
+ * numeric_functions?: array,
+ * datetime_functions?: array,
+ * },
+ * filters?: array,
+ * }>,
+ * identity_generation_preferences?: array,
+ * }>,
+ * resolve_target_entities?: array,
+ * },
+ * }
+ * @psalm-type DoctrineMigrationsConfig = array{
+ * enable_service_migrations?: bool, // Whether to enable fetching migrations from the service container. // Default: false
+ * migrations_paths?: array,
+ * services?: array,
+ * factories?: array,
+ * storage?: array{ // Storage to use for migration status metadata.
+ * table_storage?: array{ // The default metadata storage, implemented as a table in the database.
+ * table_name?: scalar|null, // Default: null
+ * version_column_name?: scalar|null, // Default: null
+ * version_column_length?: scalar|null, // Default: null
+ * executed_at_column_name?: scalar|null, // Default: null
+ * execution_time_column_name?: scalar|null, // Default: null
+ * },
+ * },
+ * migrations?: list,
+ * connection?: scalar|null, // Connection name to use for the migrations database. // Default: null
+ * em?: scalar|null, // Entity manager name to use for the migrations database (available when doctrine/orm is installed). // Default: null
+ * all_or_nothing?: scalar|null, // Run all migrations in a transaction. // Default: false
+ * check_database_platform?: scalar|null, // Adds an extra check in the generated migrations to allow execution only on the same platform as they were initially generated on. // Default: true
+ * custom_template?: scalar|null, // Custom template path for generated migration classes. // Default: null
+ * organize_migrations?: scalar|null, // Organize migrations mode. Possible values are: "BY_YEAR", "BY_YEAR_AND_MONTH", false // Default: false
+ * enable_profiler?: bool, // Whether or not to enable the profiler collector to calculate and visualize migration status. This adds some queries overhead. // Default: false
+ * transactional?: bool, // Whether or not to wrap migrations in a single transaction. // Default: true
+ * }
+ * @psalm-type MakerConfig = array{
+ * root_namespace?: scalar|null, // Default: "App"
+ * generate_final_classes?: bool, // Default: true
+ * generate_final_entities?: bool, // Default: false
+ * }
+ * @psalm-type TwigConfig = array{
+ * form_themes?: list,
+ * globals?: array,
+ * autoescape_service?: scalar|null, // Default: null
+ * autoescape_service_method?: scalar|null, // Default: null
+ * base_template_class?: scalar|null, // Deprecated: The child node "base_template_class" at path "twig.base_template_class" is deprecated.
+ * cache?: scalar|null, // Default: true
+ * charset?: scalar|null, // Default: "%kernel.charset%"
+ * debug?: bool, // Default: "%kernel.debug%"
+ * strict_variables?: bool, // Default: "%kernel.debug%"
+ * auto_reload?: scalar|null,
+ * optimizations?: int,
+ * default_path?: scalar|null, // The default path used to load templates. // Default: "%kernel.project_dir%/templates"
+ * file_name_pattern?: list,
+ * paths?: array,
+ * date?: array{ // The default format options used by the date filter.
+ * format?: scalar|null, // Default: "F j, Y H:i"
+ * interval_format?: scalar|null, // Default: "%d days"
+ * timezone?: scalar|null, // The timezone used when formatting dates, when set to null, the timezone returned by date_default_timezone_get() is used. // Default: null
+ * },
+ * number_format?: array{ // The default format options for the number_format filter.
+ * decimals?: int, // Default: 0
+ * decimal_point?: scalar|null, // Default: "."
+ * thousands_separator?: scalar|null, // Default: ","
+ * },
+ * mailer?: array{
+ * html_to_text_converter?: scalar|null, // A service implementing the "Symfony\Component\Mime\HtmlToTextConverter\HtmlToTextConverterInterface". // Default: null
+ * },
+ * }
+ * @psalm-type SecurityConfig = array{
+ * access_denied_url?: scalar|null, // Default: null
+ * session_fixation_strategy?: "none"|"migrate"|"invalidate", // Default: "migrate"
+ * hide_user_not_found?: bool, // Deprecated: The "hide_user_not_found" option is deprecated and will be removed in 8.0. Use the "expose_security_errors" option instead.
+ * expose_security_errors?: \Symfony\Component\Security\Http\Authentication\ExposeSecurityLevel::None|\Symfony\Component\Security\Http\Authentication\ExposeSecurityLevel::AccountStatus|\Symfony\Component\Security\Http\Authentication\ExposeSecurityLevel::All, // Default: "none"
+ * erase_credentials?: bool, // Default: true
+ * access_decision_manager?: array{
+ * strategy?: "affirmative"|"consensus"|"unanimous"|"priority",
+ * service?: scalar|null,
+ * strategy_service?: scalar|null,
+ * allow_if_all_abstain?: bool, // Default: false
+ * allow_if_equal_granted_denied?: bool, // Default: true
+ * },
+ * password_hashers?: array,
+ * hash_algorithm?: scalar|null, // Name of hashing algorithm for PBKDF2 (i.e. sha256, sha512, etc..) See hash_algos() for a list of supported algorithms. // Default: "sha512"
+ * key_length?: scalar|null, // Default: 40
+ * ignore_case?: bool, // Default: false
+ * encode_as_base64?: bool, // Default: true
+ * iterations?: scalar|null, // Default: 5000
+ * cost?: int, // Default: null
+ * memory_cost?: scalar|null, // Default: null
+ * time_cost?: scalar|null, // Default: null
+ * id?: scalar|null,
+ * }>,
+ * providers?: array,
+ * },
+ * entity?: array{
+ * class: scalar|null, // The full entity class name of your user class.
+ * property?: scalar|null, // Default: null
+ * manager_name?: scalar|null, // Default: null
+ * },
+ * memory?: array{
+ * users?: array,
+ * }>,
+ * },
+ * ldap?: array{
+ * service: scalar|null,
+ * base_dn: scalar|null,
+ * search_dn?: scalar|null, // Default: null
+ * search_password?: scalar|null, // Default: null
+ * extra_fields?: list,
+ * default_roles?: list,
+ * role_fetcher?: scalar|null, // Default: null
+ * uid_key?: scalar|null, // Default: "sAMAccountName"
+ * filter?: scalar|null, // Default: "({uid_key}={user_identifier})"
+ * password_attribute?: scalar|null, // Default: null
+ * },
+ * }>,
+ * firewalls: array,
+ * security?: bool, // Default: true
+ * user_checker?: scalar|null, // The UserChecker to use when authenticating users in this firewall. // Default: "security.user_checker"
+ * request_matcher?: scalar|null,
+ * access_denied_url?: scalar|null,
+ * access_denied_handler?: scalar|null,
+ * entry_point?: scalar|null, // An enabled authenticator name or a service id that implements "Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface".
+ * provider?: scalar|null,
+ * stateless?: bool, // Default: false
+ * lazy?: bool, // Default: false
+ * context?: scalar|null,
+ * logout?: array{
+ * enable_csrf?: bool|null, // Default: null
+ * csrf_token_id?: scalar|null, // Default: "logout"
+ * csrf_parameter?: scalar|null, // Default: "_csrf_token"
+ * csrf_token_manager?: scalar|null,
+ * path?: scalar|null, // Default: "/logout"
+ * target?: scalar|null, // Default: "/"
+ * invalidate_session?: bool, // Default: true
+ * clear_site_data?: list<"*"|"cache"|"cookies"|"storage"|"executionContexts">,
+ * delete_cookies?: array,
+ * },
+ * switch_user?: array{
+ * provider?: scalar|null,
+ * parameter?: scalar|null, // Default: "_switch_user"
+ * role?: scalar|null, // Default: "ROLE_ALLOWED_TO_SWITCH"
+ * target_route?: scalar|null, // Default: null
+ * },
+ * required_badges?: list,
+ * custom_authenticators?: list,
+ * login_throttling?: array{
+ * limiter?: scalar|null, // A service id implementing "Symfony\Component\HttpFoundation\RateLimiter\RequestRateLimiterInterface".
+ * max_attempts?: int, // Default: 5
+ * interval?: scalar|null, // Default: "1 minute"
+ * lock_factory?: scalar|null, // The service ID of the lock factory used by the login rate limiter (or null to disable locking). // Default: null
+ * cache_pool?: string, // The cache pool to use for storing the limiter state // Default: "cache.rate_limiter"
+ * storage_service?: string, // The service ID of a custom storage implementation, this precedes any configured "cache_pool" // Default: null
+ * },
+ * x509?: array{
+ * provider?: scalar|null,
+ * user?: scalar|null, // Default: "SSL_CLIENT_S_DN_Email"
+ * credentials?: scalar|null, // Default: "SSL_CLIENT_S_DN"
+ * user_identifier?: scalar|null, // Default: "emailAddress"
+ * },
+ * remote_user?: array{
+ * provider?: scalar|null,
+ * user?: scalar|null, // Default: "REMOTE_USER"
+ * },
+ * login_link?: array{
+ * check_route: scalar|null, // Route that will validate the login link - e.g. "app_login_link_verify".
+ * check_post_only?: scalar|null, // If true, only HTTP POST requests to "check_route" will be handled by the authenticator. // Default: false
+ * signature_properties: list,
+ * lifetime?: int, // The lifetime of the login link in seconds. // Default: 600
+ * max_uses?: int, // Max number of times a login link can be used - null means unlimited within lifetime. // Default: null
+ * used_link_cache?: scalar|null, // Cache service id used to expired links of max_uses is set.
+ * success_handler?: scalar|null, // A service id that implements Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface.
+ * failure_handler?: scalar|null, // A service id that implements Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface.
+ * provider?: scalar|null, // The user provider to load users from.
+ * secret?: scalar|null, // Default: "%kernel.secret%"
+ * always_use_default_target_path?: bool, // Default: false
+ * default_target_path?: scalar|null, // Default: "/"
+ * login_path?: scalar|null, // Default: "/login"
+ * target_path_parameter?: scalar|null, // Default: "_target_path"
+ * use_referer?: bool, // Default: false
+ * failure_path?: scalar|null, // Default: null
+ * failure_forward?: bool, // Default: false
+ * failure_path_parameter?: scalar|null, // Default: "_failure_path"
+ * },
+ * form_login?: array{
+ * provider?: scalar|null,
+ * remember_me?: bool, // Default: true
+ * success_handler?: scalar|null,
+ * failure_handler?: scalar|null,
+ * check_path?: scalar|null, // Default: "/login_check"
+ * use_forward?: bool, // Default: false
+ * login_path?: scalar|null, // Default: "/login"
+ * username_parameter?: scalar|null, // Default: "_username"
+ * password_parameter?: scalar|null, // Default: "_password"
+ * csrf_parameter?: scalar|null, // Default: "_csrf_token"
+ * csrf_token_id?: scalar|null, // Default: "authenticate"
+ * enable_csrf?: bool, // Default: false
+ * post_only?: bool, // Default: true
+ * form_only?: bool, // Default: false
+ * always_use_default_target_path?: bool, // Default: false
+ * default_target_path?: scalar|null, // Default: "/"
+ * target_path_parameter?: scalar|null, // Default: "_target_path"
+ * use_referer?: bool, // Default: false
+ * failure_path?: scalar|null, // Default: null
+ * failure_forward?: bool, // Default: false
+ * failure_path_parameter?: scalar|null, // Default: "_failure_path"
+ * },
+ * form_login_ldap?: array{
+ * provider?: scalar|null,
+ * remember_me?: bool, // Default: true
+ * success_handler?: scalar|null,
+ * failure_handler?: scalar|null,
+ * check_path?: scalar|null, // Default: "/login_check"
+ * use_forward?: bool, // Default: false
+ * login_path?: scalar|null, // Default: "/login"
+ * username_parameter?: scalar|null, // Default: "_username"
+ * password_parameter?: scalar|null, // Default: "_password"
+ * csrf_parameter?: scalar|null, // Default: "_csrf_token"
+ * csrf_token_id?: scalar|null, // Default: "authenticate"
+ * enable_csrf?: bool, // Default: false
+ * post_only?: bool, // Default: true
+ * form_only?: bool, // Default: false
+ * always_use_default_target_path?: bool, // Default: false
+ * default_target_path?: scalar|null, // Default: "/"
+ * target_path_parameter?: scalar|null, // Default: "_target_path"
+ * use_referer?: bool, // Default: false
+ * failure_path?: scalar|null, // Default: null
+ * failure_forward?: bool, // Default: false
+ * failure_path_parameter?: scalar|null, // Default: "_failure_path"
+ * service?: scalar|null, // Default: "ldap"
+ * dn_string?: scalar|null, // Default: "{user_identifier}"
+ * query_string?: scalar|null,
+ * search_dn?: scalar|null, // Default: ""
+ * search_password?: scalar|null, // Default: ""
+ * },
+ * json_login?: array{
+ * provider?: scalar|null,
+ * remember_me?: bool, // Default: true
+ * success_handler?: scalar|null,
+ * failure_handler?: scalar|null,
+ * check_path?: scalar|null, // Default: "/login_check"
+ * use_forward?: bool, // Default: false
+ * login_path?: scalar|null, // Default: "/login"
+ * username_path?: scalar|null, // Default: "username"
+ * password_path?: scalar|null, // Default: "password"
+ * },
+ * json_login_ldap?: array{
+ * provider?: scalar|null,
+ * remember_me?: bool, // Default: true
+ * success_handler?: scalar|null,
+ * failure_handler?: scalar|null,
+ * check_path?: scalar|null, // Default: "/login_check"
+ * use_forward?: bool, // Default: false
+ * login_path?: scalar|null, // Default: "/login"
+ * username_path?: scalar|null, // Default: "username"
+ * password_path?: scalar|null, // Default: "password"
+ * service?: scalar|null, // Default: "ldap"
+ * dn_string?: scalar|null, // Default: "{user_identifier}"
+ * query_string?: scalar|null,
+ * search_dn?: scalar|null, // Default: ""
+ * search_password?: scalar|null, // Default: ""
+ * },
+ * access_token?: array{
+ * provider?: scalar|null,
+ * remember_me?: bool, // Default: true
+ * success_handler?: scalar|null,
+ * failure_handler?: scalar|null,
+ * realm?: scalar|null, // Default: null
+ * token_extractors?: list,
+ * token_handler: string|array{
+ * id?: scalar|null,
+ * oidc_user_info?: string|array{
+ * base_uri: scalar|null, // Base URI of the userinfo endpoint on the OIDC server, or the OIDC server URI to use the discovery (require "discovery" to be configured).
+ * discovery?: array{ // Enable the OIDC discovery.
+ * cache?: array{
+ * id: scalar|null, // Cache service id to use to cache the OIDC discovery configuration.
+ * },
+ * },
+ * claim?: scalar|null, // Claim which contains the user identifier (e.g. sub, email, etc.). // Default: "sub"
+ * client?: scalar|null, // HttpClient service id to use to call the OIDC server.
+ * },
+ * oidc?: array{
+ * discovery?: array{ // Enable the OIDC discovery.
+ * base_uri: list,
+ * cache?: array{
+ * id: scalar|null, // Cache service id to use to cache the OIDC discovery configuration.
+ * },
+ * },
+ * claim?: scalar|null, // Claim which contains the user identifier (e.g.: sub, email..). // Default: "sub"
+ * audience: scalar|null, // Audience set in the token, for validation purpose.
+ * issuers: list,
+ * algorithm?: array,
+ * algorithms: list,
+ * key?: scalar|null, // Deprecated: The "key" option is deprecated and will be removed in 8.0. Use the "keyset" option instead. // JSON-encoded JWK used to sign the token (must contain a "kty" key).
+ * keyset?: scalar|null, // JSON-encoded JWKSet used to sign the token (must contain a list of valid public keys).
+ * encryption?: bool|array{
+ * enabled?: bool, // Default: false
+ * enforce?: bool, // When enabled, the token shall be encrypted. // Default: false
+ * algorithms: list,
+ * keyset: scalar|null, // JSON-encoded JWKSet used to decrypt the token (must contain a list of valid private keys).
+ * },
+ * },
+ * cas?: array{
+ * validation_url: scalar|null, // CAS server validation URL
+ * prefix?: scalar|null, // CAS prefix // Default: "cas"
+ * http_client?: scalar|null, // HTTP Client service // Default: null
+ * },
+ * oauth2?: scalar|null,
+ * },
+ * },
+ * http_basic?: array{
+ * provider?: scalar|null,
+ * realm?: scalar|null, // Default: "Secured Area"
+ * },
+ * http_basic_ldap?: array{
+ * provider?: scalar|null,
+ * realm?: scalar|null, // Default: "Secured Area"
+ * service?: scalar|null, // Default: "ldap"
+ * dn_string?: scalar|null, // Default: "{user_identifier}"
+ * query_string?: scalar|null,
+ * search_dn?: scalar|null, // Default: ""
+ * search_password?: scalar|null, // Default: ""
+ * },
+ * remember_me?: array{
+ * secret?: scalar|null, // Default: "%kernel.secret%"
+ * service?: scalar|null,
+ * user_providers?: list,
+ * catch_exceptions?: bool, // Default: true
+ * signature_properties?: list,
+ * token_provider?: string|array{
+ * service?: scalar|null, // The service ID of a custom remember-me token provider.
+ * doctrine?: bool|array{
+ * enabled?: bool, // Default: false
+ * connection?: scalar|null, // Default: null
+ * },
+ * },
+ * token_verifier?: scalar|null, // The service ID of a custom rememberme token verifier.
+ * name?: scalar|null, // Default: "REMEMBERME"
+ * lifetime?: int, // Default: 31536000
+ * path?: scalar|null, // Default: "/"
+ * domain?: scalar|null, // Default: null
+ * secure?: true|false|"auto", // Default: false
+ * httponly?: bool, // Default: true
+ * samesite?: null|"lax"|"strict"|"none", // Default: null
+ * always_remember_me?: bool, // Default: false
+ * remember_me_parameter?: scalar|null, // Default: "_remember_me"
+ * },
+ * }>,
+ * access_control?: list,
+ * attributes?: array,
+ * route?: scalar|null, // Default: null
+ * methods?: list,
+ * allow_if?: scalar|null, // Default: null
+ * roles?: list,
+ * }>,
+ * role_hierarchy?: array>,
+ * }
+ * @psalm-type WebProfilerConfig = array{
+ * toolbar?: bool|array{ // Profiler toolbar configuration
+ * enabled?: bool, // Default: false
+ * ajax_replace?: bool, // Replace toolbar on AJAX requests // Default: false
+ * },
+ * intercept_redirects?: bool, // Default: false
+ * excluded_ajax_paths?: scalar|null, // Default: "^/((index|app(_[\\w]+)?)\\.php/)?_wdt"
+ * }
+ * @psalm-type TwigExtraConfig = array{
+ * cache?: bool|array{
+ * enabled?: bool, // Default: false
+ * },
+ * html?: bool|array{
+ * enabled?: bool, // Default: false
+ * },
+ * markdown?: bool|array{
+ * enabled?: bool, // Default: false
+ * },
+ * intl?: bool|array{
+ * enabled?: bool, // Default: true
+ * },
+ * cssinliner?: bool|array{
+ * enabled?: bool, // Default: false
+ * },
+ * inky?: bool|array{
+ * enabled?: bool, // Default: false
+ * },
+ * string?: bool|array{
+ * enabled?: bool, // Default: false
+ * },
+ * commonmark?: array{
+ * renderer?: array{ // Array of options for rendering HTML.
+ * block_separator?: scalar|null,
+ * inner_separator?: scalar|null,
+ * soft_break?: scalar|null,
+ * },
+ * html_input?: "strip"|"allow"|"escape", // How to handle HTML input.
+ * allow_unsafe_links?: bool, // Remove risky link and image URLs by setting this to false. // Default: true
+ * max_nesting_level?: int, // The maximum nesting level for blocks. // Default: 9223372036854775807
+ * max_delimiters_per_line?: int, // The maximum number of strong/emphasis delimiters per line. // Default: 9223372036854775807
+ * slug_normalizer?: array{ // Array of options for configuring how URL-safe slugs are created.
+ * instance?: mixed,
+ * max_length?: int, // Default: 255
+ * unique?: mixed,
+ * },
+ * commonmark?: array{ // Array of options for configuring the CommonMark core extension.
+ * enable_em?: bool, // Default: true
+ * enable_strong?: bool, // Default: true
+ * use_asterisk?: bool, // Default: true
+ * use_underscore?: bool, // Default: true
+ * unordered_list_markers?: list,
+ * },
+ * ...
+ * },
+ * }
+ * @psalm-type SymfonycastsVerifyEmailConfig = array{
+ * lifetime?: int, // The length of time in seconds that a signed URI is valid for after it is created. // Default: 3600
+ * }
+ * @psalm-type SymfonycastsSassConfig = array{
+ * root_sass?: list,
+ * binary?: scalar|null, // The Sass binary to use // Default: null
+ * sass_options?: array{
+ * style?: "compressed"|"expanded", // The style of the generated CSS: compressed or expanded. // Default: "expanded"
+ * charset?: bool, // Whether to include the charset declaration in the generated Sass.
+ * error_css?: bool, // Emit a CSS file when an error occurs.
+ * source_map?: bool, // Whether to generate source maps. // Default: true
+ * embed_sources?: bool, // Embed source file contents in source maps.
+ * embed_source_map?: bool, // Embed source map contents in CSS. // Default: "%kernel.debug%"
+ * load_path?: list,
+ * quiet?: bool, // Don't print warnings.
+ * quiet_deps?: bool, // Don't print compiler warnings from dependencies.
+ * stop_on_error?: bool, // Don't compile more files once an error is encountered.
+ * trace?: bool, // Print full Dart stack traces for exceptions.
+ * },
+ * embed_sourcemap?: bool|null, // Deprecated: Option "embed_sourcemap" at "symfonycasts_sass.embed_sourcemap" is deprecated. Use "sass_options.embed_source_map" instead". // Default: null
+ * }
+ * @psalm-type StimulusConfig = array{
+ * controller_paths?: list,
+ * controllers_json?: scalar|null, // Default: "%kernel.project_dir%/assets/controllers.json"
+ * }
+ * @psalm-type TurboConfig = array{
+ * broadcast?: bool|array{
+ * enabled?: bool, // Default: true
+ * entity_template_prefixes?: list,
+ * doctrine_orm?: bool|array{ // Enable the Doctrine ORM integration
+ * enabled?: bool, // Default: true
+ * },
+ * },
+ * default_transport?: scalar|null, // Default: "default"
+ * }
+ * @psalm-type StofDoctrineExtensionsConfig = array{
+ * orm?: array,
+ * mongodb?: array,
+ * class?: array{
+ * translatable?: scalar|null, // Default: "Gedmo\\Translatable\\TranslatableListener"
+ * timestampable?: scalar|null, // Default: "Gedmo\\Timestampable\\TimestampableListener"
+ * blameable?: scalar|null, // Default: "Gedmo\\Blameable\\BlameableListener"
+ * sluggable?: scalar|null, // Default: "Gedmo\\Sluggable\\SluggableListener"
+ * tree?: scalar|null, // Default: "Gedmo\\Tree\\TreeListener"
+ * loggable?: scalar|null, // Default: "Gedmo\\Loggable\\LoggableListener"
+ * sortable?: scalar|null, // Default: "Gedmo\\Sortable\\SortableListener"
+ * softdeleteable?: scalar|null, // Default: "Gedmo\\SoftDeleteable\\SoftDeleteableListener"
+ * uploadable?: scalar|null, // Default: "Gedmo\\Uploadable\\UploadableListener"
+ * reference_integrity?: scalar|null, // Default: "Gedmo\\ReferenceIntegrity\\ReferenceIntegrityListener"
+ * },
+ * uploadable?: array{
+ * default_file_path?: scalar|null, // Default: null
+ * mime_type_guesser_class?: scalar|null, // Default: "Stof\\DoctrineExtensionsBundle\\Uploadable\\MimeTypeGuesserAdapter"
+ * default_file_info_class?: scalar|null, // Default: "Stof\\DoctrineExtensionsBundle\\Uploadable\\UploadedFileInfo"
+ * validate_writable_directory?: bool, // Default: true
+ * },
+ * default_locale?: scalar|null, // Default: "en"
+ * translation_fallback?: bool, // Default: false
+ * persist_default_translation?: bool, // Default: false
+ * skip_translation_on_load?: bool, // Default: false
+ * metadata_cache_pool?: scalar|null, // Default: null
+ * }
+ * @psalm-type SentryConfig = array{
+ * dsn?: scalar|null, // If this value is not provided, the SDK will try to read it from the SENTRY_DSN environment variable. If that variable also does not exist, the SDK will not send any events.
+ * register_error_listener?: bool, // Default: true
+ * register_error_handler?: bool, // Default: true
+ * logger?: scalar|null, // The service ID of the PSR-3 logger used to log messages coming from the SDK client. Be aware that setting the same logger of the application may create a circular loop when an event fails to be sent. // Default: null
+ * options?: array{
+ * integrations?: mixed, // Default: []
+ * default_integrations?: bool,
+ * prefixes?: list,
+ * sample_rate?: float, // The sampling factor to apply to events. A value of 0 will deny sending any event, and a value of 1 will send all events.
+ * enable_tracing?: bool,
+ * traces_sample_rate?: float, // The sampling factor to apply to transactions. A value of 0 will deny sending any transaction, and a value of 1 will send all transactions.
+ * traces_sampler?: scalar|null,
+ * profiles_sample_rate?: float, // The sampling factor to apply to profiles. A value of 0 will deny sending any profiles, and a value of 1 will send all profiles. Profiles are sampled in relation to traces_sample_rate
+ * enable_logs?: bool,
+ * attach_stacktrace?: bool,
+ * attach_metric_code_locations?: bool,
+ * context_lines?: int,
+ * environment?: scalar|null, // Default: "%kernel.environment%"
+ * logger?: scalar|null,
+ * spotlight?: bool,
+ * spotlight_url?: scalar|null,
+ * release?: scalar|null, // Default: "%env(default::SENTRY_RELEASE)%"
+ * server_name?: scalar|null,
+ * ignore_exceptions?: list,
+ * ignore_transactions?: list,
+ * before_send?: scalar|null,
+ * before_send_transaction?: scalar|null,
+ * before_send_check_in?: scalar|null,
+ * before_send_metrics?: scalar|null,
+ * before_send_log?: scalar|null,
+ * trace_propagation_targets?: mixed,
+ * tags?: array,
+ * error_types?: scalar|null,
+ * max_breadcrumbs?: int,
+ * before_breadcrumb?: mixed,
+ * in_app_exclude?: list,
+ * in_app_include?: list,
+ * send_default_pii?: bool,
+ * max_value_length?: int,
+ * transport?: scalar|null,
+ * http_client?: scalar|null,
+ * http_proxy?: scalar|null,
+ * http_proxy_authentication?: scalar|null,
+ * http_connect_timeout?: float, // The maximum number of seconds to wait while trying to connect to a server. It works only when using the default transport.
+ * http_timeout?: float, // The maximum execution time for the request+response as a whole. It works only when using the default transport.
+ * http_ssl_verify_peer?: bool,
+ * http_compression?: bool,
+ * capture_silenced_errors?: bool,
+ * max_request_body_size?: "none"|"small"|"medium"|"always",
+ * class_serializers?: array,
+ * },
+ * messenger?: bool|array{
+ * enabled?: bool, // Default: false
+ * capture_soft_fails?: bool, // Default: true
+ * isolate_breadcrumbs_by_message?: bool, // Default: false
+ * },
+ * tracing?: bool|array{
+ * enabled?: bool, // Default: true
+ * dbal?: bool|array{
+ * enabled?: bool, // Default: true
+ * connections?: list,
+ * },
+ * twig?: bool|array{
+ * enabled?: bool, // Default: true
+ * },
+ * cache?: bool|array{
+ * enabled?: bool, // Default: true
+ * },
+ * http_client?: bool|array{
+ * enabled?: bool, // Default: true
+ * },
+ * console?: array{
+ * excluded_commands?: list,
+ * },
+ * },
+ * }
+ * @psalm-type DamaDoctrineTestConfig = array{
+ * enable_static_connection?: mixed, // Default: true
+ * enable_static_meta_data_cache?: bool, // Default: true
+ * enable_static_query_cache?: bool, // Default: true
+ * connection_keys?: list,
+ * }
+ * @psalm-type ConfigType = array{
+ * imports?: ImportsConfig,
+ * parameters?: ParametersConfig,
+ * services?: ServicesConfig,
+ * framework?: FrameworkConfig,
+ * doctrine?: DoctrineConfig,
+ * doctrine_migrations?: DoctrineMigrationsConfig,
+ * twig?: TwigConfig,
+ * security?: SecurityConfig,
+ * twig_extra?: TwigExtraConfig,
+ * symfonycasts_verify_email?: SymfonycastsVerifyEmailConfig,
+ * symfonycasts_sass?: SymfonycastsSassConfig,
+ * stimulus?: StimulusConfig,
+ * turbo?: TurboConfig,
+ * stof_doctrine_extensions?: StofDoctrineExtensionsConfig,
+ * "when@dev"?: array{
+ * imports?: ImportsConfig,
+ * parameters?: ParametersConfig,
+ * services?: ServicesConfig,
+ * framework?: FrameworkConfig,
+ * doctrine?: DoctrineConfig,
+ * doctrine_migrations?: DoctrineMigrationsConfig,
+ * maker?: MakerConfig,
+ * twig?: TwigConfig,
+ * security?: SecurityConfig,
+ * web_profiler?: WebProfilerConfig,
+ * twig_extra?: TwigExtraConfig,
+ * symfonycasts_verify_email?: SymfonycastsVerifyEmailConfig,
+ * symfonycasts_sass?: SymfonycastsSassConfig,
+ * stimulus?: StimulusConfig,
+ * turbo?: TurboConfig,
+ * stof_doctrine_extensions?: StofDoctrineExtensionsConfig,
+ * },
+ * "when@prod"?: array{
+ * imports?: ImportsConfig,
+ * parameters?: ParametersConfig,
+ * services?: ServicesConfig,
+ * framework?: FrameworkConfig,
+ * doctrine?: DoctrineConfig,
+ * doctrine_migrations?: DoctrineMigrationsConfig,
+ * twig?: TwigConfig,
+ * security?: SecurityConfig,
+ * twig_extra?: TwigExtraConfig,
+ * symfonycasts_verify_email?: SymfonycastsVerifyEmailConfig,
+ * sentry?: SentryConfig,
+ * symfonycasts_sass?: SymfonycastsSassConfig,
+ * stimulus?: StimulusConfig,
+ * turbo?: TurboConfig,
+ * stof_doctrine_extensions?: StofDoctrineExtensionsConfig,
+ * },
+ * "when@test"?: array{
+ * imports?: ImportsConfig,
+ * parameters?: ParametersConfig,
+ * services?: ServicesConfig,
+ * framework?: FrameworkConfig,
+ * doctrine?: DoctrineConfig,
+ * doctrine_migrations?: DoctrineMigrationsConfig,
+ * twig?: TwigConfig,
+ * security?: SecurityConfig,
+ * web_profiler?: WebProfilerConfig,
+ * twig_extra?: TwigExtraConfig,
+ * symfonycasts_verify_email?: SymfonycastsVerifyEmailConfig,
+ * symfonycasts_sass?: SymfonycastsSassConfig,
+ * stimulus?: StimulusConfig,
+ * turbo?: TurboConfig,
+ * dama_doctrine_test?: DamaDoctrineTestConfig,
+ * stof_doctrine_extensions?: StofDoctrineExtensionsConfig,
+ * },
+ * ...,
+ * }>
+ * }
+ */
+final class App
+{
+ /**
+ * @param ConfigType $config
+ *
+ * @psalm-return ConfigType
+ */
+ public static function config(array $config): array
+ {
+ return AppReference::config($config);
+ }
+}
+
+namespace Symfony\Component\Routing\Loader\Configurator;
+
+/**
+ * This class provides array-shapes for configuring the routes of an application.
+ *
+ * Example:
+ *
+ * ```php
+ * // config/routes.php
+ * namespace Symfony\Component\Routing\Loader\Configurator;
+ *
+ * return Routes::config([
+ * 'controllers' => [
+ * 'resource' => 'routing.controllers',
+ * ],
+ * ]);
+ * ```
+ *
+ * @psalm-type RouteConfig = array{
+ * path: string|array,
+ * controller?: string,
+ * methods?: string|list,
+ * requirements?: array,
+ * defaults?: array,
+ * options?: array,
+ * host?: string|array,
+ * schemes?: string|list,
+ * condition?: string,
+ * locale?: string,
+ * format?: string,
+ * utf8?: bool,
+ * stateless?: bool,
+ * }
+ * @psalm-type ImportConfig = array{
+ * resource: string,
+ * type?: string,
+ * exclude?: string|list,
+ * prefix?: string|array,
+ * name_prefix?: string,
+ * trailing_slash_on_root?: bool,
+ * controller?: string,
+ * methods?: string|list,
+ * requirements?: array,
+ * defaults?: array,
+ * options?: array,
+ * host?: string|array,
+ * schemes?: string|list,
+ * condition?: string,
+ * locale?: string,
+ * format?: string,
+ * utf8?: bool,
+ * stateless?: bool,
+ * }
+ * @psalm-type AliasConfig = array{
+ * alias: string,
+ * deprecated?: array{package:string, version:string, message?:string},
+ * }
+ * @psalm-type RoutesConfig = array{
+ * "when@dev"?: array,
+ * "when@prod"?: array,
+ * "when@test"?: array,
+ * ...
+ * }
+ */
+final class Routes
+{
+ /**
+ * @param RoutesConfig $config
+ *
+ * @psalm-return RoutesConfig
+ */
+ public static function config(array $config): array
+ {
+ return $config;
+ }
+}
diff --git a/phpunit.dist.xml b/phpunit.dist.xml
index 0b31da2..5feec8b 100644
--- a/phpunit.dist.xml
+++ b/phpunit.dist.xml
@@ -27,8 +27,12 @@
src
+
+ src/DataFixtures
+
+
diff --git a/rector.php b/rector.php
index 3702cc1..911f31e 100644
--- a/rector.php
+++ b/rector.php
@@ -13,6 +13,7 @@ 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)
@@ -26,7 +27,6 @@ return RectorConfig::configure()
privatization: true,
instanceOf: true,
earlyReturn: true,
- strictBooleans: true,
rectorPreset: true,
phpunitCodeQuality: true,
doctrineCodeQuality: true,
diff --git a/src/Command/AddSettingsCommand.php b/src/Command/AddSettingsCommand.php
deleted file mode 100644
index e9e22a5..0000000
--- a/src/Command/AddSettingsCommand.php
+++ /dev/null
@@ -1,41 +0,0 @@
-seasonRepository->findAll() as $season) {
- if (null !== $season->settings) {
- continue;
- }
-
- $io->text('Adding settings to season : '.$season->seasonCode);
- $season->settings = new SeasonSettings();
- }
-
- $this->entityManager->flush();
-
- return Command::SUCCESS;
- }
-}
diff --git a/src/Command/ClaimSeasonCommand.php b/src/Command/ClaimSeasonCommand.php
index 42a8897..e6dfd1b 100644
--- a/src/Command/ClaimSeasonCommand.php
+++ b/src/Command/ClaimSeasonCommand.php
@@ -8,9 +8,8 @@ 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\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
+use Tvdt\Entity\Season;
use Tvdt\Repository\SeasonRepository;
use Tvdt\Repository\UserRepository;
@@ -18,7 +17,7 @@ use Tvdt\Repository\UserRepository;
name: 'tvdt:claim-season',
description: 'Give a user owner rights on a season',
)]
-readonly class ClaimSeasonCommand
+final readonly class ClaimSeasonCommand
{
public function __construct(private UserRepository $userRepository, private SeasonRepository $seasonRepository, private EntityManagerInterface $entityManager) {}
@@ -27,14 +26,11 @@ readonly class ClaimSeasonCommand
string $seasonCode,
#[Argument]
string $email,
- InputInterface $input,
- OutputInterface $output,
+ SymfonyStyle $io,
): int {
- $io = new SymfonyStyle($input, $output);
-
try {
- $season = $this->seasonRepository->findOneBy(['seasonCode' => $seasonCode]);
- if (null === $season) {
+ $season = $this->seasonRepository->findOneBySeasonCode($seasonCode);
+ if (!$season instanceof Season) {
throw new \InvalidArgumentException('Season not found');
}
diff --git a/src/Command/MakeAdminCommand.php b/src/Command/MakeAdminCommand.php
index ca66b67..4c3d1c2 100644
--- a/src/Command/MakeAdminCommand.php
+++ b/src/Command/MakeAdminCommand.php
@@ -7,8 +7,6 @@ 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\Input\InputInterface;
-use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Tvdt\Repository\UserRepository;
@@ -16,17 +14,15 @@ use Tvdt\Repository\UserRepository;
name: 'tvdt:make-admin',
description: 'Give a user the role admin',
)]
-readonly class MakeAdminCommand
+final readonly class MakeAdminCommand
{
public function __construct(private UserRepository $userRepository) {}
public function __invoke(
#[Argument]
string $email,
- InputInterface $input,
- OutputInterface $output,
+ SymfonyStyle $io,
): int {
- $io = new SymfonyStyle($input, $output);
try {
$this->userRepository->makeAdmin($email);
} catch (\InvalidArgumentException) {
diff --git a/src/Controller/Backoffice/BackofficeController.php b/src/Controller/Backoffice/BackofficeController.php
index fb62d52..2c9a16d 100644
--- a/src/Controller/Backoffice/BackofficeController.php
+++ b/src/Controller/Backoffice/BackofficeController.php
@@ -26,6 +26,7 @@ final class BackofficeController extends AbstractController
public function __construct(
private readonly SeasonRepository $seasonRepository,
private readonly Security $security,
+ private readonly QuizSpreadsheetService $excel,
) {}
#[Route('/backoffice/', name: 'tvdt_backoffice_index')]
@@ -68,9 +69,9 @@ final class BackofficeController extends AbstractController
}
#[Route('/backoffice/template', name: 'tvdt_backoffice_template', priority: 10)]
- public function getTemplate(QuizSpreadsheetService $excel): Response
+ public function getTemplate(): StreamedResponse
{
- $response = new StreamedResponse($excel->generateTemplate());
+ $response = new StreamedResponse($this->excel->generateTemplate());
$response->headers->set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
$response->headers->set('Content-Disposition', 'attachment; filename="template.xlsx"');
diff --git a/src/Controller/Backoffice/PrepareEliminationController.php b/src/Controller/Backoffice/PrepareEliminationController.php
index 460a36b..9040571 100644
--- a/src/Controller/Backoffice/PrepareEliminationController.php
+++ b/src/Controller/Backoffice/PrepareEliminationController.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Tvdt\Controller\Backoffice;
use Doctrine\ORM\EntityManagerInterface;
+use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
@@ -17,14 +18,16 @@ use Tvdt\Factory\EliminationFactory;
final class PrepareEliminationController extends AbstractController
{
+ public function __construct(private readonly EliminationFactory $eliminationFactory) {}
+
#[Route(
'/backoffice/season/{seasonCode:season}/quiz/{quiz}/elimination/prepare',
name: 'tvdt_prepare_elimination',
requirements: ['seasonCode' => self::SEASON_CODE_REGEX, 'quiz' => Requirement::UUID],
)]
- public function index(Season $season, Quiz $quiz, EliminationFactory $eliminationFactory): Response
+ public function index(Season $season, Quiz $quiz): RedirectResponse
{
- $elimination = $eliminationFactory->createEliminationFromQuiz($quiz);
+ $elimination = $this->eliminationFactory->createEliminationFromQuiz($quiz);
return $this->redirectToRoute('tvdt_prepare_elimination_view', ['elimination' => $elimination->id]);
}
diff --git a/src/Controller/Backoffice/QuizController.php b/src/Controller/Backoffice/QuizController.php
index ad2c91e..a44ec34 100644
--- a/src/Controller/Backoffice/QuizController.php
+++ b/src/Controller/Backoffice/QuizController.php
@@ -19,7 +19,6 @@ use Tvdt\Entity\Candidate;
use Tvdt\Entity\Quiz;
use Tvdt\Entity\Season;
use Tvdt\Exception\ErrorClearingQuizException;
-use Tvdt\Repository\CandidateRepository;
use Tvdt\Repository\QuizCandidateRepository;
use Tvdt\Repository\QuizRepository;
use Tvdt\Security\Voter\SeasonVoter;
@@ -29,8 +28,9 @@ use Tvdt\Security\Voter\SeasonVoter;
class QuizController extends AbstractController
{
public function __construct(
- private readonly CandidateRepository $candidateRepository,
+ private readonly QuizRepository $quizRepository,
private readonly TranslatorInterface $translator,
+ private readonly QuizCandidateRepository $quizCandidateRepository,
) {}
#[IsGranted(SeasonVoter::EDIT, subject: 'season')]
@@ -44,7 +44,7 @@ class QuizController extends AbstractController
return $this->render('backoffice/quiz.html.twig', [
'season' => $season,
'quiz' => $quiz,
- 'result' => $this->candidateRepository->getScores($quiz),
+ 'result' => $this->quizRepository->getScores($quiz),
]);
}
@@ -72,10 +72,10 @@ class QuizController extends AbstractController
name: 'tvdt_backoffice_quiz_clear',
requirements: ['quiz' => Requirement::UUID],
)]
- public function clearQuiz(Quiz $quiz, QuizRepository $quizRepository): RedirectResponse
+ public function clearQuiz(Quiz $quiz): RedirectResponse
{
try {
- $quizRepository->clearQuiz($quiz);
+ $this->quizRepository->clearQuiz($quiz);
$this->addFlash('success', $this->translator->trans('Quiz cleared'));
} catch (ErrorClearingQuizException) {
$this->addFlash('error', $this->translator->trans('Error clearing quiz'));
@@ -90,9 +90,9 @@ class QuizController extends AbstractController
name: 'tvdt_backoffice_quiz_delete',
requirements: ['quiz' => Requirement::UUID],
)]
- public function deleteQuiz(Quiz $quiz, QuizRepository $quizRepository): RedirectResponse
+ public function deleteQuiz(Quiz $quiz): RedirectResponse
{
- $quizRepository->deleteQuiz($quiz);
+ $this->quizRepository->deleteQuiz($quiz);
$this->addFlash('success', $this->translator->trans('Quiz deleted'));
@@ -105,7 +105,7 @@ class QuizController extends AbstractController
name: 'tvdt_backoffice_modify_correction',
requirements: ['quiz' => Requirement::UUID, 'candidate' => Requirement::UUID],
)]
- public function modifyCorrection(Quiz $quiz, Candidate $candidate, QuizCandidateRepository $quizCandidateRepository, Request $request): RedirectResponse
+ public function modifyCorrection(Quiz $quiz, Candidate $candidate, Request $request): RedirectResponse
{
if (!$request->isMethod('POST')) {
throw new MethodNotAllowedHttpException(['POST']);
@@ -113,7 +113,7 @@ class QuizController extends AbstractController
$corrections = (float) $request->request->get('corrections');
- $quizCandidateRepository->setCorrectionsForCandidate($quiz, $candidate, $corrections);
+ $this->quizCandidateRepository->setCorrectionsForCandidate($quiz, $candidate, $corrections);
return $this->redirectToRoute('tvdt_backoffice_quiz', ['seasonCode' => $quiz->season->seasonCode, 'quiz' => $quiz->id]);
}
diff --git a/src/Controller/Backoffice/SeasonController.php b/src/Controller/Backoffice/SeasonController.php
index 69ea4d8..198ca9a 100644
--- a/src/Controller/Backoffice/SeasonController.php
+++ b/src/Controller/Backoffice/SeasonController.php
@@ -30,6 +30,7 @@ class SeasonController extends AbstractController
public function __construct(
private readonly TranslatorInterface $translator,
private readonly EntityManagerInterface $em,
+ private readonly QuizSpreadsheetService $quizSpreadsheet,
) {}
#[IsGranted(SeasonVoter::EDIT, subject: 'season')]
@@ -87,7 +88,7 @@ class SeasonController extends AbstractController
requirements: ['seasonCode' => self::SEASON_CODE_REGEX],
priority: 10,
)]
- public function addQuiz(Request $request, Season $season, QuizSpreadsheetService $quizSpreadsheet): Response
+ public function addQuiz(Request $request, Season $season): Response
{
$quiz = new Quiz();
$form = $this->createForm(UploadQuizFormType::class, $quiz);
@@ -98,7 +99,7 @@ class SeasonController extends AbstractController
/* @var UploadedFile $sheet */
$sheet = $form->get('sheet')->getData();
- $quizSpreadsheet->xlsxToQuiz($quiz, $sheet);
+ $this->quizSpreadsheet->xlsxToQuiz($quiz, $sheet);
$quiz->season = $season;
$this->em->persist($quiz);
diff --git a/src/Controller/EliminationController.php b/src/Controller/EliminationController.php
index 4b885e9..6e9aab8 100644
--- a/src/Controller/EliminationController.php
+++ b/src/Controller/EliminationController.php
@@ -26,7 +26,7 @@ use function Symfony\Component\Translation\t;
#[IsGranted('ROLE_USER')]
final class EliminationController extends AbstractController
{
- public function __construct(private readonly TranslatorInterface $translator) {}
+ public function __construct(private readonly TranslatorInterface $translator, private readonly CandidateRepository $candidateRepository) {}
#[IsGranted(SeasonVoter::ELIMINATION, 'elimination')]
#[Route('/elimination/{elimination}', name: 'tvdt_elimination', requirements: ['elimination' => Requirement::UUID])]
@@ -50,9 +50,9 @@ final class EliminationController extends AbstractController
#[IsGranted(SeasonVoter::ELIMINATION, 'elimination')]
#[Route('/elimination/{elimination}/{candidateHash}', name: 'tvdt_elimination_candidate', requirements: ['elimination' => Requirement::UUID, 'candidateHash' => self::CANDIDATE_HASH_REGEX])]
- public function candidateScreen(Elimination $elimination, string $candidateHash, CandidateRepository $candidateRepository): Response
+ public function candidateScreen(Elimination $elimination, string $candidateHash): Response
{
- $candidate = $candidateRepository->getCandidateByHash($elimination->quiz->season, $candidateHash);
+ $candidate = $this->candidateRepository->getCandidateByHash($elimination->quiz->season, $candidateHash);
if (!$candidate instanceof Candidate) {
$this->addFlash(FlashType::Warning,
t('Cound not find candidate with name %name%', ['%name%' => Base64::base64UrlDecode($candidateHash)])->trans($this->translator),
diff --git a/src/Controller/LoginController.php b/src/Controller/LoginController.php
index 65a8661..946d75b 100644
--- a/src/Controller/LoginController.php
+++ b/src/Controller/LoginController.php
@@ -15,17 +15,17 @@ use Tvdt\Enum\FlashType;
#[AsController]
final class LoginController extends AbstractController
{
+ public function __construct(private readonly AuthenticationUtils $authenticationUtils, private readonly TranslatorInterface $translator) {}
+
#[Route(path: '/login', name: 'tvdt_login_login')]
- public function login(AuthenticationUtils $authenticationUtils, TranslatorInterface $translator): Response
+ public function login(): Response
{
// get the login error if there is one
- $error = $authenticationUtils->getLastAuthenticationError();
-
+ $error = $this->authenticationUtils->getLastAuthenticationError();
// last username entered by the user
- $lastUsername = $authenticationUtils->getLastUsername();
-
+ $lastUsername = $this->authenticationUtils->getLastUsername();
if ($error instanceof AuthenticationException) {
- $this->addFlash(FlashType::Danger, $translator->trans($error->getMessageKey(), $error->getMessageData(), 'security'));
+ $this->addFlash(FlashType::Danger, $this->translator->trans($error->getMessageKey(), $error->getMessageData(), 'security'));
}
return $this->render('backoffice/login/login.html.twig', [
diff --git a/src/Controller/QuizController.php b/src/Controller/QuizController.php
index fb5b9e1..07412bf 100644
--- a/src/Controller/QuizController.php
+++ b/src/Controller/QuizController.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace Tvdt\Controller;
+use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Attribute\AsController;
@@ -22,7 +23,6 @@ use Tvdt\Form\SelectSeasonType;
use Tvdt\Helpers\Base64;
use Tvdt\Repository\AnswerRepository;
use Tvdt\Repository\CandidateRepository;
-use Tvdt\Repository\GivenAnswerRepository;
use Tvdt\Repository\QuestionRepository;
use Tvdt\Repository\QuizCandidateRepository;
use Tvdt\Repository\SeasonRepository;
@@ -30,10 +30,10 @@ use Tvdt\Repository\SeasonRepository;
#[AsController]
final class QuizController extends AbstractController
{
- public function __construct(private readonly TranslatorInterface $translator) {}
+ public function __construct(private readonly TranslatorInterface $translator, private readonly EntityManagerInterface $entityManager, private readonly SeasonRepository $seasonRepository, private readonly CandidateRepository $candidateRepository, private readonly QuestionRepository $questionRepository, private readonly AnswerRepository $answerRepository, private readonly QuizCandidateRepository $quizCandidateRepository) {}
#[Route(path: '/', name: 'tvdt_quiz_select_season', methods: ['GET', 'POST'])]
- public function selectSeason(Request $request, SeasonRepository $seasonRepository): Response
+ public function selectSeason(Request $request): Response
{
$form = $this->createForm(SelectSeasonType::class);
$form->handleRequest($request);
@@ -41,7 +41,7 @@ final class QuizController extends AbstractController
if ($form->isSubmitted() && $form->isValid()) {
$seasonCode = $form->get('season_code')->getData();
- if ([] === $seasonRepository->findBy(['seasonCode' => $seasonCode])) {
+ if ([] === $this->seasonRepository->findBy(['seasonCode' => $seasonCode])) {
$this->addFlash(FlashType::Warning, $this->translator->trans('Invalid season code'));
return $this->redirectToRoute('tvdt_quiz_select_season');
@@ -80,13 +80,8 @@ final class QuizController extends AbstractController
Season $season,
string $nameHash,
Request $request,
- CandidateRepository $candidateRepository,
- QuestionRepository $questionRepository,
- AnswerRepository $answerRepository,
- GivenAnswerRepository $givenAnswerRepository,
- QuizCandidateRepository $quizCandidateRepository,
): Response {
- $candidate = $candidateRepository->getCandidateByHash($season, $nameHash);
+ $candidate = $this->candidateRepository->getCandidateByHash($season, $nameHash);
if (!$candidate instanceof Candidate) {
$this->addFlash(FlashType::Danger, $this->translator->trans('Candidate not found'));
@@ -103,28 +98,34 @@ final class QuizController extends AbstractController
}
if ('POST' === $request->getMethod()) {
- $answer = $answerRepository->findOneBy(['id' => $request->request->get('answer')]);
+ // TODO: Extract saving answer logic to a service
+ $answer = $this->answerRepository->findOneBy(['id' => $request->request->get('answer')]);
if (!$answer instanceof Answer) {
throw new BadRequestHttpException('Invalid Answer ID');
}
$givenAnswer = new GivenAnswer($candidate, $answer->question->quiz, $answer);
- $givenAnswerRepository->save($givenAnswer);
+ $this->entityManager->persist($givenAnswer);
+ $this->entityManager->flush();
+ // end of extarcting saving answer logic
return $this->redirectToRoute('tvdt_quiz_quiz_page', ['seasonCode' => $season->seasonCode, 'nameHash' => $nameHash]);
}
- $question = $questionRepository->findNextQuestionForCandidate($candidate);
+ // TODO: Extract getting next question logic to a service
+ $question = $this->questionRepository->findNextQuestionForCandidate($candidate);
+ // Keep creating flash here based on the return type of service call
if (!$question instanceof Question) {
$this->addFlash(FlashType::Success, $this->translator->trans('Quiz completed'));
return $this->redirectToRoute('tvdt_quiz_enter_name', ['seasonCode' => $season->seasonCode]);
}
- $quizCandidateRepository->createIfNotExist($quiz, $candidate);
+ $this->quizCandidateRepository->createIfNotExist($quiz, $candidate);
+ // end of extracting getting next question logic
return $this->render('quiz/question.twig', ['candidate' => $candidate, 'question' => $question, 'season' => $season]);
}
}
diff --git a/src/Controller/RegistrationController.php b/src/Controller/RegistrationController.php
index 3248a56..803ca30 100644
--- a/src/Controller/RegistrationController.php
+++ b/src/Controller/RegistrationController.php
@@ -9,6 +9,7 @@ use Psr\Log\LoggerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\SecurityBundle\Security;
+use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
@@ -23,15 +24,12 @@ use Tvdt\Security\EmailVerifier;
final class RegistrationController extends AbstractController
{
- public function __construct(private readonly EmailVerifier $emailVerifier, private readonly TranslatorInterface $translator) {}
+ public function __construct(private readonly EmailVerifier $emailVerifier, private readonly TranslatorInterface $translator, private readonly UserPasswordHasherInterface $userPasswordHasher, private readonly Security $security, private readonly LoggerInterface $logger, private readonly UserRepository $userRepository) {}
#[Route('/register', name: 'tvdt_register')]
public function register(
Request $request,
- UserPasswordHasherInterface $userPasswordHasher,
- Security $security,
EntityManagerInterface $entityManager,
- LoggerInterface $logger,
): Response {
$user = new User();
$form = $this->createForm(RegistrationFormType::class, $user);
@@ -41,7 +39,7 @@ final class RegistrationController extends AbstractController
/** @var string $plainPassword */
$plainPassword = $form->get('plainPassword')->getData();
- $user->password = $userPasswordHasher->hashPassword($user, $plainPassword);
+ $user->password = $this->userPasswordHasher->hashPassword($user, $plainPassword);
$entityManager->persist($user);
$entityManager->flush();
@@ -55,10 +53,10 @@ final class RegistrationController extends AbstractController
->htmlTemplate('backoffice/registration/confirmation_email.html.twig'),
);
} catch (TransportExceptionInterface $e) {
- $logger->error($e->getMessage());
+ $this->logger->error($e->getMessage());
}
- $response = $security->login($user, 'form_login', 'main');
+ $response = $this->security->login($user, 'form_login', 'main');
\assert($response instanceof Response);
return $response;
@@ -70,7 +68,7 @@ final class RegistrationController extends AbstractController
}
#[Route('/verify/email', name: 'tvdt_verify_email')]
- public function verifyUserEmail(Request $request, TranslatorInterface $translator, UserRepository $userRepository): Response
+ public function verifyUserEmail(Request $request): RedirectResponse
{
$id = $request->query->get('id');
@@ -78,7 +76,7 @@ final class RegistrationController extends AbstractController
return $this->redirectToRoute('tvdt_register');
}
- $user = $userRepository->find($id);
+ $user = $this->userRepository->find($id);
if (null === $user) {
return $this->redirectToRoute('tvdt_register');
@@ -88,7 +86,7 @@ final class RegistrationController extends AbstractController
try {
$this->emailVerifier->handleEmailConfirmation($request, $user);
} catch (VerifyEmailExceptionInterface $verifyEmailException) {
- $this->addFlash('verify_email_error', $translator->trans($verifyEmailException->getReason(), [], 'VerifyEmailBundle'));
+ $this->addFlash('verify_email_error', $this->translator->trans($verifyEmailException->getReason(), [], 'VerifyEmailBundle'));
return $this->redirectToRoute('tvdt_register');
}
diff --git a/src/DataFixtures/KrtekFixtures.php b/src/DataFixtures/KrtekFixtures.php
index 8f5bdbf..29cfb9c 100644
--- a/src/DataFixtures/KrtekFixtures.php
+++ b/src/DataFixtures/KrtekFixtures.php
@@ -5,6 +5,7 @@ declare(strict_types=1);
namespace Tvdt\DataFixtures;
use Doctrine\Bundle\FixturesBundle\Fixture;
+use Doctrine\Bundle\FixturesBundle\FixtureGroupInterface;
use Doctrine\Persistence\ObjectManager;
use Tvdt\Entity\Answer;
use Tvdt\Entity\Candidate;
@@ -12,8 +13,15 @@ use Tvdt\Entity\Question;
use Tvdt\Entity\Quiz;
use Tvdt\Entity\Season;
-class KrtekFixtures extends Fixture
+final class KrtekFixtures extends Fixture implements FixtureGroupInterface
{
+ public const string KRTEK_SEASON = 'krtek-seaspm';
+
+ public static function getGroups(): array
+ {
+ return ['test', 'dev'];
+ }
+
public function load(ObjectManager $manager): void
{
$season = new Season();
@@ -41,6 +49,8 @@ class KrtekFixtures extends Fixture
$season->addQuiz($this->createQuiz2($season));
$manager->flush();
+
+ $this->addReference(self::KRTEK_SEASON, $season);
}
private function createQuiz1(Season $season): Quiz
diff --git a/src/DataFixtures/TestFixtures.php b/src/DataFixtures/TestFixtures.php
new file mode 100644
index 0000000..0c5be0a
--- /dev/null
+++ b/src/DataFixtures/TestFixtures.php
@@ -0,0 +1,75 @@
+email = 'test@example.org';
+ $user->password = $this->passwordHasher->hashPassword($user, self::PASSWORD);
+
+ $manager->persist($user);
+
+ $user = new User();
+ $user->email = 'krtek-admin@example.org';
+ $user->password = $this->passwordHasher->hashPassword($user, self::PASSWORD);
+
+ $manager->persist($user);
+
+ $krtek = $this->getReference(KrtekFixtures::KRTEK_SEASON, Season::class);
+ $krtek->addOwner($user);
+
+ $anotherSeason = new Season();
+ $anotherSeason->name = 'Another Season';
+ $anotherSeason->seasonCode = 'bbbbb';
+
+ $manager->persist($anotherSeason);
+ $this->addReference('another-season', $anotherSeason);
+
+ $user = new User();
+ $user->email = 'user1@example.org';
+ $user->password = $this->passwordHasher->hashPassword($user, self::PASSWORD);
+
+ $manager->persist($user);
+ $user->addSeason($anotherSeason);
+
+ $user = new User();
+ $user->email = 'user2@example.org';
+ $user->password = $this->passwordHasher->hashPassword($user, self::PASSWORD);
+
+ $manager->persist($user);
+
+ $krtek->addOwner($user);
+ $anotherSeason->addOwner($user);
+
+ $manager->flush();
+ }
+}
diff --git a/src/Entity/Elimination.php b/src/Entity/Elimination.php
index 8875a3a..416ae0b 100644
--- a/src/Entity/Elimination.php
+++ b/src/Entity/Elimination.php
@@ -6,7 +6,7 @@ namespace Tvdt\Entity;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
-use Safe\DateTimeImmutable;
+use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\HttpFoundation\InputBag;
use Symfony\Component\Uid\Uuid;
@@ -30,6 +30,7 @@ class Elimination
#[ORM\Column(type: Types::JSONB)]
public array $data = [];
+ #[Gedmo\Timestampable(on: 'create')]
#[ORM\Column(type: Types::DATETIMETZ_IMMUTABLE, nullable: false)]
public private(set) \DateTimeImmutable $created;
@@ -54,12 +55,10 @@ class Elimination
public function getScreenColour(?string $name): ?string
{
+ if (null === $name) {
+ return null;
+ }
+
return $this->data[$name] ?? null;
}
-
- #[ORM\PrePersist]
- public function setCreatedAtValue(): void
- {
- $this->created = new DateTimeImmutable();
- }
}
diff --git a/src/Entity/GivenAnswer.php b/src/Entity/GivenAnswer.php
index 549f1fb..fb5edea 100644
--- a/src/Entity/GivenAnswer.php
+++ b/src/Entity/GivenAnswer.php
@@ -6,13 +6,12 @@ namespace Tvdt\Entity;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
-use Safe\DateTimeImmutable;
+use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
use Tvdt\Repository\GivenAnswerRepository;
#[ORM\Entity(repositoryClass: GivenAnswerRepository::class)]
-#[ORM\HasLifecycleCallbacks]
class GivenAnswer
{
#[ORM\Column(type: UuidType::NAME, unique: true)]
@@ -21,6 +20,7 @@ class GivenAnswer
#[ORM\Id]
public private(set) Uuid $id;
+ #[Gedmo\Timestampable(on: 'create')]
#[ORM\Column(type: Types::DATETIMETZ_IMMUTABLE, nullable: false)]
public private(set) \DateTimeImmutable $created;
@@ -37,10 +37,4 @@ class GivenAnswer
#[ORM\ManyToOne(inversedBy: 'givenAnswers')]
private(set) Answer $answer,
) {}
-
- #[ORM\PrePersist]
- public function setCreatedAtValue(): void
- {
- $this->created = new DateTimeImmutable();
- }
}
diff --git a/src/Entity/QuizCandidate.php b/src/Entity/QuizCandidate.php
index ca104bb..c3054d9 100644
--- a/src/Entity/QuizCandidate.php
+++ b/src/Entity/QuizCandidate.php
@@ -6,13 +6,12 @@ namespace Tvdt\Entity;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
-use Safe\DateTimeImmutable;
+use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Bridge\Doctrine\Types\UuidType;
use Symfony\Component\Uid\Uuid;
use Tvdt\Repository\QuizCandidateRepository;
#[ORM\Entity(repositoryClass: QuizCandidateRepository::class)]
-#[ORM\HasLifecycleCallbacks]
#[ORM\UniqueConstraint(columns: ['candidate_id', 'quiz_id'])]
class QuizCandidate
{
@@ -25,6 +24,7 @@ class QuizCandidate
#[ORM\Column]
public float $corrections = 0;
+ #[Gedmo\Timestampable(on: 'create')]
#[ORM\Column(type: Types::DATETIMETZ_IMMUTABLE)]
public private(set) \DateTimeImmutable $created;
@@ -37,10 +37,4 @@ class QuizCandidate
#[ORM\ManyToOne(inversedBy: 'quizData')]
public Candidate $candidate,
) {}
-
- #[ORM\PrePersist]
- public function setCreatedAtValue(): void
- {
- $this->created = new DateTimeImmutable();
- }
}
diff --git a/src/Entity/Season.php b/src/Entity/Season.php
index f7ac04a..a116000 100644
--- a/src/Entity/Season.php
+++ b/src/Entity/Season.php
@@ -98,7 +98,7 @@ class Season
return $this->owners->contains($user);
}
- public function generateSeasonCode(): self
+ public function generateSeasonCode(): void
{
$code = '';
$len = mb_strlen(self::SEASON_CODE_CHARACTERS) - 1;
@@ -108,7 +108,5 @@ class Season
}
$this->seasonCode = $code;
-
- return $this;
}
}
diff --git a/src/Enum/FlashType.php b/src/Enum/FlashType.php
index 8f93f73..8e4621b 100644
--- a/src/Enum/FlashType.php
+++ b/src/Enum/FlashType.php
@@ -7,11 +7,18 @@ namespace Tvdt\Enum;
enum FlashType: string
{
case Primary = 'primary';
+
case Secondary = 'secondary';
+
case Success = 'success';
+
case Danger = 'danger';
+
case Warning = 'warning';
+
case Info = 'info';
+
case Light = 'light';
+
case Dark = 'dark';
}
diff --git a/src/Factory/EliminationFactory.php b/src/Factory/EliminationFactory.php
index 7ce5d2c..10a9d79 100644
--- a/src/Factory/EliminationFactory.php
+++ b/src/Factory/EliminationFactory.php
@@ -7,12 +7,12 @@ namespace Tvdt\Factory;
use Doctrine\ORM\EntityManagerInterface;
use Tvdt\Entity\Elimination;
use Tvdt\Entity\Quiz;
-use Tvdt\Repository\CandidateRepository;
+use Tvdt\Repository\QuizRepository;
final readonly class EliminationFactory
{
public function __construct(
- private CandidateRepository $candidateRepository,
+ private QuizRepository $quizRepository,
private EntityManagerInterface $em,
) {}
@@ -21,7 +21,7 @@ final readonly class EliminationFactory
$elimination = new Elimination($quiz);
$this->em->persist($elimination);
- $scores = $this->candidateRepository->getScores($quiz);
+ $scores = $this->quizRepository->getScores($quiz);
$simpleScores = [];
diff --git a/src/Repository/CandidateRepository.php b/src/Repository/CandidateRepository.php
index 028fece..d883794 100644
--- a/src/Repository/CandidateRepository.php
+++ b/src/Repository/CandidateRepository.php
@@ -6,12 +6,8 @@ namespace Tvdt\Repository;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
-use Safe\DateTimeImmutable;
-use Safe\Exceptions\DatetimeException;
use Safe\Exceptions\UrlException;
-use Tvdt\Dto\Result;
use Tvdt\Entity\Candidate;
-use Tvdt\Entity\Quiz;
use Tvdt\Entity\Season;
use Tvdt\Helpers\Base64;
@@ -42,49 +38,4 @@ class CandidateRepository extends ServiceEntityRepository
->setParameter('name', $name)
->getOneOrNullResult();
}
-
- public function save(Candidate $candidate, bool $flush = true): void
- {
- $this->getEntityManager()->persist($candidate);
-
- if ($flush) {
- $this->getEntityManager()->flush();
- }
- }
-
- /**
- * @throws DatetimeException
- *
- * @return list
- */
- public function getScores(Quiz $quiz): array
- {
- $result = $this->getEntityManager()->createQuery(<<setParameter('quiz', $quiz)->getResult();
-
- return array_map(static fn (array $row): Result => new Result(
- id: $row['id'],
- name: $row['name'],
- correct: (int) $row['correct'],
- corrections: $row['corrections'],
- time: new DateTimeImmutable($row['end_time'])->diff($row['start_time']),
- score: $row['score'],
- ), $result);
- }
}
diff --git a/src/Repository/GivenAnswerRepository.php b/src/Repository/GivenAnswerRepository.php
index b8a13df..096f23e 100644
--- a/src/Repository/GivenAnswerRepository.php
+++ b/src/Repository/GivenAnswerRepository.php
@@ -17,13 +17,4 @@ class GivenAnswerRepository extends ServiceEntityRepository
{
parent::__construct($registry, GivenAnswer::class);
}
-
- public function save(GivenAnswer $givenAnswer, bool $flush = true): void
- {
- $this->getEntityManager()->persist($givenAnswer);
-
- if ($flush) {
- $this->getEntityManager()->flush();
- }
- }
}
diff --git a/src/Repository/QuizRepository.php b/src/Repository/QuizRepository.php
index 2f72807..92d468d 100644
--- a/src/Repository/QuizRepository.php
+++ b/src/Repository/QuizRepository.php
@@ -7,10 +7,10 @@ namespace Tvdt\Repository;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Psr\Log\LoggerInterface;
-use Tvdt\Entity\Elimination;
-use Tvdt\Entity\GivenAnswer;
+use Safe\DateTimeImmutable;
+use Safe\Exceptions\DatetimeException;
+use Tvdt\Dto\Result;
use Tvdt\Entity\Quiz;
-use Tvdt\Entity\QuizCandidate;
use Tvdt\Exception\ErrorClearingQuizException;
/**
@@ -29,28 +29,36 @@ class QuizRepository extends ServiceEntityRepository
$em = $this->getEntityManager();
$em->beginTransaction();
try {
- $em->createQueryBuilder()
- ->delete()->from(QuizCandidate::class, 'qc')
- ->where('qc.quiz = :quiz')
+ $em->createQuery(<<setParameter('quiz', $quiz)
- ->getQuery()->execute();
+ ->execute();
- $em->createQueryBuilder()
- ->delete()->from(GivenAnswer::class, 'ga')
- ->where('ga.quiz = :quiz')
+ $em->createQuery(<<setParameter('quiz', $quiz)
- ->getQuery()->execute();
- $em->createQueryBuilder()
- ->delete()->from(Elimination::class, 'e')
- ->where('e.quiz = :quiz')
+ ->execute();
+
+ $em->createQuery(<<setParameter('quiz', $quiz)
- ->getQuery()->execute();
- } catch (\Throwable $throwable) {
+ ->execute();
+ }
+ // @codeCoverageIgnoreStart
+ catch (\Throwable $throwable) {
$this->logger->error($throwable->getMessage());
$em->rollback();
throw new ErrorClearingQuizException(previous: $throwable);
}
+ // @codeCoverageIgnoreEnd
+
$em->commit();
}
@@ -59,4 +67,40 @@ class QuizRepository extends ServiceEntityRepository
$this->getEntityManager()->remove($quiz);
$this->getEntityManager()->flush();
}
+
+ /**
+ * @throws DatetimeException
+ *
+ * @return list
+ */
+ public function getScores(Quiz $quiz): array
+ {
+ $result = $this->getEntityManager()->createQuery(<<setParameter('quiz', $quiz)->getResult();
+
+ return array_map(static fn (array $row): Result => new Result(
+ id: $row['id'],
+ name: $row['name'],
+ correct: (int) $row['correct'],
+ corrections: $row['corrections'],
+ time: $row['start_time']->diff(new DateTimeImmutable($row['end_time'])),
+ score: $row['score'],
+ ), $result);
+ }
}
diff --git a/src/Repository/SeasonRepository.php b/src/Repository/SeasonRepository.php
index 194817d..d07d2a7 100644
--- a/src/Repository/SeasonRepository.php
+++ b/src/Repository/SeasonRepository.php
@@ -19,6 +19,17 @@ class SeasonRepository extends ServiceEntityRepository
parent::__construct($registry, Season::class);
}
+ public function findOneBySeasonCode(string $seasonCode): ?Season
+ {
+ return $this->getEntityManager()->createQuery(<<setParameter('seasonCode', $seasonCode)
+ ->setMaxResults(1)
+ ->getOneOrNullResult();
+ }
+
/** @return list Returns an array of Season objects */
public function getSeasonsForUser(User $user): array
{
diff --git a/src/Security/Voter/SeasonVoter.php b/src/Security/Voter/SeasonVoter.php
index 16fb8e4..85fa9e2 100644
--- a/src/Security/Voter/SeasonVoter.php
+++ b/src/Security/Voter/SeasonVoter.php
@@ -48,24 +48,14 @@ final class SeasonVoter extends Voter
return true;
}
- switch (true) {
- case $subject instanceof Answer:
- $season = $subject->question->quiz->season;
- break;
- case $subject instanceof Elimination:
- case $subject instanceof Question:
- $season = $subject->quiz->season;
- break;
- case $subject instanceof Candidate:
- case $subject instanceof Quiz:
- $season = $subject->season;
- break;
- case $subject instanceof Season:
- $season = $subject;
- break;
- default:
- return false;
- }
+ $season = match (true) {
+ $subject instanceof Answer => $subject->question->quiz->season,
+ $subject instanceof Elimination,
+ $subject instanceof Question => $subject->quiz->season,
+ $subject instanceof Candidate,
+ $subject instanceof Quiz => $subject->season,
+ $subject instanceof Season => $subject,
+ };
return match ($attribute) {
self::EDIT, self::DELETE, self::ELIMINATION => $season->isOwner($user),
diff --git a/src/Service/QuizSpreadsheetService.php b/src/Service/QuizSpreadsheetService.php
index 8aa951c..7a1178d 100644
--- a/src/Service/QuizSpreadsheetService.php
+++ b/src/Service/QuizSpreadsheetService.php
@@ -55,6 +55,10 @@ class QuizSpreadsheetService
/** @throws SpreadsheetDataException */
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);
$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
{
@@ -120,4 +127,9 @@ class QuizSpreadsheetService
return static fn () => $writer->save('php://output');
}
+
+ private function isSpreadsheetFile(File $file): bool
+ {
+ return 'xlsx' === $file->getExtension();
+ }
}
diff --git a/symfony.lock b/symfony.lock
index 331a929..3445edc 100644
--- a/symfony.lock
+++ b/symfony.lock
@@ -1,4 +1,16 @@
{
+ "dama/doctrine-test-bundle": {
+ "version": "8.4",
+ "recipe": {
+ "repo": "github.com/symfony/recipes-contrib",
+ "branch": "main",
+ "version": "8.3",
+ "ref": "dfc51177476fb39d014ed89944cde53dc3326d23"
+ },
+ "files": [
+ "config/packages/dama_doctrine_test_bundle.yaml"
+ ]
+ },
"doctrine/deprecations": {
"version": "1.1",
"recipe": {
@@ -72,31 +84,44 @@
]
},
"phpunit/phpunit": {
- "version": "12.1",
+ "version": "12.4",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
- "version": "10.0",
- "ref": "bb22cf8d8c554a623b427d5f3416b538f5525233"
+ "version": "11.1",
+ "ref": "1117deb12541f35793eec9fff7494d7aa12283fc"
},
"files": [
".env.test",
+ "bin/phpunit",
"phpunit.dist.xml",
"tests/bootstrap.php"
]
},
"sentry/sentry-symfony": {
- "version": "5.2",
+ "version": "5.6",
"recipe": {
"repo": "github.com/symfony/recipes-contrib",
"branch": "main",
"version": "5.0",
- "ref": "c3decefe8a11a5da43adaf827a6cd66695586113"
+ "ref": "b6cb4b34429dadecd7187852123be19d628fa37a"
},
"files": [
"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": {
"version": "7.2",
"recipe": {
diff --git a/tests/Command/ClaimSeasonCommandTest.php b/tests/Command/ClaimSeasonCommandTest.php
new file mode 100644
index 0000000..4cd6634
--- /dev/null
+++ b/tests/Command/ClaimSeasonCommandTest.php
@@ -0,0 +1,70 @@
+assertInstanceOf(KernelInterface::class, self::$kernel);
+
+ $this->seasonRepository = $container->get(SeasonRepository::class);
+ $application = new Application(self::$kernel);
+ $command = $application->find('tvdt:claim-season');
+ $this->commandTester = new CommandTester($command);
+ }
+
+ public function testSeasonClaim(): void
+ {
+ $this->commandTester->execute([
+ 'season-code' => 'krtek',
+ 'email' => 'test@example.org',
+ ]);
+
+ $season = $this->seasonRepository->findOneBySeasonCode('krtek');
+
+ $this->assertInstanceOf(Season::class, $season);
+
+ $this->assertSame(Command::SUCCESS, $this->commandTester->getStatusCode());
+ $this->assertCount(3, $season->owners);
+ }
+
+ public function testInvalidEmailFails(): void
+ {
+ $this->commandTester->execute([
+ 'season-code' => 'krtek',
+ 'email' => 'nonexisting@example.org',
+ ]);
+
+ $this->assertSame(Command::FAILURE, $this->commandTester->getStatusCode());
+ }
+
+ public function testInvalidSeasonCodeFails(): void
+ {
+ $this->commandTester->execute([
+ 'season-code' => 'dhadk',
+ 'email' => 'test@example.org',
+ ]);
+
+ $this->assertSame(Command::FAILURE, $this->commandTester->getStatusCode());
+ }
+}
diff --git a/tests/Command/MakeAdminCommandTest.php b/tests/Command/MakeAdminCommandTest.php
new file mode 100644
index 0000000..a904455
--- /dev/null
+++ b/tests/Command/MakeAdminCommandTest.php
@@ -0,0 +1,57 @@
+assertInstanceOf(KernelInterface::class, self::$kernel);
+
+ $this->userRepository = $container->get(UserRepository::class);
+ $application = new Application(self::$kernel);
+ $command = $application->find('tvdt:make-admin');
+ $this->commandTester = new CommandTester($command);
+ }
+
+ public function testMakeAdmin(): void
+ {
+ $this->commandTester->execute([
+ 'email' => 'test@example.org',
+ ]);
+
+ $user = $this->userRepository->findOneBy(['email' => 'test@example.org']);
+ $this->assertInstanceOf(User::class, $user);
+
+ $this->assertSame(Command::SUCCESS, $this->commandTester->getStatusCode());
+ $this->assertContains('ROLE_ADMIN', $user->roles);
+ }
+
+ public function testInvalidEmailFails(): void
+ {
+ $this->commandTester->execute([
+ 'email' => 'nonexisting@example.org',
+ ]);
+
+ $this->assertSame(Command::FAILURE, $this->commandTester->getStatusCode());
+ }
+}
diff --git a/tests/Helpers/Base64Test.php b/tests/Helpers/Base64Test.php
new file mode 100644
index 0000000..114c8f4
--- /dev/null
+++ b/tests/Helpers/Base64Test.php
@@ -0,0 +1,41 @@
+assertSame('TWFyaWpu', Base64::base64UrlEncode('Marijn'));
+ $this->assertSame('UGhpbGluZQ', Base64::base64UrlEncode('Philine'));
+
+ $this->assertSame('_g', Base64::base64UrlEncode(\chr(254)));
+ $this->assertSame('-g', Base64::base64UrlEncode(\chr(250)));
+ }
+
+ public function testBase64UrlDecode(): void
+ {
+ $this->assertSame('Marijn', Base64::base64UrlDecode('TWFyaWpu'));
+ $this->assertSame('Philine', Base64::base64UrlDecode('UGhpbGluZQ'));
+
+ $this->assertSame(\chr(254), Base64::base64UrlDecode('_g'));
+ $this->assertSame(\chr(250), Base64::base64UrlDecode('-g'));
+ }
+
+ public function testBase64UrlDecodeCanHandlePadding(): void
+ {
+ $this->assertSame('Philine', Base64::base64UrlDecode('UGhpbGluZQ=='));
+ }
+
+ public function testBase64UrlDecodeThrowsExceptionOnInvalidInput(): void
+ {
+ $this->expectException(UrlException::class);
+ Base64::base64UrlDecode('Philine==');
+ }
+}
diff --git a/tests/Repository/CandidateRepositoryTest.php b/tests/Repository/CandidateRepositoryTest.php
new file mode 100644
index 0000000..0a78eea
--- /dev/null
+++ b/tests/Repository/CandidateRepositoryTest.php
@@ -0,0 +1,56 @@
+ */
+ public static function candidateHashDataProvider(): iterable
+ {
+ yield 'Normal' => ['Q2xhdWRpYQ'];
+ yield 'lowercase' => ['Y2xhdWRpYQ'];
+ yield 'UPPERCASE' => ['Q0xBVURJQQ'];
+ }
+
+ #[DataProvider('candidateHashDataProvider')]
+ public function testGetCandidateByHash(string $hash): void
+ {
+ $krtekSeason = $this->getSeasonByCode('krtek');
+ $candidate = $this->candidateRepository->getCandidateByHash(
+ $krtekSeason,
+ $hash,
+ );
+
+ $this->assertInstanceOf(Candidate::class, $candidate);
+
+ $this->assertSame('Claudia', $candidate->name);
+ }
+
+ public function testGetCandidateByHashUnknownHashReturnsNull(): void
+ {
+ $krtekSeason = $this->getSeasonByCode('krtek');
+ $result = $this->candidateRepository->getCandidateByHash(
+ $krtekSeason,
+ 'TWFyaWpu',
+ );
+ $this->assertNotInstanceOf(Candidate::class, $result);
+ }
+
+ public function testGetCandidateByHashInvalidBase64HashReturnsNull(): void
+ {
+ $krtekSeason = $this->getSeasonByCode('krtek');
+ $result = $this->candidateRepository->getCandidateByHash(
+ $krtekSeason,
+ 'TWFyaWpu*',
+ );
+ $this->assertNotInstanceOf(Candidate::class, $result);
+ }
+}
diff --git a/tests/Repository/DatabaseTestCase.php b/tests/Repository/DatabaseTestCase.php
new file mode 100644
index 0000000..5687699
--- /dev/null
+++ b/tests/Repository/DatabaseTestCase.php
@@ -0,0 +1,70 @@
+entityManager = self::getContainer()->get(EntityManagerInterface::class);
+
+ $this->candidateRepository = self::getContainer()->get(CandidateRepository::class);
+ $this->questionRepository = self::getContainer()->get(QuestionRepository::class);
+ $this->quizCandidateRepository = self::getContainer()->get(QuizCandidateRepository::class);
+ $this->quizRepository = self::getContainer()->get(QuizRepository::class);
+ $this->seasonRepository = self::getContainer()->get(SeasonRepository::class);
+ $this->userRepository = self::getContainer()->get(UserRepository::class);
+ }
+
+ protected function getUserByEmail(string $email): User
+ {
+ $user = $this->userRepository->findOneBy(['email' => $email]);
+ $this->assertInstanceOf(User::class, $user);
+
+ return $user;
+ }
+
+ protected function getSeasonByCode(string $code): Season
+ {
+ $season = $this->seasonRepository->findOneBySeasonCode($code);
+ $this->assertInstanceOf(Season::class, $season);
+
+ return $season;
+ }
+
+ protected function getCandidateBySeasonAndName(Season $season, string $name): Candidate
+ {
+ $candidate = $this->candidateRepository->findOneBy(['season' => $season, 'name' => $name]);
+ $this->assertInstanceOf(Candidate::class, $candidate);
+
+ return $candidate;
+ }
+}
diff --git a/tests/Repository/QuestionRepositoryTest.php b/tests/Repository/QuestionRepositoryTest.php
new file mode 100644
index 0000000..52f2b3e
--- /dev/null
+++ b/tests/Repository/QuestionRepositoryTest.php
@@ -0,0 +1,87 @@
+getSeasonByCode('krtek');
+ $candidate = $this->getCandidateBySeasonAndName($krtekSeason, 'Tom');
+
+ $question = $this->questionRepository->findNextQuestionForCandidate($candidate);
+ $this->assertInstanceOf(Question::class, $question);
+ $this->assertSame('Is de Krtek een man of een vrouw?', $question->question, 'Wrong first question');
+
+ $this->answerQuestion($question, $candidate);
+
+ $question = $this->questionRepository->findNextQuestionForCandidate($candidate);
+ $this->assertInstanceOf(Question::class, $question);
+ $this->assertSame('Hoeveel broers heeft de Krtek?', $question->question, 'Wrong second question');
+
+ $question = $this->questionRepository->findNextQuestionForCandidate($candidate);
+ $this->assertInstanceOf(Question::class, $question);
+ $this->assertSame('Hoeveel broers heeft de Krtek?', $question->question, 'Getting question a second time fails');
+
+ $quiz = $krtekSeason->quizzes->last();
+ $this->assertInstanceOf(Quiz::class, $quiz);
+ $krtekSeason->activeQuiz = $quiz;
+ $this->entityManager->flush();
+
+ $question = $this->questionRepository->findNextQuestionForCandidate($candidate);
+ $this->assertInstanceOf(Question::class, $question);
+ $this->assertSame('Is de Krtek een man of een vrouw?', $question->question, 'Wrong question after switching season.');
+ }
+
+ public function testFindNextQuestionGivesNullWhenAllQuestionsAnswered(): void
+ {
+ $krtekSeason = $this->getSeasonByCode('krtek');
+ $candidate = $this->getCandidateBySeasonAndName($krtekSeason, 'Tom');
+
+ for ($i = 0; $i < 15; ++$i) {
+ $question = $this->questionRepository->findNextQuestionForCandidate($candidate);
+ $this->assertInstanceOf(Question::class, $question);
+ $this->answerQuestion($question, $candidate);
+ }
+
+ $question = $this->questionRepository->findNextQuestionForCandidate($candidate);
+
+ $this->assertNotInstanceOf(Question::class, $question);
+ }
+
+ public function testFindNextQuestionWithNoActiveQuizReturnsNull(): void
+ {
+ $krtekSeason = $this->getSeasonByCode('krtek');
+ $candidate = $this->getCandidateBySeasonAndName($krtekSeason, 'Tom');
+
+ $krtekSeason->activeQuiz = null;
+ $this->entityManager->flush();
+
+ $question = $this->questionRepository->findNextQuestionForCandidate($candidate);
+
+ $this->assertNotInstanceOf(Question::class, $question);
+ }
+
+ private function answerQuestion(Question $question, Candidate $candidate): void
+ {
+ $answer = $question->answers->first();
+ $this->assertInstanceOf(Answer::class, $answer);
+ $this->entityManager->persist(new GivenAnswer(
+ $candidate,
+ $question->quiz,
+ $answer,
+ ));
+ $this->entityManager->flush();
+ }
+}
diff --git a/tests/Repository/QuizCandidateRepositoryTest.php b/tests/Repository/QuizCandidateRepositoryTest.php
new file mode 100644
index 0000000..8ee5aac
--- /dev/null
+++ b/tests/Repository/QuizCandidateRepositoryTest.php
@@ -0,0 +1,72 @@
+getSeasonByCode('krtek');
+ $candidate = $this->getCandidateBySeasonAndName($krtekSeason, 'Myrthe');
+ $quiz = $krtekSeason->activeQuiz;
+ $this->assertInstanceOf(Quiz::class, $quiz);
+
+ $result = $this->quizCandidateRepository->createIfNotExist($quiz, $candidate);
+ $this->assertTrue($result);
+
+ $quizCandidate = $this->quizCandidateRepository->findOneBy([
+ 'candidate' => $candidate,
+ 'quiz' => $quiz,
+ ]);
+
+ $this->assertInstanceOf(QuizCandidate::class, $quizCandidate);
+
+ $result = $this->quizCandidateRepository->createIfNotExist($quiz, $candidate);
+ $this->assertFalse($result);
+ }
+
+ public function testSetCorrectionsForCandidateUpdatesCandidateCorrectly(): void
+ {
+ $krtekSeason = $this->getSeasonByCode('krtek');
+ $candidate = $this->getCandidateBySeasonAndName($krtekSeason, 'Myrthe');
+ $quiz = $krtekSeason->activeQuiz;
+ $this->assertInstanceOf(Quiz::class, $quiz);
+
+ $this->quizCandidateRepository->createIfNotExist($quiz, $candidate);
+
+ $this->quizCandidateRepository->setCorrectionsForCandidate(
+ $quiz, $candidate, 3.5,
+ );
+
+ $quizCandidate = $this->quizCandidateRepository->findOneBy([
+ 'candidate' => $candidate,
+ 'quiz' => $quiz,
+ ]);
+
+ $this->assertInstanceOf(QuizCandidate::class, $quizCandidate);
+
+ $this->assertEqualsWithDelta(3.5, $quizCandidate->corrections, 0.1);
+ }
+
+ public function testCannotGiveCorrectionsToCandidateWithoutResult(): void
+ {
+ $krtekSeason = $this->getSeasonByCode('krtek');
+ $candidate = $this->getCandidateBySeasonAndName($krtekSeason, 'Myrthe');
+ $quiz = $krtekSeason->activeQuiz;
+ $this->assertInstanceOf(Quiz::class, $quiz);
+
+ $this->expectException(\InvalidArgumentException::class);
+
+ $this->quizCandidateRepository->setCorrectionsForCandidate(
+ $quiz, $candidate, 3.5,
+ );
+ }
+}
diff --git a/tests/Repository/QuizRepositoryTest.php b/tests/Repository/QuizRepositoryTest.php
new file mode 100644
index 0000000..79f0ad9
--- /dev/null
+++ b/tests/Repository/QuizRepositoryTest.php
@@ -0,0 +1,214 @@
+getSeasonByCode('krtek');
+ $quiz = $krtekSeason->activeQuiz;
+ $this->assertInstanceOf(Quiz::class, $quiz);
+
+ $this->quizRepository->clearQuiz($quiz);
+
+ $this->entityManager->refresh($krtekSeason);
+
+ $this->assertEmpty($quiz->candidateData);
+ $this->assertEmpty($quiz->eliminations);
+
+ /** @var GivenAnswerRepository $givenAnswerRepository */
+ $givenAnswerRepository = self::getContainer()->get(GivenAnswerRepository::class);
+ $this->assertEmpty($givenAnswerRepository->findBy(['quiz' => $quiz]));
+ }
+
+ public function testDeleteQuiz(): void
+ {
+ $krtekSeason = $this->getSeasonByCode('krtek');
+ $quiz = $krtekSeason->quizzes->last();
+ $this->assertInstanceOf(Quiz::class, $quiz);
+
+ $this->quizRepository->deleteQuiz($quiz);
+
+ $this->entityManager->refresh($krtekSeason);
+
+ $this->assertCount(1, $krtekSeason->quizzes);
+ }
+
+ public function testTimeForCandidate(): void
+ {
+ $clock = new MockClock('2025-11-01 16:00:00');
+ self::getContainer()->set(ClockInterface::class, $clock);
+ $krtekSeason = $this->getSeasonByCode('krtek');
+ $candidate = $this->getCandidateBySeasonAndName($krtekSeason, 'Iris');
+
+ $quiz = $krtekSeason->activeQuiz;
+ $this->assertInstanceOf(Quiz::class, $quiz);
+
+ // Start Quiz
+ $qc = new QuizCandidate($quiz, $candidate);
+ $this->entityManager->persist($qc);
+ $this->entityManager->flush();
+
+ for ($i = 0; $i < 15; ++$i) {
+ $question = $this->questionRepository->findNextQuestionForCandidate($candidate);
+ $this->assertInstanceOf(Question::class, $question);
+
+ $answer = $question->answers->first();
+ $this->assertInstanceOf(Answer::class, $answer);
+
+ $clock->sleep(10 + $i);
+ $qa = new GivenAnswer($candidate, $quiz, $answer);
+ $this->entityManager->persist($qa);
+ $this->entityManager->flush();
+ }
+
+ $result = $this->quizRepository->getScores($quiz);
+
+ $this->assertSame('Iris', $result[0]->name);
+ $this->assertSame(5, $result[0]->correct);
+ $this->assertEqualsWithDelta(5.0, $result[0]->score, \PHP_FLOAT_EPSILON);
+
+ $this->assertSame(4, $result[0]->time->i);
+ $this->assertSame(15, $result[0]->time->s);
+ }
+
+ public function testScoresAreCalculatedCorrectly(): void
+ {
+ $clock = new MockClock('2025-11-01 16:00:00');
+ self::getContainer()->set(ClockInterface::class, $clock);
+ $krtekSeason = $this->getSeasonByCode('krtek');
+ $candidate1 = $this->getCandidateBySeasonAndName($krtekSeason, 'Iris');
+ $candidate2 = $this->getCandidateBySeasonAndName($krtekSeason, 'Philine');
+
+ $quiz = $krtekSeason->activeQuiz;
+ $this->assertInstanceOf(Quiz::class, $quiz);
+
+ $qc1 = new QuizCandidate($quiz, $candidate1);
+ $qc2 = new QuizCandidate($quiz, $candidate2);
+ $this->entityManager->persist($qc1);
+ $this->entityManager->persist($qc2);
+ $this->entityManager->flush();
+
+ for ($i = 0; $i < 15; ++$i) {
+ $question = $this->questionRepository->findNextQuestionForCandidate($candidate1);
+ $this->assertInstanceOf(Question::class, $question);
+
+ $answer1 = $question->answers->first();
+ $answer2 = $question->answers[intdiv(\count($question->answers), 2)];
+ $this->assertInstanceOf(Answer::class, $answer1);
+ $this->assertInstanceOf(Answer::class, $answer2);
+
+ $clock->sleep(10);
+
+ $qa = new GivenAnswer($candidate1, $quiz, $answer1);
+ $this->entityManager->persist($qa);
+ $qa = new GivenAnswer($candidate2, $quiz, $answer2);
+ $this->entityManager->persist($qa);
+
+ $this->entityManager->flush();
+ }
+
+ $scores = $this->quizRepository->getScores($quiz);
+ $this->assertCount(2, $scores);
+ $this->assertSame('Iris', $scores[0]->name);
+ $this->assertSame('Philine', $scores[1]->name);
+ $this->assertEqualsWithDelta(5.0, $scores[0]->score, \PHP_FLOAT_EPSILON);
+ $this->assertEqualsWithDelta(4.0, $scores[1]->score, \PHP_FLOAT_EPSILON);
+ }
+
+ public function testCorrectionsCalculatedCorrectly(): void
+ {
+ $clock = new MockClock('2025-11-01 16:00:00');
+ self::getContainer()->set(ClockInterface::class, $clock);
+ $krtekSeason = $this->getSeasonByCode('krtek');
+ $candidate = $this->getCandidateBySeasonAndName($krtekSeason, 'Iris');
+
+ $quiz = $krtekSeason->activeQuiz;
+ $this->assertInstanceOf(Quiz::class, $quiz);
+
+ $qc = new QuizCandidate($quiz, $candidate);
+ $this->entityManager->persist($qc);
+ $this->entityManager->flush();
+
+ for ($i = 0; $i < 15; ++$i) {
+ $question = $this->questionRepository->findNextQuestionForCandidate($candidate);
+ $this->assertInstanceOf(Question::class, $question);
+
+ $answer = $question->answers->first();
+ $this->assertInstanceOf(Answer::class, $answer);
+
+ $clock->sleep(10);
+ $qa = new GivenAnswer($candidate, $quiz, $answer);
+ $this->entityManager->persist($qa);
+ $this->entityManager->flush();
+ }
+
+ $qc->corrections = 2;
+ $this->entityManager->flush();
+
+ $result = $this->quizRepository->getScores($quiz);
+
+ $this->assertEqualsWithDelta(7.0, $result[0]->score, \PHP_FLOAT_EPSILON);
+ }
+
+ public function testCandidatesWithSameScoreAreSortedCorrectlyByTime(): void
+ {
+ $clock = new MockClock('2025-11-01 16:00:00');
+ self::getContainer()->set(ClockInterface::class, $clock);
+ $krtekSeason = $this->getSeasonByCode('krtek');
+ $candidate1 = $this->getCandidateBySeasonAndName($krtekSeason, 'Iris');
+ $candidate2 = $this->getCandidateBySeasonAndName($krtekSeason, 'Philine');
+
+ $quiz = $krtekSeason->activeQuiz;
+ $this->assertInstanceOf(Quiz::class, $quiz);
+
+ $qc1 = new QuizCandidate($quiz, $candidate1);
+ $this->entityManager->persist($qc1);
+ $clock->sleep(10);
+ $qc2 = new QuizCandidate($quiz, $candidate2);
+ $this->entityManager->persist($qc2);
+ $this->entityManager->flush();
+
+ for ($i = 0; $i < 15; ++$i) {
+ $question = $this->questionRepository->findNextQuestionForCandidate($candidate1);
+ $this->assertInstanceOf(Question::class, $question);
+
+ $answer1 = $question->answers->first();
+ $answer2 = $question->answers->last();
+ $this->assertInstanceOf(Answer::class, $answer1);
+ $this->assertInstanceOf(Answer::class, $answer2);
+
+ $clock->sleep(10);
+
+ $qa = new GivenAnswer($candidate1, $quiz, $answer1);
+ $this->entityManager->persist($qa);
+
+ $qa = new GivenAnswer($candidate2, $quiz, $answer2);
+ $this->entityManager->persist($qa);
+
+ $this->entityManager->flush();
+ }
+
+ $result = $this->quizRepository->getScores($quiz);
+
+ $this->assertEqualsWithDelta(5.0, $result[0]->score, \PHP_FLOAT_EPSILON);
+ $this->assertEqualsWithDelta(5.0, $result[1]->score, \PHP_FLOAT_EPSILON);
+ $this->assertSame('Philine', $result[0]->name);
+ $this->assertSame('Iris', $result[1]->name);
+ }
+}
diff --git a/tests/Repository/SeasonRepositoryTest.php b/tests/Repository/SeasonRepositoryTest.php
new file mode 100644
index 0000000..589d1cc
--- /dev/null
+++ b/tests/Repository/SeasonRepositoryTest.php
@@ -0,0 +1,59 @@
+getUserByEmail('krtek-admin@example.org');
+
+ $seasons = $this->seasonRepository->getSeasonsForUser($user);
+ $this->assertCount(1, $seasons);
+ $this->assertSame('krtek', $seasons[0]->seasonCode);
+
+ $user = $this->getUserByEmail('user1@example.org');
+
+ $seasons = $this->seasonRepository->getSeasonsForUser($user);
+ $this->assertCount(1, $seasons);
+ $this->assertSame('bbbbb', $seasons[0]->seasonCode);
+ }
+
+ public function testUserWithMultipleSeasons(): void
+ {
+ $user = $this->getUserByEmail('user2@example.org');
+ $seasons = $this->seasonRepository->getSeasonsForUser($user);
+
+ $this->assertCount(2, $seasons);
+ $this->assertSame('bbbbb', $seasons[0]->seasonCode);
+ $this->assertSame('krtek', $seasons[1]->seasonCode);
+ }
+
+ public function testGetSeasonsForUserWithoutSeasonsReturnsEmpty(): void
+ {
+ $user = $this->getUserByEmail('test@example.org');
+
+ $seasons = $this->seasonRepository->getSeasonsForUser($user);
+ $this->assertEmpty($seasons);
+ }
+
+ public function testFindOneBySeasonCode(): void
+ {
+ $season = $this->seasonRepository->findOneBySeasonCode('krtek');
+ $this->assertInstanceOf(Season::class, $season);
+ $this->assertSame('krtek', $season->seasonCode);
+ }
+
+ public function testFindOneBySeasonCodeUnknownSeasonReturnsNull(): void
+ {
+ $season = $this->seasonRepository->findOneBySeasonCode('invalid');
+ $this->assertNotInstanceOf(Season::class, $season);
+ }
+}
diff --git a/tests/Repository/UserRepositoryTest.php b/tests/Repository/UserRepositoryTest.php
new file mode 100644
index 0000000..8770e5b
--- /dev/null
+++ b/tests/Repository/UserRepositoryTest.php
@@ -0,0 +1,45 @@
+get(UserPasswordHasherInterface::class);
+ $user = $this->getUserByEmail('user1@example.org');
+
+ $newHash = $passwordHasher->hashPassword($user, TestFixtures::PASSWORD);
+
+ $this->assertNotSame($newHash, $user->password);
+ $this->userRepository->upgradePassword($user, $newHash);
+
+ $this->entityManager->refresh($user);
+ $this->assertSame($newHash, $user->password);
+ }
+
+ public function testMakeAdmin(): void
+ {
+ $user = $this->getUserByEmail('test@example.org');
+ assertEmpty($user->roles);
+ $this->userRepository->makeAdmin('test@example.org');
+ $this->entityManager->refresh($user);
+ $this->assertSame(['ROLE_ADMIN'], $user->roles);
+ }
+
+ public function testMakeAdminInvalidEmail(): void
+ {
+ $this->expectException(\InvalidArgumentException::class);
+ $this->userRepository->makeAdmin('invalid@example.org');
+ }
+}
diff --git a/tests/Security/Voter/SeasonVoterTest.php b/tests/Security/Voter/SeasonVoterTest.php
index 884939b..e882af7 100644
--- a/tests/Security/Voter/SeasonVoterTest.php
+++ b/tests/Security/Voter/SeasonVoterTest.php
@@ -4,11 +4,13 @@ declare(strict_types=1);
namespace Tvdt\Tests\Security\Voter;
+use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\MockObject\Stub;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\VoterInterface;
+use Symfony\Component\Security\Core\User\UserInterface;
use Tvdt\Entity\Answer;
use Tvdt\Entity\Candidate;
use Tvdt\Entity\Elimination;
@@ -18,6 +20,7 @@ use Tvdt\Entity\Season;
use Tvdt\Entity\User;
use Tvdt\Security\Voter\SeasonVoter;
+#[CoversClass(SeasonVoter::class)]
final class SeasonVoterTest extends TestCase
{
private SeasonVoter $seasonVoter;
@@ -51,27 +54,58 @@ final class SeasonVoterTest extends TestCase
{
$season = self::createStub(Season::class);
$season->method('isOwner')->willReturn(true);
-
- $quiz = self::createStub(Quiz::class);
- $quiz->season = $season;
-
- $elimination = self::createStub(Elimination::class);
- $elimination->quiz = $quiz;
+ yield 'Season' => [$season];
$candidate = self::createStub(Candidate::class);
$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->quiz = $quiz;
+ yield 'Question' => [$question];
$answer = self::createStub(Answer::class);
$answer->question = $question;
-
- yield 'Season' => [$season];
- yield 'Elimination' => [$elimination];
- yield 'Quiz' => [$quiz];
- yield 'Candidate' => [$candidate];
- yield 'Question' => [$question];
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']));
+ }
}