Skip to content

Commit d9e7e39

Browse files
authored
Merge pull request #1978 from greg0ire/3.0.x
Merge 2.17.x up into 3.0.x
2 parents 8d67dd0 + c3a2c5f commit d9e7e39

File tree

6 files changed

+147
-59
lines changed

6 files changed

+147
-59
lines changed

UPGRADE-2.17.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,20 @@ Configuration
88

99
This option is a no-op when using `doctrine/orm` 3 and has been conditionally
1010
deprecated. You should stop using it as soon as you upgrade to Doctrine ORM 3.
11+
12+
ConnectionFactory::createConnection() signature change
13+
------------------------------------------------------
14+
15+
The signature of `ConnectionFactory::createConnection()` will change with
16+
version 3.0 of the bundle.
17+
18+
As soon as you upgrade to Doctrine DBAL 4, you should use stop passing an event
19+
manager argument.
20+
21+
```diff
22+
- $connectionFactory->createConnection($params, $config, $eventManager, $mappingTypes)
23+
+ $connectionFactory->createConnection($params, $config, $mappingTypes)
24+
```
25+
26+
As a small breaking change, it is no longer fully possible to use named
27+
arguments with that method until 3.0.

config/dbal.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
->set('doctrine.dbal.connection_factory.class', ConnectionFactory::class)
3030
->set('doctrine.class', Registry::class)
3131
->set('doctrine.entity_managers', [])
32-
->set('doctrine.default_entity_manager', null);
32+
->set('doctrine.default_entity_manager', '');
3333

3434
$container->services()
3535

src/ConnectionFactory.php

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717
use Doctrine\DBAL\Platforms\AbstractPlatform;
1818
use Doctrine\DBAL\Tools\DsnParser;
1919
use Doctrine\DBAL\Types\Type;
20+
use Doctrine\Deprecations\Deprecation;
2021
use InvalidArgumentException;
2122

