From 67db0b9dd51b4cbbc42b3ad05489c1bc7f146997 Mon Sep 17 00:00:00 2001 From: Nathan Boiron Date: Sat, 29 Mar 2025 16:32:43 +0100 Subject: [PATCH] Mise en place de Doctrine ORM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Comme discuté lors du dernier point mensuel, on avait décidé de tenter une transition vers Doctrine en mode ORM pour unifier les différents accès à la base de données. Dans ce commit, il n'y a qu'une seule table de mappée avec l'ORM afin de simplifier la review et de s'assurer que tout fonctionne correctement en production avant de poursuivre avec d'autres tables. Certaines options sont commentées car elles n'existent qu'à partir de la v3 de `doctrine/orm`. --- app/AppKernel.php | 2 + app/config/config.yml | 1 + app/config/packages/doctrine.yaml | 55 ++ app/config/services.yml | 18 +- composer.json | 2 + composer.lock | 646 +++++++++++++++++- .../AppBundle/VideoNotifier/HistoryEntry.php | 24 + .../VideoNotifier/HistoryRepository.php | 46 +- 8 files changed, 749 insertions(+), 45 deletions(-) create mode 100644 app/config/packages/doctrine.yaml diff --git a/app/AppKernel.php b/app/AppKernel.php index 69cf6b618..a99c5a085 100644 --- a/app/AppKernel.php +++ b/app/AppKernel.php @@ -4,6 +4,7 @@ use AppBundle\AppBundle; use CCMBenchmark\TingBundle\TingBundle; +use Doctrine\Bundle\DoctrineBundle\DoctrineBundle; use Ekino\NewRelicBundle\EkinoNewRelicBundle; use EWZ\Bundle\RecaptchaBundle\EWZRecaptchaBundle; use JMS\SerializerBundle\JMSSerializerBundle; @@ -34,6 +35,7 @@ public function registerBundles(): array new PrestaSitemapBundle(), new EWZRecaptchaBundle(), new EkinoNewRelicBundle(), + new DoctrineBundle(), ]; if (in_array($this->getEnvironment(), ['dev', 'test'], true)) { diff --git a/app/config/config.yml b/app/config/config.yml index dc073f84c..7433b2168 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -3,6 +3,7 @@ imports: - { resource: security.yml } - { resource: services.yml } - { resource: packages/http_client.yaml } + - { resource: packages/doctrine.yaml } # Put parameters here that don't need to change on each machine where the app is deployed # http://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration diff --git a/app/config/packages/doctrine.yaml b/app/config/packages/doctrine.yaml new file mode 100644 index 000000000..e4d71c2a8 --- /dev/null +++ b/app/config/packages/doctrine.yaml @@ -0,0 +1,55 @@ +doctrine: + dbal: +# url: '%env(resolve:DATABASE_URL)%' + url: 'mysql://%database_user%:%database_password%@%database_host%:%database_port%/%database_name%?charset=utf8mb4' + + # IMPORTANT: You MUST configure your server version, + # either here or in the DATABASE_URL env var + server_version: '5' + + profiling_collect_backtrace: '%kernel.debug%' + use_savepoints: true + orm: + auto_generate_proxy_classes: true +# enable_lazy_ghost_objects: true +# report_fields_where_declared: true +# validate_xml_mapping: true + naming_strategy: doctrine.orm.naming_strategy.underscore_number_aware +# identity_generation_preferences: +# Doctrine\DBAL\Platforms\MySqlPlatform: identity + auto_mapping: true + mappings: + AppBundle: + type: annotation + is_bundle: false + dir: '%kernel.project_dir%/../sources/AppBundle' + prefix: 'AppBundle' + alias: AppBundle + controller_resolver: + auto_mapping: false + +when@test: + doctrine: + dbal: + # "TEST_TOKEN" is typically set by ParaTest +# dbname_suffix: '_test%env(default::TEST_TOKEN)%' + +when@prod: + doctrine: + orm: + auto_generate_proxy_classes: false + proxy_dir: '%kernel.build_dir%/doctrine/orm/Proxies' + query_cache_driver: + type: pool + pool: doctrine.system_cache_pool + result_cache_driver: + type: pool + pool: doctrine.result_cache_pool + + framework: + cache: + pools: + doctrine.result_cache_pool: + adapter: cache.app + doctrine.system_cache_pool: + adapter: cache.system diff --git a/app/config/services.yml b/app/config/services.yml index c0ba96462..ea46a991a 100644 --- a/app/config/services.yml +++ b/app/config/services.yml @@ -26,7 +26,6 @@ services: db_password: '%database_password%' lock_mode: !php/const Symfony\Component\HttpFoundation\Session\Storage\Handler\PdoSessionHandler::LOCK_NONE - AppBundle\Command\: resource: '../../sources/AppBundle/Command/*' autowire: true @@ -703,14 +702,6 @@ services: tags: - { name: twig.extension } - Doctrine\DBAL\Configuration: ~ - Doctrine\DBAL\Connection: - factory: [Doctrine\DBAL\DriverManager, 'getConnection'] - arguments: - - {url: 'mysql://%database_user%:%database_password%@%database_host%:%database_port%/%database_name%?charset=utf8mb4'} - - '@Doctrine\DBAL\Configuration' - - Symfony\Component\HttpFoundation\Session\SessionInterface: alias: 'session' public: true @@ -753,14 +744,9 @@ services: $apiAppPassword: '%bluesky.api.app_password%' AppBundle\VideoNotifier\HistoryRepository: - arguments: - $connection: '@Doctrine\DBAL\Connection' + autowire: true AppBundle\VideoNotifier\Engine: + autowire: true arguments: $transports: !tagged_iterator app.social_network.transport - $planningRepository: '@AppBundle\Event\Model\Repository\PlanningRepository' - $talkRepository: '@AppBundle\Event\Model\Repository\TalkRepository' - $speakerRepository: '@AppBundle\Event\Model\Repository\SpeakerRepository' - $historyRepository: '@AppBundle\VideoNotifier\HistoryRepository' - $logger: '@logger' diff --git a/composer.json b/composer.json index c997c04fb..dea804bb2 100644 --- a/composer.json +++ b/composer.json @@ -18,6 +18,8 @@ "cocur/slugify": "^2.3", "cuyz/valinor": "^0.17.1", "doctrine/dbal": "^2.5", + "doctrine/doctrine-bundle": "^2.7", + "doctrine/orm": "^2.20", "ekino/newrelic-bundle": "^2.4", "erusev/parsedown": "^1.6", "excelwebzone/recaptcha-bundle": "^1.5", diff --git a/composer.lock b/composer.lock index 9ad2a31da..c250a2e3a 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": "94131ce091b57b6a8560ea6cad345173", + "content-hash": "a146d23eb5f91d26183920d220f7dc9b", "packages": [ { "name": "algolia/algoliasearch-client-php", @@ -1068,6 +1068,167 @@ ], "time": "2022-05-20T20:06:54+00:00" }, + { + "name": "doctrine/collections", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/collections.git", + "reference": "2b44dd4cbca8b5744327de78bafef5945c7e7b5e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/collections/zipball/2b44dd4cbca8b5744327de78bafef5945c7e7b5e", + "reference": "2b44dd4cbca8b5744327de78bafef5945c7e7b5e", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^0.5.3 || ^1", + "php": "^7.1.3 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0 || ^10.0", + "phpstan/phpstan": "^1.4.8", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.1.5", + "vimeo/psalm": "^4.22" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Collections library that adds additional functionality on top of PHP arrays.", + "homepage": "https://www.doctrine-project.org/projects/collections.html", + "keywords": [ + "array", + "collections", + "iterators", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/collections/issues", + "source": "https://github.com/doctrine/collections/tree/1.8.0" + }, + "time": "2022-09-01T20:12:10+00:00" + }, + { + "name": "doctrine/common", + "version": "3.5.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/common.git", + "reference": "d9ea4a54ca2586db781f0265d36bea731ac66ec5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/common/zipball/d9ea4a54ca2586db781f0265d36bea731ac66ec5", + "reference": "d9ea4a54ca2586db781f0265d36bea731ac66ec5", + "shasum": "" + }, + "require": { + "doctrine/persistence": "^2.0 || ^3.0 || ^4.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0 || ^10.0", + "doctrine/collections": "^1", + "phpstan/phpstan": "^1.4.1", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0", + "squizlabs/php_codesniffer": "^3.0", + "symfony/phpunit-bridge": "^6.1", + "vimeo/psalm": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and much more.", + "homepage": "https://www.doctrine-project.org/projects/common.html", + "keywords": [ + "common", + "doctrine", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/common/issues", + "source": "https://github.com/doctrine/common/tree/3.5.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcommon", + "type": "tidelift" + } + ], + "time": "2025-01-01T22:12:03+00:00" + }, { "name": "doctrine/dbal", "version": "2.13.9", @@ -1222,6 +1383,120 @@ }, "time": "2024-12-07T21:18:45+00:00" }, + { + "name": "doctrine/doctrine-bundle", + "version": "2.7.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/DoctrineBundle.git", + "reference": "22d53b2c5ad03929628fb4a928b01135585b7179" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/22d53b2c5ad03929628fb4a928b01135585b7179", + "reference": "22d53b2c5ad03929628fb4a928b01135585b7179", + "shasum": "" + }, + "require": { + "doctrine/annotations": "^1", + "doctrine/cache": "^1.11 || ^2.0", + "doctrine/dbal": "^2.13.1 || ^3.3.2", + "doctrine/persistence": "^2.2 || ^3", + "doctrine/sql-formatter": "^1.0.1", + "php": "^7.1 || ^8.0", + "symfony/cache": "^4.4 || ^5.4 || ^6.0", + "symfony/config": "^4.4.3 || ^5.4 || ^6.0", + "symfony/console": "^4.4 || ^5.4 || ^6.0", + "symfony/dependency-injection": "^4.4.18 || ^5.4 || ^6.0", + "symfony/deprecation-contracts": "^2.1 || ^3", + "symfony/doctrine-bridge": "^4.4.22 || ^5.4 || ^6.0", + "symfony/framework-bundle": "^4.4 || ^5.4 || ^6.0", + "symfony/service-contracts": "^1.1.1 || ^2.0 || ^3" + }, + "conflict": { + "doctrine/orm": "<2.11 || >=3.0", + "twig/twig": "<1.34 || >=2.0,<2.4" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0", + "doctrine/orm": "^2.11 || ^3.0", + "friendsofphp/proxy-manager-lts": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.0 || ^9.3 || ^10.0", + "psalm/plugin-phpunit": "^0.16.1", + "psalm/plugin-symfony": "^3", + "psr/log": "^1.1.4 || ^2.0 || ^3.0", + "symfony/phpunit-bridge": "^6.1", + "symfony/property-info": "^4.4 || ^5.4 || ^6.0", + "symfony/proxy-manager-bridge": "^4.4 || ^5.4 || ^6.0", + "symfony/security-bundle": "^4.4 || ^5.4 || ^6.0", + "symfony/twig-bridge": "^4.4 || ^5.4 || ^6.0", + "symfony/validator": "^4.4 || ^5.4 || ^6.0", + "symfony/web-profiler-bundle": "^4.4 || ^5.4 || ^6.0", + "symfony/yaml": "^4.4 || ^5.4 || ^6.0", + "twig/twig": "^1.34 || ^2.12 || ^3.0", + "vimeo/psalm": "^4.7" + }, + "suggest": { + "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.", + "ext-pdo": "*", + "symfony/web-profiler-bundle": "To use the data collector." + }, + "type": "symfony-bundle", + "autoload": { + "psr-4": { + "Doctrine\\Bundle\\DoctrineBundle\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Doctrine Project", + "homepage": "https://www.doctrine-project.org/" + } + ], + "description": "Symfony DoctrineBundle", + "homepage": "https://www.doctrine-project.org", + "keywords": [ + "database", + "dbal", + "orm", + "persistence" + ], + "support": { + "issues": "https://github.com/doctrine/DoctrineBundle/issues", + "source": "https://github.com/doctrine/DoctrineBundle/tree/2.7.2" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdoctrine-bundle", + "type": "tidelift" + } + ], + "time": "2022-12-07T12:07:11+00:00" + }, { "name": "doctrine/event-manager", "version": "1.2.0", @@ -1558,6 +1833,259 @@ ], "time": "2024-02-05T11:35:39+00:00" }, + { + "name": "doctrine/orm", + "version": "2.20.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/orm.git", + "reference": "19912de9270fa6abb3d25a1a37784af6b818d534" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/orm/zipball/19912de9270fa6abb3d25a1a37784af6b818d534", + "reference": "19912de9270fa6abb3d25a1a37784af6b818d534", + "shasum": "" + }, + "require": { + "composer-runtime-api": "^2", + "doctrine/cache": "^1.12.1 || ^2.1.1", + "doctrine/collections": "^1.5 || ^2.1", + "doctrine/common": "^3.0.3", + "doctrine/dbal": "^2.13.1 || ^3.2", + "doctrine/deprecations": "^0.5.3 || ^1", + "doctrine/event-manager": "^1.2 || ^2", + "doctrine/inflector": "^1.4 || ^2.0", + "doctrine/instantiator": "^1.3 || ^2", + "doctrine/lexer": "^2 || ^3", + "doctrine/persistence": "^2.4 || ^3", + "ext-ctype": "*", + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3", + "symfony/console": "^4.2 || ^5.0 || ^6.0 || ^7.0", + "symfony/polyfill-php72": "^1.23", + "symfony/polyfill-php80": "^1.16" + }, + "conflict": { + "doctrine/annotations": "<1.13 || >= 3.0" + }, + "require-dev": { + "doctrine/annotations": "^1.13 || ^2", + "doctrine/coding-standard": "^9.0.2 || ^12.0", + "phpbench/phpbench": "^0.16.10 || ^1.0", + "phpstan/extension-installer": "~1.1.0 || ^1.4", + "phpstan/phpstan": "~1.4.10 || 2.0.3", + "phpstan/phpstan-deprecation-rules": "^1 || ^2", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", + "psr/log": "^1 || ^2 || ^3", + "squizlabs/php_codesniffer": "3.7.2", + "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7.0", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2 || ^7.0", + "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "suggest": { + "ext-dom": "Provides support for XSD validation for XML mapping files", + "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0", + "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" + }, + "bin": [ + "bin/doctrine" + ], + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\ORM\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "Object-Relational-Mapper for PHP", + "homepage": "https://www.doctrine-project.org/projects/orm.html", + "keywords": [ + "database", + "orm" + ], + "support": { + "issues": "https://github.com/doctrine/orm/issues", + "source": "https://github.com/doctrine/orm/tree/2.20.2" + }, + "time": "2025-02-04T19:17:01+00:00" + }, + { + "name": "doctrine/persistence", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/persistence.git", + "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/0ea965320cec355dba75031c1b23d4c78362e3ff", + "reference": "0ea965320cec355dba75031c1b23d4c78362e3ff", + "shasum": "" + }, + "require": { + "doctrine/event-manager": "^1 || ^2", + "php": "^7.2 || ^8.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0" + }, + "conflict": { + "doctrine/common": "<2.10" + }, + "require-dev": { + "doctrine/coding-standard": "^12", + "doctrine/common": "^3.0", + "phpstan/phpstan": "1.12.7", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5.38 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Persistence\\": "src/Persistence" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.", + "homepage": "https://www.doctrine-project.org/projects/persistence.html", + "keywords": [ + "mapper", + "object", + "odm", + "orm", + "persistence" + ], + "support": { + "issues": "https://github.com/doctrine/persistence/issues", + "source": "https://github.com/doctrine/persistence/tree/3.4.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fpersistence", + "type": "tidelift" + } + ], + "time": "2024-10-30T19:48:12+00:00" + }, + { + "name": "doctrine/sql-formatter", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/sql-formatter.git", + "reference": "3447381095d32a171fe3a58323749f44dbb5ac7d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/sql-formatter/zipball/3447381095d32a171fe3a58323749f44dbb5ac7d", + "reference": "3447381095d32a171fe3a58323749f44dbb5ac7d", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0", + "phpstan/phpstan": "^1.0", + "phpunit/phpunit": "^8.5 || ^9.6", + "vimeo/psalm": "^4.11" + }, + "bin": [ + "bin/sql-formatter" + ], + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\SqlFormatter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jeremy Dorn", + "email": "jeremy@jeremydorn.com", + "homepage": "https://jeremydorn.com/" + } + ], + "description": "a PHP SQL highlighting library", + "homepage": "https://github.com/doctrine/sql-formatter/", + "keywords": [ + "highlight", + "sql" + ], + "support": { + "issues": "https://github.com/doctrine/sql-formatter/issues", + "source": "https://github.com/doctrine/sql-formatter/tree/1.3.0" + }, + "time": "2024-05-06T21:49:18+00:00" + }, { "name": "ekino/newrelic-bundle", "version": "2.4.0", @@ -6084,6 +6612,122 @@ ], "time": "2024-09-25T14:11:13+00:00" }, + { + "name": "symfony/doctrine-bridge", + "version": "v5.4.48", + "source": { + "type": "git", + "url": "https://github.com/symfony/doctrine-bridge.git", + "reference": "43ed5e31c9188e4f4d3845d16986db4a86644eef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/43ed5e31c9188e4f4d3845d16986db4a86644eef", + "reference": "43ed5e31c9188e4f4d3845d16986db4a86644eef", + "shasum": "" + }, + "require": { + "doctrine/event-manager": "~1.0", + "doctrine/persistence": "^2|^3", + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.1|^2|^3" + }, + "conflict": { + "doctrine/dbal": "<2.13.1", + "doctrine/lexer": "<1.1", + "doctrine/orm": "<2.7.4", + "symfony/cache": "<5.4", + "symfony/dependency-injection": "<4.4", + "symfony/form": "<5.4.38|>=6,<6.4.6", + "symfony/http-kernel": "<5", + "symfony/messenger": "<4.4", + "symfony/property-info": "<5", + "symfony/proxy-manager-bridge": "<4.4.19", + "symfony/security-bundle": "<5", + "symfony/security-core": "<5.3", + "symfony/validator": "<5.4.25|>=6,<6.2.12|>=6.3,<6.3.1" + }, + "require-dev": { + "doctrine/annotations": "^1.10.4|^2", + "doctrine/collections": "^1.0|^2.0", + "doctrine/data-fixtures": "^1.1|^2", + "doctrine/dbal": "^2.13.1|^3|^4", + "doctrine/orm": "^2.7.4|^3", + "psr/log": "^1|^2|^3", + "symfony/cache": "^5.4|^6.0", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/doctrine-messenger": "^5.1|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/form": "^5.4.38|^6.4.6", + "symfony/http-kernel": "^5.0|^6.0", + "symfony/messenger": "^4.4|^5.0|^6.0", + "symfony/property-access": "^4.4|^5.0|^6.0", + "symfony/property-info": "^5.0|^6.0", + "symfony/proxy-manager-bridge": "^4.4|^5.0|^6.0", + "symfony/security-core": "^5.3|^6.0", + "symfony/stopwatch": "^4.4|^5.0|^6.0", + "symfony/translation": "^4.4|^5.0|^6.0", + "symfony/uid": "^5.1|^6.0", + "symfony/validator": "^5.4.25|~6.2.12|^6.3.1", + "symfony/var-dumper": "^4.4|^5.0|^6.0" + }, + "suggest": { + "doctrine/data-fixtures": "", + "doctrine/dbal": "", + "doctrine/orm": "", + "symfony/form": "", + "symfony/property-info": "", + "symfony/validator": "" + }, + "type": "symfony-bridge", + "autoload": { + "psr-4": { + "Symfony\\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": "Provides integration for Doctrine with various Symfony components", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/doctrine-bridge/tree/v5.4.48" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-20T10:49:45+00:00" + }, { "name": "symfony/error-handler", "version": "v5.4.46", diff --git a/sources/AppBundle/VideoNotifier/HistoryEntry.php b/sources/AppBundle/VideoNotifier/HistoryEntry.php index eddf7e3a6..758a48d03 100644 --- a/sources/AppBundle/VideoNotifier/HistoryEntry.php +++ b/sources/AppBundle/VideoNotifier/HistoryEntry.php @@ -4,10 +4,34 @@ namespace AppBundle\VideoNotifier; +use Doctrine\ORM\Mapping as ORM; + +/** + * @ORM\Entity(repositoryClass=HistoryEntryRepository::class) + * @ORM\Table(name="video_notifier_history") + */ class HistoryEntry { + /** + * @ORM\Id() + * @ORM\GeneratedValue() + * @ORM\Column(type="integer") + */ + private ?int $id = null; + + /** + * @ORM\Column(type="integer", nullable=false, name="talk_id") + */ private int $talkId; + + /** + * @ORM\Column(type="string", length=255, nullable=true) + */ private ?string $statusIdBluesky = null; + + /** + * @ORM\Column(type="string", length=255, nullable=true) + */ private ?string $statusIdMastodon = null; public function __construct(int $talkId) diff --git a/sources/AppBundle/VideoNotifier/HistoryRepository.php b/sources/AppBundle/VideoNotifier/HistoryRepository.php index b2e642228..d2ad484f7 100644 --- a/sources/AppBundle/VideoNotifier/HistoryRepository.php +++ b/sources/AppBundle/VideoNotifier/HistoryRepository.php @@ -5,32 +5,23 @@ namespace AppBundle\VideoNotifier; use AppBundle\Event\Model\Talk; -use Doctrine\DBAL\Connection; +use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; +use Doctrine\Persistence\ManagerRegistry; -final class HistoryRepository +/** + * @extends ServiceEntityRepository + */ +final class HistoryRepository extends ServiceEntityRepository { - private Connection $connection; - - public function __construct(Connection $connection) + public function __construct(ManagerRegistry $registry) { - $this->connection = $connection; + parent::__construct($registry, HistoryEntry::class); } - public function insert(HistoryEntry $entry): void + public function insert(HistoryEntry $history): void { - $this->connection->createQueryBuilder() - ->insert('video_notifier_history') - ->values([ - 'talk_id' => '?', - 'status_id_bluesky' => '?', - 'status_id_mastodon' => '?', - ]) - ->setParameters([ - $entry->getTalkId(), - $entry->getStatusIdBluesky(), - $entry->getStatusIdMastodon(), - ]) - ->execute(); + $this->getEntityManager()->persist($history); + $this->getEntityManager()->flush(); } /** @@ -39,20 +30,19 @@ public function insert(HistoryEntry $entry): void */ public function getNumberOfStatusesPerTalk(array $talks): array { - $rows = ($qb = $this->connection->createQueryBuilder()) - ->from('video_notifier_history', 'h') - ->select('h.talk_id', 'COUNT(h.id) AS quantity') + $rows = ($qb = $this->createQueryBuilder('h')) + ->select('h.talkId', 'COUNT(h.id) AS quantity') ->where( - $qb->expr()->in('h.talk_id', array_map(fn (Talk $talk) => $talk->getId(), $talks)) + $qb->expr()->in('h.talkId', array_map(fn (Talk $talk) => $talk->getId(), $talks)) ) - ->groupBy('h.talk_id') - ->execute() - ->fetchAllAssociative(); + ->groupBy('h.talkId') + ->getQuery() + ->execute(); $map = []; foreach ($rows as $row) { - $map[$row['talk_id']] = $row['quantity']; + $map[$row['talkId']] = $row['quantity']; } return $map;