diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php index d8a44596947..a77cdc011c9 100644 --- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php +++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php @@ -2148,10 +2148,8 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte $parts['fragment'] = $this->viewsTokenReplace($parts['fragment'], $tokens); // Handle query parameters where the key is part of an array. - // For example, f[0] for facets. - array_walk_recursive($parts['query'], function (&$value) use ($tokens) { - $value = $this->viewsTokenReplace($value, $tokens); - }); + // For example, f[0] for facets or field_name[id]=id for exposed filters. + $parts['query'] = $this->recursiveReplaceTokens($parts['query'], $tokens); $options = $parts; } @@ -2170,6 +2168,34 @@ abstract class DisplayPluginBase extends PluginBase implements DisplayPluginInte return $url; } + /** + * Replace the query parameters recursively, both key and value. + * + * @param array $parts + * Query parts of the request. + * @param array $tokens + * Tokens for replacement. + * + * @return array + * The parameters with replacements done. + */ + protected function recursiveReplaceTokens(array $parts, array $tokens): array { + foreach ($parts as $key => $value) { + if (is_array($value)) { + $value = $this->recursiveReplaceTokens($value, $tokens); + } + else { + $value = $this->viewsTokenReplace($value, $tokens); + } + if (!is_int($key)) { + unset($parts[$key]); + $key = $this->viewsTokenReplace($key, $tokens); + } + $parts[$key] = $value; + } + return $parts; + } + /** * {@inheritdoc} */ diff --git a/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php b/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php index 93f2292fde5..b8d7726b05d 100644 --- a/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php +++ b/core/modules/views/tests/src/Functional/Plugin/DisplayTest.php @@ -300,6 +300,14 @@ class DisplayTest extends ViewTestBase { $output = (string) $renderer->renderRoot($output); $this->assertStringContainsString('/node/22?date=22&foo=bar', $output, 'The read more link with href "/node/22?date=22&foo=bar" was found.'); + // Test more link with array arguments in path. + $view->display_handler->setOption('link_url', 'node/{{ raw_arguments.age }}?date[{{ raw_arguments.age }}]={{ raw_arguments.age }}&foo=bar'); + $view->setArguments([22]); + $this->executeView($view); + $output = $view->preview(); + $output = (string) $renderer->renderRoot($output); + $this->assertStringContainsString('/node/22?date%5B22%5D=22&foo=bar', $output, 'The read more link with href "/node/22?date[22]=22&foo=bar" was found.'); + // Test more link with arguments in fragment. $view->display_handler->setOption('link_url', 'node?date={{ raw_arguments.age }}&foo=bar#{{ raw_arguments.age }}'); $view->setArguments([22]);