diff -u b/core/lib/Drupal/Component/DependencyInjection/Container.php b/core/lib/Drupal/Component/DependencyInjection/Container.php --- b/core/lib/Drupal/Component/DependencyInjection/Container.php +++ b/core/lib/Drupal/Component/DependencyInjection/Container.php @@ -276,7 +276,7 @@ $arguments = $this->resolveServicesAndParameters($arguments); } } - call_user_func_array([$service, $method], $arguments); + [$service, $method](...$arguments); } } diff -u b/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php b/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php --- b/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php +++ b/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php @@ -95,7 +95,7 @@ $arguments = $call[1]; $arguments = $this->resolveServicesAndParameters($arguments); } - call_user_func_array([$service, $method], $arguments); + [$service, $method](...$arguments); } } diff -u b/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php --- b/core/lib/Drupal/Core/Form/FormBuilder.php +++ b/core/lib/Drupal/Core/Form/FormBuilder.php @@ -523,12 +523,7 @@ $form['#attributes']['class'][] = Html::getClass($build_info['base_form_id']); } - // We need to pass $form_state by reference in order for forms to modify it, - // since call_user_func_array() requires that referenced variables are - // passed explicitly. - $args = array_merge([$form, &$form_state], $args); - - $form = $callback(...$args); + $form = $callback(...array_merge([$form, &$form_state], $args)); // If the form returns a response, skip subsequent page construction by // throwing an exception. // @see Drupal\Core\EventSubscriber\EnforcedFormResponseSubscriber @@ -1004,7 +999,7 @@ if (isset($element['#process']) && !$element['#processed']) { foreach ($element['#process'] as $callback) { $complete_form = &$form_state->getCompleteForm(); - $element = call_user_func_array($form_state->prepareCallback($callback), [&$element, &$form_state, &$complete_form]); + $element = $form_state->prepareCallback($callback)(...[&$element, &$form_state, &$complete_form]); } $element['#processed'] = TRUE; } @@ -1075,7 +1070,7 @@ // after normal input parsing has been completed. if (isset($element['#after_build']) && !isset($element['#after_build_done'])) { foreach ($element['#after_build'] as $callback) { - $element = call_user_func_array($form_state->prepareCallback($callback), [$element, &$form_state]); + $element = $form_state->prepareCallback($callback)(...[$element, &$form_state]); } $element['#after_build_done'] = TRUE; } @@ -1255,7 +1250,7 @@ // Skip all value callbacks except safe ones like text if the CSRF // token was invalid. if (!$form_state->hasInvalidToken() || $this->valueCallableIsSafe($value_callable)) { - $element['#value'] = call_user_func_array($value_callable, [&$element, $input, &$form_state]); + $element['#value'] = $value_callable(...[&$element, $input, &$form_state]); } else { $input = NULL; @@ -1274,7 +1269,7 @@ if (!isset($element['#value'])) { // Call #type_value without a second argument to request default_value // handling. - $element['#value'] = call_user_func_array($value_callable, [&$element, FALSE, &$form_state]); + $element['#value'] = $value_callable(...[&$element, FALSE, &$form_state]); // Final catch. If we haven't set a value yet, use the explicit default // value. Avoid image buttons (which come with garbage value), so we diff -u b/core/tests/Drupal/KernelTests/Core/Entity/EntityDecoupledTranslationRevisionsTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDecoupledTranslationRevisionsTest.php --- b/core/tests/Drupal/KernelTests/Core/Entity/EntityDecoupledTranslationRevisionsTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDecoupledTranslationRevisionsTest.php @@ -292,7 +292,7 @@ $revision_id = NULL; foreach ($sequence as $index => $step) { $this->stepIndex = $index; - $revision_id = call_user_func_array([$this, 'doEditStep'], $step); + $revision_id = [$this, 'doEditStep'](...$step); } return $revision_id; } only in patch2: unchanged: --- a/core/includes/batch.inc +++ b/core/includes/batch.inc @@ -292,7 +292,7 @@ function _batch_process() { 'finished' => &$finished, 'message' => &$task_message, ]; - call_user_func_array($callback, array_merge($args, [&$batch_context])); + $callback(...array_merge($args, [&$batch_context])); if ($finished >= 1) { // Make sure this step is not counted twice when computing $current. @@ -427,7 +427,7 @@ function _batch_next_set() { // We use our stored copies of $form and $form_state to account for // possible alterations by previous form submit handlers. $complete_form = &$batch['form_state']->getCompleteForm(); - call_user_func_array($callback, [&$complete_form, &$batch['form_state']]); + $callback(...[&$complete_form, &$batch['form_state']]); } return TRUE; } @@ -453,7 +453,7 @@ function _batch_finished() { if (is_callable($batch_set['finished'])) { $queue = _batch_queue($batch_set); $operations = $queue->getAllItems(); - $batch_set_result = call_user_func_array($batch_set['finished'], [$batch_set['success'], $batch_set['results'], $operations, \Drupal::service('date.formatter')->formatInterval((int) ($batch_set['elapsed'] / 1000))]); + $batch_set_result = $batch_set['finished'](...[$batch_set['success'], $batch_set['results'], $operations, \Drupal::service('date.formatter')->formatInterval((int) ($batch_set['elapsed'] / 1000))]); // If a batch 'finished' callback requested a redirect after the batch // is complete, save that for later use. If more than one batch set // returned a redirect, the last one is used. only in patch2: unchanged: --- a/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotationBridgeDecorator.php +++ b/core/lib/Drupal/Component/Annotation/Plugin/Discovery/AnnotationBridgeDecorator.php @@ -69,7 +69,7 @@ public function getDefinitions() { * The method result. */ public function __call($method, $args) { - return call_user_func_array([$this->decorated, $method], $args); + return [$this->decorated, $method](...$args); } } only in patch2: unchanged: --- a/core/lib/Drupal/Component/ClassFinder/ClassFinder.php +++ b/core/lib/Drupal/Component/ClassFinder/ClassFinder.php @@ -14,7 +14,7 @@ public function findFile($class) { $loaders = spl_autoload_functions(); foreach ($loaders as $loader) { if (is_array($loader) && isset($loader[0]) && is_object($loader[0]) && method_exists($loader[0], 'findFile')) { - $file = call_user_func_array([$loader[0], 'findFile'], [$class]); + $file = [$loader[0], 'findFile'](...[$class]); // Different implementations return different empty values. For example, // \Composer\Autoload\ClassLoader::findFile() returns FALSE whilst // \Drupal\Component\ClassFinder\ClassFinderInterface::findFile() only in patch2: unchanged: --- a/core/lib/Drupal/Component/Datetime/DateTimePlus.php +++ b/core/lib/Drupal/Component/Datetime/DateTimePlus.php @@ -357,7 +357,7 @@ public function __call($method, array $args) { throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', static::class, $method)); } - $result = call_user_func_array([$this->dateTimeObject, $method], $args); + $result = [$this->dateTimeObject, $method](...$args); return $result === $this->dateTimeObject ? $this : $result; } @@ -395,7 +395,7 @@ public static function __callStatic($method, $args) { if (!method_exists('\DateTime', $method)) { throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', static::class, $method)); } - return call_user_func_array(['\DateTime', $method], $args); + return ['\DateTime', $method](...$args); } /** only in patch2: unchanged: --- a/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php +++ b/core/lib/Drupal/Component/Plugin/Discovery/DerivativeDiscoveryDecorator.php @@ -248,7 +248,7 @@ protected function mergeDerivativeDefinition($base_plugin_definition, $derivativ * Passes through all unknown calls onto the decorated object. */ public function __call($method, $args) { - return call_user_func_array([$this->decorated, $method], $args); + return [$this->decorated, $method](...$args); } } only in patch2: unchanged: --- a/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscoveryDecorator.php +++ b/core/lib/Drupal/Component/Plugin/Discovery/StaticDiscoveryDecorator.php @@ -61,7 +61,7 @@ public function getDefinitions() { * Passes through all unknown calls onto the decorated object. */ public function __call($method, $args) { - return call_user_func_array([$this->decorated, $method], $args); + return [$this->decorated, $method](...$args); } } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Config/ConfigImporter.php +++ b/core/lib/Drupal/Core/Config/ConfigImporter.php @@ -510,7 +510,7 @@ public function doSyncStep($sync_step, &$context) { } elseif (is_callable($sync_step)) { \Drupal::service('config.installer')->setSyncing(TRUE); - call_user_func_array($sync_step, [&$context, $this]); + $sync_step(...[&$context, $this]); } else { throw new \InvalidArgumentException('Invalid configuration synchronization step'); only in patch2: unchanged: --- a/core/lib/Drupal/Core/Database/Install/Tasks.php +++ b/core/lib/Drupal/Core/Database/Install/Tasks.php @@ -154,7 +154,7 @@ public function runTasks() { } if (method_exists($this, $task['function'])) { // Returning false is fatal. No other tasks can run. - if (FALSE === call_user_func_array([$this, $task['function']], $task['arguments'])) { + if (FALSE === [$this, $task['function']](...$task['arguments'])) { break; } } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Database/Query/SelectExtender.php +++ b/core/lib/Drupal/Core/Database/Query/SelectExtender.php @@ -76,14 +76,14 @@ public function hasTag($tag) { * {@inheritdoc} */ public function hasAllTags() { - return call_user_func_array([$this->query, 'hasAllTags'], func_get_args()); + return [$this->query, 'hasAllTags'](...func_get_args()); } /** * {@inheritdoc} */ public function hasAnyTag() { - return call_user_func_array([$this->query, 'hasAnyTag'], func_get_args()); + return [$this->query, 'hasAnyTag'](...func_get_args()); } /** @@ -510,7 +510,7 @@ public function __clone() { * to handle any additional methods. */ public function __call($method, $args) { - $return = call_user_func_array([$this->query, $method], $args); + $return = [$this->query, $method](...$args); // Some methods will return the called object as part of a fluent interface. // Others will return some useful value. If it's a value, then the caller only in patch2: unchanged: --- a/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php +++ b/core/lib/Drupal/Core/DependencyInjection/ContainerBuilder.php @@ -133,7 +133,7 @@ protected function callMethod($service, $call, array &$inlineServices = array()) } } - call_user_func_array(array($service, $call[0]), $this->resolveServices($this->getParameterBag()->resolveValue($call[1]))); + [$service, $call[0]](...$this->resolveServices($this->getParameterBag()->resolveValue($call[1]))); } /** only in patch2: unchanged: --- a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php @@ -936,9 +936,9 @@ protected function invokeFieldMethod($method, ContentEntityInterface $entity) { // fields should be invoked only on the default entity translation. $fields = $translation->isDefaultTranslation() ? $translation->getFields() : $translation->getTranslatableFields(); foreach ($fields as $name => $items) { - // call_user_func_array() is way slower than a direct call so we avoid - // using it if have no parameters. - $result[$langcode][$name] = $args ? call_user_func_array([$items, $method], $args) : $items->{$method}(); + // Argument unpacking may be slower than a direct call so we avoid using + // it if have no parameters. + $result[$langcode][$name] = $args ? [$items, $method](...$args) : $items->{$method}(); } } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Entity/EntityForm.php +++ b/core/lib/Drupal/Core/Entity/EntityForm.php @@ -296,7 +296,7 @@ public function buildEntity(array $form, FormStateInterface $form_state) { // properties. if (isset($form['#entity_builders'])) { foreach ($form['#entity_builders'] as $function) { - call_user_func_array($form_state->prepareCallback($function), [$entity->getEntityTypeId(), $entity, &$form, &$form_state]); + $form_state->prepareCallback($function)(...[$entity->getEntityTypeId(), $entity, &$form, &$form_state]); } } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Extension/Extension.php +++ b/core/lib/Drupal/Core/Extension/Extension.php @@ -159,7 +159,7 @@ public function __call($method, array $args) { if (!isset($this->splFileInfo)) { $this->splFileInfo = new \SplFileInfo($this->root . '/' . $this->pathname); } - return call_user_func_array([$this->splFileInfo, $method], $args); + return [$this->splFileInfo, $method](...$args); } /** only in patch2: unchanged: --- a/core/lib/Drupal/Core/Field/FieldItemList.php +++ b/core/lib/Drupal/Core/Field/FieldItemList.php @@ -228,9 +228,9 @@ protected function delegateMethod($method) { $result = []; $args = array_slice(func_get_args(), 1); foreach ($this->list as $delta => $item) { - // call_user_func_array() is way slower than a direct call so we avoid - // using it if have no parameters. - $result[$delta] = $args ? call_user_func_array([$item, $method], $args) : $item->{$method}(); + // Argument unpacking may be slower than a direct call so we avoid using + // it if have no parameters. + $result[$delta] = $args ? [$item, $method](...$args) : $item->{$method}(); } return $result; } only in patch2: unchanged: --- a/core/lib/Drupal/Core/FileTransfer/Form/FileTransferAuthorizeForm.php +++ b/core/lib/Drupal/Core/FileTransfer/Form/FileTransferAuthorizeForm.php @@ -321,7 +321,7 @@ protected function runOperation($filetransfer) { $operation = $this->getRequest()->getSession()->remove('authorize_operation'); require_once $operation['file']; - return call_user_func_array($operation['callback'], array_merge([$filetransfer], $operation['arguments'])); + return $operation['callback'](...array_merge([$filetransfer], $operation['arguments'])); } } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php +++ b/core/lib/Drupal/Core/Form/FormAjaxResponseBuilder.php @@ -66,7 +66,7 @@ public function buildResponse(Request $request, array $form, FormStateInterface if (empty($callback) || !is_callable($callback)) { throw new HttpException(500, 'The specified #ajax callback is empty or not callable.'); } - $result = call_user_func_array($callback, [&$form, &$form_state, $request]); + $result = $callback(...[&$form, &$form_state, $request]); // If the callback is an #ajax callback, the result is a render array, and // we need to turn it into an AJAX response, so that we can add any commands only in patch2: unchanged: --- a/core/lib/Drupal/Core/Form/FormSubmitter.php +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php @@ -111,7 +111,7 @@ public function executeSubmitHandlers(&$form, FormStateInterface &$form_state) { $batch['has_form_submits'] = TRUE; } else { - call_user_func_array($form_state->prepareCallback($callback), [&$form, &$form_state]); + $form_state->prepareCallback($callback)(...[&$form, &$form_state]); } } } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Form/FormValidator.php +++ b/core/lib/Drupal/Core/Form/FormValidator.php @@ -79,7 +79,7 @@ public function executeValidateHandlers(&$form, FormStateInterface &$form_state) } foreach ($handlers as $callback) { - call_user_func_array($form_state->prepareCallback($callback), [&$form, &$form_state]); + $form_state->prepareCallback($callback)(...[&$form, &$form_state]); } } @@ -279,7 +279,7 @@ protected function doValidateForm(&$elements, FormStateInterface &$form_state, $ elseif (isset($elements['#element_validate'])) { foreach ($elements['#element_validate'] as $callback) { $complete_form = &$form_state->getCompleteForm(); - call_user_func_array($form_state->prepareCallback($callback), [&$elements, &$form_state, &$complete_form]); + $form_state->prepareCallback($callback)(...[&$elements, &$form_state, &$complete_form]); } } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Plugin/Discovery/InfoHookDecorator.php +++ b/core/lib/Drupal/Core/Plugin/Discovery/InfoHookDecorator.php @@ -57,7 +57,7 @@ function (callable $hook, string $module) use (&$definitions) { * Passes through all unknown calls onto the decorated object. */ public function __call($method, $args) { - return call_user_func_array([$this->decorated, $method], $args); + return [$this->decorated, $method](...$args); } } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Plugin/Discovery/YamlDiscoveryDecorator.php +++ b/core/lib/Drupal/Core/Plugin/Discovery/YamlDiscoveryDecorator.php @@ -47,7 +47,7 @@ public function getDefinitions() { * Passes through all unknown calls onto the decorated object. */ public function __call($method, $args) { - return call_user_func_array([$this->decorated, $method], $args); + return [$this->decorated, $method](...$args); } } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Routing/AccessAwareRouter.php +++ b/core/lib/Drupal/Core/Routing/AccessAwareRouter.php @@ -60,7 +60,7 @@ public function __construct(RouterInterface $router, AccessManagerInterface $acc */ public function __call($name, $arguments) { // Ensure to call every other function to the router. - return call_user_func_array([$this->router, $name], $arguments); + return [$this->router, $name](...$arguments); } /** only in patch2: unchanged: --- a/core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php +++ b/core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php @@ -98,7 +98,7 @@ public function doTrustedCallback(callable $callback, array $args, $message, $er } // @TODO Allow named arguments in https://www.drupal.org/node/3174150 - return call_user_func_array($callback, array_values($args)); + return $callback(...array_values($args)); } } only in patch2: unchanged: --- a/core/lib/Drupal/Core/Theme/ThemeManager.php +++ b/core/lib/Drupal/Core/Theme/ThemeManager.php @@ -282,7 +282,7 @@ public function render($hook, array $variables) { if (isset($info['preprocess functions'])) { foreach ($info['preprocess functions'] as $preprocessor_function) { if (is_callable($preprocessor_function)) { - call_user_func_array($preprocessor_function, [&$variables, $hook, $info]); + $preprocessor_function(...[&$variables, $hook, $info]); } } // Allow theme preprocess functions to set $variables['#attached'] and only in patch2: unchanged: --- a/core/modules/field/src/Plugin/migrate/process/ProcessField.php +++ b/core/modules/field/src/Plugin/migrate/process/ProcessField.php @@ -132,7 +132,7 @@ protected function callMethodOnFieldPlugin(MigrateFieldPluginManagerInterface $f if (!is_callable([$plugin_instance, $method])) { throw new MigrateException('The specified method does not exist or is not callable.'); } - return call_user_func_array([$plugin_instance, $method], [$row]); + return [$plugin_instance, $method](...[$row]); } } only in patch2: unchanged: --- a/core/modules/field_ui/src/Element/FieldUiTable.php +++ b/core/modules/field_ui/src/Element/FieldUiTable.php @@ -69,7 +69,7 @@ public static function tablePreRender($elements) { unset($list[$name]); // Determine the region for the row. - $region_name = call_user_func_array($row['#region_callback'], [&$row]); + $region_name = $row['#region_callback'](...[&$row]); // Add the element in the tree. // phpcs:ignore DrupalPractice.CodeAnalysis.VariableAnalysis.UnusedVariable only in patch2: unchanged: --- a/core/modules/locale/locale.compare.inc +++ b/core/modules/locale/locale.compare.inc @@ -246,7 +246,7 @@ function locale_translation_batch_status_build($projects = [], $langcodes = []) ->setFinishCallback('locale_translation_batch_status_finished'); array_walk($operations, function ($operation) use ($batch_builder) { - call_user_func_array([$batch_builder, 'addOperation'], $operation); + [$batch_builder, 'addOperation'](...$operation); }); return $batch_builder->toArray(); only in patch2: unchanged: --- a/core/modules/locale/locale.fetch.inc +++ b/core/modules/locale/locale.fetch.inc @@ -45,7 +45,7 @@ function locale_translation_batch_update_build($projects = [], $langcodes = [], // Download and import translations. $operations = array_merge($operations, _locale_translation_fetch_operations($projects, $langcodes, $options)); array_walk($operations, function ($operation) use ($batch_builder) { - call_user_func_array([$batch_builder, 'addOperation'], $operation); + [$batch_builder, 'addOperation'](...$operation); }); return $batch_builder->toArray(); @@ -76,7 +76,7 @@ function locale_translation_batch_fetch_build($projects = [], $langcodes = [], $ ->setFinishCallback('locale_translation_batch_fetch_finished'); $operations = _locale_translation_fetch_operations($projects, $langcodes, $options); array_walk($operations, function ($operation) use ($batch_builder) { - call_user_func_array([$batch_builder, 'addOperation'], $operation); + [$batch_builder, 'addOperation'](...$operation); }); return $batch_builder->toArray(); } only in patch2: unchanged: --- a/core/modules/migrate/src/Plugin/Discovery/ProviderFilterDecorator.php +++ b/core/modules/migrate/src/Plugin/Discovery/ProviderFilterDecorator.php @@ -93,7 +93,7 @@ public function getDefinitions() { * The return value from the method on the decorated object. */ public function __call($method, array $args) { - return call_user_func_array([$this->decorated, $method], $args); + return [$this->decorated, $method](...$args); } } only in patch2: unchanged: --- a/core/modules/migrate/src/Plugin/NoSourcePluginDecorator.php +++ b/core/modules/migrate/src/Plugin/NoSourcePluginDecorator.php @@ -52,7 +52,7 @@ public function getDefinitions() { * The return value from the method on the decorated object. */ public function __call($method, array $args) { - return call_user_func_array([$this->decorated, $method], $args); + return [$this->decorated, $method](...$args); } } only in patch2: unchanged: --- a/core/modules/migrate_drupal/src/FieldDiscovery.php +++ b/core/modules/migrate_drupal/src/FieldDiscovery.php @@ -145,14 +145,7 @@ public function addBundleFieldProcesses(MigrationInterface $migration, $entity_t if ($plugin) { $method = $plugin_definition['field_plugin_method'] ?? 'defineValueProcessPipeline'; - call_user_func_array([ - $plugin, - $method, - ], [ - $migration, - $field_name, - $field_info, - ]); + [$plugin, $method](...[$migration, $field_name, $field_info]); } else { // Default to a get process plugin if this is a value migration. only in patch2: unchanged: --- a/core/modules/rest/src/RequestHandler.php +++ b/core/modules/rest/src/RequestHandler.php @@ -216,7 +216,7 @@ protected function delegateToRestResourcePlugin(RouteMatchInterface $route_match $arguments = $argument_resolver->getArguments([$resource, $method]); // Invoke the operation on the resource plugin. - return call_user_func_array([$resource, $method], $arguments); + return [$resource, $method](...$arguments); } /** only in patch2: unchanged: --- a/core/modules/settings_tray/tests/src/FunctionalJavascript/SettingsTrayBlockFormTest.php +++ b/core/modules/settings_tray/tests/src/FunctionalJavascript/SettingsTrayBlockFormTest.php @@ -49,7 +49,7 @@ protected function setUp(): void { */ public function testBlocks() { foreach ($this->getBlockTests() as $test) { - call_user_func_array([$this, 'doTestBlocks'], array_values($test)); + [$this, 'doTestBlocks'](...array_values($test)); } } only in patch2: unchanged: --- a/core/modules/system/tests/src/Functional/Entity/EntityReferenceSelection/EntityReferenceSelectionAccessTest.php +++ b/core/modules/system/tests/src/Functional/Entity/EntityReferenceSelection/EntityReferenceSelectionAccessTest.php @@ -99,10 +99,10 @@ protected function assertReferenceable(array $selection_options, array $tests, s foreach ($tests as $test) { foreach ($test['arguments'] as $arguments) { - $result = call_user_func_array([$handler, 'getReferenceableEntities'], $arguments); + $result = [$handler, 'getReferenceableEntities'](...$arguments); $this->assertEquals($test['result'], $result, new FormattableMarkup('Valid result set returned by @handler.', ['@handler' => $handler_name])); - $result = call_user_func_array([$handler, 'countReferenceableEntities'], $arguments); + $result = [$handler, 'countReferenceableEntities'](...$arguments); if (!empty($test['result'])) { $bundle = key($test['result']); $count = count($test['result'][$bundle]); only in patch2: unchanged: --- a/core/modules/views/src/Plugin/views/HandlerBase.php +++ b/core/modules/views/src/Plugin/views/HandlerBase.php @@ -471,7 +471,7 @@ public function showExposeForm(&$form, FormStateInterface $form_state) { public function access(AccountInterface $account) { if (isset($this->definition['access callback']) && function_exists($this->definition['access callback'])) { if (isset($this->definition['access arguments']) && is_array($this->definition['access arguments'])) { - return call_user_func_array($this->definition['access callback'], [$account] + $this->definition['access arguments']); + return $this->definition['access callback'](...[$account] + $this->definition['access arguments']); } return $this->definition['access callback']($account); } only in patch2: unchanged: --- a/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php +++ b/core/modules/views/src/Plugin/views/argument/ArgumentPluginBase.php @@ -715,7 +715,7 @@ public function defaultAction($info = NULL) { } if (!empty($info['method args'])) { - return call_user_func_array([&$this, $info['method']], $info['method args']); + return [&$this, $info['method']](...$info['method args']); } else { return $this->{$info['method']}(); only in patch2: unchanged: --- a/core/modules/views/src/Plugin/views/field/MachineName.php +++ b/core/modules/views/src/Plugin/views/field/MachineName.php @@ -31,7 +31,7 @@ public function getValueOptions() { if (isset($this->definition['options callback']) && is_callable($this->definition['options callback'])) { if (isset($this->definition['options arguments']) && is_array($this->definition['options arguments'])) { - $this->valueOptions = call_user_func_array($this->definition['options callback'], $this->definition['options arguments']); + $this->valueOptions = $this->definition['options callback'](...$this->definition['options arguments']); } else { $this->valueOptions = call_user_func($this->definition['options callback']); only in patch2: unchanged: --- a/core/modules/views/src/Plugin/views/filter/InOperator.php +++ b/core/modules/views/src/Plugin/views/filter/InOperator.php @@ -65,7 +65,7 @@ public function getValueOptions() { if (isset($this->definition['options callback']) && is_callable($this->definition['options callback'])) { if (isset($this->definition['options arguments']) && is_array($this->definition['options arguments'])) { - $this->valueOptions = call_user_func_array($this->definition['options callback'], $this->definition['options arguments']); + $this->valueOptions = $this->definition['options callback'](...$this->definition['options arguments']); } else { $this->valueOptions = call_user_func($this->definition['options callback']); only in patch2: unchanged: --- a/core/modules/views_ui/src/ViewUI.php +++ b/core/modules/views_ui/src/ViewUI.php @@ -253,7 +253,7 @@ public function standardSubmit($form, FormStateInterface $form_state) { } $submit_handler = [$form_state->getFormObject(), 'submitForm']; - call_user_func_array($submit_handler, [&$form, $form_state]); + $submit_handler(...[&$form, $form_state]); } /** @@ -897,7 +897,7 @@ public function isLocked() { * Passes through all unknown calls onto the storage object. */ public function __call($method, $args) { - return call_user_func_array([$this->storage, $method], $args); + return [$this->storage, $method](...$args); } /** only in patch2: unchanged: --- a/core/modules/views_ui/tests/src/Unit/ViewUIObjectTest.php +++ b/core/modules/views_ui/tests/src/Unit/ViewUIObjectTest.php @@ -62,7 +62,7 @@ public function testEntityDecoration() { foreach ($args as $arg) { $method_mock->with($this->equalTo($arg)); } - call_user_func_array([$view_ui, $method], $args); + [$view_ui, $method](...$args); } $storage->expects($this->once()) only in patch2: unchanged: --- a/core/tests/Drupal/KernelTests/Core/Database/LoggingTest.php +++ b/core/tests/Drupal/KernelTests/Core/Database/LoggingTest.php @@ -25,7 +25,7 @@ public function testEnableLogging() { $this->connection->query('SELECT [age] FROM {test} WHERE [name] = :name', [':name' => 'Ringo'])->fetchCol(); // Trigger a call that does not have file in the backtrace. - call_user_func_array([Database::getConnection(), 'query'], ['SELECT [age] FROM {test} WHERE [name] = :name', [':name' => 'Ringo']])->fetchCol(); + [Database::getConnection(), 'query'](...['SELECT [age] FROM {test} WHERE [name] = :name', [':name' => 'Ringo']])->fetchCol(); $queries = Database::getLog('testing', 'default'); only in patch2: unchanged: --- a/core/tests/Drupal/Tests/Component/Plugin/Discovery/StaticDiscoveryDecoratorTest.php +++ b/core/tests/Drupal/Tests/Component/Plugin/Discovery/StaticDiscoveryDecoratorTest.php @@ -222,7 +222,7 @@ function () { // Exercise __call. $this->assertEquals( $args, - \call_user_func_array([$mock_decorated, $method], $args) + [$mock_decorated, $method](...$args) ); } only in patch2: unchanged: --- a/core/tests/Drupal/Tests/Core/Config/ReadOnlyStorageTest.php +++ b/core/tests/Drupal/Tests/Core/Config/ReadOnlyStorageTest.php @@ -51,8 +51,8 @@ protected function setUp(): void { public function testReadOperations($method, $arguments, $fixture) { $this->setRandomFixtureConfig($fixture); - $expected = call_user_func_array([$this->memory, $method], $arguments); - $actual = call_user_func_array([$this->storage, $method], $arguments); + $expected = [$this->memory, $method](...$arguments); + $actual = [$this->storage, $method](...$arguments); $this->assertEquals($expected, $actual); } @@ -96,7 +96,7 @@ public function testWriteOperations($method, $arguments, $fixture) { static::replaceStorageContents($this->memory, $backup); try { - call_user_func_array([$this->storage, $method], $arguments); + [$this->storage, $method](...$arguments); $this->fail("exception not thrown"); } catch (\BadMethodCallException $exception) { only in patch2: unchanged: --- a/core/tests/Drupal/Tests/Core/Session/WriteSafeSessionHandlerTest.php +++ b/core/tests/Drupal/Tests/Core/Session/WriteSafeSessionHandlerTest.php @@ -135,17 +135,17 @@ public function testOtherMethods($method, $expected_result, $args) { ->will($this->returnValue($expected_result)); // Set the parameter matcher. - call_user_func_array([$invocation, 'with'], $args); + [$invocation, 'with'](...$args); // Test with writable session. $this->assertTrue($this->sessionHandler->isSessionWritable()); - $actual_result = call_user_func_array([$this->sessionHandler, $method], $args); + $actual_result = [$this->sessionHandler, $method](...$args); $this->assertSame($expected_result, $actual_result); // Test with non-writable session. $this->sessionHandler->setSessionWritable(FALSE); $this->assertFalse($this->sessionHandler->isSessionWritable()); - $actual_result = call_user_func_array([$this->sessionHandler, $method], $args); + $actual_result = [$this->sessionHandler, $method](...$args); $this->assertSame($expected_result, $actual_result); }