class MigrationPluginManager in Drupal 9
Same name in this branch
- 9 core/modules/migrate_drupal/src/MigrationPluginManager.php \Drupal\migrate_drupal\MigrationPluginManager
- 9 core/modules/migrate/src/Plugin/MigrationPluginManager.php \Drupal\migrate\Plugin\MigrationPluginManager
Same name and namespace in other branches
- 8 core/modules/migrate/src/Plugin/MigrationPluginManager.php \Drupal\migrate\Plugin\MigrationPluginManager
Plugin manager for migration plugins.
Hierarchy
- class \Drupal\Component\Plugin\PluginManagerBase implements PluginManagerInterface uses DiscoveryTrait
- class \Drupal\Core\Plugin\DefaultPluginManager implements CachedDiscoveryInterface, PluginManagerInterface, CacheableDependencyInterface uses DiscoveryCachedTrait, UseCacheBackendTrait
- class \Drupal\migrate\Plugin\MigrationPluginManager implements MigrateBuildDependencyInterface, MigrationPluginManagerInterface
- class \Drupal\Core\Plugin\DefaultPluginManager implements CachedDiscoveryInterface, PluginManagerInterface, CacheableDependencyInterface uses DiscoveryCachedTrait, UseCacheBackendTrait
Expanded class hierarchy of MigrationPluginManager
2 files declare their use of MigrationPluginManager
- MigrationPluginManager.php in core/
modules/ migrate_drupal/ src/ MigrationPluginManager.php - MigrationPluginManagerTest.php in core/
modules/ migrate/ tests/ src/ Unit/ MigrationPluginManagerTest.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\PluginView 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', [
'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;
$plugin_ids = $this
->expandPluginIds($migration_ids);
$instances = [];
foreach ($plugin_ids as $plugin_id) {
$instances[$plugin_id] = $factory
->createInstance($plugin_id, isset($configuration[$plugin_id]) ? $configuration[$plugin_id] : []);
}
foreach ($instances as $migration) {
$migration
->set('migration_dependencies', array_map([
$this,
'expandPluginIds',
], $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)) : [];
}
/**
* Expand derivative migration dependencies.
*
* 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.
*
* @return array
* An array of expanded plugin ids.
*/
protected function expandPluginIds(array $migration_ids) {
$plugin_ids = [];
foreach ($migration_ids as $id) {
$plugin_ids += preg_grep('/^' . preg_quote($id, '/') . PluginBase::DERIVATIVE_SEPARATOR . '/', array_keys($this
->getDefinitions()));
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 = isset($dynamic_ids[$dependency]) ? $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 = isset($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
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DefaultPluginManager:: |
protected | property | Additional namespaces the annotation discovery mechanism should scan for annotation definitions. | |
DefaultPluginManager:: |
protected | property | Name of the alter hook if one should be invoked. | |
DefaultPluginManager:: |
protected | property | The cache key. | |
DefaultPluginManager:: |
protected | property | An array of cache tags to use for the cached definitions. | |
DefaultPluginManager:: |
protected | property | An object that implements \Traversable which contains the root paths keyed by the corresponding namespace to look for plugin implementations. | |
DefaultPluginManager:: |
protected | property | The name of the annotation that contains the plugin definition. | |
DefaultPluginManager:: |
protected | property | The subdirectory within a namespace to look for plugins, or FALSE if the plugins are in the top level of the namespace. | |
DefaultPluginManager:: |
protected | function | Invokes the hook to alter the definitions if the alter hook is set. | 1 |
DefaultPluginManager:: |
protected | function | Sets the alter hook name. | |
DefaultPluginManager:: |
public | function |
Clears static and persistent plugin definition caches. Overrides CachedDiscoveryInterface:: |
6 |
DefaultPluginManager:: |
protected | function | Extracts the provider from a plugin definition. | |
DefaultPluginManager:: |
public | function |
The cache contexts associated with this object. Overrides CacheableDependencyInterface:: |
|
DefaultPluginManager:: |
protected | function | Returns the cached plugin definitions of the decorated discovery class. | |
DefaultPluginManager:: |
public | function |
The maximum age for which this object may be cached. Overrides CacheableDependencyInterface:: |
|
DefaultPluginManager:: |
public | function |
The cache tags associated with this object. Overrides CacheableDependencyInterface:: |
|
DefaultPluginManager:: |
public | function |
Gets the definition of all plugins for this type. Overrides DiscoveryTrait:: |
2 |
DefaultPluginManager:: |
protected | function |
Gets the plugin factory. Overrides PluginManagerBase:: |
|
DefaultPluginManager:: |
public | function | Performs extra processing on plugin definitions. | 13 |
DefaultPluginManager:: |
protected | function | Determines if the provider of a definition exists. | 3 |
DefaultPluginManager:: |
public | function | Initialize the cache backend. | |
DefaultPluginManager:: |
protected | function | Sets a cache of plugin definitions for the decorated discovery class. | |
DefaultPluginManager:: |
public | function |
Disable the use of caches. Overrides CachedDiscoveryInterface:: |
1 |
DiscoveryCachedTrait:: |
protected | property | Cached definitions array. | 1 |
DiscoveryCachedTrait:: |
public | function |
Overrides DiscoveryTrait:: |
3 |
DiscoveryTrait:: |
protected | function | Gets a specific plugin definition. | |
DiscoveryTrait:: |
public | function | ||
MigrationPluginManager:: |
protected | property |
Provides default values for migrations. Overrides DefaultPluginManager:: |
|
MigrationPluginManager:: |
protected | property |
The module handler. Overrides DefaultPluginManager:: |
|
MigrationPluginManager:: |
protected | property |
The interface the plugins should implement. Overrides DefaultPluginManager:: |
|
MigrationPluginManager:: |
protected | function | Add one or more dependencies to a graph. | |
MigrationPluginManager:: |
public | function |
Builds a dependency tree for the migrations and set their order. Overrides MigrateBuildDependencyInterface:: |
|
MigrationPluginManager:: |
public | function |
Creates a pre-configured instance of a plugin. Overrides PluginManagerBase:: |
|
MigrationPluginManager:: |
public | function |
Create pre-configured instance of plugin derivatives. Overrides MigrationPluginManagerInterface:: |
|
MigrationPluginManager:: |
public | function |
Create migrations given a tag. Overrides MigrationPluginManagerInterface:: |
|
MigrationPluginManager:: |
public | function |
Creates a stub migration plugin from a definition array. Overrides MigrationPluginManagerInterface:: |
|
MigrationPluginManager:: |
protected | function | Expand derivative migration dependencies. | |
MigrationPluginManager:: |
protected | function |
Finds plugin definitions. Overrides DefaultPluginManager:: |
|
MigrationPluginManager:: |
protected | function |
Gets the plugin discovery. Overrides DefaultPluginManager:: |
|
MigrationPluginManager:: |
public | function |
Construct a migration plugin manager. Overrides DefaultPluginManager:: |
1 |
PluginManagerBase:: |
protected | property | The object that discovers plugins managed by this manager. | |
PluginManagerBase:: |
protected | property | The object that instantiates plugins managed by this manager. | |
PluginManagerBase:: |
protected | property | The object that returns the preconfigured plugin instance appropriate for a particular runtime condition. | |
PluginManagerBase:: |
public | function |
Gets a preconfigured instance of a plugin. Overrides MapperInterface:: |
6 |
PluginManagerBase:: |
protected | function | Allows plugin managers to specify custom behavior if a plugin is not found. | 1 |
UseCacheBackendTrait:: |
protected | property | Cache backend instance. | |
UseCacheBackendTrait:: |
protected | property | Flag whether caches should be used or skipped. | |
UseCacheBackendTrait:: |
protected | function | Fetches from the cache backend, respecting the use caches flag. | |
UseCacheBackendTrait:: |
protected | function | Stores data in the persistent cache, respecting the use caches flag. |