Skip to content

Commit 74a3c95

Browse files
authored
Merge pull request #298 from goetas/doctrine-em-detect
Detect the entity manager in a compiler pass
2 parents e173764 + 50919b6 commit 74a3c95

File tree

5 files changed

+88
-85
lines changed

5 files changed

+88
-85
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Bundle\MigrationsBundle\DependencyInjection\CompilerPass;
6+
7+
use Doctrine\Migrations\DependencyFactory;
8+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
9+
use Symfony\Component\DependencyInjection\ContainerBuilder;
10+
use Symfony\Component\DependencyInjection\Reference;
11+
use function sprintf;
12+
13+
class ConfigureDependencyFactoryPass implements CompilerPassInterface
14+
{
15+
public function process(ContainerBuilder $container) : void
16+
{
17+
$preferredEm = $container->getParameter('doctrine.migrations.preferred_em');
18+
$diDefinition = $container->getDefinition('doctrine.migrations.dependency_factory');
19+
20+
$emID = sprintf('doctrine.orm.%s_entity_manager', $preferredEm ?: 'default');
21+
22+
if ($container->has($emID)) {
23+
$container->getDefinition('doctrine.migrations.em_loader')
24+
->setArgument(0, new Reference($emID));
25+
26+
$diDefinition->setFactory([DependencyFactory::class, 'fromEntityManager']);
27+
$diDefinition->setArgument(1, new Reference('doctrine.migrations.em_loader'));
28+
} else {
29+
$preferredConnection = $container->getParameter('doctrine.migrations.preferred_connection');
30+
$connectionId = sprintf('doctrine.dbal.%s_connection', $preferredConnection ?: 'default');
31+
$container->getDefinition('doctrine.migrations.connection_loader')
32+
->setArgument(0, new Reference($connectionId));
33+
34+
$diDefinition->setFactory([DependencyFactory::class, 'fromConnection']);
35+
$diDefinition->setArgument(1, new Reference('doctrine.migrations.connection_loader'));
36+
}
37+
}
38+
}

DependencyInjection/DoctrineMigrationsExtension.php

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace Doctrine\Bundle\MigrationsBundle\DependencyInjection;
66

7-
use Doctrine\Migrations\DependencyFactory;
87
use Doctrine\Migrations\Metadata\Storage\MetadataStorage;
98
use Doctrine\Migrations\Metadata\Storage\TableMetadataStorageConfiguration;
109
use InvalidArgumentException;
@@ -14,7 +13,6 @@
1413
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
1514
use Symfony\Component\DependencyInjection\Reference;
1615
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
17-
use function sprintf;
1816

1917
/**
2018
* DoctrineMigrationsExtension.
@@ -98,22 +96,8 @@ public function load(array $configs, ContainerBuilder $container) : void
9896
);
9997
}
10098

101-
$emID = sprintf('doctrine.orm.%s_entity_manager', $config['em'] ?: 'default');
102-
103-
if ($container->has($emID)) {
104-
$container->getDefinition('doctrine.migrations.em_loader')
105-
->setArgument(0, new Reference($emID));
106-
107-
$diDefinition->setFactory([DependencyFactory::class, 'fromEntityManager']);
108-
$diDefinition->setArgument(1, new Reference('doctrine.migrations.em_loader'));
109-
} else {
110-
$connectionId = sprintf('doctrine.dbal.%s_connection', $config['connection'] ?? 'default');
111-
$container->getDefinition('doctrine.migrations.connection_loader')
112-
->setArgument(0, new Reference($connectionId));
113-
114-
$diDefinition->setFactory([DependencyFactory::class, 'fromConnection']);
115-
$diDefinition->setArgument(1, new Reference('doctrine.migrations.connection_loader'));
116-
}
99+
$container->setParameter('doctrine.migrations.preferred_em', $config['em']);
100+
$container->setParameter('doctrine.migrations.preferred_connection', $config['connection']);
117101
}
118102

119103
/**

DoctrineMigrationsBundle.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
namespace Doctrine\Bundle\MigrationsBundle;
55

6+
use Doctrine\Bundle\MigrationsBundle\DependencyInjection\CompilerPass\ConfigureDependencyFactoryPass;
7+
use Symfony\Component\DependencyInjection\ContainerBuilder;
68
use Symfony\Component\HttpKernel\Bundle\Bundle;
79

810
/**
@@ -13,4 +15,8 @@
1315
*/
1416
class DoctrineMigrationsBundle extends Bundle
1517
{
18+
public function build(ContainerBuilder $builder)
19+
{
20+
$builder->addCompilerPass(new ConfigureDependencyFactoryPass());
21+
}
1622
}

