Problem/Motivation
The function getAvailableGlobalTokens in class PluginBase (core/modules/views/src/Plugins/views/PluginBase.php) contains an array union operator.
public function getAvailableGlobalTokens($prepared = FALSE, array $types = []) {
$info = \Drupal::token()->getInfo();
// Site and view tokens should always be available.
$types += ['site', 'view'];
$available = array_intersect_key($info['tokens'], array_flip($types));
This does not deliver the expected array merge result (refer to https://www.php.net/manual/en/language.operators.array.php), but rather the elements from the right hand array are appended to the left hand array where they have a different key. Therefore if the argument $types passed into the function above has the value "['date']", the resulting $types array will be "['date', 'view']". This is not what is required.
There may well be other instances of incorrect use of the array union operator in the views module.
Steps to reproduce
Proposed resolution
The function should use an array_merge as follows:
public function getAvailableGlobalTokens($prepared = FALSE, array $types = []) {
$info = \Drupal::token()->getInfo();
// Site and view tokens should always be available.
$types = array_unique(array_merge($types, ['site', 'view']));
$available = array_intersect_key($info['tokens'], array_flip($types));
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|
Issue fork drupal-3152267
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
- 3152267-invalid-use-of
changes, plain diff MR !16168
Comments
Comment #2
jayelless commentedPatch attached. This issue is also present in 8.9.x, and the patch also fixes the problems in that version.
Comment #3
kevinvhengst commentedHi James,
Good catch! Your patch seems to resolve the issue you mentioned.
Test result prior to your change When calling
getAvailableGlobalTokes(FALSE, $types)Where $types is['test-1', 'test-2']: $types after the union operator is equal to['test-1', 'test-2'].Test result with your patch applied using the same arguments as above:
$types using
array_unique(array_merge($types, ['site', 'view']));is equal to['test-1', 'test-2', 'site', view']as expected.Comment #4
kevinvhengst commentedComment #6
s_bhandari commentedComment #7
s_bhandari commentedAdded a patch to address the issue.
Comment #8
s_bhandari commentedComment #12
andreasderijckeIssue is still present in 10.1.x: https://git.drupalcode.org/project/drupal/-/blob/10.1.x/core/modules/vie...
Patch still applies in 9.4.8.
Comment #13
alexpottThe fix in #7 looks great. It'd be nice to have some test coverage of this to prove we'd fixed it and also ensure we don't break it in the future.
Comment #19
quietone commentedComment #20
quietone commentedComment #21
quietone commentedI converted to an MR and added a test. Did I miss any test cases?
Comment #22
quietone commentedComment #23
lendudeLeft some comments
Comment #24
quietone commented@lendude, thanks for the prompt review.
I've updated the test. I didn't see a way to create a test for duplicates but added the array_unique anyway. Then tests failed with an 'array to string conversion' because the array is multidimensional and "array_unique() is not intended to work on multi dimensional arrays".
Comment #25
lendudeWell that is a good argument against array_unique! Thanks for trying!
Then this looks ready
Comment #30
godotislateCommitted and pushed bb1b9c2 to main, 02b66e0 to 11.x, and 8976ec4 to 11.4.x. Thanks!