Problem/Motivation

The Token::replace() method supports a $options['callback'] parameter to allow modules to provide token replacements. However, the documentation previously referred to this as a “function”, even though any valid PHP callable (such as object method or closure) is technically supported.

This lack of clarity caused confusion, especially during the Drupal 8 port of the Token contrib module, where object-oriented approaches (e.g., service classes with methods) became more common.

Steps to reproduce

  1. Use a service class method (e.g., [$this, 'myMethod']) as the callback for Token::replace().
  2. Read the documentation and note it refers to it as a "function".
  3. This can cause a developer to question if non-function callables are supported or behave correctly.

Proposed resolution

Clarify the callback parameter in the docblock of \Drupal\Core\Utility\Token::replace() to specify that any callable is accepted. This brings the documentation in line with actual behavior.

This is a documentation-only change and does not alter any existing logic or behavior.

Remaining tasks

  • Update docblock for Token::replace() to reflect callable support
  • Review and approval

User interface changes

None.

API changes

None. The method already accepts any callable. This change is to the documentation only.

Data model changes

None.

Release notes snippet

Clarified documentation for the Token::replace() method to state that any valid callable can be passed via the $options['callback'] parameter.

Issue fork drupal-1975136

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

xano’s picture

Status: Active » Needs review
StatusFileSize
new1.61 KB

Status: Needs review » Needs work

The last submitted patch, drupal_1975136_00.patch, failed testing.

xano’s picture

Status: Needs work » Needs review
StatusFileSize
new1.64 KB
xano’s picture

1979138#5 explains that this is not possible in PHP 5.3. I did confirm that it works in PHP 5.4, though.

xano’s picture

#3: drupal_1975136_01.patch queued for re-testing.

xano’s picture

StatusFileSize
new1.91 KB
xano’s picture

StatusFileSize
new1.91 KB

I don't know what's up with the testbot. Let's try again.

Status: Needs review » Needs work

The last submitted patch, drupal_1975136_6.patch, failed testing.

dave reid’s picture

I get fixing the documentation, but I'm not sure this is really necessary. Are we going to convert all hooks and alters to use this? If so, then I'd welcome this change.

xano’s picture

All over core we are supporting any callable as callbacks instead of just functions. Most of form API has now been converted, for instance. Hooks are untouched, but that is partly because they are functions by definition.

xano’s picture

Status: Needs work » Needs review

7: drupal_1975136_6.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, 7: drupal_1975136_6.patch, failed testing.

Status: Needs work » Needs review

kim.pepper queued 7: drupal_1975136_6.patch for re-testing.

kim.pepper’s picture

Issue summary: View changes

This is important for any module that is implementing calling Token->replace() from a service class that doesn't have a procedural callback method.

Status: Needs review » Needs work

The last submitted patch, 7: drupal_1975136_6.patch, failed testing.

xano’s picture

Status: Needs work » Needs review
StatusFileSize
new1.22 KB
new3.15 KB

Status: Needs review » Needs work

The last submitted patch, 16: drupal_1975136_16.patch, failed testing.

xano’s picture

Status: Needs work » Needs review
StatusFileSize
new575 bytes
new3.12 KB
kim.pepper’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me. Needs change notice.

berdir’s picture

Hm.

This makes this an API change because now you have to return the replacements. Makes kind of sense, but it's not needed to fix this issue.

If you use call_user_func_array($callable, array(&$replacements, $data, $options)) then it would possible to allow non-function callables without changing how they work.

kim.pepper’s picture

Status: Reviewed & tested by the community » Needs work
xano’s picture

If you use call_user_func_array($callable, array(&$replacements, $data, $options)) then it would possible to allow non-function callables without changing how they work.

Cool! Is that a recently added feature of PHP? I was always told call_user_func*() did not support references at all, so I never thought of invoking the callback this way.

xano’s picture

Status: Needs work » Needs review
StatusFileSize
new2.36 KB
new2.92 KB
berdir’s picture

Status: Needs review » Reviewed & tested by the community

Nope, that always worked, that's how all of our dynamic callbacks with by reference arguments like form validate and submit work.

Back to RTBC if it passes.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 23: drupal_1975136_23.patch, failed testing.

xano’s picture

Status: Needs work » Needs review
StatusFileSize
new679 bytes
new2.91 KB
kim.pepper’s picture

  1. +++ b/core/modules/user/user.module
    @@ -1072,7 +1072,7 @@ function user_mail($key, &$message, $params) {
    - * @param $replacements
    + * @param array $replacements
    +++ b/core/modules/user/user.module
    @@ -1084,7 +1084,7 @@ function user_mail($key, &$message, $params) {
    -function user_mail_tokens(&$replacements, $data, $options) {
    +function user_mail_tokens(array &$replacements, $data, $options) {
    

    These changes are aren't required anymore and seem unrelated.

kim.pepper’s picture

@Xano are you still working on this?

xano’s picture

Assigned: xano » Unassigned

Not at the moment. Feel free to do some work on this.

kim.pepper’s picture

StatusFileSize
new1.89 KB
new1.01 KB

Fixes for #27

kim.pepper’s picture

Title: Token::replace() should document that it accepts any type of callable » Token::replace() should accept any type of callable
Issue summary: View changes
kim.pepper’s picture

Issue summary: View changes
larowlan’s picture

Status: Needs review » Reviewed & tested by the community

looks good

chx’s picture

/me scratches head. Why is this patch necessary? Aren't we running PHP 5.4? http://3v4l.org/GctSA

chx’s picture

Status: Reviewed & tested by the community » Needs work

The doxygen update from function to callable is useful I guess but the code change, nah.

berdir’s picture

Was not aware of this, are we using it like this anywhere? I know for sure that we don't for example in the form system.

chx’s picture

If we don't we should. I thought the patches were usually just changing if function_exists to is_callable.

xano’s picture

#2320491: Add a callable resolver could be interesting for this issue.

dave reid’s picture

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.2.x-dev

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev

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

Drupal 9.3.15 was released on June 1st, 2022 and is the final full bugfix release for the Drupal 9.3.x series. Drupal 9.3.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.4.x-dev branch from now on, and new development or disruptive changes should 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.

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

Drupal 9.4.9 was released on December 7, 2022 and is the final full bugfix release for the Drupal 9.4.x series. Drupal 9.4.x will not receive any further development aside from security fixes. Drupal 9 bug reports should be targeted for the 9.5.x-dev branch from now on, and new development or disruptive changes should 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.

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

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs work » Postponed (maintainer needs more info)
Issue tags: +stale-issue-cleanup

Thank you for creating this issue to improve Drupal.

We are working to decide if this task is still relevant to a currently supported version of Drupal. There hasn't been any discussion here for over 8 years which suggests that this has either been implemented or is no longer relevant. Your thoughts on this will allow a decision to be made.

Since we need more information to move forward with this issue, the status is now Postponed (maintainer needs more info). If we don't receive additional information to help with the issue, it may be closed after three months.

Thanks!

berdir’s picture

Status: Postponed (maintainer needs more info) » Active

Still useful, but per #34, we only need the docblock change.

smustgrave’s picture

Think a valid novice task?

berdir’s picture

Absolutely. Task: Convert the first chunk in the patch to a merge request.

juandhr made their first commit to this issue’s fork.

shubham_pareek_19’s picture

Working on it.

shubham_pareek_19’s picture

Status: Active » Needs review

made the suggested changes please review.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs issue summary update
shubham_pareek_19’s picture

Issue summary: View changes
shubham_pareek_19’s picture

Status: Needs work » Reviewed & tested by the community

summary updated.

catch’s picture

Title: Token::replace() should accept any type of callable » Token::replace() should document that any kind of callable is allowed

  • catch committed 73afbc79 on 10.6.x
    Issue #1975136 by xano, kim.pepper, shubham_pareek_19, berdir, chx:...

  • catch committed 30b1c77b on 11.x
    Issue #1975136 by xano, kim.pepper, shubham_pareek_19, berdir, chx:...
catch’s picture

Version: 11.x-dev » 10.6.x-dev
Status: Reviewed & tested by the community » Fixed

Committed/pushed to 11.x and cherry-picked to 10.6.x, thanks!

Status: Fixed » Closed (fixed)

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