Commit 971c9460 authored by catch's avatar catch

Issue #2684689 by jgrunert, Jo Fitzgerald, heddn, phenaproxima, chx,...

Issue #2684689 by jgrunert, Jo Fitzgerald, heddn, phenaproxima, chx, nevergone, bendeguz.csirmaz, Dylan Donkersgoed, iMiksu, maxocub, Gábor Hojtsy: SubProcess process plugin doesn't support passing context values from source plugin
parent 25807667
......@@ -17,6 +17,13 @@
* - 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.
* - include_source: (optional) If TRUE, all source plugin configuration and
* values will be copied into the sub-processed row in a new property named
* for the source_key configuration value (see below). Defaults to FALSE.
* - source_key: (optional) If include_source is TRUE, this
* is the name of the property of the sub-processed row which will contain
* the source configuration and values. Ignored if include_source is
* FALSE. Defaults to 'source' if no value is provided.
*
* Example 1:
*
......@@ -163,14 +170,38 @@
*/
class SubProcess extends ProcessPluginBase {
/**
* SubProcess constructor.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition) {
$configuration += [
'include_source' => FALSE,
'source_key' => 'source',
];
parent::__construct($configuration, $plugin_id, $plugin_definition);
}
/**
* {@inheritdoc}
*/
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
$return = [];
$return = $source = [];
if ($this->configuration['include_source']) {
$key = $this->configuration['source_key'];
$source[$key] = $row->getSource();
}
if (is_array($value) || $value instanceof \Traversable) {
foreach ($value as $key => $new_value) {
$new_row = new Row($new_value, []);
$new_row = new Row($new_value + $source);
$migrate_executable->processRow($new_row, $this->configuration['process']);
$destination = $new_row->getDestination();
if (array_key_exists('key', $this->configuration)) {
......
......@@ -3,10 +3,12 @@
namespace Drupal\Tests\migrate\Unit\process;
use Drupal\migrate\MigrateExecutable;
use Drupal\migrate\MigrateMessageInterface;
use Drupal\migrate\Plugin\migrate\process\Get;
use Drupal\migrate\Plugin\migrate\process\SubProcess;
use Drupal\migrate\Row;
use Drupal\Tests\migrate\Unit\MigrateTestCase;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
/**
* Tests the sub_process process plugin.
......@@ -31,21 +33,16 @@ class SubProcessTest extends MigrateTestCase {
/**
* Tests the sub_process process plugin.
*
* @dataProvider providerTestSubProcess
*/
public function testSubProcess() {
$migration = $this->getMigration();
public function testSubProcess($process_configuration, $source_values = []) {
$migration = $this->getMigration($process_configuration);
// Set up the properties for the sub_process.
$configuration = [
'process' => [
'foo' => 'source_foo',
'id' => 'source_id',
],
'key' => '@id',
];
$plugin = new SubProcess($configuration, 'sub_process', []);
$plugin = new SubProcess($process_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) {
foreach ($process_configuration['process'] as $destination => $source) {
$sub_process_plugins[$destination][] = new Get(['source' => $source], 'get', []);
}
$migration->expects($this->at(1))
......@@ -56,27 +53,76 @@ public function testSubProcess() {
$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);
$event_dispatcher = $this->getMock(EventDispatcherInterface::class);
$migrate_executable = new MigrateExecutable($migration, $this->getMock(MigrateMessageInterface::class), $event_dispatcher);
// The current value of the pipeline.
$current_value = [
[
'source_foo' => 'test',
'source_id' => 42,
],
] + $source_values,
];
// This is not used but the interface requires it, so create an empty row.
$row = new Row();
$row = new Row($source_values);
// 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(1, count($new_value));
$this->assertSame(2, count($new_value[42]));
$this->assertCount(1, $new_value);
$this->assertCount(count($process_configuration['process']), $new_value[42]);
$this->assertSame('test', $new_value[42]['foo']);
if ($source_values) {
$this->assertSame('source_baz', $new_value[42]['baaa']);
}
$this->assertSame(42, $new_value[42]['id']);
}
/**
* Data provider for testSubProcess().
*/
public function providerTestSubProcess() {
return [
'no source context' => [
'process configuration' => [
'process' => [
'foo' => 'source_foo',
'id' => 'source_id',
],
'key' => '@id',
],
],
'default source key' => [
'process configuration' => [
'process' => [
'foo' => 'source_foo',
'id' => 'source_id',
'baaa' => 'source/baf',
],
'key' => '@id',
'include_source' => TRUE,
],
'source values' => [
'baf' => 'source_baz',
],
],
'renamed source key' => [
'process configuration' => [
'process' => [
'foo' => 'source_foo',
'id' => 'source_id',
'baaa' => 'my_source/baf',
],
'key' => '@id',
'include_source' => TRUE,
'source_key' => 'my_source',
],
'source values' => [
'baf' => 'source_baz',
],
],
];
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment