From 696b40ca803443839f1331dfa23ae45845a970a0 Mon Sep 17 00:00:00 2001 From: matthieu Date: Wed, 20 May 2026 00:05:49 +0200 Subject: [PATCH] feat(mail) : install symfony/messenger + browser-kit + ENCRYPTION_KEY test (deps Phase 3) - ajoute symfony/messenger ^8.0 et symfony/doctrine-messenger ^8.0 pour la sync mail async - ajoute symfony/browser-kit + css-selector en dev pour tests fonctionnels WebTestCase - ENCRYPTION_KEY ajoutee dans phpunit.dist.xml pour permettre le chiffrement en test - MESSENGER_TRANSPORT_DSN configure (Doctrine), messenger.yaml minimal (sera enrichi en Task 12) - fix(orm) : ClientTicket - migre uniqueConstraints en attribut separe (Doctrine ORM 4 deprecation) Co-Authored-By: Claude Opus 4.7 (1M context) --- .env | 7 + composer.json | 6 +- composer.lock | 379 ++++++++++++++++++++++++++++++++- config/packages/messenger.yaml | 6 + config/reference.php | 8 +- phpunit.dist.xml | 6 + src/Entity/ClientTicket.php | 8 +- 7 files changed, 408 insertions(+), 12 deletions(-) create mode 100644 config/packages/messenger.yaml diff --git a/.env b/.env index fccfe41..b7692f4 100644 --- a/.env +++ b/.env @@ -26,3 +26,10 @@ ENCRYPTION_KEY=change_me_in_env_local # postgresql+advisory://db_user:db_password@localhost/db_name LOCK_DSN=flock ###< symfony/lock ### + +###> symfony/messenger ### +# Choose one of the transports below +# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages +# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages +MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 +###< symfony/messenger ### diff --git a/composer.json b/composer.json index 6b15e9b..aae37ad 100644 --- a/composer.json +++ b/composer.json @@ -21,6 +21,7 @@ "sabre/vobject": "^4.5", "symfony/asset": "8.0.*", "symfony/console": "8.0.*", + "symfony/doctrine-messenger": "^8.0", "symfony/dotenv": "8.0.*", "symfony/expression-language": "8.0.*", "symfony/flex": "^2", @@ -28,6 +29,7 @@ "symfony/http-client": "8.0.*", "symfony/lock": "8.0.*", "symfony/mcp-bundle": "^0.6.0", + "symfony/messenger": "^8.0", "symfony/mime": "8.0.*", "symfony/monolog-bundle": "^4.0", "symfony/property-access": "8.0.*", @@ -95,6 +97,8 @@ "require-dev": { "doctrine/doctrine-fixtures-bundle": "^4.3", "friendsofphp/php-cs-fixer": "^3.94", - "phpunit/phpunit": "^13.0" + "phpunit/phpunit": "^13.0", + "symfony/browser-kit": "^8.0", + "symfony/css-selector": "^8.0" } } diff --git a/composer.lock b/composer.lock index b871c3d..b48e773 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": "0a35f14eff2d93998449dc614f02d610", + "content-hash": "dc72ee68996f3f738763eafd350bc0e0", "packages": [ { "name": "api-platform/doctrine-common", @@ -5841,6 +5841,82 @@ ], "time": "2026-03-06T13:17:40+00:00" }, + { + "name": "symfony/doctrine-messenger", + "version": "v8.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/doctrine-messenger.git", + "reference": "88329a3faba5023cfb569b3fc5b8a771336c4a88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/doctrine-messenger/zipball/88329a3faba5023cfb569b3fc5b8a771336c4a88", + "reference": "88329a3faba5023cfb569b3fc5b8a771336c4a88", + "shasum": "" + }, + "require": { + "doctrine/dbal": "^4.3", + "php": ">=8.4", + "symfony/messenger": "^7.4|^8.0", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "doctrine/persistence": "<1.3" + }, + "require-dev": { + "doctrine/persistence": "^1.3|^2|^3", + "symfony/property-access": "^7.4|^8.0", + "symfony/serializer": "^7.4|^8.0" + }, + "type": "symfony-messenger-bridge", + "autoload": { + "psr-4": { + "Symfony\\Component\\Messenger\\Bridge\\Doctrine\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Doctrine Messenger Bridge", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/doctrine-messenger/tree/v8.0.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "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": "2026-02-20T07:51:53+00:00" + }, { "name": "symfony/dotenv", "version": "v8.0.7", @@ -7099,6 +7175,96 @@ ], "time": "2026-03-04T16:39:24+00:00" }, + { + "name": "symfony/messenger", + "version": "v8.0.11", + "source": { + "type": "git", + "url": "https://github.com/symfony/messenger.git", + "reference": "c451c175724fc781c777783aaec3b7999ceb0621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/messenger/zipball/c451c175724fc781c777783aaec3b7999ceb0621", + "reference": "c451c175724fc781c777783aaec3b7999ceb0621", + "shasum": "" + }, + "require": { + "php": ">=8.4", + "psr/log": "^1|^2|^3", + "symfony/clock": "^7.4|^8.0" + }, + "conflict": { + "symfony/console": "<7.4", + "symfony/event-dispatcher-contracts": "<2.5", + "symfony/lock": "<7.4", + "symfony/serializer": "<7.4.4|>=8.0,<8.0.4" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/console": "^7.4|^8.0", + "symfony/dependency-injection": "^7.4|^8.0", + "symfony/event-dispatcher": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/lock": "^7.4|^8.0", + "symfony/process": "^7.4|^8.0", + "symfony/property-access": "^7.4|^8.0", + "symfony/rate-limiter": "^7.4|^8.0", + "symfony/routing": "^7.4|^8.0", + "symfony/serializer": "^7.4.4|^8.0.4", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^7.4|^8.0", + "symfony/validator": "^7.4|^8.0", + "symfony/var-dumper": "^7.4|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Messenger\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Samuel Roze", + "email": "samuel.roze@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps applications send and receive messages to/from other applications or via message queues", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/messenger/tree/v8.0.11" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "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": "2026-05-13T12:07:53+00:00" + }, { "name": "symfony/mime", "version": "v8.0.7", @@ -13128,6 +13294,217 @@ ], "time": "2024-10-20T05:08:20+00:00" }, + { + "name": "symfony/browser-kit", + "version": "v8.0.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/browser-kit.git", + "reference": "f5a28fca785416cf489dd579011e74c831100cc3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/browser-kit/zipball/f5a28fca785416cf489dd579011e74c831100cc3", + "reference": "f5a28fca785416cf489dd579011e74c831100cc3", + "shasum": "" + }, + "require": { + "php": ">=8.4", + "symfony/dom-crawler": "^7.4|^8.0" + }, + "require-dev": { + "symfony/css-selector": "^7.4|^8.0", + "symfony/http-client": "^7.4|^8.0", + "symfony/mime": "^7.4|^8.0", + "symfony/process": "^7.4|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\BrowserKit\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "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/v8.0.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "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": "2026-03-30T15:14:47+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v8.0.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "3665cfade90565430909b906394c73c8739e57d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/3665cfade90565430909b906394c73c8739e57d0", + "reference": "3665cfade90565430909b906394c73c8739e57d0", + "shasum": "" + }, + "require": { + "php": ">=8.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Converts CSS selectors to XPath expressions", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v8.0.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "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": "2026-04-18T13:51:42+00:00" + }, + { + "name": "symfony/dom-crawler", + "version": "v8.0.8", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "284ace90732b445b027728b5e0eec6418a17a364" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/284ace90732b445b027728b5e0eec6418a17a364", + "reference": "284ace90732b445b027728b5e0eec6418a17a364", + "shasum": "" + }, + "require": { + "php": ">=8.4", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.0" + }, + "require-dev": { + "symfony/css-selector": "^7.4|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases DOM navigation for HTML and XML documents", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dom-crawler/tree/v8.0.8" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "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": "2026-03-30T15:14:47+00:00" + }, { "name": "symfony/process", "version": "v8.0.5", diff --git a/config/packages/messenger.yaml b/config/packages/messenger.yaml new file mode 100644 index 0000000..e1aa710 --- /dev/null +++ b/config/packages/messenger.yaml @@ -0,0 +1,6 @@ +framework: + messenger: + transports: + sync: 'sync://' + + routing: {} diff --git a/config/reference.php b/config/reference.php index bd1717f..145877b 100644 --- a/config/reference.php +++ b/config/reference.php @@ -301,7 +301,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * }, * }, * translator?: bool|array{ // Translator configuration - * enabled?: bool|Param, // Default: false + * enabled?: bool|Param, // Default: true * fallbacks?: list, * logging?: bool|Param, // Default: false * formatter?: scalar|Param|null, // Default: "translator.formatter.default" @@ -413,7 +413,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * enabled?: bool|Param, // Default: true * }, * lock?: bool|string|array{ // Lock configuration - * enabled?: bool|Param, // Default: false + * enabled?: bool|Param, // Default: true * resources?: array>, * }, * semaphore?: bool|string|array{ // Semaphore configuration @@ -421,7 +421,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * resources?: array, * }, * messenger?: bool|array{ // Messenger configuration - * enabled?: bool|Param, // Default: false + * enabled?: bool|Param, // Default: true * routing?: array, * }>, @@ -1360,7 +1360,7 @@ use Symfony\Component\Config\Loader\ParamConfigurator as Param; * include_type?: bool|Param, // Always include @var in updates (including delete ones). // Default: false * }, * messenger?: bool|array{ - * enabled?: bool|Param, // Default: false + * enabled?: bool|Param, // Default: true * }, * elasticsearch?: bool|array{ * enabled?: bool|Param, // Default: false diff --git a/phpunit.dist.xml b/phpunit.dist.xml index bec7cd2..817239b 100644 --- a/phpunit.dist.xml +++ b/phpunit.dist.xml @@ -22,6 +22,12 @@ + + + + + + diff --git a/src/Entity/ClientTicket.php b/src/Entity/ClientTicket.php index 54a4d7e..b825c2f 100644 --- a/src/Entity/ClientTicket.php +++ b/src/Entity/ClientTicket.php @@ -47,12 +47,8 @@ use Symfony\Component\Validator\Constraints as Assert; order: ['createdAt' => 'DESC'], )] #[ORM\Entity(repositoryClass: ClientTicketRepository::class)] -#[ORM\Table( - name: 'client_ticket', - uniqueConstraints: [ - new ORM\UniqueConstraint(name: 'uniq_client_ticket_project_number', columns: ['project_id', 'number']), - ], -)] +#[ORM\Table(name: 'client_ticket')] +#[ORM\UniqueConstraint(name: 'uniq_client_ticket_project_number', columns: ['project_id', 'number'])] class ClientTicket { public const string TYPE_BUG = 'bug';