Issue #2845486 by Jo Fitzgerald, quietone, gaurav.kapoor, ohthehugemanatee, heddn, Yogesh Pawar, catch, shabana.navas, phenaproxima, mikeryan: Rename Migration process plugin and add documentation
parent
13e8aca2c8
commit
d15ee7148f
|
|
@ -7,7 +7,7 @@ source:
|
|||
process:
|
||||
iid: iid
|
||||
fid:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_aggregator_feed
|
||||
source: fid
|
||||
title: title
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ source:
|
|||
process:
|
||||
iid: iid
|
||||
fid:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_aggregator_feed
|
||||
source: fid
|
||||
title: title
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ process:
|
|||
id: bid
|
||||
info: info
|
||||
'body/format':
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_filter_format
|
||||
source: format
|
||||
'body/value': body
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ process:
|
|||
id: bid
|
||||
info: info
|
||||
'body/format':
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_filter_format
|
||||
source: format
|
||||
'body/value': body
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ process:
|
|||
method: process
|
||||
source: plid
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_book
|
||||
destination:
|
||||
plugin: book
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ process:
|
|||
# the cid field to allow incremental migrations.
|
||||
cid: cid
|
||||
pid:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_comment
|
||||
source: pid
|
||||
entity_id: nid
|
||||
|
|
@ -32,7 +32,7 @@ process:
|
|||
thread: thread
|
||||
'comment_body/value': comment
|
||||
'comment_body/format':
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_filter_format
|
||||
source: format
|
||||
destination:
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ process:
|
|||
# the cid field to allow incremental migrations.
|
||||
cid: cid
|
||||
pid:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_comment
|
||||
source: pid
|
||||
entity_id: nid
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ process:
|
|||
user_default_enabled: contact_default_status
|
||||
'flood/limit': contact_hourly_threshold
|
||||
default_form:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: contact_category
|
||||
source: default_category
|
||||
destination:
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ process:
|
|||
user_default_enabled: contact_default_status
|
||||
'flood/limit': contact_threshold_limit
|
||||
default_form:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: contact_category
|
||||
source: default_category
|
||||
destination:
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ process:
|
|||
# field migration.
|
||||
field_type_exists:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_field
|
||||
source:
|
||||
- field_name
|
||||
|
|
@ -29,7 +29,7 @@ process:
|
|||
entity_type: 'constants/entity_type'
|
||||
bundle:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_node_type
|
||||
source: type_name
|
||||
-
|
||||
|
|
@ -37,7 +37,7 @@ process:
|
|||
method: row
|
||||
view_mode:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_view_modes
|
||||
source:
|
||||
- view_mode
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ process:
|
|||
# field migration.
|
||||
field_type_exists:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_field
|
||||
source:
|
||||
- field_name
|
||||
|
|
@ -29,7 +29,7 @@ process:
|
|||
field_name: field_name
|
||||
bundle:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_node_type
|
||||
source: type_name
|
||||
-
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ process:
|
|||
# field migration.
|
||||
field_type_exists:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_field
|
||||
source:
|
||||
- field_name
|
||||
|
|
@ -29,7 +29,7 @@ process:
|
|||
method: row
|
||||
bundle:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_node_type
|
||||
source: type_name
|
||||
-
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ process:
|
|||
# field migration.
|
||||
field_type_exists:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_field
|
||||
source:
|
||||
- field_name
|
||||
|
|
@ -29,7 +29,7 @@ process:
|
|||
bundle: bundle
|
||||
view_mode:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_view_modes
|
||||
source:
|
||||
- entity_type
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ process:
|
|||
# field migration.
|
||||
field_type_exists:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_field
|
||||
source:
|
||||
- field_name
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ process:
|
|||
source: upload
|
||||
process:
|
||||
target_id:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_file
|
||||
source: fid
|
||||
display: list
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ process:
|
|||
entity_type: 'constants/entity_type'
|
||||
bundle:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_node_type
|
||||
source: node_type
|
||||
-
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ process:
|
|||
'topics/page_limit': forum_per_page
|
||||
'topics/order': forum_order
|
||||
vocabulary:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_taxonomy_vocabulary
|
||||
source: forum_nav_vocabulary
|
||||
destination:
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ process:
|
|||
'topics/page_limit': forum_per_page
|
||||
'topics/order': forum_order
|
||||
vocabulary:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_taxonomy_vocabulary
|
||||
source: forum_nav_vocabulary
|
||||
destination:
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ process:
|
|||
description: description
|
||||
menu_name:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
# The menu migration is in the system module.
|
||||
migration: d6_menu
|
||||
source: menu_name
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ process:
|
|||
description: description
|
||||
menu_name:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_menu
|
||||
source: menu_name
|
||||
-
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ use Drupal\migrate\Row;
|
|||
* process:
|
||||
* uid:
|
||||
* -
|
||||
* plugin: migration
|
||||
* plugin: migration_lookup
|
||||
* migration: users
|
||||
* source: author
|
||||
* -
|
||||
|
|
|
|||
|
|
@ -2,16 +2,8 @@
|
|||
|
||||
namespace Drupal\migrate\Plugin\migrate\process;
|
||||
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\migrate\MigrateSkipProcessException;
|
||||
use Drupal\migrate\Plugin\MigratePluginManagerInterface;
|
||||
use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
|
||||
use Drupal\migrate\Plugin\MigrateIdMapInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
@trigger_error('The ' . __NAMESPACE__ . '\Migration is deprecated in
|
||||
Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\MigrationLookup', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Calculates the value of a property based on a previous migration.
|
||||
|
|
@ -21,156 +13,8 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
|
|||
* @MigrateProcessPlugin(
|
||||
* id = "migration"
|
||||
* )
|
||||
*
|
||||
* @deprecated in Drupal 8.3.x and will be removed in Drupal 9.0.x.
|
||||
* Use \Drupal\migrate\Plugin\migrate\process\MigrationLookup instead.
|
||||
*/
|
||||
class Migration extends ProcessPluginBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The process plugin manager.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\MigratePluginManager
|
||||
*/
|
||||
protected $processPluginManager;
|
||||
|
||||
/**
|
||||
* The migration plugin manager.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface
|
||||
*/
|
||||
protected $migrationPluginManager;
|
||||
|
||||
/**
|
||||
* The migration to be executed.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\MigrationInterface
|
||||
*/
|
||||
protected $migration;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, MigrationPluginManagerInterface $migration_plugin_manager, MigratePluginManagerInterface $process_plugin_manager) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->migrationPluginManager = $migration_plugin_manager;
|
||||
$this->migration = $migration;
|
||||
$this->processPluginManager = $process_plugin_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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('plugin.manager.migration'),
|
||||
$container->get('plugin.manager.migrate.process')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
$migration_ids = $this->configuration['migration'];
|
||||
if (!is_array($migration_ids)) {
|
||||
$migration_ids = [$migration_ids];
|
||||
}
|
||||
if (!is_array($value)) {
|
||||
$value = [$value];
|
||||
}
|
||||
$this->skipOnEmpty($value);
|
||||
$self = FALSE;
|
||||
/** @var \Drupal\migrate\Plugin\MigrationInterface[] $migrations */
|
||||
$destination_ids = NULL;
|
||||
$source_id_values = [];
|
||||
$migrations = $this->migrationPluginManager->createInstances($migration_ids);
|
||||
foreach ($migrations as $migration_id => $migration) {
|
||||
if ($migration_id == $this->migration->id()) {
|
||||
$self = TRUE;
|
||||
}
|
||||
if (isset($this->configuration['source_ids'][$migration_id])) {
|
||||
$configuration = ['source' => $this->configuration['source_ids'][$migration_id]];
|
||||
$source_id_values[$migration_id] = $this->processPluginManager
|
||||
->createInstance('get', $configuration, $this->migration)
|
||||
->transform(NULL, $migrate_executable, $row, $destination_property);
|
||||
}
|
||||
else {
|
||||
$source_id_values[$migration_id] = $value;
|
||||
}
|
||||
// Break out of the loop as soon as a destination ID is found.
|
||||
if ($destination_ids = $migration->getIdMap()->lookupDestinationId($source_id_values[$migration_id])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$destination_ids && !empty($this->configuration['no_stub'])) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!$destination_ids && ($self || isset($this->configuration['stub_id']) || count($migrations) == 1)) {
|
||||
// If the lookup didn't succeed, figure out which migration will do the
|
||||
// stubbing.
|
||||
if ($self) {
|
||||
$migration = $this->migration;
|
||||
}
|
||||
elseif (isset($this->configuration['stub_id'])) {
|
||||
$migration = $migrations[$this->configuration['stub_id']];
|
||||
}
|
||||
else {
|
||||
$migration = reset($migrations);
|
||||
}
|
||||
$destination_plugin = $migration->getDestinationPlugin(TRUE);
|
||||
// Only keep the process necessary to produce the destination ID.
|
||||
$process = $migration->getProcess();
|
||||
|
||||
// We already have the source ID values but need to key them for the Row
|
||||
// constructor.
|
||||
$source_ids = $migration->getSourcePlugin()->getIds();
|
||||
$values = [];
|
||||
foreach (array_keys($source_ids) as $index => $source_id) {
|
||||
$values[$source_id] = $source_id_values[$migration->id()][$index];
|
||||
}
|
||||
|
||||
$stub_row = new Row($values + $migration->getSourceConfiguration(), $source_ids, TRUE);
|
||||
|
||||
// Do a normal migration with the stub row.
|
||||
$migrate_executable->processRow($stub_row, $process);
|
||||
$destination_ids = [];
|
||||
try {
|
||||
$destination_ids = $destination_plugin->import($stub_row);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$migration->getIdMap()->saveMessage($stub_row->getSourceIdValues(), $e->getMessage());
|
||||
}
|
||||
|
||||
if ($destination_ids) {
|
||||
$migration->getIdMap()->saveIdMapping($stub_row, $destination_ids, MigrateIdMapInterface::STATUS_NEEDS_UPDATE);
|
||||
}
|
||||
}
|
||||
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 FALSE.
|
||||
*
|
||||
* @param mixed $value
|
||||
* The incoming value to transform.
|
||||
*
|
||||
* @throws \Drupal\migrate\MigrateSkipProcessException
|
||||
*/
|
||||
protected function skipOnEmpty(array $value) {
|
||||
if (!array_filter($value)) {
|
||||
throw new MigrateSkipProcessException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
class Migration extends MigrationLookup { }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,260 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\migrate\Plugin\migrate\process;
|
||||
|
||||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
||||
use Drupal\migrate\MigrateSkipProcessException;
|
||||
use Drupal\migrate\Plugin\MigratePluginManagerInterface;
|
||||
use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
|
||||
use Drupal\migrate\Plugin\MigrateIdMapInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\Row;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* 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. If you have
|
||||
* migrated the user accounts in a migration named "users", you would specify
|
||||
* the following:
|
||||
*
|
||||
* @code
|
||||
* process:
|
||||
* uid:
|
||||
* plugin: migration_lookup
|
||||
* migration: users
|
||||
* source: author
|
||||
* @endcode
|
||||
*
|
||||
* This takes the value of the author property in the source data, and looks it
|
||||
* up in the map table associated with the users migration, returning the
|
||||
* resulting user ID and assigning it to the destination uid property.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @code
|
||||
* process:
|
||||
* uid:
|
||||
* plugin: migration_lookup
|
||||
* migration:
|
||||
* - users
|
||||
* - members
|
||||
* source_ids:
|
||||
* users:
|
||||
* - author
|
||||
* members:
|
||||
* - id
|
||||
* @endcode
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
* @code
|
||||
* process:
|
||||
* uid:
|
||||
* plugin: migration_lookup
|
||||
* migration:
|
||||
* - users
|
||||
* - members
|
||||
* stub_id: members
|
||||
* @endcode
|
||||
*
|
||||
* In the above example, the value of stub_id selects the members migration to
|
||||
* create any stub entities.
|
||||
*
|
||||
* To prevent the creation of a stub entity when no relationship is found in the
|
||||
* migration map, use no_stub:
|
||||
*
|
||||
* @code
|
||||
* process:
|
||||
* uid:
|
||||
* plugin: migration_lookup
|
||||
* migration: users
|
||||
* no_stub: true
|
||||
* source: author
|
||||
* @endcode
|
||||
*
|
||||
* @see \Drupal\migrate\Plugin\MigrateProcessInterface
|
||||
*
|
||||
* @MigrateProcessPlugin(
|
||||
* id = "migration_lookup"
|
||||
* )
|
||||
*/
|
||||
class MigrationLookup extends ProcessPluginBase implements ContainerFactoryPluginInterface {
|
||||
|
||||
/**
|
||||
* The process plugin manager.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\MigratePluginManager
|
||||
*/
|
||||
protected $processPluginManager;
|
||||
|
||||
/**
|
||||
* The migration plugin manager.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\MigrationPluginManagerInterface
|
||||
*/
|
||||
protected $migrationPluginManager;
|
||||
|
||||
/**
|
||||
* The migration to be executed.
|
||||
*
|
||||
* @var \Drupal\migrate\Plugin\MigrationInterface
|
||||
*/
|
||||
protected $migration;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, MigrationPluginManagerInterface $migration_plugin_manager, MigratePluginManagerInterface $process_plugin_manager) {
|
||||
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
||||
$this->migrationPluginManager = $migration_plugin_manager;
|
||||
$this->migration = $migration;
|
||||
$this->processPluginManager = $process_plugin_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@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('plugin.manager.migration'),
|
||||
$container->get('plugin.manager.migrate.process')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
$migration_ids = $this->configuration['migration'];
|
||||
if (!is_array($migration_ids)) {
|
||||
$migration_ids = [$migration_ids];
|
||||
}
|
||||
if (!is_array($value)) {
|
||||
$value = [$value];
|
||||
}
|
||||
$this->skipOnEmpty($value);
|
||||
$self = FALSE;
|
||||
/** @var \Drupal\migrate\Plugin\MigrationInterface[] $migrations */
|
||||
$destination_ids = NULL;
|
||||
$source_id_values = [];
|
||||
$migrations = $this->migrationPluginManager->createInstances($migration_ids);
|
||||
foreach ($migrations as $migration_id => $migration) {
|
||||
if ($migration_id == $this->migration->id()) {
|
||||
$self = TRUE;
|
||||
}
|
||||
if (isset($this->configuration['source_ids'][$migration_id])) {
|
||||
$configuration = ['source' => $this->configuration['source_ids'][$migration_id]];
|
||||
$source_id_values[$migration_id] = $this->processPluginManager
|
||||
->createInstance('get', $configuration, $this->migration)
|
||||
->transform(NULL, $migrate_executable, $row, $destination_property);
|
||||
}
|
||||
else {
|
||||
$source_id_values[$migration_id] = $value;
|
||||
}
|
||||
// Break out of the loop as soon as a destination ID is found.
|
||||
if ($destination_ids = $migration->getIdMap()->lookupDestinationId($source_id_values[$migration_id])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$destination_ids && !empty($this->configuration['no_stub'])) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!$destination_ids && ($self || isset($this->configuration['stub_id']) || count($migrations) == 1)) {
|
||||
// If the lookup didn't succeed, figure out which migration will do the
|
||||
// stubbing.
|
||||
if ($self) {
|
||||
$migration = $this->migration;
|
||||
}
|
||||
elseif (isset($this->configuration['stub_id'])) {
|
||||
$migration = $migrations[$this->configuration['stub_id']];
|
||||
}
|
||||
else {
|
||||
$migration = reset($migrations);
|
||||
}
|
||||
$destination_plugin = $migration->getDestinationPlugin(TRUE);
|
||||
// Only keep the process necessary to produce the destination ID.
|
||||
$process = $migration->getProcess();
|
||||
|
||||
// We already have the source ID values but need to key them for the Row
|
||||
// constructor.
|
||||
$source_ids = $migration->getSourcePlugin()->getIds();
|
||||
$values = [];
|
||||
foreach (array_keys($source_ids) as $index => $source_id) {
|
||||
$values[$source_id] = $source_id_values[$migration->id()][$index];
|
||||
}
|
||||
|
||||
$stub_row = new Row($values + $migration->getSourceConfiguration(), $source_ids, TRUE);
|
||||
|
||||
// Do a normal migration with the stub row.
|
||||
$migrate_executable->processRow($stub_row, $process);
|
||||
$destination_ids = [];
|
||||
try {
|
||||
$destination_ids = $destination_plugin->import($stub_row);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
$migration->getIdMap()->saveMessage($stub_row->getSourceIdValues(), $e->getMessage());
|
||||
}
|
||||
|
||||
if ($destination_ids) {
|
||||
$migration->getIdMap()->saveIdMapping($stub_row, $destination_ids, MigrateIdMapInterface::STATUS_NEEDS_UPDATE);
|
||||
}
|
||||
}
|
||||
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 FALSE.
|
||||
*
|
||||
* @param mixed $value
|
||||
* The incoming value to transform.
|
||||
*
|
||||
* @throws \Drupal\migrate\MigrateSkipProcessException
|
||||
*/
|
||||
protected function skipOnEmpty(array $value) {
|
||||
if (!array_filter($value)) {
|
||||
throw new MigrateSkipProcessException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ source:
|
|||
type: external_test
|
||||
process:
|
||||
nid:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
source: name
|
||||
migration: external_translated_test_node
|
||||
type: constants/type
|
||||
|
|
|
|||
|
|
@ -0,0 +1,202 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests\migrate\Unit\process;
|
||||
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\migrate\MigrateSkipProcessException;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
use Drupal\migrate\Plugin\migrate\process\MigrationLookup;
|
||||
use Drupal\migrate\Plugin\MigrateDestinationInterface;
|
||||
use Drupal\migrate\Plugin\MigrateIdMapInterface;
|
||||
use Drupal\migrate\Plugin\MigratePluginManager;
|
||||
use Drupal\migrate\Plugin\MigrateSourceInterface;
|
||||
use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
|
||||
use Prophecy\Argument;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\MigrationLookup
|
||||
* @group migrate
|
||||
*/
|
||||
class MigrationLookupTest extends MigrateProcessTestCase {
|
||||
|
||||
/**
|
||||
* @covers ::transform
|
||||
*/
|
||||
public function testTransformWithStubSkipping() {
|
||||
$migration_plugin = $this->prophesize(MigrationInterface::class);
|
||||
$migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class);
|
||||
$process_plugin_manager = $this->prophesize(MigratePluginManager::class);
|
||||
|
||||
$destination_id_map = $this->prophesize(MigrateIdMapInterface::class);
|
||||
$destination_migration = $this->prophesize(MigrationInterface::class);
|
||||
$destination_migration->getIdMap()->willReturn($destination_id_map->reveal());
|
||||
$destination_id_map->lookupDestinationId([1])->willReturn(NULL);
|
||||
|
||||
// Ensure the migration plugin manager returns our migration.
|
||||
$migration_plugin_manager->createInstances(Argument::exact(['destination_migration']))
|
||||
->willReturn(['destination_migration' => $destination_migration->reveal()]);
|
||||
|
||||
$configuration = [
|
||||
'no_stub' => TRUE,
|
||||
'migration' => 'destination_migration',
|
||||
];
|
||||
|
||||
$migration_plugin->id()->willReturn('actual_migration');
|
||||
$destination_migration->getDestinationPlugin(TRUE)->shouldNotBeCalled();
|
||||
|
||||
$migration = new MigrationLookup($configuration, '', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal());
|
||||
$result = $migration->transform(1, $this->migrateExecutable, $this->row, '');
|
||||
$this->assertNull($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers ::transform
|
||||
*/
|
||||
public function testTransformWithStubbing() {
|
||||
$migration_plugin = $this->prophesize(MigrationInterface::class);
|
||||
$migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class);
|
||||
$process_plugin_manager = $this->prophesize(MigratePluginManager::class);
|
||||
|
||||
$destination_id_map = $this->prophesize(MigrateIdMapInterface::class);
|
||||
$destination_migration = $this->prophesize('Drupal\migrate\Plugin\Migration');
|
||||
$destination_migration->getIdMap()->willReturn($destination_id_map->reveal());
|
||||
$migration_plugin_manager->createInstances(['destination_migration'])
|
||||
->willReturn(['destination_migration' => $destination_migration->reveal()]);
|
||||
$destination_id_map->lookupDestinationId([1])->willReturn(NULL);
|
||||
$destination_id_map->saveIdMapping(Argument::any(), Argument::any(), MigrateIdMapInterface::STATUS_NEEDS_UPDATE)->willReturn(NULL);
|
||||
|
||||
$configuration = [
|
||||
'no_stub' => FALSE,
|
||||
'migration' => 'destination_migration',
|
||||
];
|
||||
|
||||
$migration_plugin->id()->willReturn('actual_migration');
|
||||
$destination_migration->id()->willReturn('destination_migration');
|
||||
$destination_migration->getDestinationPlugin(TRUE)->shouldBeCalled();
|
||||
$destination_migration->getProcess()->willReturn([]);
|
||||
$destination_migration->getSourceConfiguration()->willReturn([]);
|
||||
|
||||
$source_plugin = $this->prophesize(MigrateSourceInterface::class);
|
||||
$source_plugin->getIds()->willReturn(['nid']);
|
||||
$destination_migration->getSourcePlugin()->willReturn($source_plugin->reveal());
|
||||
$destination_plugin = $this->prophesize(MigrateDestinationInterface::class);
|
||||
$destination_plugin->import(Argument::any())->willReturn([2]);
|
||||
$destination_migration->getDestinationPlugin(TRUE)->willReturn($destination_plugin->reveal());
|
||||
|
||||
$migration = new MigrationLookup($configuration, '', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal());
|
||||
$result = $migration->transform(1, $this->migrateExecutable, $this->row, '');
|
||||
$this->assertEquals(2, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that processing is skipped when the input value is empty.
|
||||
*/
|
||||
public function testSkipOnEmpty() {
|
||||
$migration_plugin = $this->prophesize(MigrationInterface::class);
|
||||
$migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class);
|
||||
$process_plugin_manager = $this->prophesize(MigratePluginManager::class);
|
||||
|
||||
$configuration = [
|
||||
'migration' => 'foobaz',
|
||||
];
|
||||
$migration_plugin->id()->willReturn(uniqid());
|
||||
$migration = new MigrationLookup($configuration, 'migration_lookup', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal());
|
||||
$this->setExpectedException(MigrateSkipProcessException::class);
|
||||
$migration->transform(0, $this->migrateExecutable, $this->row, 'foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests a successful lookup.
|
||||
*
|
||||
* @dataProvider successfulLookupDataProvider
|
||||
*
|
||||
* @param array $source_id_values
|
||||
* The source id(s) of the migration map.
|
||||
* @param array $destination_id_values
|
||||
* The destination id(s) of the migration map.
|
||||
* @param string|array $source_value
|
||||
* The source value(s) for the migration process plugin.
|
||||
* @param string|array $expected_value
|
||||
* The expected value(s) of the migration process plugin.
|
||||
*/
|
||||
public function testSuccessfulLookup($source_id_values, $destination_id_values, $source_value, $expected_value) {
|
||||
$migration_plugin = $this->prophesize(MigrationInterface::class);
|
||||
$migration_plugin_manager = $this->prophesize(MigrationPluginManagerInterface::class);
|
||||
$process_plugin_manager = $this->prophesize(MigratePluginManager::class);
|
||||
|
||||
$configuration = [
|
||||
'migration' => 'foobaz',
|
||||
];
|
||||
$migration_plugin->id()->willReturn(uniqid());
|
||||
|
||||
$id_map = $this->prophesize(MigrateIdMapInterface::class);
|
||||
$id_map->lookupDestinationId($source_id_values)->willReturn($destination_id_values);
|
||||
$migration_plugin->getIdMap()->willReturn($id_map->reveal());
|
||||
|
||||
$migration_plugin_manager->createInstances(['foobaz'])
|
||||
->willReturn(['foobaz' => $migration_plugin->reveal()]);
|
||||
|
||||
$migrationStorage = $this->prophesize(EntityStorageInterface::class);
|
||||
$migrationStorage
|
||||
->loadMultiple(['foobaz'])
|
||||
->willReturn([$migration_plugin->reveal()]);
|
||||
|
||||
$migration = new MigrationLookup($configuration, 'migration_lookup', [], $migration_plugin->reveal(), $migration_plugin_manager->reveal(), $process_plugin_manager->reveal());
|
||||
$this->assertSame($expected_value, $migration->transform($source_value, $this->migrateExecutable, $this->row, 'foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides data for the successful lookup test.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function successfulLookupDataProvider() {
|
||||
return [
|
||||
// Test data for scalar to scalar.
|
||||
[
|
||||
// Source ID of the migration map.
|
||||
[1],
|
||||
// Destination ID of the migration map.
|
||||
[3],
|
||||
// Input value for the migration plugin.
|
||||
1,
|
||||
// Expected output value of the migration plugin.
|
||||
3,
|
||||
],
|
||||
// Test data for scalar to array.
|
||||
[
|
||||
// Source ID of the migration map.
|
||||
[1],
|
||||
// Destination IDs of the migration map.
|
||||
[3, 'foo'],
|
||||
// Input value for the migration plugin.
|
||||
1,
|
||||
// Expected output values of the migration plugin.
|
||||
[3, 'foo'],
|
||||
],
|
||||
// Test data for array to scalar.
|
||||
[
|
||||
// Source IDs of the migration map.
|
||||
[1, 3],
|
||||
// Destination ID of the migration map.
|
||||
['foo'],
|
||||
// Input values for the migration plugin.
|
||||
[1, 3],
|
||||
// Expected output value of the migration plugin.
|
||||
'foo',
|
||||
],
|
||||
// Test data for array to array.
|
||||
[
|
||||
// Source IDs of the migration map.
|
||||
[1, 3],
|
||||
// Destination IDs of the migration map.
|
||||
[3, 'foo'],
|
||||
// Input values for the migration plugin.
|
||||
[1, 3],
|
||||
// Expected output values of the migration plugin.
|
||||
[3, 'foo'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
namespace Drupal\Tests\migrate\Unit\process;
|
||||
|
||||
@trigger_error('The ' . __NAMESPACE__ . '\MigrationTest is deprecated in
|
||||
Drupal 8.4.0 and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\MigrationLookupTest', E_USER_DEPRECATED);
|
||||
|
||||
use Drupal\Core\Entity\EntityStorageInterface;
|
||||
use Drupal\migrate\MigrateSkipProcessException;
|
||||
use Drupal\migrate\Plugin\MigrationInterface;
|
||||
|
|
@ -14,6 +17,9 @@ use Drupal\migrate\Plugin\MigrationPluginManagerInterface;
|
|||
use Prophecy\Argument;
|
||||
|
||||
/**
|
||||
* @deprecated in Drupal 8.4.x, to be removed before Drupal 9.0.x. Use
|
||||
* \Drupal\Tests\migrate\Unit\process\MigrationLookupTest instead.
|
||||
*
|
||||
* @coversDefaultClass \Drupal\migrate\Plugin\migrate\process\Migration
|
||||
* @group migrate
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ process:
|
|||
promote: promote
|
||||
sticky: sticky
|
||||
'body/format':
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_filter_format
|
||||
source: format
|
||||
'body/value': body
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ process:
|
|||
promote: promote
|
||||
sticky: sticky
|
||||
'body/format':
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_filter_format
|
||||
source: format
|
||||
'body/value': body
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ process:
|
|||
promote: promote
|
||||
sticky: sticky
|
||||
'body/format':
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_filter_format
|
||||
source: format
|
||||
'body/value': body
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ process:
|
|||
index:
|
||||
- 1
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_node_translation
|
||||
destination:
|
||||
plugin: url_alias
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ process:
|
|||
index:
|
||||
- 1
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_node_translation
|
||||
destination:
|
||||
plugin: url_alias
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ source:
|
|||
uri_scheme: 'internal:/'
|
||||
process:
|
||||
shortcut_set:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_shortcut_set
|
||||
source: menu_name
|
||||
title: link_title
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@ source:
|
|||
process:
|
||||
uid:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_user
|
||||
source: uid
|
||||
-
|
||||
plugin: skip_on_empty
|
||||
method: row
|
||||
set_name:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_shortcut_set
|
||||
source: set_name
|
||||
destination:
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ process:
|
|||
# the tid field to allow incremental migrations.
|
||||
tid: tid
|
||||
vid:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_taxonomy_vocabulary
|
||||
source: vid
|
||||
name: name
|
||||
|
|
@ -22,7 +22,7 @@ process:
|
|||
method: process
|
||||
source: parent
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_taxonomy_term
|
||||
parent:
|
||||
plugin: default_value
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ source:
|
|||
process:
|
||||
nid:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_node
|
||||
source: nid
|
||||
-
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ source:
|
|||
process:
|
||||
vid:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_node
|
||||
source: vid
|
||||
-
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ process:
|
|||
options: 'constants/options'
|
||||
bundle: type
|
||||
field_name:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_taxonomy_vocabulary
|
||||
source: vid
|
||||
destination:
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ process:
|
|||
options/weight: 'constants/options/weight'
|
||||
bundle: type
|
||||
field_name:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_taxonomy_vocabulary
|
||||
source: vid
|
||||
destination:
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ process:
|
|||
type: 'constants/type'
|
||||
field_name:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_taxonomy_vocabulary
|
||||
source: vid
|
||||
-
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ process:
|
|||
bundle: type
|
||||
field_name:
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_taxonomy_vocabulary
|
||||
source: vid
|
||||
-
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ process:
|
|||
# the tid field to allow incremental migrations.
|
||||
tid: tid
|
||||
vid:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_taxonomy_vocabulary
|
||||
source: vid
|
||||
name: name
|
||||
|
|
@ -24,7 +24,7 @@ process:
|
|||
method: process
|
||||
source: parent
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_taxonomy_term
|
||||
parent:
|
||||
plugin: default_value
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ process:
|
|||
name: name
|
||||
weight: weight
|
||||
parent:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: taxonomy_term_stub_test
|
||||
source: parent
|
||||
destination:
|
||||
|
|
|
|||
|
|
@ -32,11 +32,11 @@ process:
|
|||
fallback_to_site_default: true
|
||||
init: init
|
||||
roles:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_user_role
|
||||
source: roles
|
||||
user_picture:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d6_user_picture_file
|
||||
source: uid
|
||||
no_stub: true
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ process:
|
|||
fallback_to_site_default: true
|
||||
init: init
|
||||
roles:
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_user_role
|
||||
source: roles
|
||||
user_picture:
|
||||
|
|
@ -40,7 +40,7 @@ process:
|
|||
source: picture
|
||||
default_value: null
|
||||
-
|
||||
plugin: migration
|
||||
plugin: migration_lookup
|
||||
migration: d7_file
|
||||
destination:
|
||||
plugin: entity:user
|
||||
|
|
|
|||
Loading…
Reference in New Issue