Tokens are not correctly replaced

Created on 30 April 2021, over 3 years ago
Updated 23 June 2023, over 1 year ago

Problem/Motivation

I have a custom entity ("o_app") that has a user reference field ("responsible"). I created a new token for this field - "user_card". This token is replaced with nice rendered information about the user.

Steps to reproduce

My event dispatcher.

<?php

namespace Drupal\my_module\EventSubscriber;

use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\core_event_dispatcher\Event\Token\TokensInfoEvent;
use Drupal\core_event_dispatcher\Event\Token\TokensReplacementEvent;
use Drupal\core_event_dispatcher\ValueObject\Token;
use Drupal\hook_event_dispatcher\HookEventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * Hooks Subscriber.
 */
class HooksSubscriber implements EventSubscriberInterface {

  use StringTranslationTrait;

  /**
   * Drupal\Core\Session\AccountProxyInterface definition.
   *
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
  protected $currentUser;

  /**
   * The renderer.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;

  /**
   * Constructs a new HooksSubscriber object.
   *
   * @param \Drupal\Core\Session\AccountProxyInterface $current_user
   *   The current user.
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   The renderer.
   */
  public function __construct(
    AccountProxyInterface $current_user,
    RendererInterface $renderer
  ) {
    $this->currentUser = $current_user;
    $this->renderer = $renderer;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[HookEventDispatcherInterface::TOKEN_INFO] = ['tokenInfo'];
    $events[HookEventDispatcherInterface::TOKEN_REPLACEMENT] = ['tokenReplacement'];

    return $events;
  }

  /**
   * The hook_token_info() implementation.
   *
   * @param \Drupal\core_event_dispatcher\Event\Token\TokensInfoEvent $event
   *   The event.
   */
  public function tokenInfo(TokensInfoEvent $event) {
    $token = Token::create('user', 'user_card_theme', $this->t('User Card theme'));
    $token->setDescription('Used for email about status changes.');
    $event->addToken($token);
  }

  /**
   * The hook_tokens() implementation.
   *
   * @param \Drupal\core_event_dispatcher\Event\Token\TokensReplacementEvent $event
   *   The event.
   */
  public function tokenReplacement(TokensReplacementEvent $event) {
    if ($event->forToken('user', 'user_card_theme')) {
      /** @var \Drupal\user\UserInterface $user_entity */
      $user_entity = $event->getData('user');
      $data = [
        '#theme' => 'user_card_email_theme',
        '#account' => $user_entity,
      ];
      $data = $this->renderer->renderPlain($data);
      $event->setReplacementValue('user', 'user_card_theme', $data);
    }
  }

}

$this->token->replace('[o_app:responsible:entity:user_card_theme]', ['o_app' => $application])
^This doesn't replace the custom token because there is no such replacement. The HooksSubscriber::tokenReplacement() method returns
["[user:user_card_theme]" => .....] instead of ["[o_app:responsible:entity:user_card_theme]" => .....].

🐛 Bug report
Status

Needs work

Version

2.0

Component

Code

Created by

🇺🇦Ukraine nikita_tt

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024