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
|
||||
type: type
|
||||
upload:
|
||||
plugin: iterator
|
||||
plugin: sub_process
|
||||
source: upload
|
||||
process:
|
||||
target_id:
|
||||
|
|
|
@ -11,7 +11,7 @@ process:
|
|||
name: name
|
||||
cache: cache
|
||||
filters:
|
||||
plugin: iterator
|
||||
plugin: sub_process
|
||||
source: filters
|
||||
key: '@id'
|
||||
process:
|
||||
|
|
|
@ -10,7 +10,7 @@ process:
|
|||
cache: cache
|
||||
weight: weight
|
||||
filters:
|
||||
plugin: iterator
|
||||
plugin: sub_process
|
||||
source: filters
|
||||
key: '@id'
|
||||
process:
|
||||
|
|
|
@ -8,7 +8,7 @@ process:
|
|||
name: name
|
||||
label: label
|
||||
effects:
|
||||
plugin: iterator
|
||||
plugin: sub_process
|
||||
source: effects
|
||||
process:
|
||||
id: name
|
||||
|
|
|
@ -2,65 +2,20 @@
|
|||
|
||||
namespace Drupal\migrate\Plugin\migrate\process;
|
||||
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\Row;
|
||||
@trigger_error('The ' . __NAMESPACE__ . '\Iterator is deprecated in
|
||||
Drupal 8.4.x and will be removed before Drupal 9.0.0. Instead, use ' . __NAMESPACE__ . '\SubProcess', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* 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(
|
||||
* id = "iterator",
|
||||
* handle_multiples = TRUE
|
||||
* )
|
||||
*/
|
||||
class Iterator extends ProcessPluginBase {
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
class Iterator extends SubProcess {}
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* @group legacy
|
||||
*/
|
||||
public function testIterator() {
|
||||
$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