From ebcf3780082c3a12de103795ea5757081f74aabb Mon Sep 17 00:00:00 2001 From: Gregoire PARIS Date: Thu, 9 Oct 2025 17:24:51 +0200 Subject: [PATCH 1/5] Deprecate methods related to annotations and yaml These methods are removed in the next major version. --- UPGRADE-2.18.md | 15 ++++++++ .../Compiler/DoctrineOrmMappingsPass.php | 18 ++++++++++ .../Compiler/DoctrineOrmMappingsPassTest.php | 34 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 UPGRADE-2.18.md create mode 100644 tests/DependencyInjection/Compiler/DoctrineOrmMappingsPassTest.php diff --git a/UPGRADE-2.18.md b/UPGRADE-2.18.md new file mode 100644 index 000000000..8d6ada070 --- /dev/null +++ b/UPGRADE-2.18.md @@ -0,0 +1,15 @@ +UPGRADE FROM 2.17 to 2.18 +========================= + +DoctrineOrmMappingsPass +----------------------- + +### The `DoctrineOrmMappingsPass::createYamlMappingDriver()` method is deprecated + +This method is deprecated with no replacement planned and will be removed in +DoctrineBundle 3.0. + +### The `DoctrineOrmMappingsPass::createAnnotationMappingDriver()` method is deprecated + +This method is deprecated with no replacement planned and will be removed in +DoctrineBundle 3.0. diff --git a/src/DependencyInjection/Compiler/DoctrineOrmMappingsPass.php b/src/DependencyInjection/Compiler/DoctrineOrmMappingsPass.php index ef7b798e6..4ec6bd378 100644 --- a/src/DependencyInjection/Compiler/DoctrineOrmMappingsPass.php +++ b/src/DependencyInjection/Compiler/DoctrineOrmMappingsPass.php @@ -4,6 +4,7 @@ namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler; +use Doctrine\Deprecations\Deprecation; use Doctrine\ORM\Mapping\Driver\AnnotationDriver; use Doctrine\ORM\Mapping\Driver\AttributeDriver; use Doctrine\ORM\Mapping\Driver\XmlDriver; @@ -76,6 +77,8 @@ public static function createXmlMappingDriver(array $namespaces, array $managerP } /** + * @deprecated no replacement planned + * * @param string[] $namespaces Hashmap of directory path to namespace * @param string[] $managerParameters List of parameters that could which object manager name * your bundle uses. This compiler pass will automatically @@ -90,6 +93,12 @@ public static function createXmlMappingDriver(array $namespaces, array $managerP */ public static function createYamlMappingDriver(array $namespaces, array $managerParameters = [], $enabledParameter = false, array $aliasMap = []) { + Deprecation::trigger( + 'doctrine/doctrine-bundle', + 'https://github.com/doctrine/DoctrineBundle/pull/2088', + 'The "%s()" method is deprecated and will be removed in DoctrineBundle 3.0.', + __METHOD__, + ); $locator = new Definition(SymfonyFileLocator::class, [$namespaces, '.orm.yml']); /* @phpstan-ignore class.notFound */ $driver = new Definition(YamlDriver::class, [$locator]); @@ -119,6 +128,8 @@ public static function createPhpMappingDriver(array $namespaces, array $managerP } /** + * @deprecated no replacement planned + * * @param string[] $namespaces List of namespaces that are handled with annotation mapping * @param string[] $directories List of directories to look for annotated classes * @param string[] $managerParameters List of parameters that could which object manager name @@ -135,6 +146,13 @@ public static function createPhpMappingDriver(array $namespaces, array $managerP */ public static function createAnnotationMappingDriver(array $namespaces, array $directories, array $managerParameters = [], $enabledParameter = false, array $aliasMap = [], bool $reportFieldsWhereDeclared = false) { + Deprecation::trigger( + 'doctrine/doctrine-bundle', + 'https://github.com/doctrine/DoctrineBundle/pull/2088', + 'The "%s()" method is deprecated and will be removed in DoctrineBundle 3.0.', + __METHOD__, + ); + $reader = new Reference('annotation_reader'); /* @phpstan-ignore class.notFound */ $driver = new Definition(AnnotationDriver::class, [$reader, $directories, $reportFieldsWhereDeclared]); diff --git a/tests/DependencyInjection/Compiler/DoctrineOrmMappingsPassTest.php b/tests/DependencyInjection/Compiler/DoctrineOrmMappingsPassTest.php new file mode 100644 index 000000000..1736cef2a --- /dev/null +++ b/tests/DependencyInjection/Compiler/DoctrineOrmMappingsPassTest.php @@ -0,0 +1,34 @@ +expectDeprecationWithIdentifier('https://github.com/doctrine/DoctrineBundle/pull/2088'); + + DoctrineOrmMappingsPass::createYamlMappingDriver(['/path/to/namespace' => 'App\\Entity']); + } + + #[IgnoreDeprecations] + public function testCreateAnnotationMappingDriverIsDeprecated(): void + { + $this->expectDeprecationWithIdentifier('https://github.com/doctrine/DoctrineBundle/pull/2088'); + + DoctrineOrmMappingsPass::createAnnotationMappingDriver( + ['App\\Entity'], + ['/path/to/entities'], + ); + } +} From 087c7eb3948a65da43fe503be61063759a2a685d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Thu, 9 Oct 2025 21:03:31 +0200 Subject: [PATCH 2/5] Update branch metadata 2.18.x has been created, so: - 2.16.x is no longer maintained; - 2.17.x becomes the current branch; - 2.18.x is the next minor branch. --- .doctrine-project.json | 10 ++++++++-- .symfony.bundle.yaml | 7 ++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.doctrine-project.json b/.doctrine-project.json index ca091627a..73ba9db54 100644 --- a/.doctrine-project.json +++ b/.doctrine-project.json @@ -10,16 +10,22 @@ "slug": "latest", "upcoming": true }, + { + "name": "2.18", + "branchName": "2.18.x", + "slug": "2.18", + "upcoming": true + }, { "name": "2.17", "branchName": "2.17.x", "slug": "2.17", - "upcoming": true + "current": true }, { "name": "2.16", "slug": "2.16", - "current": true + "maintained": false }, { "name": "2.15", diff --git a/.symfony.bundle.yaml b/.symfony.bundle.yaml index 55ec8acbd..f06cf8cb6 100644 --- a/.symfony.bundle.yaml +++ b/.symfony.bundle.yaml @@ -12,9 +12,10 @@ branches: - "2.15.x" - "2.16.x" - "2.17.x" + - "2.18.x" maintained_branches: - - "2.16.x" - "2.17.x" + - "2.18.x" doc_dir: "docs/en/" -current_branch: "2.16.x" -dev_branch: "2.17.x" +current_branch: "2.17.x" +dev_branch: "2.18.x" From a69e11e8333a3098a726790e166c8a515b224ffa Mon Sep 17 00:00:00 2001 From: Gregoire PARIS Date: Fri, 10 Oct 2025 17:44:56 +0200 Subject: [PATCH 3/5] Restore some more lines from v6 of the bridge I am not sure how I messed this up, but I managed to omit these lines when copy/pasting from the diff I put at https://github.com/doctrine/DoctrineBundle/issues/2082#issuecomment-3384590648 --- src/DependencyInjection/DoctrineExtension.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/DependencyInjection/DoctrineExtension.php b/src/DependencyInjection/DoctrineExtension.php index 0ef52ddd5..35bfa9a27 100644 --- a/src/DependencyInjection/DoctrineExtension.php +++ b/src/DependencyInjection/DoctrineExtension.php @@ -302,13 +302,22 @@ protected function registerMappingDrivers(array $objectManager, ContainerBuilder if ($container->hasDefinition($mappingService)) { $mappingDriverDef = $container->getDefinition($mappingService); $args = $mappingDriverDef->getArguments(); - if ($driverType === 'attribute') { + if ($driverType === 'annotation') { $args[1] = array_merge(array_values($driverPaths), $args[1]); } else { $args[0] = array_merge(array_values($driverPaths), $args[0]); } $mappingDriverDef->setArguments($args); + } elseif ($driverType === 'attribute') { + $mappingDriverDef = new Definition($this->getMetadataDriverClass($driverType), [ + array_values($driverPaths), + ]); + } elseif ($driverType === 'annotation') { + $mappingDriverDef = new Definition($this->getMetadataDriverClass($driverType), [ + new Reference($this->getObjectManagerElementName('metadata.annotation_reader')), + array_values($driverPaths), + ]); } else { $mappingDriverDef = new Definition($this->getMetadataDriverClass($driverType), [ array_values($driverPaths), From 262a4b6fdeb9273f80d5e1cfeb6db0a0fc066aca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Fri, 10 Oct 2025 18:01:33 +0200 Subject: [PATCH 4/5] Revert "Deprecate passing an event manager to CF::createConnection()" This reverts commit 7f0164e89174ceff929e1985972e31dc4f7d10a6, that contains a breaking change. Fixes #2091 --- UPGRADE-2.17.md | 17 ---- src/ConnectionFactory.php | 46 +-------- src/DependencyInjection/DoctrineExtension.php | 13 +-- tests/ConnectionFactoryTest.php | 30 ------ .../AbstractDoctrineExtensionTestCase.php | 94 +++++++++---------- 5 files changed, 58 insertions(+), 142 deletions(-) diff --git a/UPGRADE-2.17.md b/UPGRADE-2.17.md index 4b76ff35e..52578346a 100644 --- a/UPGRADE-2.17.md +++ b/UPGRADE-2.17.md @@ -26,20 +26,3 @@ deprecated. You should stop using it as soon as you upgrade to Doctrine DBAL 4. This option is a no-op when using `doctrine/dbal` 4 and has been conditionally deprecated. You should stop using it as soon as you upgrade to Doctrine DBAL 4. - -ConnectionFactory::createConnection() signature change ------------------------------------------------------- - -The signature of `ConnectionFactory::createConnection()` will change with -version 3.0 of the bundle. - -As soon as you upgrade to Doctrine DBAL 4, you should use stop passing an event -manager argument. - -```diff -- $connectionFactory->createConnection($params, $config, $eventManager, $mappingTypes) -+ $connectionFactory->createConnection($params, $config, $mappingTypes) -``` - -As a small breaking change, it is no longer fully possible to use named -arguments with that method until 3.0. diff --git a/src/ConnectionFactory.php b/src/ConnectionFactory.php index e45ec81d8..1245e3849 100644 --- a/src/ConnectionFactory.php +++ b/src/ConnectionFactory.php @@ -24,8 +24,6 @@ use function array_merge; use function class_exists; -use function func_num_args; -use function is_array; use function is_subclass_of; use function method_exists; @@ -63,52 +61,18 @@ public function __construct( /** * Create a connection by name. * - * @param mixed[] $params - * @param EventManager|array|null $eventManagerOrMappingTypes - * @param array $deprecatedMappingTypes + * @param mixed[] $params + * @param array $mappingTypes * @phpstan-param Params $params * * @return Connection - * - * @no-named-arguments */ - public function createConnection( - array $params, - Configuration|null $config = null, - EventManager|array|null $eventManagerOrMappingTypes = [], - array $deprecatedMappingTypes = [], - ) { - if (! method_exists(Connection::class, 'getEventManager') && $eventManagerOrMappingTypes instanceof EventManager) { + public function createConnection(array $params, Configuration|null $config = null, EventManager|null $eventManager = null, array $mappingTypes = []) + { + if (! method_exists(Connection::class, 'getEventManager') && $eventManager !== null) { throw new InvalidArgumentException('Passing an EventManager instance is not supported with DBAL > 3'); } - if (is_array($eventManagerOrMappingTypes) && func_num_args() === 4) { - throw new InvalidArgumentException('Passing mapping types both as 3rd and 4th argument makes no sense.'); - } - - if ($eventManagerOrMappingTypes instanceof EventManager) { - // DBAL 3 - $eventManager = $eventManagerOrMappingTypes; - $mappingTypes = $deprecatedMappingTypes; - } elseif (is_array($eventManagerOrMappingTypes)) { - // Future signature - $eventManager = null; - $mappingTypes = $eventManagerOrMappingTypes; - } else { - // Legacy signature - if (! method_exists(Connection::class, 'getEventManager')) { - Deprecation::trigger( - 'doctrine/doctrine-bundle', - 'https://github.com/doctrine/DoctrineBundle/pull/1976', - 'Passing mapping types as 4th argument to %s is deprecated when using DBAL 4 and will not be supported in version 3.0 of the bundle. Pass them as 3rd argument instead.', - __METHOD__, - ); - } - - $eventManager = null; - $mappingTypes = $deprecatedMappingTypes; - } - if (! $this->initialized) { $this->initializeTypes(); } diff --git a/src/DependencyInjection/DoctrineExtension.php b/src/DependencyInjection/DoctrineExtension.php index 0ef52ddd5..c83622f40 100644 --- a/src/DependencyInjection/DoctrineExtension.php +++ b/src/DependencyInjection/DoctrineExtension.php @@ -695,12 +695,13 @@ protected function loadDbalConnection($name, array $connection, ContainerBuilder $def = $container ->setDefinition($connectionId, new ChildDefinition('doctrine.dbal.connection')) ->setPublic(true) - ->setArguments(array_merge( - [$options, new Reference(sprintf('doctrine.dbal.%s_connection.configuration', $name))], - // event manager must only be passed for DBAL < 4 - method_exists(Connection::class, 'getEventManager') ? [new Reference(sprintf('doctrine.dbal.%s_connection.event_manager', $name))] : [], - [$connection['mapping_types']], - )); + ->setArguments([ + $options, + new Reference(sprintf('doctrine.dbal.%s_connection.configuration', $name)), + // event manager is only supported on DBAL < 4 + method_exists(Connection::class, 'getEventManager') ? new Reference(sprintf('doctrine.dbal.%s_connection.event_manager', $name)) : null, + $connection['mapping_types'], + ]); $container ->registerAliasForArgument($connectionId, Connection::class, sprintf('%s.connection', $name)) diff --git a/tests/ConnectionFactoryTest.php b/tests/ConnectionFactoryTest.php index 82b6e18c3..2ae4a051b 100644 --- a/tests/ConnectionFactoryTest.php +++ b/tests/ConnectionFactoryTest.php @@ -10,11 +10,9 @@ use Doctrine\DBAL\Driver; use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory; use Doctrine\Deprecations\PHPUnit\VerifyDeprecations; -use InvalidArgumentException; use PHPUnit\Framework\Attributes\IgnoreDeprecations; use function array_intersect_key; -use function method_exists; class ConnectionFactoryTest extends TestCase { @@ -167,34 +165,6 @@ public function testDbnameSuffixForReplicas(): void $this->assertSame('primary_test', $parsedParams['primary']['dbname']); $this->assertSame('replica_test', $parsedParams['replica']['replica1']['dbname']); } - - public function testItThrowsWhenPassingMappingTypesTwice(): void - { - $this->expectException(InvalidArgumentException::class); - - (new ConnectionFactory())->createConnection(['driver' => 'pdo_sqlite'], null, [], []); - } - - #[IgnoreDeprecations] - public function testPassingMappingTypesAsFourthArgumentIsDeprecatedWithDbal4(): void - { - if (method_exists(Connection::class, 'getEventManager')) { - $this->markTestSkipped('DBAL 3 does not trigger the deprecation.'); - } - - $this->expectDeprecationWithIdentifier('https://github.com/doctrine/DoctrineBundle/pull/1976'); - (new ConnectionFactory())->createConnection(['driver' => 'pdo_sqlite'], null, null, []); - } - - public function testPassingMappingTypesAsFourthArgumentIsFineWithDbal3(): void - { - if (! method_exists(Connection::class, 'getEventManager')) { - $this->markTestSkipped('DBAL 4 triggers the deprecation.'); - } - - $this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/DoctrineBundle/pull/1976'); - (new ConnectionFactory())->createConnection(['driver' => 'pdo_sqlite'], null, null, []); - } } class FakeConnection extends Connection diff --git a/tests/DependencyInjection/AbstractDoctrineExtensionTestCase.php b/tests/DependencyInjection/AbstractDoctrineExtensionTestCase.php index c93351d12..a40b7616e 100644 --- a/tests/DependencyInjection/AbstractDoctrineExtensionTestCase.php +++ b/tests/DependencyInjection/AbstractDoctrineExtensionTestCase.php @@ -349,17 +349,24 @@ public function testLoadSimpleSingleConnection(): void $definition = $container->getDefinition('doctrine.dbal.default_connection'); - $this->assertDICConstructorArguments($definition, $this->getFactoryArguments([ - 'dbname' => 'db', - 'host' => 'localhost', - 'port' => null, - 'user' => 'root', - 'password' => null, - 'driver' => 'pdo_mysql', - 'driverOptions' => [], - 'defaultTableOptions' => [], - 'idle_connection_ttl' => 600, - ])); + $this->assertDICConstructorArguments($definition, [ + [ + 'dbname' => 'db', + 'host' => 'localhost', + 'port' => null, + 'user' => 'root', + 'password' => null, + 'driver' => 'pdo_mysql', + 'driverOptions' => [], + 'defaultTableOptions' => [], + 'idle_connection_ttl' => 600, + ], + new Reference('doctrine.dbal.default_connection.configuration'), + method_exists(Connection::class, 'getEventManager') + ? new Reference('doctrine.dbal.default_connection.event_manager') + : null, + [], + ]); $definition = $container->getDefinition('doctrine.orm.default_entity_manager'); $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass()); @@ -383,9 +390,8 @@ public function testLoadSimpleSingleConnectionWithoutDbName(): void $container = $this->loadContainer('orm_service_simple_single_entity_manager_without_dbname'); - $this->assertDICConstructorArguments( - $container->getDefinition('doctrine.dbal.default_connection'), - $this->getFactoryArguments([ + $this->assertDICConstructorArguments($container->getDefinition('doctrine.dbal.default_connection'), [ + [ 'host' => 'localhost', 'port' => null, 'user' => 'root', @@ -394,8 +400,13 @@ public function testLoadSimpleSingleConnectionWithoutDbName(): void 'driverOptions' => [], 'defaultTableOptions' => [], 'idle_connection_ttl' => 600, - ]), - ); + ], + new Reference('doctrine.dbal.default_connection.configuration'), + method_exists(Connection::class, 'getEventManager') + ? new Reference('doctrine.dbal.default_connection.event_manager') + : null, + [], + ]); $definition = $container->getDefinition('doctrine.orm.default_entity_manager'); $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass()); @@ -417,18 +428,25 @@ public function testLoadSingleConnection(): void $definition = $container->getDefinition('doctrine.dbal.default_connection'); - $this->assertDICConstructorArguments($definition, $this->getFactoryArguments([ - 'host' => 'localhost', - 'driver' => 'pdo_sqlite', - 'driverOptions' => [], - 'user' => 'sqlite_user', - 'port' => null, - 'password' => 'sqlite_s3cr3t', - 'dbname' => 'sqlite_db', - 'memory' => true, - 'defaultTableOptions' => [], - 'idle_connection_ttl' => 600, - ])); + $this->assertDICConstructorArguments($definition, [ + [ + 'host' => 'localhost', + 'driver' => 'pdo_sqlite', + 'driverOptions' => [], + 'user' => 'sqlite_user', + 'port' => null, + 'password' => 'sqlite_s3cr3t', + 'dbname' => 'sqlite_db', + 'memory' => true, + 'defaultTableOptions' => [], + 'idle_connection_ttl' => 600, + ], + new Reference('doctrine.dbal.default_connection.configuration'), + method_exists(Connection::class, 'getEventManager') + ? new Reference('doctrine.dbal.default_connection.event_manager') + : null, + [], + ]); $definition = $container->getDefinition('doctrine.orm.default_entity_manager'); $this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass()); @@ -1752,26 +1770,6 @@ private function compileContainer(ContainerBuilder $container): void $passConfig->addPass(new CacheCompatibilityPass()); $container->compile(); } - - /** - * @param array $params - * - * @return list The expected arguments to the connection factory - */ - private function getFactoryArguments(array $params): array - { - $args = [ - $params, - new Reference('doctrine.dbal.default_connection.configuration'), - ]; - if (method_exists(Connection::class, 'getEventManager')) { - $args[] = new Reference('doctrine.dbal.default_connection.event_manager'); - } - - $args[] = []; - - return $args; - } } class DummySchemaAssetsFilter From f0b4bb38c7ff4696591a057823d9132f52de0e10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Fri, 10 Oct 2025 19:01:52 +0200 Subject: [PATCH 5/5] Use the development file This is similar to https://github.com/doctrine/.github/pull/67 --- .github/workflows/continuous-integration.yml | 2 +- .github/workflows/test-dev-stability.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 092c2dd30..63a89fe5b 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -89,7 +89,7 @@ jobs: with: php-version: "${{ matrix.php-version }}" coverage: "pcov" - ini-values: "zend.assertions=1" + ini-file: "development" extensions: "pdo_sqlite" tools: "flex" diff --git a/.github/workflows/test-dev-stability.yml b/.github/workflows/test-dev-stability.yml index 701cfab60..82b919db6 100644 --- a/.github/workflows/test-dev-stability.yml +++ b/.github/workflows/test-dev-stability.yml @@ -35,7 +35,7 @@ jobs: uses: "shivammathur/setup-php@v2" with: php-version: "${{ matrix.php-version }}" - ini-values: "zend.assertions=1" + ini-file: "development" extensions: "pdo_sqlite" tools: "flex"