vendor/pimcore/pimcore/lib/Migrations/Configuration/ConfigurationFactory.php line 181

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4.  * Pimcore
  5.  *
  6.  * This source file is available under two different licenses:
  7.  * - GNU General Public License version 3 (GPLv3)
  8.  * - Pimcore Enterprise License (PEL)
  9.  * Full copyright and license information is available in
  10.  * LICENSE.md which is distributed with this source code.
  11.  *
  12.  * @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  13.  * @license    http://www.pimcore.org/license     GPLv3 and PEL
  14.  */
  15. namespace Pimcore\Migrations\Configuration;
  16. use Doctrine\DBAL\Migrations\OutputWriter;
  17. use Pimcore\Db\Connection;
  18. use Pimcore\Event\TestEvents;
  19. use Pimcore\Extension\Bundle\Installer\MigrationInstallerInterface;
  20. use Pimcore\Extension\Bundle\PimcoreBundleInterface;
  21. use Symfony\Component\DependencyInjection\ContainerAwareInterface;
  22. use Symfony\Component\DependencyInjection\ContainerInterface;
  23. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  24. use Symfony\Component\HttpKernel\Bundle\BundleInterface;
  25. class ConfigurationFactory implements EventSubscriberInterface
  26. {
  27.     /**
  28.      * @var ContainerInterface
  29.      */
  30.     private $container;
  31.     /**
  32.      * @var MigrationSetConfiguration[]
  33.      */
  34.     private $migrationSets = [];
  35.     /**
  36.      * @var Configuration[]
  37.      */
  38.     private $configurations = [];
  39.     /**
  40.      * @var InstallConfiguration[]
  41.      */
  42.     private $installConfigurations = [];
  43.     public function __construct(ContainerInterface $container, array $migrationSetConfigurations = [])
  44.     {
  45.         $this->container $container;
  46.         $this->buildMigrationSets($migrationSetConfigurations);
  47.     }
  48.     public static function getSubscribedEvents()
  49.     {
  50.         // reset configurations when test kernel boots
  51.         return [
  52.             TestEvents::KERNEL_BOOTED => 'reset'
  53.         ];
  54.     }
  55.     private function buildMigrationSets(array $configurations)
  56.     {
  57.         foreach ($configurations as $configuration) {
  58.             $this->registerMigrationSet(MigrationSetConfiguration::fromConfig($configuration));
  59.         }
  60.     }
  61.     public function getForSet(
  62.         string $set,
  63.         Connection $connection,
  64.         OutputWriter $outputWriter null
  65.     ) {
  66.         $migrationSet $this->getMigrationSet($set);
  67.         $configuration $this->getConfiguration($migrationSet$connection$outputWriter);
  68.         $this->injectContainerToVersions($configuration);
  69.         return $configuration;
  70.     }
  71.     public function getForBundle(
  72.         BundleInterface $bundle,
  73.         Connection $connection,
  74.         OutputWriter $outputWriter null
  75.     ): Configuration {
  76.         $migrationSet $this->getMigrationSetForBundle($bundle);
  77.         $configuration $this->getConfiguration($migrationSet$connection$outputWriter);
  78.         if ($bundle instanceof PimcoreBundleInterface) {
  79.             $installer $bundle->getInstaller();
  80.             if (null !== $installer && $installer instanceof MigrationInstallerInterface) {
  81.                 $configuration->setInstaller($installer);
  82.             }
  83.         }
  84.         $this->injectContainerToVersions($configuration);
  85.         return $configuration;
  86.     }
  87.     protected function getConfiguration(
  88.         MigrationSetConfiguration $migrationSet,
  89.         Connection $connection,
  90.         OutputWriter $outputWriter null
  91.     ): Configuration {
  92.         if (isset($this->configurations[$migrationSet->getIdentifier()])) {
  93.             return $this->configurations[$migrationSet->getIdentifier()];
  94.         }
  95.         // fetch custom connection if migration set defines a dedicated one
  96.         if (null !== $migrationSet->getConnection()) {
  97.             $connection $this->container->get(sprintf(
  98.                 'doctrine.dbal.%s_connection',
  99.                 $migrationSet->getConnection()
  100.             ));
  101.         }
  102.         $configuration = new Configuration(
  103.             $migrationSet->getIdentifier(),
  104.             $connection,
  105.             $outputWriter
  106.         );
  107.         $this->configureConfiguration($configuration$migrationSet);
  108.         $this->configurations[$migrationSet->getIdentifier()] = $configuration;
  109.         return $configuration;
  110.     }
  111.     /**
  112.      * Creates a dedicated install configuration from an existing configuration
  113.      *
  114.      * @param Configuration $configuration
  115.      * @param MigrationInstallerInterface $installer
  116.      *
  117.      * @return InstallConfiguration
  118.      */
  119.     public function getInstallConfiguration(
  120.         Configuration $configuration,
  121.         MigrationInstallerInterface $installer
  122.     ): InstallConfiguration {
  123.         $migrationSetId $configuration->getMigrationSet();
  124.         if (isset($this->installConfigurations[$migrationSetId])) {
  125.             return $this->installConfigurations[$migrationSetId];
  126.         }
  127.         $migrationSet $this->getMigrationSet($migrationSetId);
  128.         // pipe messages to original config output writer
  129.         $outputWriter = new OutputWriter(function ($message) use ($configuration) {
  130.             $configuration->getOutputWriter()->write($message);
  131.         });
  132.         $installConfiguration = new InstallConfiguration(
  133.             $installer,
  134.             $configuration->getMigrationSet(),
  135.             $configuration->getConnection(),
  136.             $outputWriter
  137.         );
  138.         $this->configureConfiguration($installConfiguration$migrationSet);
  139.         $this->installConfigurations[$migrationSetId] = $installConfiguration;
  140.         return $installConfiguration;
  141.     }
  142.     /**
  143.      * Reset all registered configurations. Can be necessary during tests when rebuilding the DB.
  144.      */
  145.     public function reset()
  146.     {
  147.         foreach ($this->configurations as $configuration) {
  148.             $configuration->reset();
  149.         }
  150.         foreach ($this->installConfigurations as $installConfiguration) {
  151.             $installConfiguration->reset();
  152.         }
  153.     }
  154.     /**
  155.      * Applies migration set configuration to configuration instance
  156.      *
  157.      * @param Configuration $configuration
  158.      * @param MigrationSetConfiguration $migrationSet
  159.      */
  160.     protected function configureConfiguration(Configuration $configurationMigrationSetConfiguration $migrationSet)
  161.     {
  162.         $configuration->setName($migrationSet->getName());
  163.         $configuration->setMigrationsNamespace($migrationSet->getNamespace());
  164.         $configuration->setMigrationsDirectory($migrationSet->getDirectory());
  165.     }
  166.     protected function injectContainerToVersions(Configuration $configuration)
  167.     {
  168.         $versions $configuration->getMigrations();
  169.         foreach ($versions as $version) {
  170.             $migration $version->getMigration();
  171.             if ($migration instanceof ContainerAwareInterface) {
  172.                 $migration->setContainer($this->container);
  173.             }
  174.         }
  175.     }
  176.     private function getMigrationSetForBundle(BundleInterface $bundle): MigrationSetConfiguration
  177.     {
  178.         if (!isset($this->migrationSets[$bundle->getName()])) {
  179.             $this->registerMigrationSet($this->buildBundleMigrationSet($bundle));
  180.         }
  181.         return $this->migrationSets[$bundle->getName()];
  182.     }
  183.     protected function buildBundleMigrationSet(BundleInterface $bundle)
  184.     {
  185.         return new MigrationSetConfiguration(
  186.             $bundle->getName(),
  187.             $bundle->getName() . ' Migrations',
  188.             $bundle->getNamespace() . '\\Migrations',
  189.             $bundle->getPath() . '/Migrations'
  190.         );
  191.     }
  192.     private function registerMigrationSet(MigrationSetConfiguration $migrationSet)
  193.     {
  194.         if (isset($this->migrationSets[$migrationSet->getIdentifier()])) {
  195.             throw new \RuntimeException(sprintf('Migration set "%s" is already registered.'$migrationSet->getIdentifier()));
  196.         }
  197.         $this->migrationSets[$migrationSet->getIdentifier()] = $migrationSet;
  198.     }
  199.     protected function getMigrationSet(string $set): MigrationSetConfiguration
  200.     {
  201.         if (!isset($this->migrationSets[$set])) {
  202.             throw new \InvalidArgumentException(sprintf('Migration set "%s" is not registered.'$set));
  203.         }
  204.         return $this->migrationSets[$set];
  205.     }
  206. }