Tests/DependencyInjection/DoctrineCommandsTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Doctrine\Bundle\MigrationsBundle\Tests\DependencyInjection;
66

7+
use Doctrine\Bundle\MigrationsBundle\DependencyInjection\CompilerPass\ConfigureDependencyFactoryPass;
78
use Doctrine\Bundle\MigrationsBundle\DependencyInjection\DoctrineMigrationsExtension;
89
use Doctrine\Migrations\Tools\Console\Command\DiffCommand;
910
use Doctrine\Migrations\Tools\Console\Command\DumpSchemaCommand;
@@ -104,6 +105,7 @@ private function getApplication() : Application
104105
],
105106
], $container);
106107

108+
$container->addCompilerPass(new ConfigureDependencyFactoryPass());
107109
$container->compile();
108110

109111
return $application;

Tests/DependencyInjection/DoctrineMigrationsExtensionTest.php

Lines changed: 40 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Doctrine\Bundle\MigrationsBundle\Tests\DependencyInjection;
66

77
use Doctrine\Bundle\MigrationsBundle\DependencyInjection\DoctrineMigrationsExtension;
8+
use Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle;
89
use Doctrine\Bundle\MigrationsBundle\Tests\Fixtures\CustomEntityManager;
910
use Doctrine\DBAL\Connection;
1011
use Doctrine\Migrations\Configuration\Configuration;
@@ -25,19 +26,19 @@
2526
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
2627
use function assert;
2728
use function method_exists;
28-
use function print_r;
2929
use function sys_get_temp_dir;
3030

