Issue #2845483 by heddn, holingpoon, Jo Fitzgerald, quietone, phenaproxima, claudiu.cristea: Rename Iterator process plugin and add documentation
parent
3c7a7782e6
commit
8a6aad980d
|
@ -9,7 +9,7 @@ process:
|
||||||
vid: vid
|
vid: vid
|
||||||
type: type
|
type: type
|
||||||
upload:
|
upload:
|
||||||
plugin: iterator
|
plugin: sub_process
|
||||||
source: upload
|
source: upload
|
||||||
process:
|
process:
|
||||||
target_id:
|
target_id:
|
||||||
|
|
|
@ -11,7 +11,7 @@ process:
|
||||||
name: name
|
name: name
|
||||||
cache: cache
|
cache: cache
|
||||||
filters:
|
filters:
|
||||||
plugin: iterator
|
plugin: sub_process
|
||||||
source: filters
|
source: filters
|
||||||
key: '@id'
|
key: '@id'
|
||||||
process:
|
process:
|
||||||
|
|
|
@ -10,7 +10,7 @@ process:
|
||||||
cache: cache
|
cache: cache
|
||||||
weight: weight
|
weight: weight
|
||||||
filters:
|
filters:
|
||||||
plugin: iterator
|
plugin: sub_process
|
||||||
source: filters
|
source: filters
|
||||||
key: '@id'
|
key: '@id'
|
||||||
process:
|
process:
|
||||||
|
|
|
@ -8,7 +8,7 @@ process:
|
||||||
name: name
|
name: name
|
||||||
label: label
|
label: label
|
||||||
effects:
|
effects:
|
||||||
plugin: iterator
|
plugin: sub_process
|
||||||
source: effects
|
source: effects
|
||||||
process:
|
process:
|
||||||
id: name
|
id: name
|
||||||
|
|
|
@ -2,65 +2,20 @@
|
||||||
|
|
||||||
namespace Drupal\migrate\Plugin\migrate\process;
|
namespace Drupal\migrate\Plugin\migrate\process;
|
||||||
|
|
||||||
use Drupal\migrate\ProcessPluginBase;
|
@trigger_error('The ' . __NAMESPACE__ . '\Iterator is deprecated in
|
||||||
use Drupal\migrate\MigrateExecutableInterface;
|
Drupal 8.4.x and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\SubProcess', E_USER_DEPRECATED);
|
||||||
use Drupal\migrate\Row;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This plugin iterates and processes an array.
|
* Iterates and processes an associative array.
|
||||||
*
|
*
|
||||||
* @link https://www.drupal.org/node/2135345 Online handbook documentation for iterator process plugin @endlink
|
* @deprecated in Drupal 8.4.x and will be removed in Drupal 9.0.x. Use
|
||||||
|
* \Drupal\migrate\Plugin\migrate\process\SubProcess instead.
|
||||||
|
*
|
||||||
|
* @see https://www.drupal.org/node/2880427
|
||||||
*
|
*
|
||||||
* @MigrateProcessPlugin(
|
* @MigrateProcessPlugin(
|
||||||
* id = "iterator",
|
* id = "iterator",
|
||||||
* handle_multiples = TRUE
|
* handle_multiples = TRUE
|
||||||
* )
|
* )
|
||||||
*/
|
*/
|
||||||
class Iterator extends ProcessPluginBase {
|
class Iterator extends SubProcess {}
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs a process pipeline on each destination property per list item.
|
|
||||||
*/
|
|
||||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
|
||||||
$return = [];
|
|
||||||
if (!is_null($value)) {
|
|
||||||
foreach ($value as $key => $new_value) {
|
|
||||||
$new_row = new Row($new_value, []);
|
|
||||||
$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\MigrateExecutableInterface $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, MigrateExecutableInterface $migrate_executable, Row $row) {
|
|
||||||
$process = ['key' => $this->configuration['key']];
|
|
||||||
$migrate_executable->processRow($row, $process, $key);
|
|
||||||
return $row->getDestinationProperty('key');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function multiple() {
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,166 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\migrate\Plugin\migrate\process;
|
||||||
|
|
||||||
|
use Drupal\migrate\ProcessPluginBase;
|
||||||
|
use Drupal\migrate\MigrateExecutableInterface;
|
||||||
|
use Drupal\migrate\Row;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs an array of arrays through its own process pipeline.
|
||||||
|
*
|
||||||
|
* The sub_process plugin accepts an array of associative arrays and runs each
|
||||||
|
* one through its own process pipeline, producing a newly keyed associative
|
||||||
|
* array of transformed values.
|
||||||
|
*
|
||||||
|
* Available configuration keys:
|
||||||
|
* - process: the plugin(s) that will process each element of the source.
|
||||||
|
* - key: runs the process pipeline for the key to determine a new dynamic
|
||||||
|
* name.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* source: Array
|
||||||
|
* (
|
||||||
|
* [upload] => Array
|
||||||
|
* (
|
||||||
|
* [0] => Array
|
||||||
|
* (
|
||||||
|
* [fid] => 1
|
||||||
|
* [list] => 0
|
||||||
|
* [description] => "File number 1"
|
||||||
|
* )
|
||||||
|
* [1] => Array
|
||||||
|
* (
|
||||||
|
* [fid] => 2
|
||||||
|
* [list] => 1
|
||||||
|
* [description] => "File number 2"
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* ...
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* The sub_process process plugin will take these arrays one at a time and run
|
||||||
|
* its own process over each one:
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* process:
|
||||||
|
* upload:
|
||||||
|
* plugin: sub_process
|
||||||
|
* source: upload
|
||||||
|
* process:
|
||||||
|
* target_id:
|
||||||
|
* plugin: migration_lookup
|
||||||
|
* migration: d6_file
|
||||||
|
* source: fid
|
||||||
|
* display: list
|
||||||
|
* description: description
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* In this case, each item in the upload array will be processed by the
|
||||||
|
* sub_process process plugin. The target_id will be found by looking up the
|
||||||
|
* destination value from a previous migration. The display and description
|
||||||
|
* fields will simply be mapped.
|
||||||
|
*
|
||||||
|
* In the next example, normally the array returned from sub_process will have
|
||||||
|
* its original keys. If you need to change the key, it is possible for the
|
||||||
|
* returned array to be keyed by one of the transformed values in the sub-array.
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* source: Array
|
||||||
|
* (
|
||||||
|
* [format] => 1
|
||||||
|
* [name] => Filtered HTML
|
||||||
|
* ...
|
||||||
|
* [filters] => Array
|
||||||
|
* (
|
||||||
|
* [0] => Array
|
||||||
|
* (
|
||||||
|
* [module] => filter
|
||||||
|
* [delta] => 2
|
||||||
|
* [weight] => 0
|
||||||
|
* )
|
||||||
|
* [1] => Array
|
||||||
|
* (
|
||||||
|
* [module] => filter
|
||||||
|
* [delta] => 0
|
||||||
|
* [weight] => 1
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* )
|
||||||
|
* ...
|
||||||
|
*
|
||||||
|
* process:
|
||||||
|
* filters:
|
||||||
|
* plugin: iterator
|
||||||
|
* source: filters
|
||||||
|
* key: "@id"
|
||||||
|
* process:
|
||||||
|
* id:
|
||||||
|
* plugin: concat
|
||||||
|
* source:
|
||||||
|
* - module
|
||||||
|
* - delta
|
||||||
|
* delimiter: _
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* In the above example, the keys of the returned array would be filter_2 and
|
||||||
|
* filter_0
|
||||||
|
*
|
||||||
|
* @see \Drupal\migrate\Plugin\MigrateProcessInterface
|
||||||
|
*
|
||||||
|
* @MigrateProcessPlugin(
|
||||||
|
* id = "sub_process",
|
||||||
|
* handle_multiples = TRUE
|
||||||
|
* )
|
||||||
|
*/
|
||||||
|
class SubProcess extends ProcessPluginBase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||||
|
$return = [];
|
||||||
|
if (is_array($value) || $value instanceof \Traversable) {
|
||||||
|
foreach ($value as $key => $new_value) {
|
||||||
|
$new_row = new Row($new_value, []);
|
||||||
|
$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 key to determine its dynamic name.
|
||||||
|
*
|
||||||
|
* @param string|int $key
|
||||||
|
* The current key.
|
||||||
|
* @param \Drupal\migrate\MigrateExecutableInterface $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, MigrateExecutableInterface $migrate_executable, Row $row) {
|
||||||
|
$process = ['key' => $this->configuration['key']];
|
||||||
|
$migrate_executable->processRow($row, $process, $key);
|
||||||
|
return $row->getDestinationProperty('key');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function multiple() {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -31,6 +31,8 @@ class IteratorTest extends MigrateTestCase {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests the iterator process plugin.
|
* Tests the iterator process plugin.
|
||||||
|
*
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testIterator() {
|
public function testIterator() {
|
||||||
$migration = $this->getMigration();
|
$migration = $this->getMigration();
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Drupal\Tests\migrate\Unit\process;
|
||||||
|
|
||||||
|
use Drupal\migrate\MigrateExecutable;
|
||||||
|
use Drupal\migrate\Plugin\migrate\process\Get;
|
||||||
|
use Drupal\migrate\Plugin\migrate\process\SubProcess;
|
||||||
|
use Drupal\migrate\Row;
|
||||||
|
use Drupal\Tests\migrate\Unit\MigrateTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the sub_process process plugin.
|
||||||
|
*
|
||||||
|
* @group migrate
|
||||||
|
*/
|
||||||
|
class SubProcessTest extends MigrateTestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The sub_process plugin being tested.
|
||||||
|
*
|
||||||
|
* @var \Drupal\migrate\Plugin\migrate\process\SubProcess
|
||||||
|
*/
|
||||||
|
protected $plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $migrationConfiguration = [
|
||||||
|
'id' => 'test',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the sub_process process plugin.
|
||||||
|
*/
|
||||||
|
public function testSubProcess() {
|
||||||
|
$migration = $this->getMigration();
|
||||||
|
// Set up the properties for the sub_process.
|
||||||
|
$configuration = [
|
||||||
|
'process' => [
|
||||||
|
'foo' => 'source_foo',
|
||||||
|
'id' => 'source_id',
|
||||||
|
],
|
||||||
|
'key' => '@id',
|
||||||
|
];
|
||||||
|
$plugin = new SubProcess($configuration, 'sub_process', []);
|
||||||
|
// Manually create the plugins. Migration::getProcessPlugins does this
|
||||||
|
// normally but the plugin system is not available.
|
||||||
|
foreach ($configuration['process'] as $destination => $source) {
|
||||||
|
$sub_process_plugins[$destination][] = new Get(['source' => $source], 'get', []);
|
||||||
|
}
|
||||||
|
$migration->expects($this->at(1))
|
||||||
|
->method('getProcessPlugins')
|
||||||
|
->willReturn($sub_process_plugins);
|
||||||
|
// Set up the key plugins.
|
||||||
|
$key_plugin['key'][] = new Get(['source' => '@id'], 'get', []);
|
||||||
|
$migration->expects($this->at(2))
|
||||||
|
->method('getProcessPlugins')
|
||||||
|
->will($this->returnValue($key_plugin));
|
||||||
|
$event_dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
|
||||||
|
$migrate_executable = new MigrateExecutable($migration, $this->getMock('Drupal\migrate\MigrateMessageInterface'), $event_dispatcher);
|
||||||
|
|
||||||
|
// The current value of the pipeline.
|
||||||
|
$current_value = [
|
||||||
|
[
|
||||||
|
'source_foo' => 'test',
|
||||||
|
'source_id' => 42,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
// This is not used but the interface requires it, so create an empty row.
|
||||||
|
$row = new Row();
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue