diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/Iterator.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/Iterator.php new file mode 100644 index 0000000000000000000000000000000000000000..34206e6677632be0edb9cfb54a9084cc85283338 --- /dev/null +++ b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/Iterator.php @@ -0,0 +1,59 @@ +<?php + +/** + * @file + * Contains \Drupal\migrate\Plugin\migrate\process\Iterator. + */ + +namespace Drupal\migrate\Plugin\migrate\process; + +use Drupal\Core\Plugin\PluginBase; +use Drupal\migrate\MigrateExecutable; +use Drupal\migrate\Plugin\MigrateProcessInterface; +use Drupal\migrate\Row; + +/** + * This plugin iterates and processes an array. + * + * @see https://drupal.org/node/2135345 + * + * @PluginId("iterator") + */ +class Iterator extends PluginBase implements MigrateProcessInterface { + + /** + * Runs a process pipeline on each destination property per list item. + */ + public function transform($value, MigrateExecutable $migrate_executable, Row $row, $destination_property) { + $return = array(); + foreach ($value as $key => $new_value) { + $new_row = new Row($new_value, array()); + $migrate_executable->processRow($new_row, $this->configuration['process']); + $destination = $new_row->getDestination(); + if (array_key_exists('key', $this->configuration)) { + $key = $this->transformKey($key, $migrate_executable, $new_row); + } + $return[$key] = $destination; + } + return $return; + } + + /** + * Runs the process pipeline for the current key. + * + * @param string|int $key + * The current key. + * @param \Drupal\migrate\MigrateExecutable $migrate_executable + * The migrate executable helper class. + * @param \Drupal\migrate\Row $row + * The current row after processing. + * @return mixed + * The transformed key. + */ + protected function transformKey($key, MigrateExecutable $migrate_executable, Row $row) { + $process = array('key' => $this->configuration['key']); + $migrate_executable->processRow($row, $process, $key); + return $row->getDestinationProperty('key'); + } + +} diff --git a/core/modules/migrate/tests/Drupal/migrate/Tests/process/IteratorTest.php b/core/modules/migrate/tests/Drupal/migrate/Tests/process/IteratorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..39aeb545f9c968cbb8a48c3313499fcb43d0571e --- /dev/null +++ b/core/modules/migrate/tests/Drupal/migrate/Tests/process/IteratorTest.php @@ -0,0 +1,101 @@ +<?php +/** + * @file + * Contains Drupal\migrate\Tests\process\IteratorTest. + */ + +namespace Drupal\migrate\Tests\process; + +use Drupal\migrate\MigrateExecutable; +use Drupal\migrate\Plugin\migrate\process\Get; +use Drupal\migrate\Plugin\migrate\process\Iterator; +use Drupal\migrate\Row; +use Drupal\migrate\Tests\MigrateTestCase; + +/** + * Tests the iterator process plugin. + * + * @group migrate + * @group Drupal + */ +class IteratorTest extends MigrateTestCase { + + /** + * The iterator plugin being tested. + * + * @var \Drupal\migrate\Plugin\migrate\process\TestIterator + */ + protected $plugin; + + /** + * @var array + */ + protected $migrationConfiguration = array( + 'id' => 'test', + ); + + /** + * @var bool + */ + protected $mapJoinable = FALSE; + + /** + * {@inheritdoc} + */ + public static function getInfo() { + return array( + 'name' => 'Iterator process plugin', + 'description' => 'Tests the iterator process plugin.', + 'group' => 'Migrate', + ); + } + + /** + * Tests the iterator process plugin. + */ + function testIterator() { + $migration = $this->getMigration(); + // Set up the properties for the iterator. + $configuration = array( + 'process' => array( + 'foo' => 'source_foo', + 'id' => 'source_id', + ), + 'key' => '@id', + ); + $plugin = new Iterator($configuration, 'iterator', array()); + // Manually create the plugins. Migration::getProcessPlugins does this + // normally but the plugin system is not available. + foreach ($configuration['process'] as $destination => $source) { + $iterator_plugins[$destination][] = new Get(array('source' => $source), 'get', array()); + } + $migration->expects($this->at(1)) + ->method('getProcessPlugins') + ->will($this->returnValue($iterator_plugins)); + // Set up the key plugins. + $key_plugin['key'][] = new Get(array('source' => '@id'), 'get', array()); + $migration->expects($this->at(2)) + ->method('getProcessPlugins') + ->will($this->returnValue($key_plugin)); + $migrate_executable = new MigrateExecutable($migration, $this->getMock('Drupal\migrate\MigrateMessageInterface')); + + // The current value of the pipeline. + $current_value = array( + array( + 'source_foo' => 'test', + 'source_id' => 42, + ), + ); + // This is not used but the interface requires it, so create an empty row. + $row = new Row(array(), array()); + + // After transformation, check to make sure that source_foo and source_id's + // values ended up in the proper destinations, and that the value of the + // key (@id) is the same as the destination ID (42). + $new_value = $plugin->transform($current_value, $migrate_executable, $row, 'test'); + $this->assertSame(count($new_value), 1); + $this->assertSame(count($new_value[42]), 2); + $this->assertSame($new_value[42]['foo'], 'test'); + $this->assertSame($new_value[42]['id'], 42); + } +}