Loading README.txt +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ Migrate Condition plugins * greater_than * has_element ("helper" condition to change handling of arrays) * in_array * in_migrate_map * is_null * is_stub * isset Loading src/Plugin/migrate_conditions/condition/InMigrateMap.php 0 → 100644 +139 −0 Original line number Diff line number Diff line <?php namespace Drupal\migrate_conditions\Plugin\migrate_conditions\condition; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\migrate\MigrateLookupInterface; use Drupal\migrate\Plugin\MigrationPluginManagerInterface; use Drupal\migrate\Row; use Drupal\migrate_conditions\Plugin\ConditionBase; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides an 'in_migrate_map' condition. * * This functions similarly to the migration_lookup process plugin with a * couple notable differences. First, this is a migrate_condition plugin, so * it returns a boolean rather than destination ids. Second, this plugin will * never create stubs and as such there is not a no_stub option. Third, the * treatment of skipped rows is configurable through the include_skipped * property. * * Available configuration keys: * - migration: The migration id or array of migration ids against which to do * a lookup. * - include_skipped: (optional) If TRUE, a source is considered to be in the * map even the row has been skipped and the destination ids are null. * Defaults to FALSE. * - negate: (optional) Whether the 'in_migrate_map' condition should be * negated. Defaults to FALSE. You can also negate the 'in_migrate_map' * plugin by using 'not:in_migrate_map' as the plugin id. * * Examples: * * Skip the row if a value is in a certain migrate map. * * @code * process: * _skip_if_in_other_migration: * plugin: skip_on_condition * method: row * source: my_source_value * condition: * plugin: in_migrate_map * migrate: some_other_migration * @endcode * * or equivalently * * @code * process: * _skip_if_in_other_migration: * plugin: skip_on_condition * method: row * source: my_source_value * condition: in_migrate_map(some_other_migration) * @endcode * * @MigrateConditionsConditionPlugin( * id = "in_migrate_map", * requires = {"migration"}, * parens = "migration" * ) */ class InMigrateMap extends ConditionBase implements ContainerFactoryPluginInterface { /** * The migrate lookup service. * * @var \Drupal\migrate\MigrateLookupInterface */ protected $migrateLookup; /** * InMigrateMap constructor. * * @param array $configuration * A configuration array containing information about the plugin instance. * @param string $plugin_id * The plugin ID. * @param mixed $plugin_definition * The plugin implementation definition. * @param Drupal\migrate\MigrateLookupInterface $migrate_lookup * The migrate lookup service. * @param Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager * The migration plugin manager. */ public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrateLookupInterface $migrate_lookup, MigrationPluginManagerInterface $migration_plugin_manager) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->configuration['include_skipped'] = $configuration['include_skipped'] ?? FALSE; $this->configuration['migration'] = (array) $configuration['migration']; foreach ($this->configuration['migration'] as $migration_id) { $migration = $migration_plugin_manager->createInstance($migration_id); if (empty($migration)) { throw new \InvalidArgumentException('The migration configured for in_migrate_map could not be loaded: ' . $migration_id); } } $this->migrateLookup = $migrate_lookup; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('migrate.lookup'), $container->get('plugin.manager.migration') ); } /** * {@inheritdoc} */ protected function doEvaluate($source, Row $row) { $lookup = $this->migrateLookup->lookup($this->configuration['migration'], (array) $source); // If the source was not found, an empty array is returned. if (empty($lookup)) { return FALSE; } // If the source was found but the row was skipped, the lookup // will be an array of arrays containing at least one NULL id. if ($this->configuration['include_skipped'] === TRUE) { return TRUE; } else { foreach ($lookup as $ids) { foreach ($ids as $id) { if (is_null($id)) { return FALSE; } } } return TRUE; } } } tests/modules/migrate_conditions_test_migrations/migrate_conditions_test_migrations.info.yml 0 → 100644 +7 −0 Original line number Diff line number Diff line name: 'Migreate Conditions Test Migrations' type: module description: 'Provides test migrations to test migrate_conditions.' package: Testing version: VERSION dependencies: - migrate_conditions:migrate_conditions tests/modules/migrate_conditions_test_migrations/migrations/in_migrate_map_test.yml 0 → 100644 +53 −0 Original line number Diff line number Diff line id: in_migrate_map_test label: "InMigrateMap Test" source: plugin: embedded_data data_rows: - id: 17 lookup: 25 - id: 25 lookup: 17 - id: 33 lookup: 33 - id: 13 lookup: 123 - id: 44 lookup: 13 ids: id: type: integer process: # This skip is so we can show what happens when a row is in the map but skipped. _skip_13: plugin: skip_on_condition method: row condition: equals(13) source: id found: plugin: evaluate_condition source: lookup condition: plugin: in_migrate_map migration: in_migrate_map_test not_found: plugin: evaluate_condition source: lookup condition: not:in_migrate_map(in_migrate_map_test) found_include_skipped: plugin: evaluate_condition source: lookup condition: plugin: in_migrate_map migration: in_migrate_map_test include_skipped: true title: plugin: concat delimiter: '-' source: - id - '@found' - '@not_found' - '@found_include_skipped' destination: plugin: entity:node default_bundle: node_lookup tests/src/Kernel/condition/InMigrateMapTest.php 0 → 100644 +77 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\migrate_conditions\Kernel\condition; use Drupal\KernelTests\KernelTestBase; use Drupal\migrate\MigrateExecutable; use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate_conditions\Plugin\migrate_conditions\condition\InMigrateMap; use Drupal\node\Entity\Node; use Drupal\Tests\node\Traits\ContentTypeCreationTrait; /** * Tests the in_migrate_map condition plugin. * * @group migrate_conditions */ class InMigrateMapTest extends KernelTestBase { use ContentTypeCreationTrait; /** * {@inheritdoc} */ protected static $modules = [ 'system', 'node', 'field', 'user', 'text', 'migrate', 'migrate_conditions', 'migrate_conditions_test_migrations', ]; /** * {@inheritdoc} */ public function setUp(): void { parent::setUp(); $this->installEntitySchema('node'); $this->installEntitySchema('user'); $this->installConfig(['node', 'user']); $this->createContentType(['type' => 'node_lookup']); } /** * Tests validation in constructor. */ public function testConstructor() { $configuration = []; $plugin_definition = \Drupal::service('plugin.manager.migrate_conditions.condition')->getDefinition('in_migrate_map'); $lookup = \Drupal::service('migrate.lookup'); $manager = \Drupal::service('plugin.manager.migration'); $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('The migration configuration is required when using the in_migrate_map condition.'); $condition = new InMigrateMap($configuration, 'in_migrate_map', $plugin_definition, $lookup, $manager); } /** * Tests in_migrate_map condition plugin. */ public function testInMigrateMap() { $manager = \Drupal::service('plugin.manager.migration'); $migration = $manager->createInstance('in_migrate_map_test'); $executable = new MigrateExecutable($migration); $result = $executable->import(); $this->assertSame(MigrationInterface::RESULT_COMPLETED, $result); $expected = '17--1-'; $this->assertEquals($expected, Node::load(1)->label()); $expected = '25-1--1'; $this->assertEquals($expected, Node::load(2)->label()); $expected = '33--1-'; $this->assertEquals($expected, Node::load(3)->label()); $expected = '44--1-1'; $this->assertEquals($expected, Node::load(4)->label()); } } Loading
README.txt +1 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ Migrate Condition plugins * greater_than * has_element ("helper" condition to change handling of arrays) * in_array * in_migrate_map * is_null * is_stub * isset Loading
src/Plugin/migrate_conditions/condition/InMigrateMap.php 0 → 100644 +139 −0 Original line number Diff line number Diff line <?php namespace Drupal\migrate_conditions\Plugin\migrate_conditions\condition; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\migrate\MigrateLookupInterface; use Drupal\migrate\Plugin\MigrationPluginManagerInterface; use Drupal\migrate\Row; use Drupal\migrate_conditions\Plugin\ConditionBase; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides an 'in_migrate_map' condition. * * This functions similarly to the migration_lookup process plugin with a * couple notable differences. First, this is a migrate_condition plugin, so * it returns a boolean rather than destination ids. Second, this plugin will * never create stubs and as such there is not a no_stub option. Third, the * treatment of skipped rows is configurable through the include_skipped * property. * * Available configuration keys: * - migration: The migration id or array of migration ids against which to do * a lookup. * - include_skipped: (optional) If TRUE, a source is considered to be in the * map even the row has been skipped and the destination ids are null. * Defaults to FALSE. * - negate: (optional) Whether the 'in_migrate_map' condition should be * negated. Defaults to FALSE. You can also negate the 'in_migrate_map' * plugin by using 'not:in_migrate_map' as the plugin id. * * Examples: * * Skip the row if a value is in a certain migrate map. * * @code * process: * _skip_if_in_other_migration: * plugin: skip_on_condition * method: row * source: my_source_value * condition: * plugin: in_migrate_map * migrate: some_other_migration * @endcode * * or equivalently * * @code * process: * _skip_if_in_other_migration: * plugin: skip_on_condition * method: row * source: my_source_value * condition: in_migrate_map(some_other_migration) * @endcode * * @MigrateConditionsConditionPlugin( * id = "in_migrate_map", * requires = {"migration"}, * parens = "migration" * ) */ class InMigrateMap extends ConditionBase implements ContainerFactoryPluginInterface { /** * The migrate lookup service. * * @var \Drupal\migrate\MigrateLookupInterface */ protected $migrateLookup; /** * InMigrateMap constructor. * * @param array $configuration * A configuration array containing information about the plugin instance. * @param string $plugin_id * The plugin ID. * @param mixed $plugin_definition * The plugin implementation definition. * @param Drupal\migrate\MigrateLookupInterface $migrate_lookup * The migrate lookup service. * @param Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager * The migration plugin manager. */ public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrateLookupInterface $migrate_lookup, MigrationPluginManagerInterface $migration_plugin_manager) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->configuration['include_skipped'] = $configuration['include_skipped'] ?? FALSE; $this->configuration['migration'] = (array) $configuration['migration']; foreach ($this->configuration['migration'] as $migration_id) { $migration = $migration_plugin_manager->createInstance($migration_id); if (empty($migration)) { throw new \InvalidArgumentException('The migration configured for in_migrate_map could not be loaded: ' . $migration_id); } } $this->migrateLookup = $migrate_lookup; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('migrate.lookup'), $container->get('plugin.manager.migration') ); } /** * {@inheritdoc} */ protected function doEvaluate($source, Row $row) { $lookup = $this->migrateLookup->lookup($this->configuration['migration'], (array) $source); // If the source was not found, an empty array is returned. if (empty($lookup)) { return FALSE; } // If the source was found but the row was skipped, the lookup // will be an array of arrays containing at least one NULL id. if ($this->configuration['include_skipped'] === TRUE) { return TRUE; } else { foreach ($lookup as $ids) { foreach ($ids as $id) { if (is_null($id)) { return FALSE; } } } return TRUE; } } }
tests/modules/migrate_conditions_test_migrations/migrate_conditions_test_migrations.info.yml 0 → 100644 +7 −0 Original line number Diff line number Diff line name: 'Migreate Conditions Test Migrations' type: module description: 'Provides test migrations to test migrate_conditions.' package: Testing version: VERSION dependencies: - migrate_conditions:migrate_conditions
tests/modules/migrate_conditions_test_migrations/migrations/in_migrate_map_test.yml 0 → 100644 +53 −0 Original line number Diff line number Diff line id: in_migrate_map_test label: "InMigrateMap Test" source: plugin: embedded_data data_rows: - id: 17 lookup: 25 - id: 25 lookup: 17 - id: 33 lookup: 33 - id: 13 lookup: 123 - id: 44 lookup: 13 ids: id: type: integer process: # This skip is so we can show what happens when a row is in the map but skipped. _skip_13: plugin: skip_on_condition method: row condition: equals(13) source: id found: plugin: evaluate_condition source: lookup condition: plugin: in_migrate_map migration: in_migrate_map_test not_found: plugin: evaluate_condition source: lookup condition: not:in_migrate_map(in_migrate_map_test) found_include_skipped: plugin: evaluate_condition source: lookup condition: plugin: in_migrate_map migration: in_migrate_map_test include_skipped: true title: plugin: concat delimiter: '-' source: - id - '@found' - '@not_found' - '@found_include_skipped' destination: plugin: entity:node default_bundle: node_lookup
tests/src/Kernel/condition/InMigrateMapTest.php 0 → 100644 +77 −0 Original line number Diff line number Diff line <?php namespace Drupal\Tests\migrate_conditions\Kernel\condition; use Drupal\KernelTests\KernelTestBase; use Drupal\migrate\MigrateExecutable; use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate_conditions\Plugin\migrate_conditions\condition\InMigrateMap; use Drupal\node\Entity\Node; use Drupal\Tests\node\Traits\ContentTypeCreationTrait; /** * Tests the in_migrate_map condition plugin. * * @group migrate_conditions */ class InMigrateMapTest extends KernelTestBase { use ContentTypeCreationTrait; /** * {@inheritdoc} */ protected static $modules = [ 'system', 'node', 'field', 'user', 'text', 'migrate', 'migrate_conditions', 'migrate_conditions_test_migrations', ]; /** * {@inheritdoc} */ public function setUp(): void { parent::setUp(); $this->installEntitySchema('node'); $this->installEntitySchema('user'); $this->installConfig(['node', 'user']); $this->createContentType(['type' => 'node_lookup']); } /** * Tests validation in constructor. */ public function testConstructor() { $configuration = []; $plugin_definition = \Drupal::service('plugin.manager.migrate_conditions.condition')->getDefinition('in_migrate_map'); $lookup = \Drupal::service('migrate.lookup'); $manager = \Drupal::service('plugin.manager.migration'); $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('The migration configuration is required when using the in_migrate_map condition.'); $condition = new InMigrateMap($configuration, 'in_migrate_map', $plugin_definition, $lookup, $manager); } /** * Tests in_migrate_map condition plugin. */ public function testInMigrateMap() { $manager = \Drupal::service('plugin.manager.migration'); $migration = $manager->createInstance('in_migrate_map_test'); $executable = new MigrateExecutable($migration); $result = $executable->import(); $this->assertSame(MigrationInterface::RESULT_COMPLETED, $result); $expected = '17--1-'; $this->assertEquals($expected, Node::load(1)->label()); $expected = '25-1--1'; $this->assertEquals($expected, Node::load(2)->label()); $expected = '33--1-'; $this->assertEquals($expected, Node::load(3)->label()); $expected = '44--1-1'; $this->assertEquals($expected, Node::load(4)->label()); } }