2223
use function array_merge;
2324
use function class_exists;
25+
use function func_num_args;
26+
use function is_array;
2427
use function is_subclass_of;
2528
use function method_exists;
2629
use function trigger_deprecation;
@@ -59,18 +62,52 @@ public function __construct(
5962
/**
6063
* Create a connection by name.
6164
*
62-
* @param mixed[] $params
63-
* @param array<string, string> $mappingTypes
65+
* @param mixed[] $params
66+
* @param EventManager|array<string, string>|null $eventManagerOrMappingTypes
67+
* @param array<string, string> $deprecatedMappingTypes
6468
* @phpstan-param Params $params
6569
*
6670
* @return Connection
71+
*
72+
* @no-named-arguments
6773
*/
68-
public function createConnection(array $params, Configuration|null $config = null, EventManager|null $eventManager = null, array $mappingTypes = [])
69-
{
70-
if (! method_exists(Connection::class, 'getEventManager') && $eventManager !== null) {
74+
public function createConnection(
75+
array $params,
76+
Configuration|null $config = null,
77+
EventManager|array|null $eventManagerOrMappingTypes = [],
78+
array $deprecatedMappingTypes = [],
79+
) {
80+
if (! method_exists(Connection::class, 'getEventManager') && $eventManagerOrMappingTypes instanceof EventManager) {
7181
throw new InvalidArgumentException('Passing an EventManager instance is not supported with DBAL > 3');
7282
}
7383

84+
if (is_array($eventManagerOrMappingTypes) && func_num_args() === 4) {
85+
throw new InvalidArgumentException('Passing mapping types both as 3rd and 4th argument makes no sense.');
86+
}
87+
88+
if ($eventManagerOrMappingTypes instanceof EventManager) {
89+
// DBAL 3
90+
$eventManager = $eventManagerOrMappingTypes;
91+
$mappingTypes = $deprecatedMappingTypes;
92+
} elseif (is_array($eventManagerOrMappingTypes)) {
93+
// Future signature
94+
$eventManager = null;
95+
$mappingTypes = $eventManagerOrMappingTypes;
96+
} else {
97+
// Legacy signature
98+
if (! method_exists(Connection::class, 'getEventManager')) {
99+
Deprecation::trigger(
100+
'doctrine/doctrine-bundle',
101+
'https://github.com/doctrine/DoctrineBundle/pull/1976',
102+
'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.',
103+
__METHOD__,
104+
);
105+
}
106+
107+
$eventManager = null;
108+
$mappingTypes = $deprecatedMappingTypes;
109+
}
110+
74111
if (! $this->initialized) {
75112
$this->initializeTypes();
76113
}

src/DependencyInjection/DoctrineExtension.php

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -299,13 +299,12 @@ protected function loadDbalConnection($name, array $connection, ContainerBuilder
299299
$def = $container
300300
->setDefinition($connectionId, new ChildDefinition('doctrine.dbal.connection'))
301301
->setPublic(true)
302-
->setArguments([
303-
$options,
304-
new Reference(sprintf('doctrine.dbal.%s_connection.configuration', $name)),
305-
// event manager is only supported on DBAL < 4
306-
method_exists(Connection::class, 'getEventManager') ? new Reference(sprintf('doctrine.dbal.%s_connection.event_manager', $name)) : null,
307-
$connection['mapping_types'],
308-
]);
302+
->setArguments(array_merge(
303+
[$options, new Reference(sprintf('doctrine.dbal.%s_connection.configuration', $name))],
304+
// event manager must only be passed for DBAL < 4
305+
method_exists(Connection::class, 'getEventManager') ? [new Reference(sprintf('doctrine.dbal.%s_connection.event_manager', $name))] : [],
306+
[$connection['mapping_types']],
307+
));
309308

310309
$container
311310
->registerAliasForArgument($connectionId, Connection::class, sprintf('%s.connection', $name))

tests/ConnectionFactoryTest.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,16 @@
77
use Doctrine\DBAL\Connection;
88
use Doctrine\DBAL\Driver;
99
use Doctrine\DBAL\Schema\DefaultSchemaManagerFactory;
10+
use Doctrine\Deprecations\PHPUnit\VerifyDeprecations;
11+
use InvalidArgumentException;
1012

1113
use function array_intersect_key;
14+
use function method_exists;
1215

1316
class ConnectionFactoryTest extends TestCase
1417
{
18+
use VerifyDeprecations;
19+
1520
private Configuration $configuration;
1621

1722
protected function setUp(): void
@@ -134,6 +139,34 @@ public function testDbnameSuffixForReplicas(): void
134139
$this->assertSame('primary_test', $parsedParams['primary']['dbname']);
135140
$this->assertSame('replica_test', $parsedParams['replica']['replica1']['dbname']);
136141
}
142+
143+
public function testItThrowsWhenPassingMappingTypesTwice(): void
144+
{
145+
$this->expectException(InvalidArgumentException::class);
146+
147+
(new ConnectionFactory())->createConnection(['driver' => 'pdo_sqlite'], null, [], []);
148+
}
149+
150+
/** @group legacy */
151+
public function testPassingMappingTypesAsFourthArgumentIsDeprecatedWithDbal4(): void
152+
{
153+
if (method_exists(Connection::class, 'getEventManager')) {
154+
$this->markTestSkipped('DBAL 3 does not trigger the deprecation.');
155+
}
156+
157+
$this->expectDeprecationWithIdentifier('https://github.com/doctrine/DoctrineBundle/pull/1976');
158+
(new ConnectionFactory())->createConnection(['driver' => 'pdo_sqlite'], null, null, []);
159+
}
160+
161+
public function testPassingMappingTypesAsFourthArgumentIsFineWithDbal3(): void
162+
{
163+
if (! method_exists(Connection::class, 'getEventManager')) {
164+
$this->markTestSkipped('DBAL 4 triggers the deprecation.');
165+
}
166+
167+
$this->expectNoDeprecationWithIdentifier('https://github.com/doctrine/DoctrineBundle/pull/1976');
168+
(new ConnectionFactory())->createConnection(['driver' => 'pdo_sqlite'], null, null, []);
169+
}
137170
}
138171

139172
class FakeConnection extends Connection

tests/DependencyInjection/AbstractDoctrineExtensionTestCase.php

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -320,24 +320,17 @@ public function testLoadSimpleSingleConnection(): void
320320

321321
$definition = $container->getDefinition('doctrine.dbal.default_connection');
322322

323-
$this->assertDICConstructorArguments($definition, [
324-
[
325-
'dbname' => 'db',
326-
'host' => 'localhost',
327-
'port' => null,
328-
'user' => 'root',
329-
'password' => null,
330-
'driver' => 'pdo_mysql',
331-
'driverOptions' => [],
332-
'defaultTableOptions' => [],
333-
'idle_connection_ttl' => 600,
334-
],
335-
new Reference('doctrine.dbal.default_connection.configuration'),
336-
method_exists(Connection::class, 'getEventManager')
337-
? new Reference('doctrine.dbal.default_connection.event_manager')
338-
: null,
339-
[],
340-
]);
323+
$this->assertDICConstructorArguments($definition, $this->getFactoryArguments([
324+
'dbname' => 'db',
325+
'host' => 'localhost',
326+
'port' => null,
327+
'user' => 'root',
328+
'password' => null,
329+
'driver' => 'pdo_mysql',
330+
'driverOptions' => [],
331+
'defaultTableOptions' => [],
332+
'idle_connection_ttl' => 600,
333+
]));
341334

342335
$definition = $container->getDefinition('doctrine.orm.default_entity_manager');
343336
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
@@ -361,8 +354,9 @@ public function testLoadSimpleSingleConnectionWithoutDbName(): void
361354

362355
$container = $this->loadContainer('orm_service_simple_single_entity_manager_without_dbname');
363356

364-
$this->assertDICConstructorArguments($container->getDefinition('doctrine.dbal.default_connection'), [
365-
[
357+
$this->assertDICConstructorArguments(
358+
$container->getDefinition('doctrine.dbal.default_connection'),
359+
$this->getFactoryArguments([
366360
'host' => 'localhost',
367361
'port' => null,
368362
'user' => 'root',
@@ -371,13 +365,8 @@ public function testLoadSimpleSingleConnectionWithoutDbName(): void
371365
'driverOptions' => [],
372366
'defaultTableOptions' => [],
373367
'idle_connection_ttl' => 600,
374-
],
375-
new Reference('doctrine.dbal.default_connection.configuration'),
376-
method_exists(Connection::class, 'getEventManager')
377-
? new Reference('doctrine.dbal.default_connection.event_manager')
378-
: null,
379-
[],
380-
]);
368+
]),
369+
);
381370

382371
$definition = $container->getDefinition('doctrine.orm.default_entity_manager');
383372
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
@@ -399,25 +388,18 @@ public function testLoadSingleConnection(): void
399388

400389
$definition = $container->getDefinition('doctrine.dbal.default_connection');
401390

402-
$this->assertDICConstructorArguments($definition, [
403-
[
404-
'host' => 'localhost',
405-
'driver' => 'pdo_sqlite',
406-
'driverOptions' => [],
407-
'user' => 'sqlite_user',
408-
'port' => null,
409-
'password' => 'sqlite_s3cr3t',
410-
'dbname' => 'sqlite_db',
411-
'memory' => true,
412-
'defaultTableOptions' => [],
413-
'idle_connection_ttl' => 600,
414-
],
415-
new Reference('doctrine.dbal.default_connection.configuration'),
416-
method_exists(Connection::class, 'getEventManager')
417-
? new Reference('doctrine.dbal.default_connection.event_manager')
418-
: null,
419-
[],
420-
]);
391+
$this->assertDICConstructorArguments($definition, $this->getFactoryArguments([
392+
'host' => 'localhost',
393+
'driver' => 'pdo_sqlite',
394+
'driverOptions' => [],
395+
'user' => 'sqlite_user',
396+
'port' => null,
397+
'password' => 'sqlite_s3cr3t',
398+
'dbname' => 'sqlite_db',
399+
'memory' => true,
400+
'defaultTableOptions' => [],
401+
'idle_connection_ttl' => 600,
402+
]));
421403

422404
$definition = $container->getDefinition('doctrine.orm.default_entity_manager');
423405
$this->assertEquals('%doctrine.orm.entity_manager.class%', $definition->getClass());
@@ -1594,6 +1576,26 @@ private function compileContainer(ContainerBuilder $container): void
15941576
$passConfig->setRemovingPasses([]);
15951577
$container->compile();
15961578
}
1579+
1580+
/**
1581+
* @param array<string, mixed> $params
1582+
*
1583+
* @return list<mixed> The expected arguments to the connection factory
1584+
*/
1585+
private function getFactoryArguments(array $params): array
1586+
{
1587+
$args = [
1588+
$params,
1589+
new Reference('doctrine.dbal.default_connection.configuration'),
1590+
];
1591+
if (method_exists(Connection::class, 'getEventManager')) {
1592+
$args[] = new Reference('doctrine.dbal.default_connection.event_manager');
1593+
}
1594+
1595+
$args[] = [];
1596+
1597+
return $args;
1598+
}
15971599
}
15981600

15991601
class DummySchemaAssetsFilter

0 commit comments

Comments
 (0)