Skip to content
Snippets Groups Projects
Unverified Commit a3ca88eb authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2882276 by benjifisher, estoyausente, nuez, kristiaanvandeneynde,...

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 b48ad909
Branches
Tags
27 merge requests!12227Issue #3181946 by jonmcl, mglaman,!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!1896Issue #2940605: Can only intentionally re-render an entity with references 20 times,!1101Issue #2412669 by claudiu.cristea, Julfabre, sidharrell, catch, daffie,...,!1039Issue #2556069 by claudiu.cristea, bnjmnm, lauriii, pfrenssen, Tim Bozeman,...,!10223132456: Fix issue where views instances are emptied before an ajax request is complete,!1012Issue #3226887: Hreflang on non-canonical content pages,!872Draft: Issue #3221319: Race condition when creating menu links and editing content deletes menu links,!825Issue #3211838 by mondrake, longwave: Convert assertions involving use of...,!795Issue #3212005 by guilhermevp, tedbow, phenaproxima: Add @throws docs to...,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10,!748#1091852 Display Bug when using #states (Forms API) with Ajax Request,!731Add a new recipe to Umami demo - Chicken souvlaki and couscous,!730Issue #3211810 by alexpott, xjm, Spokje, Amber Himes Matz, Kristen Pol,...,!700Issue #3185165 by Spokje, vipin.mittal18, Suresh Prabhu Parkala, lauriii,...,!594Put each entity type table into a details element on admin/config/regional/content-language,!592Issue #2957953: Editing menus user-experience has regressed,!579Issue #2230909: Simple decimals fail to pass validation,!560Move callback classRemove outside of the loop,!555Issue #3202493,!512Issue #3207771: Menu UI node type form documentation points to non-existent function,!485Sets the autocomplete attribute for username/password input field on login form.,!449Issue #2784233: Allow multiple vocabularies in the taxonomy filter,!429[regression] Pages Manage Fields, Manage form, Manage display should include name of content type or entity,!231Issue #2671162: summary text wysiwyg patch working fine on 9.2.0-dev,!43Resolve #3173180: Add UI for 'loading' html attribute to images,!30Issue #3182188: Updates composer usage to point at ./vendor/bin/composer
......@@ -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 @@
* 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 @@
* 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 @@ public function __construct(array $configuration, $plugin_id, $plugin_definition
* {@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 @@ public function providerCallback() {
];
}
/**
* 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 @@ public function providerCallbackExceptions() {
'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.',
],
];
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment