Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. MigrationPluginManager.php

class MigrationPluginManager

Same name in this branch
  1. 11.1.x core/modules/migrate_drupal/src/MigrationPluginManager.php \Drupal\migrate_drupal\MigrationPluginManager

Plugin manager for migration plugins.

Hierarchy

  • class \Drupal\Component\Plugin\PluginManagerBase implements \Drupal\Component\Plugin\PluginManagerInterface uses \Drupal\Component\Plugin\Discovery\DiscoveryTrait
    • class \Drupal\Core\Plugin\DefaultPluginManager extends \Drupal\Component\Plugin\PluginManagerBase implements \Drupal\Component\Plugin\PluginManagerInterface, \Drupal\Component\Plugin\Discovery\CachedDiscoveryInterface, \Drupal\Core\Cache\CacheableDependencyInterface uses \Drupal\Component\Plugin\Discovery\DiscoveryCachedTrait, \Drupal\Core\Cache\UseCacheBackendTrait
      • class \Drupal\migrate\Plugin\MigrationPluginManager extends \Drupal\Core\Plugin\DefaultPluginManager implements \Drupal\migrate\Plugin\MigrationPluginManagerInterface, \Drupal\migrate\MigrateBuildDependencyInterface

Expanded class hierarchy of MigrationPluginManager

1 file declares its use of MigrationPluginManager
MigrationPluginManager.php in core/modules/migrate_drupal/src/MigrationPluginManager.php
1 string reference to 'MigrationPluginManager'
migrate.services.yml in core/modules/migrate/migrate.services.yml
core/modules/migrate/migrate.services.yml
1 service uses MigrationPluginManager
plugin.manager.migration in core/modules/migrate/migrate.services.yml
Drupal\migrate\Plugin\MigrationPluginManager

File

core/modules/migrate/src/Plugin/MigrationPluginManager.php, line 20

Namespace

Drupal\migrate\Plugin
View source
class MigrationPluginManager extends DefaultPluginManager implements MigrationPluginManagerInterface, MigrateBuildDependencyInterface {
    
    /**
     * Provides default values for migrations.
     *
     * @var array
     */
    protected $defaults = [
        'class' => '\\Drupal\\migrate\\Plugin\\Migration',
    ];
    
    /**
     * The interface the plugins should implement.
     *
     * @var string
     */
    protected $pluginInterface = 'Drupal\\migrate\\Plugin\\MigrationInterface';
    
    /**
     * The module handler.
     *
     * @var \Drupal\Core\Extension\ModuleHandlerInterface
     */
    protected $moduleHandler;
    
    /**
     * Construct a migration plugin manager.
     *
     * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
     *   The module handler.
     * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
     *   The cache backend for the definitions.
     * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
     *   The language manager.
     */
    public function __construct(ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, LanguageManagerInterface $language_manager) {
        $this->factory = new ContainerFactory($this, $this->pluginInterface);
        $this->alterInfo('migration_plugins');
        $this->setCacheBackend($cache_backend, 'migration_plugins');
        $this->moduleHandler = $module_handler;
    }
    
    /**
     * Gets the plugin discovery.
     *
     * This method overrides DefaultPluginManager::getDiscovery() in order to
     * search for migration configurations in the MODULENAME/migrations
     * directory.
     */
    protected function getDiscovery() {
        if (!isset($this->discovery)) {
            $directories = array_map(function ($directory) {
                return [
                    $directory . '/migrations',
                ];
            }, $this->moduleHandler
                ->getModuleDirectories());
            $yaml_discovery = new YamlDirectoryDiscovery($directories, 'migrate');
            // This gets rid of migrations which try to use a non-existent source
            // plugin. The common case for this is if the source plugin has, or
            // specifies, a non-existent provider.
            $only_with_source_discovery = new NoSourcePluginDecorator($yaml_discovery);
            // This gets rid of migrations with explicit providers set if one of the
            // providers do not exist before we try to use a potentially non-existing
            // deriver. This is a rare case.
            $filtered_discovery = new ProviderFilterDecorator($only_with_source_discovery, [
                $this->moduleHandler,
                'moduleExists',
            ]);
            $this->discovery = new ContainerDerivativeDiscoveryDecorator($filtered_discovery);
        }
        return $this->discovery;
    }
    
    /**
     * {@inheritdoc}
     */
    public function createInstance($plugin_id, array $configuration = []) {
        $instances = $this->createInstances([
            $plugin_id,
        ], [
            $plugin_id => $configuration,
        ]);
        return reset($instances);
    }
    
    /**
     * {@inheritdoc}
     */
    public function createInstances($migration_id, array $configuration = []) {
        if (empty($migration_id)) {
            $migration_id = array_keys($this->getDefinitions());
        }
        $factory = $this->getFactory();
        $migration_ids = (array) $migration_id;
        // We need to expand any derivative migrations. Derivative migrations are
        // calculated by migration derivers such as D6NodeDeriver. This allows
        // migrations to depend on the base id and then have a dependency on all
        // derivative migrations. For example, d6_comment depends on d6_node but
        // after we've expanded the dependencies it will depend on d6_node:page,
        // d6_node:story and so on, for other derivative migrations.
        $plugin_ids = $this->expandPluginIds($migration_ids);
        $instances = [];
        foreach ($plugin_ids as $plugin_id) {
            $instances[$plugin_id] = $factory->createInstance($plugin_id, $configuration[$plugin_id] ?? []);
        }
        // @todo Remove loop when the ability to call ::getMigrationDependencies()
        //   without expanding plugins is removed.
        foreach ($instances as $migration) {
            $migration->set('migration_dependencies', $migration->getMigrationDependencies());
        }
        // Sort the migrations based on their dependencies.
        return $this->buildDependencyMigration($instances, []);
    }
    
    /**
     * {@inheritdoc}
     */
    public function createInstancesByTag($tag) {
        $migrations = array_filter($this->getDefinitions(), function ($migration) use ($tag) {
            return !empty($migration['migration_tags']) && in_array($tag, $migration['migration_tags']);
        });
        return $migrations ? $this->createInstances(array_keys($migrations)) : [];
    }
    
    /**
     * {@inheritdoc}
     */
    public function expandPluginIds(array $migration_ids) {
        $plugin_ids = [];
        $all_ids = array_keys($this->getDefinitions());
        foreach ($migration_ids as $id) {
            $plugin_ids = array_merge($plugin_ids, preg_grep('/^' . preg_quote($id, '/') . PluginBase::DERIVATIVE_SEPARATOR . '/', $all_ids));
            if ($this->hasDefinition($id)) {
                $plugin_ids[] = $id;
            }
        }
        return $plugin_ids;
    }
    
    /**
     * {@inheritdoc}
     */
    public function buildDependencyMigration(array $migrations, array $dynamic_ids) {
        // Migration dependencies can be optional or required. If an optional
        // dependency does not run, the current migration is still OK to go. Both
        // optional and required dependencies (if run at all) must run before the
        // current migration.
        $dependency_graph = [];
        $required_dependency_graph = [];
        $have_optional = FALSE;
        foreach ($migrations as $migration) {
            
            /** @var \Drupal\migrate\Plugin\MigrationInterface $migration */
            $id = $migration->id();
            $requirements[$id] = [];
            $dependency_graph[$id]['edges'] = [];
            $migration_dependencies = $migration->getMigrationDependencies();
            if (isset($migration_dependencies['required'])) {
                foreach ($migration_dependencies['required'] as $dependency) {
                    if (!isset($dynamic_ids[$dependency])) {
                        $this->addDependency($required_dependency_graph, $id, $dependency, $dynamic_ids);
                    }
                    $this->addDependency($dependency_graph, $id, $dependency, $dynamic_ids);
                }
            }
            if (!empty($migration_dependencies['optional'])) {
                foreach ($migration_dependencies['optional'] as $dependency) {
                    $this->addDependency($dependency_graph, $id, $dependency, $dynamic_ids);
                }
                $have_optional = TRUE;
            }
        }
        $dependency_graph = (new Graph($dependency_graph))->searchAndSort();
        if ($have_optional) {
            $required_dependency_graph = (new Graph($required_dependency_graph))->searchAndSort();
        }
        else {
            $required_dependency_graph = $dependency_graph;
        }
        $weights = [];
        foreach ($migrations as $migration_id => $migration) {
            // Populate a weights array to use with array_multisort() later.
            $weights[] = $dependency_graph[$migration_id]['weight'];
            if (!empty($required_dependency_graph[$migration_id]['paths'])) {
                $migration->set('requirements', $required_dependency_graph[$migration_id]['paths']);
            }
        }
        // Sort weights, labels, and keys in the same order as each other.
        array_multisort($weights, SORT_DESC, SORT_NUMERIC, array_keys($migrations), SORT_ASC, SORT_NATURAL, $migrations);
        return $migrations;
    }
    
    /**
     * Add one or more dependencies to a graph.
     *
     * @param array $graph
     *   The graph so far, passed by reference.
     * @param int $id
     *   The migration ID.
     * @param string $dependency
     *   The dependency string.
     * @param array $dynamic_ids
     *   The dynamic ID mapping.
     */
    protected function addDependency(array &$graph, $id, $dependency, $dynamic_ids) {
        $dependencies = $dynamic_ids[$dependency] ?? [
            $dependency,
        ];
        if (!isset($graph[$id]['edges'])) {
            $graph[$id]['edges'] = [];
        }
        $graph[$id]['edges'] += array_combine($dependencies, $dependencies);
    }
    
    /**
     * {@inheritdoc}
     */
    public function createStubMigration(array $definition) {
        $id = $definition['id'] ?? uniqid();
        return Migration::create(\Drupal::getContainer(), [], $id, $definition);
    }
    
    /**
     * Finds plugin definitions.
     *
     * @return array
     *   List of definitions to store in cache.
     *
     * @todo This is a temporary solution to the fact that migration source
     *   plugins have more than one provider. This functionality will be moved to
     *   core in https://www.drupal.org/node/2786355.
     */
    protected function findDefinitions() {
        $definitions = $this->getDiscovery()
            ->getDefinitions();
        foreach ($definitions as $plugin_id => &$definition) {
            $this->processDefinition($definition, $plugin_id);
        }
        $this->alterDefinitions($definitions);
        return ProviderFilterDecorator::filterDefinitions($definitions, function ($provider) {
            return $this->providerExists($provider);
        });
    }

}

Members

