class MigrationLookup
Same name in other branches
- 9 core/modules/migrate/src/Plugin/migrate/process/MigrationLookup.php \Drupal\migrate\Plugin\migrate\process\MigrationLookup
- 8.9.x core/modules/migrate/src/Plugin/migrate/process/MigrationLookup.php \Drupal\migrate\Plugin\migrate\process\MigrationLookup
- 11.x core/modules/migrate/src/Plugin/migrate/process/MigrationLookup.php \Drupal\migrate\Plugin\migrate\process\MigrationLookup
Looks up the value of a property based on a previous migration.
It is important to maintain relationships among content coming from the source site. For example, on the source site, a given user account may have an ID of 123, but the Drupal user account created from it may have a uid of 456. The migration process maintains the relationships between source and destination identifiers in map tables, and this information is leveraged by the migration_lookup process plugin.
Available configuration keys
- migration: A single migration ID, or an array of migration IDs.
- source_ids: (optional) An array keyed by migration IDs with values that are a list of source properties.
- stub_id: (optional) Identifies the migration which will be used to create any stub entities.
- no_stub: (optional) Prevents the creation of a stub entity when no relationship is found in the migration map.
Examples:
Consider a node migration, where you want to maintain authorship. Let's assume that users are previously migrated in a migration named 'users'. The 'users' migration saved the mapping between the source and destination IDs in a map table. The node migration example below maps the node 'uid' property so that we first take the source 'author' value and then do a lookup for the corresponding Drupal user ID from the map table.
process:
uid:
plugin: migration_lookup
migration: users
source: author
The value of 'migration' can be a list of migration IDs. When using multiple migrations it is possible each use different source identifiers. In this case one can use source_ids which is an array keyed by the migration IDs and the value is a list of source properties. See example below.
process:
uid:
plugin: migration_lookup
migration:
- users
- members
source_ids:
users:
- author
members:
- id
It's not required to describe source identifiers for each migration. If the source identifier for a migration is not specified, the default source value will be used. In the example below, the 'author' source property will be used to do a lookup in the 'users' migration, and the 'uid' property in the 'members' migration.
process:
uid:
plugin: migration_lookup
source: uid
migration:
- users
- members
source_ids:
users:
- author
If the migration_lookup plugin does not find the source ID in the migration map it will create a stub entity for the relationship to use. This stub is generated by the migration provided. In the case of multiple migrations the first value of the migration list will be used, but you can select the migration you wish to use by using the stub_id configuration key. The example below uses 'members' migration to create stub entities.
process:
uid:
plugin: migration_lookup
migration:
- users
- members
stub_id: members
To prevent the creation of a stub entity when no relationship is found in the migration map, 'no_stub' configuration can be used as shown below.
process:
uid:
plugin: migration_lookup
migration: users
no_stub: true
source: author
If the source value passed in to the plugin is NULL, boolean FALSE, an empty array or an empty string, the plugin will return NULL and stop further processing on the pipeline. This is done for backwards compatibility reasons, and future versions of this plugin should simply return NULL and allow processing to continue.
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements \Drupal\Component\Plugin\PluginInspectionInterface, \Drupal\Component\Plugin\DerivativeInspectionInterface
- class \Drupal\Core\Plugin\PluginBase extends \Drupal\Component\Plugin\PluginBase uses \Drupal\Core\StringTranslation\StringTranslationTrait, \Drupal\Core\DependencyInjection\DependencySerializationTrait, \Drupal\Core\Messenger\MessengerTrait
- class \Drupal\migrate\ProcessPluginBase extends \Drupal\Core\Plugin\PluginBase implements \Drupal\migrate\Plugin\MigrateProcessInterface
- class \Drupal\migrate\Plugin\migrate\process\MigrationLookup extends \Drupal\migrate\ProcessPluginBase implements \Drupal\Core\Plugin\ContainerFactoryPluginInterface
- class \Drupal\migrate\ProcessPluginBase extends \Drupal\Core\Plugin\PluginBase implements \Drupal\migrate\Plugin\MigrateProcessInterface
- class \Drupal\Core\Plugin\PluginBase extends \Drupal\Component\Plugin\PluginBase uses \Drupal\Core\StringTranslation\StringTranslationTrait, \Drupal\Core\DependencyInjection\DependencySerializationTrait, \Drupal\Core\Messenger\MessengerTrait
Expanded class hierarchy of MigrationLookup
See also
https://www.drupal.org/project/drupal/issues/3246666
\Drupal\migrate\Plugin\MigrateProcessInterface
1 file declares its use of MigrationLookup
- MigrationLookupTest.php in core/
modules/ migrate/ tests/ src/ Unit/ process/ MigrationLookupTest.php
File
-
core/
modules/ migrate/ src/ Plugin/ migrate/ process/ MigrationLookup.php, line 125
Namespace
Drupal\migrate\Plugin\migrate\processView source
class MigrationLookup extends ProcessPluginBase implements ContainerFactoryPluginInterface {
/**
* The migration to be executed.
*
* @var \Drupal\migrate\Plugin\MigrationInterface
*/
protected $migration;
/**
* The migrate lookup service.
*
* @var \Drupal\migrate\MigrateLookupInterface
*/
protected $migrateLookup;
/**
* The migrate stub service.
*
* @var \Drupal\migrate\MigrateStubInterface
*/
protected $migrateStub;
/**
* Constructs a MigrationLookup object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\migrate\Plugin\MigrationInterface $migration
* The Migration the plugin is being used in.
* @param \Drupal\migrate\MigrateLookupInterface $migrate_lookup
* The migrate lookup service.
* @param \Drupal\migrate\MigrateStubInterface $migrate_stub
* The migrate stub service.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, MigrateLookupInterface $migrate_lookup, MigrateStubInterface $migrate_stub) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->migration = $migration;
$this->migrateLookup = $migrate_lookup;
$this->migrateStub = $migrate_stub;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, ?MigrationInterface $migration = NULL) {
return new static($configuration, $plugin_id, $plugin_definition, $migration, $container->get('migrate.lookup'), $container->get('migrate.stub'));
}
/**
* {@inheritdoc}
*
* @throws \Drupal\migrate\MigrateException
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
$lookup_migration_ids = (array) $this->configuration['migration'];
$self = FALSE;
$destination_ids = NULL;
$source_id_values = [];
foreach ($lookup_migration_ids as $lookup_migration_id) {
$lookup_value = $value;
if ($lookup_migration_id == $this->migration
->id()) {
$self = TRUE;
}
if (isset($this->configuration['source_ids'][$lookup_migration_id])) {
$lookup_value = array_values($row->getMultiple($this->configuration['source_ids'][$lookup_migration_id]));
}
$lookup_value = (array) $lookup_value;
$this->skipInvalid($lookup_value);
if ($this->isPipelineStopped()) {
return NULL;
}
$source_id_values[$lookup_migration_id] = $lookup_value;
// Re-throw any PluginException as a MigrateException so the executable
// can shut down the migration.
try {
$destination_id_array = $this->migrateLookup
->lookup($lookup_migration_id, $lookup_value);
} catch (PluginNotFoundException $e) {
$destination_id_array = [];
} catch (MigrateException $e) {
throw $e;
} catch (\Exception $e) {
throw new MigrateException(sprintf('A %s was thrown while processing this migration lookup', gettype($e)), $e->getCode(), $e);
}
if ($destination_id_array) {
$destination_ids = array_values(reset($destination_id_array));
break;
}
}
if (!$destination_ids && !empty($this->configuration['no_stub'])) {
return NULL;
}
if (!$destination_ids && ($self || isset($this->configuration['stub_id']) || count($lookup_migration_ids) == 1)) {
// If the lookup didn't succeed, figure out which migration will do the
// stubbing.
if ($self) {
$stub_migration = $this->migration
->id();
}
elseif (isset($this->configuration['stub_id'])) {
$stub_migration = $this->configuration['stub_id'];
}
else {
$stub_migration = reset($lookup_migration_ids);
}
// Rethrow any exception as a MigrateException so the executable can shut
// down the migration.
try {
$destination_ids = $this->migrateStub
->createStub($stub_migration, $source_id_values[$stub_migration], [], FALSE);
} catch (\LogicException $e) {
// For BC reasons, we must allow attempting to stub a derived migration.
} catch (PluginNotFoundException $e) {
// For BC reasons, we must allow attempting to stub a non-existent
// migration.
} catch (MigrateException $e) {
throw $e;
} catch (MigrateSkipRowException $e) {
// Build a new message.
$skip_row_exception_message = $e->getMessage();
if (empty($skip_row_exception_message)) {
$new_message = sprintf("Migration lookup for destination '%s' attempted to create a stub using migration %s, which resulted in a row skip", $destination_property, $stub_migration);
}
else {
$new_message = sprintf("Migration lookup for destination '%s' attempted to create a stub using migration %s, which resulted in a row skip, with message '%s'", $destination_property, $stub_migration, $skip_row_exception_message);
}
throw new MigrateSkipRowException($new_message, 0);
} catch (\Exception $e) {
throw new MigrateException(sprintf('%s was thrown while attempting to stub: %s', get_class($e), $e->getMessage()), $e->getCode(), $e);
}
}
if ($destination_ids) {
if (count($destination_ids) == 1) {
return reset($destination_ids);
}
else {
return $destination_ids;
}
}
}
/**
* Skips the migration process entirely if the value is invalid.
*
* @param array $value
* The incoming value to check.
*/
protected function skipInvalid(array $value) {
if (!array_filter($value, [
$this,
'isValid',
])) {
$this->stopPipeline();
}
}
/**
* Determines if the value is valid for lookup.
*
* The only values considered invalid are: NULL, FALSE, [] and "".
*
* @param string $value
* The value to test.
*
* @return bool
* Return true if the value is valid.
*/
protected function isValid($value) {
return !in_array($value, [
NULL,
FALSE,
[],
"",
], TRUE);
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title | Overrides |
---|---|---|---|---|---|
MigrationLookup::$migrateLookup | protected | property | The migrate lookup service. | ||
MigrationLookup::$migrateStub | protected | property | The migrate stub service. | ||
MigrationLookup::$migration | protected | property | The migration to be executed. | ||
MigrationLookup::create | public static | function | Creates an instance of the plugin. | Overrides ContainerFactoryPluginInterface::create | |
MigrationLookup::isValid | protected | function | Determines if the value is valid for lookup. | ||
MigrationLookup::skipInvalid | protected | function | Skips the migration process entirely if the value is invalid. | ||
MigrationLookup::transform | public | function | Overrides ProcessPluginBase::transform | ||
MigrationLookup::__construct | public | function | Constructs a MigrationLookup object. | ||
PluginInspectionInterface::getPluginDefinition | public | function | Gets the definition of the plugin implementation. | 6 | |
PluginInspectionInterface::getPluginId | public | function | Gets the plugin ID of the plugin instance. | 2 | |
ProcessPluginBase::$stopPipeline | protected | property | Determines if processing of the pipeline is stopped. | ||
ProcessPluginBase::isPipelineStopped | public | function | Determines if the pipeline should stop processing. | Overrides MigrateProcessInterface::isPipelineStopped | |
ProcessPluginBase::multiple | public | function | Indicates whether the returned value requires multiple handling. | Overrides MigrateProcessInterface::multiple | 3 |
ProcessPluginBase::reset | public | function | Resets the internal data of a plugin. | Overrides MigrateProcessInterface::reset | |
ProcessPluginBase::stopPipeline | protected | function | Stops pipeline processing after this plugin finishes. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.