官术网_书友最值得收藏!

Using tokens

If you remember, the custom MailLogger we wrote had a $context array as an argument to its log() method. This contains some relevant information to the thing being logged--channel, uri, timestamp, user, and others. We could use this data in conjunction with the token API to include information about the user who was signed in at the moment the error happened and was logged-in in the email. This can be useful information.

We will need to do two simple things to achieve this. First, we will need to alter our MailLogger::log() method to get the user account that was signed in and pass it to the mailer in the $param array:

  /**
* {@inheritdoc}
*/
public function log($level, $message, array $context = array()) {
if ($level !== RfcLogLevel::ERROR) {
return;
}

/** @var AccountProxyInterface $account */
$account = $context['user'];
$to = $this->configFactory->get('system.site')->get('mail');
$langode = $this->configFactory->get('system.site')->get('langcode');
$variables = $this->parser->parseMessagePlaceholders($message, $context);
$markup = new FormattableMarkup($message, $variables);
\Drupal::service('plugin.manager.mail')->mail('hello_world', 'hello_world_log', $to, $langode, ['message' => $markup, 'user' => $account]);
}

An important thing to note here is that we are talking about the currently logged-in user, which means that it is not a fully loaded user, but a simple AccountProxyInterface, which is a more shallow object rather than the full entity--the user session basically. If you are ever dealing with this object and need the entire User entity, you'll need to load it by its ID. However, in our case, the user module's hook_tokens() implementation does that for us, as we will see in a moment.

Finally, we will need to alter our hook_mail() implementation to handle this user and add another string to our mail body and, of course, replace a token:

/**
* Implements hook_mail().
*/
function hello_world_mail($key, &$message, $params) {
switch ($key) {
case 'hello_world_log':
$message['from'] = \Drupal::config('system.site')->get('mail');
$message['subject'] = t('There is an error on your website');
$message['body'][] = $params['message'];
if (isset($params['user'])) {
$user_message = 'The user that was logged in: [current-user:name]';
$message['body'][] = \Drupal::token()->replace($user_message, ['current-user' => $params['user']]);
}

break;
}
}

As you can see, if we receive the user parameter, we will add a new paragraph to our email. This is a simple string that informs us about the user who was logged in. However, in doing so, we use the token service (statically) to replace that string with the token value. The replace() method of the service takes a string and optionally an array of data objects keyed by the type (group) of the tokens they should be used for.

The choice of a token and type in this case is important. The User module defines the user and current-user types. The difference between the two types, if you check inside user_tokens(), is that the latter simply delegates to the former after it loads a full user entity. We could, alternatively, have done that ourselves and then passed the user type, but why should we? If somebody has done that for us already, we should not have to do it again.

So, that's it. Now, the email message will get an extra line that contains the dynamically generated username of the currently logged-in user at the time the error happened. Under the hood, the token service scans the string, extracts the token, and calls all hook_tokens() implementations. The User module is the one that can return the replacement for this token based on the User object it receives.

主站蜘蛛池模板: 凤台县| 陆丰市| 叶城县| 凌海市| 安丘市| 云浮市| 余姚市| 昌图县| 竹山县| 隆化县| 辉南县| 巴里| 浪卡子县| 当雄县| 太仓市| 新乐市| 醴陵市| 浮山县| 清河县| 西城区| 那坡县| 德钦县| 怀安县| 闽清县| 彰化县| 九台市| 温泉县| 涡阳县| 辰溪县| 峨眉山市| 苗栗县| 腾冲县| 大厂| 湄潭县| 安化县| 万盛区| 铜梁县| 金华市| 乌拉特后旗| 司法| 碌曲县|