Title Sort descending Modifiers Object type Summary Overriden Title Overrides
DefaultPluginManager::$additionalAnnotationNamespaces protected property Additional annotation namespaces.
DefaultPluginManager::$alterHook protected property Name of the alter hook if one should be invoked.
DefaultPluginManager::$cacheKey protected property The cache key.
DefaultPluginManager::$cacheTags protected property An array of cache tags to use for the cached definitions.
DefaultPluginManager::$moduleExtensionList protected property The module extension list.
DefaultPluginManager::$namespaces protected property An object of root paths that are traversable.
DefaultPluginManager::$pluginDefinitionAnnotationName protected property The name of the annotation that contains the plugin definition.
DefaultPluginManager::$pluginDefinitionAttributeName protected property The name of the attribute that contains the plugin definition.
DefaultPluginManager::$subdir protected property The subdirectory within a namespace to look for plugins.
DefaultPluginManager::alterDefinitions protected function Invokes the hook to alter the definitions if the alter hook is set. 4
DefaultPluginManager::alterInfo protected function Sets the alter hook name.
DefaultPluginManager::clearCachedDefinitions public function Clears static and persistent plugin definition caches. Overrides CachedDiscoveryInterface::clearCachedDefinitions 9
DefaultPluginManager::extractProviderFromDefinition protected function Extracts the provider from a plugin definition.
DefaultPluginManager::getCacheContexts public function The cache contexts associated with this object. Overrides CacheableDependencyInterface::getCacheContexts
DefaultPluginManager::getCachedDefinitions protected function Returns the cached plugin definitions of the decorated discovery class.
DefaultPluginManager::getCacheMaxAge public function The maximum age for which this object may be cached. Overrides CacheableDependencyInterface::getCacheMaxAge
DefaultPluginManager::getCacheTags public function The cache tags associated with this object. Overrides CacheableDependencyInterface::getCacheTags
DefaultPluginManager::getDefinitions public function Gets the definition of all plugins for this type. Overrides DiscoveryTrait::getDefinitions 1
DefaultPluginManager::getFactory protected function Gets the plugin factory. Overrides PluginManagerBase::getFactory
DefaultPluginManager::processDefinition public function Performs extra processing on plugin definitions. 14
DefaultPluginManager::providerExists protected function Determines if the provider of a definition exists. 5
DefaultPluginManager::setCacheBackend public function Initialize the cache backend.
DefaultPluginManager::setCachedDefinitions protected function Sets a cache of plugin definitions for the decorated discovery class.
DefaultPluginManager::useCaches public function Disable the use of caches. Overrides CachedDiscoveryInterface::useCaches 1
DiscoveryCachedTrait::$definitions protected property Cached definitions array. 1
DiscoveryCachedTrait::getDefinition public function Overrides DiscoveryTrait::getDefinition 3
DiscoveryTrait::doGetDefinition protected function Gets a specific plugin definition.
DiscoveryTrait::hasDefinition public function
MigrationPluginManager::$defaults protected property Provides default values for migrations. Overrides DefaultPluginManager::$defaults
MigrationPluginManager::$moduleHandler protected property The module handler. Overrides DefaultPluginManager::$moduleHandler
MigrationPluginManager::$pluginInterface protected property The interface the plugins should implement. Overrides DefaultPluginManager::$pluginInterface
MigrationPluginManager::addDependency protected function Add one or more dependencies to a graph.
MigrationPluginManager::buildDependencyMigration public function
MigrationPluginManager::createInstance public function Overrides PluginManagerBase::createInstance
MigrationPluginManager::createInstances public function
MigrationPluginManager::createInstancesByTag public function
MigrationPluginManager::createStubMigration public function
MigrationPluginManager::expandPluginIds public function
MigrationPluginManager::findDefinitions protected function Finds plugin definitions. Overrides DefaultPluginManager::findDefinitions
MigrationPluginManager::getDiscovery protected function Gets the plugin discovery. Overrides DefaultPluginManager::getDiscovery
MigrationPluginManager::__construct public function Construct a migration plugin manager. Overrides DefaultPluginManager::__construct 1
PluginManagerBase::$discovery protected property The object that discovers plugins managed by this manager.
PluginManagerBase::$factory protected property The object that instantiates plugins managed by this manager.
PluginManagerBase::$mapper protected property The object that returns the preconfigured plugin instance appropriate for a particular runtime condition.
PluginManagerBase::getFallbackPluginId protected function Gets a fallback id for a missing plugin. 5
PluginManagerBase::getInstance public function 6
PluginManagerBase::handlePluginNotFound protected function Allows plugin managers to specify custom behavior if a plugin is not found. 1
UseCacheBackendTrait::$cacheBackend protected property Cache backend instance.
UseCacheBackendTrait::$useCaches protected property Flag whether caches should be used or skipped.
UseCacheBackendTrait::cacheGet protected function Fetches from the cache backend, respecting the use caches flag.
UseCacheBackendTrait::cacheSet protected function Stores data in the persistent cache, respecting the use caches flag.
RSS feed
Powered by Drupal