From 28a69ab3d511379ae48ce2b65fe91e8a7d9827c5 Mon Sep 17 00:00:00 2001
From: lucashedding <lucashedding@1463982.no-reply.drupal.org>
Date: Wed, 30 May 2018 11:51:21 -0600
Subject: [PATCH] Issue #2901617 by jigarius, heddn, vasi: Treating arrays as
 single or multiple values

---
 src/Plugin/migrate/process/MultipleValues.php | 58 +++++++++++++++++++
 src/Plugin/migrate/process/SingleValue.php    | 45 ++++++++++++++
 tests/src/Unit/process/MultipleValuesTest.php | 32 ++++++++++
 tests/src/Unit/process/SingleValueTest.php    | 32 ++++++++++
 4 files changed, 167 insertions(+)
 create mode 100644 src/Plugin/migrate/process/MultipleValues.php
 create mode 100644 src/Plugin/migrate/process/SingleValue.php
 create mode 100644 tests/src/Unit/process/MultipleValuesTest.php
 create mode 100644 tests/src/Unit/process/SingleValueTest.php

diff --git a/src/Plugin/migrate/process/MultipleValues.php b/src/Plugin/migrate/process/MultipleValues.php
new file mode 100644
index 00000000..be6779a1
--- /dev/null
+++ b/src/Plugin/migrate/process/MultipleValues.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Drupal\migrate_plus\Plugin\migrate\process;
+
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\Row;
+
+/**
+ * Treat an array of values as a separate / individual values.
+ *
+ * @code
+ * process:
+ *   field_authors:
+ *     -
+ *       plugin: explode
+ *       delimiter: ', '
+ *       source: authors
+ *     -
+ *       plugin: single_value
+ *     -
+ *       plugin: callback
+ *       callable: custom_sort_authors
+ *     -
+ *       plugin: multiple_values
+ * @endcode
+ *
+ * Assume the "authors" field contains comma separated author names.
+ *
+ * We split the names into multiple values and then use the "single_value"
+ * plugin to treat them as a single array of author names. After that, we
+ * pass the values through a custom sort. Callback multiple setting is false. To
+ * convert from a single value to multiple, use the "multiple_values" plugin. It
+ * will make the next plugin treat the values individually instead of an array
+ * of values.
+ *
+ * @MigrateProcessPlugin(
+ *   id = "multiple_values",
+ *   handle_multiples = TRUE
+ * )
+ */
+class MultipleValues extends ProcessPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    return $value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function multiple() {
+    return TRUE;
+  }
+
+}
diff --git a/src/Plugin/migrate/process/SingleValue.php b/src/Plugin/migrate/process/SingleValue.php
new file mode 100644
index 00000000..2583a902
--- /dev/null
+++ b/src/Plugin/migrate/process/SingleValue.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Drupal\migrate_plus\Plugin\migrate\process;
+
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\ProcessPluginBase;
+use Drupal\migrate\Row;
+
+/**
+ * Treat an array of values as a single value.
+ *
+ * @code
+ * process:
+ *   field_authors:
+ *     -
+ *       plugin: explode
+ *       delimiter: ', '
+ *       source: authors
+ *     -
+ *       plugin: single_value
+ * @endcode
+ *
+ * Assume the "authors" field contains comma separated author names.
+ *
+ * After the explode, we end up with each author name as an individual value.
+ * But if we want to perform a sort on all values using a callback, we will
+ * need to send all the values to a callable together as an array of author
+ * names. Calling the "single_value" plugin in such a case will combine all the
+ * values into a single array for the next plugin.
+ *
+ * @MigrateProcessPlugin(
+ *   id = "single_value",
+ *   handle_multiples = TRUE
+ * )
+ */
+class SingleValue extends ProcessPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    return $value;
+  }
+
+}
diff --git a/tests/src/Unit/process/MultipleValuesTest.php b/tests/src/Unit/process/MultipleValuesTest.php
new file mode 100644
index 00000000..60a520c0
--- /dev/null
+++ b/tests/src/Unit/process/MultipleValuesTest.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Drupal\Tests\migrate_plus\Unit\process;
+
+use Drupal\Tests\migrate\Unit\process\MigrateProcessTestCase;
+use Drupal\migrate_plus\Plugin\migrate\process\MultipleValues;
+
+/**
+ * @coversDefaultClass \Drupal\migrate_plus\Plugin\migrate\process\MultipleValues
+ * @group migrate
+ */
+class MultipleValuesTest extends MigrateProcessTestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    $this->plugin = new MultipleValues([], 'multiple_values', []);
+    parent::setUp();
+  }
+
+  /**
+   * Test input treated as multiple value output.
+   */
+  public function testTreatAsMultiple() {
+    $value = ['v1', 'v2', 'v3'];
+    $output = $this->plugin->transform($value, $this->migrateExecutable, $this->row, 'destinationproperty');
+    $this->assertSame($output, $value);
+    $this->assertTrue($this->plugin->multiple());
+  }
+
+}
diff --git a/tests/src/Unit/process/SingleValueTest.php b/tests/src/Unit/process/SingleValueTest.php
new file mode 100644
index 00000000..203b1c5c
--- /dev/null
+++ b/tests/src/Unit/process/SingleValueTest.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Drupal\Tests\migrate_plus\Unit\process;
+
+use Drupal\Tests\migrate\Unit\process\MigrateProcessTestCase;
+use Drupal\migrate_plus\Plugin\migrate\process\SingleValue;
+
+/**
+ * @coversDefaultClass \Drupal\migrate_plus\Plugin\migrate\process\SingleValue
+ * @group migrate
+ */
+class SingleValueTest extends MigrateProcessTestCase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    $this->plugin = new SingleValue([], 'single_value', []);
+    parent::setUp();
+  }
+
+  /**
+   * Test input treated as single value output.
+   */
+  public function testTreatAsSingle() {
+    $value = ['v1', 'v2', 'v3'];
+    $output = $this->plugin->transform($value, $this->migrateExecutable, $this->row, 'destinationproperty');
+    $this->assertSame($output, $value);
+    $this->assertFalse($this->plugin->multiple());
+  }
+
+}
-- 
GitLab