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
- Use a service class method (e.g.,
[$this, 'myMethod']) as thecallbackforToken::replace(). - Read the documentation and note it refers to it as a "function".
- 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 forToken::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.
| Comment | File | Size | Author |
|---|---|---|---|
| #30 | interdiff.txt | 1.01 KB | kim.pepper |
| #30 | 1975136-token-callable-30.patch | 1.89 KB | kim.pepper |
| #26 | drupal_1975136_26.patch | 2.91 KB | xano |
| #26 | interdiff.txt | 679 bytes | xano |
Issue fork drupal-1975136
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:
- 1975136-tokenreplace-should-accept
changes, plain diff MR !12606
Comments
Comment #1
xanoComment #3
xanoComment #4
xano1979138#5 explains that this is not possible in PHP 5.3. I did confirm that it works in PHP 5.4, though.
Comment #5
xano#3: drupal_1975136_01.patch queued for re-testing.
Comment #6
xanoComment #7
xanoI don't know what's up with the testbot. Let's try again.
Comment #9
dave reidI 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.
Comment #10
xanoAll 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.
Comment #11
xano7: drupal_1975136_6.patch queued for re-testing.
Comment #14
kim.pepperThis is important for any module that is implementing calling Token->replace() from a service class that doesn't have a procedural callback method.
Comment #16
xanoComment #18
xanoComment #19
kim.pepperLooks good to me. Needs change notice.
Comment #20
berdirHm.
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.
Comment #21
kim.pepperComment #22
xanoCool! 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.
Comment #23
xanoComment #24
berdirNope, 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.
Comment #26
xanoComment #27
kim.pepperThese changes
arearen't required anymore and seem unrelated.Comment #28
kim.pepper@Xano are you still working on this?
Comment #29
xanoNot at the moment. Feel free to do some work on this.
Comment #30
kim.pepperFixes for #27
Comment #31
kim.pepperComment #32
kim.pepperComment #33
larowlanlooks good
Comment #34
chx commented/me scratches head. Why is this patch necessary? Aren't we running PHP 5.4? http://3v4l.org/GctSA
Comment #35
chx commentedThe doxygen update from function to callable is useful I guess but the code change, nah.
Comment #36
berdirWas 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.
Comment #37
chx commentedIf we don't we should. I thought the patches were usually just changing if function_exists to is_callable.
Comment #38
xano#2320491: Add a callable resolver could be interesting for this issue.
Comment #39
dave reidComment #53
smustgrave commentedThank 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!
Comment #54
berdirStill useful, but per #34, we only need the docblock change.
Comment #55
smustgrave commentedThink a valid novice task?
Comment #56
berdirAbsolutely. Task: Convert the first chunk in the patch to a merge request.
Comment #58
shubham_pareek_19 commentedWorking on it.
Comment #60
shubham_pareek_19 commentedmade the suggested changes please review.
Comment #61
smustgrave commentedComment #62
shubham_pareek_19 commentedComment #63
shubham_pareek_19 commentedsummary updated.
Comment #64
catchComment #67
catchCommitted/pushed to 11.x and cherry-picked to 10.6.x, thanks!