Problem/Motivation
TokenTokenInfoHooks::tokenInfoAlter() automatically registers a language chained token ([entity_type:language:*]) for every content entity token type that doesn't already define its own.
This registration does not check whether the entity type actually has a langcode field. When the token is resolved, TokenTokensHooks::tokens() reads the field directly instead of using the entity's \Drupal\Core\Entity\EntityInterface::language() method.
Not every content entity is required to declare a langcode entity key / base field - it's entirely valid for a simple, non-translatable content entity to omit it. For such entities this throws:
php.ERROR: InvalidArgumentException: Field langcode is unknown. in Drupal\Core\Entity\ContentEntityBase->getTranslatedField() (line 630 of /var/www/html/web/core/lib/Drupal/Core/Entity/ContentEntityBase.php).
Note that for the field tokens it is already using this method for getting a proper language instead of direct access: TokenTokensHooks::fieldTokens()
Steps to reproduce
- Define a content entity type that does not declare a
langcodeentity key - Save an instance of this entity.
- Resolve any token from its token tree that touches the auto-registered
languagesub-tree, e.g:
<?php use Drupal\module\Entity\MyEntity; use Drupal\Core\Render\BubbleableMetadata; $entity = MyEntity::load(1); $replacements = \Drupal::token()->generate( 'my_entity', ['language:langcode' => '[my_entity:language:langcode]'], ['my_entity' => $entity], [], new BubbleableMetadata(), );This also happens implicitly when eagerly resolving a full token tree with
'values' => TRUEviaTreeBuilder::buildTree()(e.g. any token browser/preview UI built on top of Token module). Field langcode is unknown.is thrown.
Proposed resolution
Replace the direct field access with the entity's own language method:
$language_options = array_merge($options, [
'langcode' => $entity->language()->getId(),
]);
Remaining tasks
User interface changes
API changes
Data model changes
Issue fork token-3611063
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 #3
niklan