3131
class DoctrineMigrationsExtensionTest extends TestCase
3232
{
3333
public function testXmlConfigs() : void
3434
{
35-
$container = $this->getContainer();
35+
$container = $this->getContainerBuilder();
3636

3737
$conn = $this->createMock(Connection::class);
3838
$container->set('doctrine.dbal.default_connection', $conn);
3939

4040
$container->registerExtension(new DoctrineMigrationsExtension());
41+
4142
$container->setAlias('doctrine.migrations.configuration.test', new Alias('doctrine.migrations.configuration', true));
4243

4344
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Fixtures'));
@@ -51,9 +52,6 @@ public function testXmlConfigs() : void
5152

5253
public function testFullConfig() : void
5354
{
54-
$container = $this->getContainer();
55-
$extension = new DoctrineMigrationsExtension();
56-
5755
$config = [
5856
'name' => 'Doctrine Sandbox Migrations',
5957
'storage' => [
@@ -78,13 +76,11 @@ public function testFullConfig() : void
7876
'all_or_nothing' => true,
7977
'check_database_platform' => true,
8078
];
79+
$container = $this->getContainer($config);
8180

8281
$conn = $this->createMock(Connection::class);
8382
$container->set('doctrine.dbal.default_connection', $conn);
8483

85-
$extension->load(['doctrine_migrations' => $config], $container);
86-
87-
$container->getDefinition('doctrine.migrations.configuration')->setPublic(true);
8884
$container->compile();
8985

9086
$config = $container->get('doctrine.migrations.configuration');
@@ -97,20 +93,13 @@ public function testNoConfig() : void
9793
$this->expectException(InvalidConfigurationException::class);
9894
$this->expectExceptionMessage('The child node "migrations_paths" at path "doctrine_migrations" must be configured.');
9995

100-
$container = $this->getContainer();
101-
$extension = new DoctrineMigrationsExtension();
96+
$container = $this->getContainer([]);
10297

10398
$conn = $this->createMock(Connection::class);
10499
$container->set('doctrine.dbal.default_connection', $conn);
105-
106-
$extension->load([], $container);
107-
108-
$container->getDefinition('doctrine.migrations.configuration')->setPublic(true);
109100
$container->compile();
110101

111-
$config = $container->get('doctrine.migrations.configuration');
112-
113-
print_r($config);
102+
$container->get('doctrine.migrations.configuration');
114103
}
115104

116105

@@ -141,17 +130,11 @@ private function assertConfigs(?object $config) : void
141130

142131
public function testCustomSorter() : void
143132
{
144-
$container = $this->getContainer();
145-
$extension = new DoctrineMigrationsExtension();
146-
147-
$config = [
133+
$config = [
148134
'migrations_paths' => ['DoctrineMigrationsTest' => 'a'],
149135
'services' => [Comparator::class => 'my_sorter'],
150136
];
151-
152-
$extension->load(['doctrine_migrations' => $config], $container);
153-
154-
$container->getDefinition('doctrine.migrations.dependency_factory')->setPublic(true);
137+
$container = $this->getContainer($config);
155138

156139
$conn = $this->createMock(Connection::class);
157140
$container->set('doctrine.dbal.default_connection', $conn);
@@ -172,17 +155,11 @@ public function compare(Version $a, Version $b) : int
172155

173156
public function testCustomConnection() : void
174157
{
175-
$container = $this->getContainer();
176-
$extension = new DoctrineMigrationsExtension();
177-
178-
$config = [
158+
$config = [
179159
'migrations_paths' => ['DoctrineMigrationsTest' => 'a'],
180160
'connection' => 'custom',
181161
];
182-
183-
$extension->load(['doctrine_migrations' => $config], $container);
184-
185-
$container->getDefinition('doctrine.migrations.dependency_factory')->setPublic(true);
162+
$container = $this->getContainer($config);
186163

187164
$conn = $this->createMock(Connection::class);
188165
$container->set('doctrine.dbal.custom_connection', $conn);
@@ -197,20 +174,14 @@ public function testCustomConnection() : void
197174

198175
public function testPrefersEntityManagerOverConnection() : void
199176
{
200-
$container = $this->getContainer();
201-
$extension = new DoctrineMigrationsExtension();
177+
$config = [
178+
'migrations_paths' => ['DoctrineMigrationsTest' => 'a'],
179+
];
180+
$container = $this->getContainer($config);
202181

203182
$em = $this->createMock(EntityManager::class);
204183
$container->set('doctrine.orm.default_entity_manager', $em);
205184

206-
$extension->load([
207-
'doctrine_migrations' => [
208-
'migrations_paths' => ['DoctrineMigrationsTest' => 'a'],
209-
],
210-
], $container);
211-
212-
$container->getDefinition('doctrine.migrations.dependency_factory')->setPublic(true);
213-
214185
$container->compile();
215186

216187
$di = $container->get('doctrine.migrations.dependency_factory');
@@ -221,21 +192,15 @@ public function testPrefersEntityManagerOverConnection() : void
221192

222193
public function testCustomEntityManager() : void
223194
{
224-
$container = $this->getContainer();
225-
$extension = new DoctrineMigrationsExtension();
226-
227-
$config = [
195+
$config = [
228196
'em' => 'custom',
229197
'migrations_paths' => ['DoctrineMigrationsTest' => 'a'],
230198
];
199+
$container = $this->getContainer($config);
231200

232201
$em = new Definition(CustomEntityManager::class);
233202
$container->setDefinition('doctrine.orm.custom_entity_manager', $em);
234203

235-
$extension->load(['doctrine_migrations' => $config], $container);
236-
237-
$container->getDefinition('doctrine.migrations.dependency_factory')->setPublic(true);
238-
239204
$container->compile();
240205

241206
$di = $container->get('doctrine.migrations.dependency_factory');
@@ -251,24 +216,19 @@ public function testCustomEntityManager() : void
251216

252217
public function testCustomMetadataStorage() : void
253218
{
254-
$container = $this->getContainer();
255-
$extension = new DoctrineMigrationsExtension();
256-
257219
$config = [
258220
'migrations_paths' => ['DoctrineMigrationsTest' => 'a'],
259221
'services' => [MetadataStorage::class => 'mock_storage_service'],
260222
];
261223

224+
$container = $this->getContainer($config);
225+
262226
$mockStorage = $this->createMock(MetadataStorage::class);
263227
$container->set('mock_storage_service', $mockStorage);
264228

265229
$conn = $this->createMock(Connection::class);
266230
$container->set('doctrine.dbal.default_connection', $conn);
267231

268-
$extension->load(['doctrine_migrations' => $config], $container);
269-
270-
$container->getDefinition('doctrine.migrations.dependency_factory')->setPublic(true);
271-
272232
$container->compile();
273233

274234
$di = $container->get('doctrine.migrations.dependency_factory');
@@ -280,43 +240,56 @@ public function testInvalidService() : void
280240
{
281241
$this->expectException(InvalidConfigurationException::class);
282242
$this->expectExceptionMessage('Invalid configuration for path "doctrine_migrations.services": Valid services for the DoctrineMigrationsBundle must be in the "Doctrine\Migrations" namespace.');
283-
$container = $this->getContainer();
284-
$extension = new DoctrineMigrationsExtension();
285243

286-
$config = [
244+
$config = [
287245
'migrations_paths' => ['DoctrineMigrationsTest' => 'a'],
288246
'services' => ['foo' => 'mock_storage_service'],
289247
];
248+
$container = $this->getContainer($config);
290249

291250
$conn = $this->createMock(Connection::class);
292251
$container->set('doctrine.dbal.default_connection', $conn);
293252

294-
$extension->load(['doctrine_migrations' => $config], $container);
295-
296253
$container->compile();
297254
}
298255

299256
public function testCanNotSpecifyBothEmAndConnection() : void
300257
{
301258
$this->expectExceptionMessage('You cannot specify both "connection" and "em" in the DoctrineMigrationsBundle configurations');
302259
$this->expectException(InvalidArgumentException::class);
303-
$container = $this->getContainer();
304-
$extension = new DoctrineMigrationsExtension();
305260

306261
$config = [
307262
'migrations_paths' => ['DoctrineMigrationsTest' => 'a'],
308263
'em' => 'custom',
309264
'connection' => 'custom',
310265
];
311266

267+
$container = $this->getContainer($config);
268+
269+
$container->compile();
270+
}
271+
272+
/**
273+
* @param mixed[] $config
274+
*/
275+
private function getContainer(array $config) : ContainerBuilder
276+
{
277+
$container = $this->getContainerBuilder();
278+
279+
$bundle = new DoctrineMigrationsBundle();
280+
$bundle->build($container);
281+
282+
$extension = new DoctrineMigrationsExtension();
283+
312284
$extension->load(['doctrine_migrations' => $config], $container);
313285

314286
$container->getDefinition('doctrine.migrations.dependency_factory')->setPublic(true);
287+
$container->getDefinition('doctrine.migrations.configuration')->setPublic(true);
315288

316-
$container->compile();
289+
return $container;
317290
}
318291

319-
private function getContainer() : ContainerBuilder
292+
private function getContainerBuilder() : ContainerBuilder
320293
{
321294
return new ContainerBuilder(new ParameterBag([
322295
'kernel.debug' => false,

0 commit comments

Comments
 (0)