diff --git a/DependencyInjection/CompilerPass/RegisterMigrationsPass.php b/DependencyInjection/CompilerPass/RegisterMigrationsPass.php new file mode 100644 index 0000000..b4795b9 --- /dev/null +++ b/DependencyInjection/CompilerPass/RegisterMigrationsPass.php @@ -0,0 +1,44 @@ +findTaggedServiceIds('doctrine_migrations.migration', true) as $id => $attributes) { + $definition = $container->getDefinition($id); + $definition->setBindings([ + Connection::class => new BoundArgument(new Reference('doctrine.migrations.connection')), + LoggerInterface::class => new BoundArgument(new Reference('doctrine.migrations.logger')), + ]); + + $migrationRefs[$id] = new TypedReference($id, $definition->getClass()); + } + + if ($migrationRefs !== []) { + $container->getDefinition('doctrine.migrations.filter_service_migration_finder') + ->replaceArgument(1, new ServiceLocatorArgument($migrationRefs)); + $container->getDefinition('doctrine.migrations.service_migrations_repository') + ->replaceArgument(1, new ServiceLocatorArgument($migrationRefs)); + } else { + $container->removeDefinition('doctrine.migrations.connection'); + $container->removeDefinition('doctrine.migrations.logger'); + $container->removeDefinition('doctrine.migrations.filter_service_migration_finder'); + $container->removeDefinition('doctrine.migrations.service_migrations_repository'); + } + } +} diff --git a/DependencyInjection/DoctrineMigrationsExtension.php b/DependencyInjection/DoctrineMigrationsExtension.php index e855d10..62ecf70 100644 --- a/DependencyInjection/DoctrineMigrationsExtension.php +++ b/DependencyInjection/DoctrineMigrationsExtension.php @@ -6,6 +6,7 @@ use Doctrine\Bundle\MigrationsBundle\Collector\MigrationsCollector; use Doctrine\Bundle\MigrationsBundle\Collector\MigrationsFlattener; +use Doctrine\Migrations\AbstractMigration; use Doctrine\Migrations\Metadata\Storage\MetadataStorage; use Doctrine\Migrations\Metadata\Storage\TableMetadataStorageConfiguration; use Doctrine\Migrations\Version\MigrationFactory; @@ -52,6 +53,9 @@ public function load(array $configs, ContainerBuilder $container): void $loader->load('services.xml'); + $container->registerForAutoconfiguration(AbstractMigration::class) + ->addTag('doctrine_migrations.migration'); + $configurationDefinition = $container->getDefinition('doctrine.migrations.configuration'); foreach ($config['migrations_paths'] as $ns => $path) { diff --git a/DoctrineMigrationsBundle.php b/DoctrineMigrationsBundle.php index c91edf5..80e3e0a 100644 --- a/DoctrineMigrationsBundle.php +++ b/DoctrineMigrationsBundle.php @@ -1,8 +1,11 @@ addCompilerPass(new ConfigureDependencyFactoryPass()); + $container->addCompilerPass(new ConfigureDependencyFactoryPass()); + $container->addCompilerPass(new RegisterMigrationsPass()); } } diff --git a/MigrationFinder/FilterServiceMigrationFinder.php b/MigrationFinder/FilterServiceMigrationFinder.php new file mode 100644 index 0000000..53860da --- /dev/null +++ b/MigrationFinder/FilterServiceMigrationFinder.php @@ -0,0 +1,46 @@ +migrationFinder = $migrationFinder; + $this->container = $container; + } + + /** + * {@inheritDoc} + */ + public function findMigrations(string $directory, ?string $namespace = null): array + { + $migrations = $this->migrationFinder->findMigrations( + $directory, + $namespace + ); + + foreach ($migrations as $i => $migration) { + if (! $this->container->has($migration)) { + continue; + } + + unset($migrations[$i]); + } + + return array_values($migrations); + } +} diff --git a/MigrationsRepository/ServiceMigrationsRepository.php b/MigrationsRepository/ServiceMigrationsRepository.php new file mode 100644 index 0000000..3b47a5a --- /dev/null +++ b/MigrationsRepository/ServiceMigrationsRepository.php @@ -0,0 +1,98 @@ +migrationRepository = $migrationRepository; + $this->container = $container; + } + + public function hasMigration(string $version): bool + { + return $this->container->has($version) || $this->migrationRepository->hasMigration($version); + } + + public function getMigration(Version $version): AvailableMigration + { + if (! isset($this->migrations[(string) $version]) && ! $this->loadMigrationFromContainer($version)) { + return $this->migrationRepository->getMigration($version); + } + + return $this->migrations[(string) $version]; + } + + /** + * Returns a non-sorted set of migrations. + */ + public function getMigrations(): AvailableMigrationsSet + { + $this->loadMigrationsFromContainer(); + + $migrations = $this->migrations; + foreach ($this->migrationRepository->getMigrations()->getItems() as $availableMigration) { + $version = $availableMigration->getVersion(); + + if (isset($migrations[(string) $version])) { + throw DuplicateMigrationVersion::new( + (string) $version, + (string) $version + ); + } + + $migrations[(string) $version] = $availableMigration; + } + + return new AvailableMigrationsSet($migrations); + } + + private function loadMigrationsFromContainer(): void + { + foreach ($this->container->getProvidedServices() as $id) { + if (isset($this->migrations[$id])) { + continue; + } + + $this->loadMigrationFromContainer(new Version($id)); + } + } + + private function loadMigrationFromContainer(Version $version): bool + { + if (! $this->container->has((string) $version)) { + return false; + } + + $migration = $this->container->get((string) $version); + assert($migration instanceof AbstractMigration); + + $this->migrations[(string) $version] = new AvailableMigration($version, $migration); + + return true; + } +} diff --git a/Resources/config/services.xml b/Resources/config/services.xml index cb97871..b0e3154 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -11,6 +11,14 @@ + + Doctrine\Migrations\Finder\MigrationFinder + + + + Doctrine\Migrations\MigrationsRepository + + @@ -146,6 +154,38 @@ + + + + + + + + + + + + + + + migrations locator + + + + + + + + + migrations locator + +