Fatal error when using two identical tokens in a string.

Created on 4 October 2024, 6 months ago

Problem/Motivation

When I put two identical tokens in a string it creates a fatal error on the website.

For example:
/[node:field_dummy]/dummy?type:[node:field_test|node:field_dummy]

It will create a site fatal error when the token is processed.

Steps to reproduce

Use the same token twice in the same string, one of which is in the token_or format.
For example:
/[node:field_dummy]/dummy?type:[node:field_test|node:field_dummy]

Proposed resolution

I found that this problem is created in \Drupal\token_or\Token::scan(...) in the array_merge_recursive(...) function.

 /**
   * {@inheritdoc}
   */
  public function scan($text) {
    ...
    return array_merge_recursive($results, parent::scan(implode(' ', $sub_tokens)));
  }

When the example above is processed, the main tokens are merged with the sub tokens, resulting in a return in the following format:

[
  'node' => [
    'field_dummy' => [
      '[node:field_dummy]',
      '[node:field_dummy]',
    ],
    'field_test' => '[node:field_test]',
  ],
]

While the expected would be the following:

[
  'node' => [
    'field_dummy' => '[node:field_dummy]',
    'field_test' => '[node:field_test]',
  ],
]

As the value of the field_dummy key is an array instead of a string, it generates fatal errors on the website when the token follows the processing pipeline.

To resolve this behavior we must change function array_merge_recursive(...) to NestedArray::mergeDeep(...).

Difference between array_merge_recursive(...) and NestedArray::mergeDeep(...)

The NestedArray::mergeDeep() function is similar to PHP's array_merge_recursive() function, but it handles non-array values differently.
When merging values that are not both arrays, the latter value replaces the former rather than merging with it.

Example:

/**
 * This results in:
 *
 * [
 *  'node' => [
 *     'field_dummy' => [
 *       '[node:field_dummy]',
 *       '[node:field_dummy]',
 *     ],
 *     'field_test' => '[node:field_test]',
 *   ]
 * ]
 */
$incorrect = array_merge_recursive($tokens, $sub_tokens);
/**
 * This results in:
 *
 * [
 *  'node' => [
 *     'field_dummy' => '[node:field_dummy]',
 *     'field_test' => '[node:field_test]',
 *   ]
 * ]
 */
$correct = NestedArray::mergeDeep($tokens, $sub_tokens);

Remaining tasks

None.

User interface changes

None.

API changes

None.

Data model changes

None.

πŸ› Bug report
Status

Active

Version

2.2

Component

Code

Created by

πŸ‡΅πŸ‡ΉPortugal lolgm

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024