Skip to content

Commit 5435638

Browse files
committed
add service factories
1 parent 7376b1c commit 5435638

File tree

4 files changed

+69
-0
lines changed

4 files changed

+69
-0
lines changed

DependencyInjection/Configuration.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,21 @@ public function getConfigTreeBuilder() : TreeBuilder
6868
->prototype('scalar')->end()
6969
->end()
7070

71+
->arrayNode('factories')
72+
->info('A set of callables to pass to the underlying doctrine/migrations library as services, allowing to change its behaviour.')
73+
->useAttributeAsKey('factory')
74+
->defaultValue([])
75+
->validate()
76+
->ifTrue(static function ($v) {
77+
return count(array_filter(array_keys($v), static function (string $doctrineService) : bool {
78+
return strpos($doctrineService, 'Doctrine\Migrations\\') !==0;
79+
}));
80+
})
81+
->thenInvalid('Valid callables for the DoctrineMigrationsBundle must be in the "Doctrine\Migrations" namespace.')
82+
->end()
83+
->prototype('scalar')->end()
84+
->end()
85+
7186
->arrayNode('storage')
7287
->addDefaultsIfNotSet()
7388
->info('Storage to use for migration status metadata.')

DependencyInjection/DoctrineMigrationsExtension.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ public function load(array $configs, ContainerBuilder $container) : void
7171
$diDefinition->addMethodCall('setDefinition', [$doctrineId, new ServiceClosureArgument(new Reference($symfonyId))]);
7272
}
7373

74+
foreach ($config['factories'] as $doctrineId => $symfonyId) {
75+
$diDefinition->addMethodCall('setDefinition', [$doctrineId, new Reference($symfonyId)]);
76+
}
77+
7478
if (! isset($config['services'][MetadataStorage::class])) {
7579
$storageConfiguration = $config['storage']['table_storage'];
7680

Resources/doc/index.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,21 @@ application:
8888
# Custom migration classes factory
8989
'Doctrine\Migrations\Version\MigrationFactory': ~
9090
91+
factories:
92+
# Custom migration sorting service id via callables (MyCallableFactory must be a callable)
93+
'Doctrine\Migrations\Version\Comparator': 'MyCallableFactory'
94+
95+
96+
97+
98+
- The ``services`` node allows you to provide custom services to the underlying ``DependencyFactory`` part
99+
of ``doctrine/migrations``.
100+
101+
- The node ``factories`` is similar to ``services``, with the difference that it accepts only callables.
102+
The provided callable must return the service to be passed to the ``DependencyFactory``.
103+
The callable will receive as first argument the ``DependencyFactory`` itself,
104+
allowing you to fetch other dependencies from the factory while instantiating your custom dependencies.
105+
91106
Usage
92107
-----
93108

Tests/DependencyInjection/DoctrineMigrationsExtensionTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,41 @@ public function __invoke() : void
205205
self::assertInstanceOf(DependencyFactory::class, $di);
206206
}
207207

208+
public function testServiceFactory() : void
209+
{
210+
$mockComparator = $this->createMock(Comparator::class);
211+
$config = [
212+
'factories' => [Comparator::class => 'my_sorter'],
213+
];
214+
215+
$container = $this->getContainer($config);
216+
217+
$conn = $this->createMock(Connection::class);
218+
$container->set('doctrine.dbal.default_connection', $conn);
219+
220+
$sorterFactory = new class($mockComparator) {
221+
/** @var Comparator */
222+
private $comparator;
223+
224+
public function __construct(Comparator $comparator)
225+
{
226+
$this->comparator = $comparator;
227+
}
228+
229+
public function __invoke(DependencyFactory $di) : Comparator
230+
{
231+
return $this->comparator;
232+
}
233+
};
234+
$container->set('my_sorter', $sorterFactory);
235+
236+
$container->compile();
237+
238+
$di = $container->get('doctrine.migrations.dependency_factory');
239+
self::assertInstanceOf(DependencyFactory::class, $di);
240+
self::assertSame($mockComparator, $di->getVersionComparator());
241+
}
242+
208243
public function testCustomConnection() : void
209244
{
210245
$config = [

0 commit comments

Comments
 (0)