Skip to content

Commit ea5caf6

Browse files
committed
Add service migrations
1 parent 1dd4290 commit ea5caf6

File tree

6 files changed

+135
-3
lines changed

6 files changed

+135
-3
lines changed

AbstractServiceMigration.php

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Bundle\MigrationsBundle;
6+
7+
use Doctrine\DBAL\Connection;
8+
use Doctrine\Migrations\AbstractMigration;
9+
use Psr\Container\ContainerInterface;
10+
use Psr\Log\LoggerInterface;
11+
use Symfony\Contracts\Service\ServiceSubscriberInterface;
12+
13+
abstract class AbstractServiceMigration extends AbstractMigration implements ServiceSubscriberInterface
14+
{
15+
/** @var ContainerInterface */
16+
protected $container;
17+
18+
final public function __construct(Connection $connection, LoggerInterface $logger, ContainerInterface $container)
19+
{
20+
parent::__construct($connection, $logger);
21+
22+
$this->container = $container;
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Bundle\MigrationsBundle\DependencyInjection\CompilerPass;
6+
7+
use Doctrine\Bundle\MigrationsBundle\AbstractServiceMigration;
8+
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
9+
use Symfony\Component\DependencyInjection\ChildDefinition;
10+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
11+
use Symfony\Component\DependencyInjection\ContainerBuilder;
12+
use Symfony\Component\DependencyInjection\TypedReference;
13+
14+
use function is_subclass_of;
15+
16+
class RegisterMigrationsPass implements CompilerPassInterface
17+
{
18+
public function process(ContainerBuilder $container): void
19+
{
20+
$migrationRefs = [];
21+
22+
foreach ($container->findTaggedServiceIds('doctrine_migrations.migration', true) as $id => $attributes) {
23+
$class = $container->getDefinition($id)->getClass();
24+
if (is_subclass_of($class, AbstractServiceMigration::class)) {
25+
$definition = new ChildDefinition('doctrine_migrations.abstract_migration');
26+
$definition->setClass($class);
27+
$definition->addTag('container.service_subscriber');
28+
29+
$container->setDefinition($id, $definition);
30+
31+
$migrationRefs[$id] = new TypedReference($id, $class);
32+
} else {
33+
$container->removeDefinition($id);
34+
}
35+
}
36+
37+
if ($migrationRefs !== []) {
38+
$container->getDefinition('doctrine.migrations.service_migrations_factory')
39+
->replaceArgument(1, new ServiceLocatorArgument($migrationRefs));
40+
} else {
41+
$container->removeDefinition('doctrine.migrations.service_migrations_factory');
42+
}
43+
}
44+
}

DependencyInjection/DoctrineMigrationsExtension.php

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Doctrine\Bundle\MigrationsBundle\Collector\MigrationsCollector;
88
use Doctrine\Bundle\MigrationsBundle\Collector\MigrationsFlattener;
9+
use Doctrine\Migrations\AbstractMigration;
910
use Doctrine\Migrations\Metadata\Storage\MetadataStorage;
1011
use Doctrine\Migrations\Metadata\Storage\TableMetadataStorageConfiguration;
1112
use Doctrine\Migrations\Version\MigrationFactory;
@@ -52,6 +53,9 @@ public function load(array $configs, ContainerBuilder $container): void
5253

5354
$loader->load('services.xml');
5455

56+
$container->registerForAutoconfiguration(AbstractMigration::class)
57+
->addTag('doctrine_migrations.migration');
58+
5559
$configurationDefinition = $container->getDefinition('doctrine.migrations.configuration');
5660

5761
foreach ($config['migrations_paths'] as $ns => $path) {

DoctrineMigrationsBundle.php

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace Doctrine\Bundle\MigrationsBundle;
46

57
use Doctrine\Bundle\MigrationsBundle\DependencyInjection\CompilerPass\ConfigureDependencyFactoryPass;
8+
use Doctrine\Bundle\MigrationsBundle\DependencyInjection\CompilerPass\RegisterMigrationsPass;
69
use Symfony\Component\DependencyInjection\ContainerBuilder;
710
use Symfony\Component\HttpKernel\Bundle\Bundle;
811

@@ -14,9 +17,9 @@
1417
*/
1518
class DoctrineMigrationsBundle extends Bundle
1619
{
17-
/** @return void */
18-
public function build(ContainerBuilder $container)
20+
public function build(ContainerBuilder $container): void
1921
{
20-
$container->addCompilerPass(new ConfigureDependencyFactoryPass());
22+
$container->addCompilerPass(new ConfigureDependencyFactoryPass());
23+
$container->addCompilerPass(new RegisterMigrationsPass());
2124
}
2225
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Bundle\MigrationsBundle\MigrationsFactory;
6+
7+
use Doctrine\Migrations\AbstractMigration;
8+
use Doctrine\Migrations\Version\MigrationFactory;
9+
use Psr\Container\ContainerInterface;
10+
11+
class ServiceMigrationFactory implements MigrationFactory
12+
{
13+
/** @var MigrationFactory */
14+
private $migrationFactory;
15+
16+
/** @var ContainerInterface */
17+
private $container;
18+
19+
public function __construct(MigrationFactory $migrationFactory, ContainerInterface $container)
20+
{
21+
$this->migrationFactory = $migrationFactory;
22+
$this->container = $container;
23+
}
24+
25+
public function createVersion(string $migrationClassName): AbstractMigration
26+
{
27+
if ($this->container->has($migrationClassName)) {
28+
return $this->container->get($migrationClassName);
29+
}
30+
31+
return $this->migrationFactory->createVersion($migrationClassName);
32+
}
33+
}

Resources/config/services.xml

+24
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@
4242
<factory service="doctrine.migrations.dependency_factory" method="getMigrationFactory"/>
4343
</service>
4444

45+
<service id="doctrine.migrations.service_migrations_factory"
46+
class="Doctrine\Bundle\MigrationsBundle\MigrationsFactory\ServiceMigrationFactory"
47+
decorates="doctrine.migrations.migrations_factory" decoration-priority="-1"
48+
>
49+
<argument id="doctrine.migrations.service_migrations_factory.inner" type="service" />
50+
<argument type="abstract">migrations locator</argument>
51+
</service>
52+
4553
<service id="doctrine.migrations.container_aware_migrations_factory"
4654
class="Doctrine\Bundle\MigrationsBundle\MigrationsFactory\ContainerAwareMigrationFactory"
4755
decorates="doctrine.migrations.migrations_factory"
@@ -146,6 +154,22 @@
146154
<tag name="console.command" command="doctrine:migrations:version" />
147155
</service>
148156

157+
<service id="doctrine_migrations.abstract_migration" class="Doctrine\Bundle\MigrationsBundle\AbstractServiceMigration" abstract="true">
158+
159+
<argument type="service">
160+
<service class="Doctrine\DBAL\Connection">
161+
<factory service="doctrine.migrations.dependency_factory" method="getConnection" />
162+
</service>
163+
</argument>
164+
<argument type="service">
165+
<service class="Psr\Log\LoggerInterface">
166+
<factory service="doctrine.migrations.dependency_factory" method="getLogger" />
167+
</service>
168+
</argument>
169+
<argument></argument>
170+
171+
</service>
172+
149173
</services>
150174

151175
</container>

0 commit comments

Comments
 (0)