diff --git a/core/modules/migrate/src/Plugin/migrate/process/Concat.php b/core/modules/migrate/src/Plugin/migrate/process/Concat.php index e3323b4..e394147 100644 --- a/core/modules/migrate/src/Plugin/migrate/process/Concat.php +++ b/core/modules/migrate/src/Plugin/migrate/process/Concat.php @@ -16,6 +16,8 @@ * Available configuration keys: * - delimiter: (optional) A delimiter, or glue string, to insert between the * strings. + * - exclude_empty: (optional) If set, empty values will be excluded from the + * output. Defaults to FALSE. * * Examples: * @@ -49,6 +51,38 @@ * and "/" as the delimiter, if the 'foo' property is "wambooli" and the 'bar' * property is "pastafazoul", new_text_field will be "wambooli/pastafazoul". * + * You can also choose to exclude empty values from the output. + * + * @code + * process: + * new_text_field: + * plugin: concat + * source: + * - foo + * - bar + * - oof + * delimiter: / + * @endcode + * + * For example, if the 'foo' property is "wambooli" and the 'bar' property is + * NULL and the 'oof' property is "pastafazoul", with a delimiter of "/", + * new_text_field will be "wambooli//pastafazoul". + * + * @code + * process: + * new_text_field: + * plugin: concat + * source: + * - foo + * - bar + * - oof + * exclude_empty: TRUE + * delimiter: / + * @endcode + * + * While, in the same case, but with exclude_empty set to TRUE, new_text_field + * will be "wambooli/pastafazoul". + * * @see \Drupal\migrate\Plugin\MigrateProcessInterface * * @MigrateProcessPlugin( @@ -64,6 +98,9 @@ class Concat extends ProcessPluginBase { public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { if (is_array($value)) { $delimiter = isset($this->configuration['delimiter']) ? $this->configuration['delimiter'] : ''; + if (!empty($this->configuration['exclude_empty'])) { + $value = array_filter($value); + } return implode($delimiter, $value); } else { diff --git a/core/modules/migrate/tests/src/Unit/process/ConcatTest.php b/core/modules/migrate/tests/src/Unit/process/ConcatTest.php index ea93e46..cce1d71 100644 --- a/core/modules/migrate/tests/src/Unit/process/ConcatTest.php +++ b/core/modules/migrate/tests/src/Unit/process/ConcatTest.php @@ -1,10 +1,5 @@ plugin = new TestConcat(); - parent::setUp(); + public function testConcatWithoutDelimiter($input, $expected, $configuration = []) { + $this->plugin = new Concat($configuration, '', []); + $value = $this->plugin->transform($input, $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->assertSame($expected, $value); } /** - * Test concat works without a delimiter. + * Data provider for testConcatWithoutDelimiter(). */ - public function testConcatWithoutDelimiter() { - $value = $this->plugin->transform(['foo', 'bar'], $this->migrateExecutable, $this->row, 'destinationproperty'); - $this->assertSame($value, 'foobar'); + public function providerConcatWithoutDelimiter() { + return [ + 'no configuration' => [['foo', 'bar'], 'foobar'], + 'with delimiter' => [['foo', 'bar'], 'foo_bar', ['delimiter' => '_']], + 'no delimiter, exclude_empty is true' => [ + ['foo', NULL, 'bar'], + 'foobar', + ['exclude_empty' => TRUE] + ], + 'no delimiter, exclude_empty is false' => [ + ['foo', NULL, 'bar'], + 'foobar', + ['exclude_empty' => FALSE] + ], + 'with delimiter, exclude_empty is true, NULL' => [ + ['foo', NULL, 'bar'], + 'foo_bar', + ['delimiter' => '_', 'exclude_empty' => TRUE] + ], + 'with delimiter, exclude_empty is false, NULL' => [ + ['foo', NULL, 'bar'], + 'foo__bar', + ['delimiter' => '_', 'exclude_empty' => FALSE] + ], + 'with delimiter, exclude_empty is not set, NULL' => [ + ['foo', NULL, 'bar'], + 'foo__bar', + ['delimiter' => '_'] + ], + 'with delimiter, exclude_empty is true, empty string' => [ + ['foo', '', 'bar'], + 'foo_bar', + ['delimiter' => '_', 'exclude_empty' => TRUE] + ], + 'with delimiter, exclude_empty is false, empty string' => [ + ['foo', '', 'bar'], + 'foo__bar', + ['delimiter' => '_', 'exclude_empty' => FALSE] + ], + 'with delimiter, exclude_empty is not set, empty string' => [ + ['foo', '', 'bar'], + 'foo__bar', + ['delimiter' => '_'] + ], + 'with delimiter, exclude_empty is true, zero' => [ + ['foo', 0, 'bar'], + 'foo_0_bar', + ['delimiter' => '_', 'exclude_empty' => TRUE] + ], + 'with delimiter, exclude_empty is true, space' => [ + ['foo', ' ', 'bar'], + 'foo_ _bar', + ['delimiter' => '_', 'exclude_empty' => TRUE] + ], + ]; } /** * Test concat fails properly on non-arrays. */ public function testConcatWithNonArray() { + $this->plugin = new Concat([], '', []); $this->setExpectedException(MigrateException::class); $this->plugin->transform('foo', $this->migrateExecutable, $this->row, 'destinationproperty'); } - /** - * Test concat works without a delimiter. - */ - public function testConcatWithDelimiter() { - $this->plugin->setDelimiter('_'); - $value = $this->plugin->transform(['foo', 'bar'], $this->migrateExecutable, $this->row, 'destinationproperty'); - $this->assertSame($value, 'foo_bar'); - } - -} - -class TestConcat extends Concat { - public function __construct() { - } - - /** - * Set the delimiter. - * - * @param string $delimiter - * The new delimiter. - */ - public function setDelimiter($delimiter) { - $this->configuration['delimiter'] = $delimiter; - } - }