Problem/Motivation
On Drupal 11, Smart Trim triggers a fatal error when tokens are evaluated:
//Call to undefined function _token_field_label() line 34
$labels = _token_field_label($entity_type_id, $field_name);
The error originates from:
modules/contrib/smart_trim/smart_trim.tokens.inc line 34
Specifically in hook_token_info_alter(), where Smart Trim calls the internal Token helper function _token_field_label().
This function no longer exists in Drupal 11, causing a hard failure for anonymous users and during cache rebuilds.
Steps to reproduce
- Install Drupal 11.3.x
- Enable the Token module
- Enable Smart Trim 2.2.0
- Rebuild caches or load a page that evaluates tokens (often anonymous pages)
Runtime proof
drush php:eval "var_dump(function_exists('_token_field_label'));"
Output on Drupal 11:
bool(false)
Proposed resolution
foreach ($fields as $field_name => $field) {
assert($field instanceof FieldStorageDefinitionInterface);
//$labels = _token_field_label($entity_type_id, $field_name);
//$label = array_shift($labels);
// Drupal 11–safe way to get the label.
$label = $field->getLabel() ?: $field_name;
if ($field->getType() === 'text_with_summary') {
$info['tokens'][$token_type][$field_name . '-smart-trim'] = [
'name' => t('@label (Smart trim summary)', ['@label' => $label]),
'description' => t('Smart trimmed version of the field or the summary.'),
];
}
}
| Comment | File | Size | Author |
|---|---|---|---|
| #12 | 3566575-12.patch | 1.76 KB | jonasanne |
Issue fork smart_trim-3566575
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
Comment #2
harpade commentedComment #3
aelfendir commentedI just encountered this same issue with Drupal 10.5.8 and Smart Trim 2.2.0 when updating modules.
Apparently related to recent changes in Token module (https://www.drupal.org/project/token/releases/8.x-1.17). Token updated from 1.16.0 to 1.17.0 in my case. When I downgrade Token back to 1.16.0, the error goes away.
Comment #4
jurgenhaasJust ran into this as well, and yes, the function
_token_field_labelno longer exists in the token module since they implemented OO hooks in the latest release. Functions with a leading underscore like_token_field_labelare private and shouldn't ever be used as it is expected that they either change or disappear without notice.This one is now
\Drupal\custom_field\Hook\TokenHooks::tokenFieldLabel, but with a private scope, so it can't be used even with an update code here in smart_trim. To solve this, the method needs to be implemented by smart_trim itself.Comment #6
jurgenhaasComment #7
mrshowermanI have the same issue. Was working on a solution when I found out that @jurgenhaas had already fixed it.
Left a small nit on the MR, otherwise working fine.
Agree that this is critical. Thanks!
Comment #8
mrshowermanComment #9
lostcarpark commentedHmmm, this is probably the quickest to fix the problem, but I don't love it as a long term solution.
We are replacing a global public internal function (that we probably shouldn't have been calling in the first place), with our own global public internal function.
I think a cleaner solution would be to create a service to provide our version of the function. This would mean that the function wouldn't need to be loaded into memory until needed (afaik, global functions have to be always loaded). It would also allow the functions dependencies to be injected. Unfortunately, I think we'd have to use
\Deupal::service()to call our service function from the tokens.inc file.As an aside, why are we still using tokens.inc files in modules, rather than a plugin?
Comment #10
jurgenhaas@lostcarpark couldn't agree more. As you said, this needs a quick resolution and hence, this approach is probably the right way for a patch release maybe as soon as today?
The proper solution would be to implement OO hooks in smart_trim as well. That would then also bring tokens into a hook class, you don't even need plugins for that.
Comment #11
kieran.cottPatch from mr !119 works for me, grateful for the speedy response on this!
Comment #12
jonasanne commentedUploading the diff of the MR to use it as a patch.
I can confirm this patch works!
Thanks for the quick fix.
Comment #15
ckhaliloHi,
I have made some changes in My PR, with Dependency Injection.
This fix for both D10 and D11
Best Regards
Khalil
Comment #16
ben25 commentedthanks for the quick work on this guys! lots of sites are breaking due to this lol
Comment #17
lostcarpark commentedTests were failing. The issue seems to have been with field storage creation for Body field. I've added creation if not found to fix. Passing in !119. Will cherry-pick into !120.
Comment #18
lostcarpark commented!120 tests are now passing for all except
previous major. This seems to be because there isn't an entry for SmartTrimHooks in services.yml.Comment #19
joegl commentedPatch in #12 applies successfully to 2.2.0. The latest changes to MR 119 do not apply cleanly as a patch. I did not test MR 120.
Comment #20
lostcarpark commented@jurgenhaas, I will be talking with @ultimike later today. If we could have this issue RTBC, I'm sure it would help him to get a release with the fix as quickly as possible.
I'm wondering is there a test case we can add to explicitly cover off this bug, or is it enough that the existing tests fail without it?
Comment #21
lostcarpark commented@ckhalilo I do like this approach. Will discuss which change to go with with @ultimike. I wonder did you omit to push the updated services.yml, as the SmartTrimHooks class isn't defined as a service, which prevents the .module file hooks from calling it.
Comment #22
ckhaliloHi @lostcarpark
The service already updated : https://git.drupalcode.org/project/smart_trim/-/blob/f54812b37c6c8ad21f1...
Take your time.
Best Regards.
Khalil
Comment #24
digitaltodd commentedI'm seeing this too - just reported it in token, since I just did an update
https://www.drupal.org/project/token/issues/3566726
on drupal 10.6.1
Comment #25
ultimikeI've reviewed this during DrupalEasy Office Hours with @lostcarpark and others - thanks so much to @harpade, @jurgenhass, @lostcarpark, @mrshowerman, @jonasanne, and @ckhalilo.
I added one small comment to clarify the change in the test.
Before tagging a new release, I'm going to leave this at "Needs review" - will someone please confirm that this all works in older version(s) of Token (8.x-1.16 or slightly earlier.)
thanks,
-mike
Comment #27
johnatas commentedHey,
I can confirm the patch #12 is OK with :
Thanks for the work.
Comment #28
helmo commentedThanks,
I can also confirm that the patch from #12 works on core 10.6.2 and token 1.17.0
I first noticed the problem when visiting /admin/reports/status
Comment #29
ultimikeI DM'd with @markie earlier today and he suggested that we update the composer.json to require Token 8.1-1.17
I'm away from my laptop for the next few days - can someone else do this, please?
thanks,
-mike
Comment #31
lostcarpark commentedI've opened MR !121 which updates the minimum version of Token to 8.x-1.17.
I suggest a new minor release. It's been over a year since 2.2.0 was released, and there are several unreleased features in the 2.x branch, including the token support, so a 2.3.0 release would make sense.
Comment #33
johnatas commentedHi,
Version 2.3.1 fixes the issue. Can we consider this issue as resolved?
Comment #34
aelfendir commentedThanks for the swift action on this issue, everyone!
I tested Smart Trim 2.3.1 with Token 1.17.0 (on Drupal 10.5.8) and everything seems to work fine now.
Comment #35
mark_fullmerSince Token 1.17.0 declares its core compatibility at ^10.3, if Smart Trim is going to declare its minimum compatible version of Token at 1.17.0, then Smart Trim's minimum core compatibility becomes ^10.3. Right now, it's set to ^10.1.
Comment #36
eduardo morales albertiWe got the following error on our site on the site install after upgrading from the 2.2.0 to 2.3.1 from Drupal 11.2.10:
We need more info, but here is the backtrace:
Comment #37
eduardo morales albertiIt is quite similar to the issue https://www.drupal.org/project/drupal/issues/3495587 and could be related to the plugin definition. We are not sure, but it is possible that field plugin properties do not support translation. At least we saw that on other modules https://git.drupalcode.org/project/butils/-/commit/b9a19526f68975f389c11...
And in this case, the error seems to come from the translated field label.
https://git.drupalcode.org/project/smart_trim/-/blob/2.x/src/Plugin/Fiel...
Comment #38
eduardo morales albertiThe smart_trim 2.3.1 version introduced a new SmartTrimTokens class that calls $this->entityFieldManager->getFieldLabels().
\Drupal\Core\Entity\EntityFieldManager::getFieldLabels
$field->getLabel() returns a TranslatableMarkup object, not a plain string. Then on line 722, the code tries to use this object as an array key:
isset($label_counter[$label]) // $label is a TranslatableMarkup object
In PHP 8.x, you cannot use an object as an array key unless it's explicitly convertible. The isset() call attempts to access $label_counter using a TranslatableMarkup object as the offset, which throws:
TypeError: Cannot access offset of type Drupal\Core\StringTranslation\TranslatableMarkup in isset or empty
Comment #39
eduardo morales albertiIt is possible that it is related to our serializer (igbinary)
On comment https://www.drupal.org/project/drupal/issues/3495587#comment-16234991
When Drupal caches field definitions (which include labels), the serializer affects how TranslatableMarkup objects are stored and retrieved:
- With standard PHP serializer: Sometimes cached TranslatableMarkup objects might get converted to strings during serialization/unserialization cycles
- With igbinary: Object types are preserved more strictly, so TranslatableMarkup objects remain as objects when retrieved from cache
But there is a Drupal core bug at line 722 - the code should always cast $label to string before using it as an array key, regardless of serializer:
$label = (string) $field->getLabel();
So the bug is in Drupal core, and not smart_trim.
Comment #40
jds1I had this issue on 10.6.2 and Smart Trim 2.2.0. Upgrading to 2.3.1 fixed it. Based on comments #33 and #34 I'm marking this RTBC. Not sure if the other comments later in this issue warrant moving this back to "Needs Work" or creating a follow-up, but I leave that up to the community =)
Comment #41
joegl commentedThis should be probably be closed since the specific issue was addressed and merged in a recent release. Eduardo may want to open a new issue.
Comment #42
ultimikeMarking this as fixed.
I moved updating the Drupal core version requirement to #3569291: Update Drupal core requirement to ^10.3
-mike
Comment #44
eduardo morales albertiCreated issue to solve the compatibility with D11.3 https://www.drupal.org/project/smart_trim/issues/3570967
Comment #46
mstrelan commentedSince 2.2.0 claims it is compatible with ^11 this should be backported to a 2.2.x branch.