Problem/Motivation

When token->scan is called with null as a string, preg_match_all will throw a deprecated warning in PHP8+.

Steps to reproduce

Call token->scan(Null)

Proposed resolution

Deprecate calling token->scan with a non-string parameter. Add a string typehint in Drupal 11.

Draft change record

Remaining tasks

  • Change record

User interface changes

none

API changes

Deprecated loosely typed parameter in Drupal 10.
Typehint added in Drupal 11.

Data model changes

none

Release notes snippet

none

Issue fork drupal-3267785

Command icon 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:

Comments

kriboogh created an issue. See original summary.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Christopher Riley’s picture

Thank you for this patch, this issue was making me crazier than usual.

Christopher Riley’s picture

Spoke too soon. I applied the patch but when I go the dev page for node tokens it still kicks with an error this time. Time to go back to digging.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

ciprian.stavovei’s picture

Status: Active » Needs review
StatusFileSize
new865 bytes

I also encountered this issue in multiple scenarios and first I tried creating/applying patches for each module that uses Token and was having this issue but in the end got to the conclusion that the best would be to fix the problem at the root and not in every place that method is used.
I tried the fix from the pull request from this issue and it fixed our problem. Before that I dag a lot to find where the scan() or replace() methods were being used and to prevent "NULL" from being passed but couldn't get to the bottom of all. So then I tried to fix it at the root and it worked fine and didn't create any other issue. I Added the fix from the PR also as patch so that people can easily apply it until this gets merged.
I believe that it would be much better to get this fixed in core and not in every other module where it is being used.

damienmckenna’s picture

The Token::scan() API documentation specifically states that the first argument should be a string, not a NULL, so it should be up to other code to make sure the argument isn't a NULL.

scott_euser’s picture

So really this is a symptom of another bug, that token_default_tokens_alter() in the Token module sometimes sends NULL to the token replacement service. In my case:

1. content type A has entity reference field to content type B
2. use token in metatag module to output [field_reference_example:entity:url] from content type A
3. open example of content type A where reference field is empty
4. error shown

\Drupal::service('token_default.manager')->replaceMissingTokensWithDefaults(...) possibly returns NULL replacements. Patch attached, but possibly this is still just solving a symptom rather than the problem.

If the others who experienced this issue can also confirm that you have Token contrib module in place, I think we can safely move this issue over to Token.

scott_euser’s picture

Apologies, its Token Default not Token that was the cause of the problem for me. I created an issue for that here https://www.drupal.org/project/token_default/issues/3320681 - if others can confirm that that also stops the php notice for them, we can close this issue.

darvanen’s picture

Status: Needs review » Needs work
Issue tags: +Bug Smash Initiative

I agree that this issue originates elsewhere but don't close this issue, we can use it to implement strong typing on the scan() function. We'll need:

  1. A patch for Drupal 10 which catches non-string parameters, triggers a drupal deprecation warning and replaces NULL with an empty string
  2. A patch for Drupal 11 which sets a string type on the $text parameter and has no deprecation warning or replacement

This might qualify as a task though, rather than a bug, I'll ask in #bugsmash.

darvanen’s picture

Title: Token scan preg_match_all deprecation warning » Deprecate passing non-string parameters to \Drupal\Core\Utility\Token::scan then implement typehint
Category: Bug report » Task

Verdict's in, moving to task.

darvanen’s picture

Issue summary: View changes
Status: Needs work » Needs review
Issue tags: +Needs change record
StatusFileSize
new860 bytes

It would seem I was wrong about a patch for Drupal 11, I'm not sure how that is being handled.

Here's a patch adding the deprecation. I don't *think* this needs a test but I could be wrong.

darvanen’s picture

StatusFileSize
new859 bytes

Oops, bad copy/paste in previous patch. Let's try that again.

rahul.shinde’s picture

LGTM Thanks @darvanen.

acbramley’s picture

and replaces NULL with an empty string

Is this not relevant anymore? Seems like it would be needed?

darvanen’s picture

Issue summary: View changes
Issue tags: -Needs change record
StatusFileSize
new652 bytes
new885 bytes

Thanks @acbramley, I did forget that, I also completely forgot the change record, here's a draft.

darvanen’s picture

StatusFileSize
new767 bytes
new890 bytes

Oops, this should work better. I have tested casting NULL to a string and it does work.

smustgrave’s picture

Status: Needs review » Needs work

Believe the change record needs to be in the trigger_error no?

darvanen’s picture

Status: Needs work » Needs review
StatusFileSize
new865 bytes
new931 bytes

Good point, the example I copied from didn't have one but you're right, that should be there.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs Review Queue Initiative

That was quick! Looks good to me.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new4.29 KB
new5.2 KB

We should be adding test coverage of this deprecation because it contains some logic. I looked for existing test coverage of Token::scan() and I found core/modules/system/tests/src/Functional/System/TokenScanTest.php which is a pointless functional test - it can be a unit test - and I found a unit test \Drupal\Tests\Core\Utility\TokenTest - which sets up a token service for us to use in testing - so I moved everything there.

rohan-sinha’s picture

Status: Needs review » Reviewed & tested by the community

Tested the Patch on #22 working fine for me, D10

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed f2e1dcd and pushed to 10.1.x. Thanks!

  • catch committed f2e1dcdc on 10.1.x
    Issue #3267785 by darvanen, kriboogh, alexpott, ciprian.stavovei,...
catch’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

darvanen’s picture

@catch do we need to adjust 11.x now that it is available? Or is that something that happens later?

Oh I see it's just an issue queue placeholder. How *do* we ensure 11 gets updated?