Рассмотрим два варианта, как зацепиться к отправляемым письмам и внести туда свои изменения.
Первый вариант заключается в прямом изменении тела письма перед отправкой. Для этого мы реализуем hook_mail_alter(&message).
MAIL ALTER хук
Переменная $message содержит весь набор данных, используемых при отправке письма. Там есть и имя модуля, и ключ письма, а также дополнительные данные, передаваемые в MailManagerInterface::mail как $params.
Рассмотрим гипотетический пример, подстановки некого кода верификации из учетной записи пользователя во время отправки сообщения о регистрации пользователя. Мы предполагаем, что было создано дополнительное поле для сущности user — field_verification_code.
| 1 2 3 4 5 6 7 8 9 10 11 | /**  * implements hook_mail_alter  */ function MYMODULE_mail_alter(&$message) {   if ($message['module'] == 'user' && $message['key'] == 'register_pending_approval') {     $message['body'] = str_replace(       'verification_code',        $message['params']['account']->field_verification_code->value,       $message['body']);   } } | 
Объявление токена
То, что мы делали в предыдущем примере можно реализовать, используя токены, которые являются частью ядра системы, начиная с 8й версии.
Давайте объявим токен [user:verification-code], и при использовании его в шаблоне письма, он автоматически будет заменяться значением, которое мы запрограммируем.
Хуки подсистемы токенов должны быть объявлены в файле MYMODULE.tokens.inc. Это hook_tokens_info и hook_tokens. Первый описывает новые токены, а второй их реализует.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | <?php /**  * @file  * Builds placeholder replacement tokens for user-related data.  */ use Drupal\Core\Render\BubbleableMetadata; /**  * Implements hook_token_info().  */ function MYMODULE_token_info() {   // формируются массивы с типами и кодами токенов   // я дополняю группу user, токеном verification-code   $types['user'] = [     'name' => t('Users'),     'description' => t('Tokens related to individual user accounts.'),     'needs-data' => 'user',   ];   $user['verification-code'] = [     'name' => t("Verification code."),     'description' => t("Verification code after user registration."),   ];   return [     'types' => $types,     'tokens' => ['user' => $user],   ]; } /**  * Implements hook_tokens().  */ function api_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {   $token_service = \Drupal::token();   $url_options = ['absolute' => TRUE];   if (isset($options['langcode'])) {     $url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']);     $langcode = $options['langcode'];   }   else {     $langcode = NULL;   }   $replacements = [];   if ($type == 'user' && !empty($data['user'])) {     /** @var \Drupal\user\UserInterface $account */     $account = $data['user'];     foreach ($tokens as $name => $original) {       switch ($name) {         // Basic user account information.         case 'verification-code':           // In the case of hook user_presave uid is not set yet.           $replacements[$original] = $account->id() ? $account->field_verification_code->value : '';           break;       }     }   }   return $replacements; } |