Issue #2882276 by benjifisher, estoyausente, nuez, kristiaanvandeneynde, alexpott, ravi.shankar, osopolar, marvil07, danflanagan8, heddn, quietone, Matroskeen, hudri, joshi.rohit100: Extended callback process plugin to call functions with multiple parameters
parent
b48ad9091d
commit
a3ca88ebbf
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\migrate\Plugin\migrate\process;
|
||||
|
||||
use Drupal\migrate\MigrateException;
|
||||
use Drupal\migrate\MigrateExecutableInterface;
|
||||
use Drupal\migrate\ProcessPluginBase;
|
||||
use Drupal\migrate\Row;
|
||||
|
@ -10,11 +11,13 @@ use Drupal\migrate\Row;
|
|||
* Passes the source value to a callback.
|
||||
*
|
||||
* The callback process plugin allows simple processing of the value, such as
|
||||
* strtolower(). The callable takes the source value as the single mandatory
|
||||
* argument. No additional arguments can be passed to the callback.
|
||||
* strtolower(). To pass more than one argument, pass an array as the source
|
||||
* and set the unpack_source option.
|
||||
*
|
||||
* Available configuration keys:
|
||||
* - callable: The name of the callable method.
|
||||
* - unpack_source: (optional) Whether to interpret the source as an array of
|
||||
* arguments.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
|
@ -38,6 +41,25 @@ use Drupal\migrate\Row;
|
|||
* source: source_field
|
||||
* @endcode
|
||||
*
|
||||
* An example where the callback accepts more than one argument:
|
||||
*
|
||||
* @code
|
||||
* source:
|
||||
* plugin: source_plugin_goes_here
|
||||
* constants:
|
||||
* slash: /
|
||||
* process:
|
||||
* field_link_url:
|
||||
* plugin: callback
|
||||
* callable: rtrim
|
||||
* unpack_source: true
|
||||
* source:
|
||||
* - url
|
||||
* - constants/slash
|
||||
* @endcode
|
||||
*
|
||||
* This will remove the trailing '/', if any, from a URL.
|
||||
*
|
||||
* @see \Drupal\migrate\Plugin\MigrateProcessInterface
|
||||
*
|
||||
* @MigrateProcessPlugin(
|
||||
|
@ -63,6 +85,12 @@ class Callback extends ProcessPluginBase {
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) {
|
||||
if (!empty($this->configuration['unpack_source'])) {
|
||||
if (!is_array($value)) {
|
||||
throw new MigrateException(sprintf("When 'unpack_source' is set, the source must be an array. Instead it was of type '%s'", gettype($value)));
|
||||
}
|
||||
return call_user_func($this->configuration['callable'], ...$value);
|
||||
}
|
||||
return call_user_func($this->configuration['callable'], $value);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Drupal\Tests\migrate\Unit\process;
|
||||
|
||||
use Drupal\migrate\MigrateException;
|
||||
use Drupal\migrate\Plugin\migrate\process\Callback;
|
||||
|
||||
/**
|
||||
|
@ -33,15 +34,60 @@ class CallbackTest extends MigrateProcessTestCase {
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test callback with valid "callable" and multiple arguments.
|
||||
*
|
||||
* @dataProvider providerCallbackArray
|
||||
*/
|
||||
public function testCallbackArray($callable, $args, $result) {
|
||||
$configuration = ['callable' => $callable, 'unpack_source' => TRUE];
|
||||
$this->plugin = new Callback($configuration, 'map', []);
|
||||
$value = $this->plugin->transform($args, $this->migrateExecutable, $this->row, 'destination_property');
|
||||
$this->assertSame($result, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for ::testCallbackArray().
|
||||
*/
|
||||
public function providerCallbackArray() {
|
||||
return [
|
||||
'date format' => [
|
||||
'date',
|
||||
['Y-m-d', 995328000],
|
||||
'2001-07-17',
|
||||
],
|
||||
'rtrim' => [
|
||||
'rtrim',
|
||||
['https://www.example.com/', '/'],
|
||||
'https://www.example.com',
|
||||
],
|
||||
'str_replace' => [
|
||||
'str_replace',
|
||||
[['One', 'two'], ['1', '2'], 'One, two, three!'],
|
||||
'1, 2, three!',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test callback exceptions.
|
||||
*
|
||||
* @param string $message
|
||||
* The expected exception message.
|
||||
* @param array $configuration
|
||||
* The plugin configuration being tested.
|
||||
* @param string $class
|
||||
* (optional) The expected exception class.
|
||||
* @param mixed $args
|
||||
* (optional) Arguments to pass to the transform() method.
|
||||
*
|
||||
* @dataProvider providerCallbackExceptions
|
||||
*/
|
||||
public function testCallbackExceptions($message, $configuration) {
|
||||
$this->expectException(\InvalidArgumentException::class);
|
||||
public function testCallbackExceptions($message, array $configuration, $class = 'InvalidArgumentException', $args = NULL) {
|
||||
$this->expectException($class);
|
||||
$this->expectExceptionMessage($message);
|
||||
$this->plugin = new Callback($configuration, 'map', []);
|
||||
$this->plugin->transform($args, $this->migrateExecutable, $this->row, 'destination_property');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,6 +103,12 @@ class CallbackTest extends MigrateProcessTestCase {
|
|||
'message' => 'The "callable" must be a valid function or method.',
|
||||
'configuration' => ['callable' => 'nonexistent_callable'],
|
||||
],
|
||||
'array required' => [
|
||||
'message' => "When 'unpack_source' is set, the source must be an array. Instead it was of type 'string'",
|
||||
'configuration' => ['callable' => 'count', 'unpack_source' => TRUE],
|
||||
'class' => MigrateException::class,
|
||||
'args' => 'This string is not an array.',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue