From 4ae3d425e777699adcb328ede1071d3f5721184e Mon Sep 17 00:00:00 2001
From: Kristiaan Van den Eynde <kristiaan@factorial.io>
Date: Wed, 10 Apr 2019 11:23:40 +0200
Subject: [PATCH] Issue #2882276 by kristiaanvandeneynde, nuez, osopolar:
 Extended callback process plugin to call functions with multiple parameters

---
 src/Plugin/migrate/process/CallbackArray.php | 89 ++++++++++++++++++++
 1 file changed, 89 insertions(+)
 create mode 100644 src/Plugin/migrate/process/CallbackArray.php

diff --git a/src/Plugin/migrate/process/CallbackArray.php b/src/Plugin/migrate/process/CallbackArray.php
new file mode 100644
index 0000000..e4f89c2
--- /dev/null
+++ b/src/Plugin/migrate/process/CallbackArray.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace Drupal\migrate_plus\Plugin\migrate\process;
+
+use Drupal\migrate\MigrateExecutableInterface;
+use Drupal\migrate\Plugin\migrate\process\Callback;
+use Drupal\migrate\Row;
+
+/**
+ * Passes the source value with additional parameters to a callback.
+ *
+ * This calls call_user_func_array() with the source value and additional
+ * parameters, whereas the original Callback plugin only calls call_user_func()
+ * with the source value.
+ *
+ * Example:
+ *
+ * @code
+ * process:
+ *   destination_field:
+ *     plugin: callback_array
+ *     callable: rtrim
+ *     source: source_field
+ *     parameters:
+ *       - '/'
+ * @endcode
+ *
+ * This will end up calling:
+ *
+ * @code
+ *   rtrim('SOURCE_VALUE', '/');
+ * @endcode
+ *
+ * You can choose which parameter is passed the source value by specifying the
+ * source_index configuration key. This defaults to '0', meaning the source is
+ * passed first, but can be set to any index supported by the callback.
+ *
+ * @code
+ * process:
+ *   destination_field:
+ *     plugin: callback_array
+ *     callable: str_replace
+ *     source: source_field
+ *     source_index: 2
+ *     parameters:
+ *       - 'search'
+ *       - 'replace'
+ * @endcode
+ *
+ * This will end up calling:
+ *
+ * @code
+ *   str_replace('SEARCH_VALUE', 'REPLACE_VALUE', 'SOURCE_VALUE');
+ * @endcode
+ *
+ * @see \Drupal\migrate\Plugin\MigrateProcessInterface
+ *
+ * @MigrateProcessPlugin(
+ *   id = "callback_array"
+ * )
+ */
+class CallbackArray extends Callback {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition) {
+    $configuration += ['source_index' => 0];
+    if (is_null($configuration['parameters'])) {
+      throw new \InvalidArgumentException('The "parameters" must be set.');
+    }
+    elseif (empty($configuration['parameters']) || !is_array($configuration['parameters'])) {
+      throw new \InvalidArgumentException('The "parameters" must be a non-empty array.');
+    }
+    elseif ($configuration['source_index'] > count($configuration['parameters'])) {
+      throw new \InvalidArgumentException('The "source_index" may not exceed the amount of "parameters".');
+    }
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
+    $parameters = array_splice($this->configuration['parameters'], $this->configuration['source_index'], 0, [$value]);
+    return call_user_func_array($this->configuration['callable'], $parameters);
+  }
+
+}
-- 
2.17.1

