Problem/Motivation
When using HTML markup with Symfony Mailer, the System Module discards the information whether the given Message in the context is an instance of MarkupInterface or not. The Symfony Mailer itself relies on the information when processing HTML Markup.
As a result, the email displays escapted HTML as plain text.
/**
* Implements hook_mail().
*/
function system_mail($key, &$message, $params) {
$token_service = \Drupal::token();
$context = $params['context'];
$subject = PlainTextOutput::renderFromHtml($token_service->replace($context['subject'], $context));
$body = $token_service->replace($context['message'], $context); // <--- even if the message is a MarkupInterface the variable $body always is a string
$message['subject'] .= str_replace(["\r", "\n"], '', $subject);
$message['body'][] = $body;
}
public function format(array $message) {
foreach ($message['body'] as &$part) {
// If the message contains HTML, convert it to plain text (which also
// wraps the mail body).
if ($part instanceof MarkupInterface) {
$part = MailFormatHelper::htmlToText($part); // <-- we want this ...
}
// If the message does not contain HTML, it still needs to be wrapped
// properly.
else {
$part = MailFormatHelper::wrapMail($part); // <-- but our HTML markup gets processed here
}
}
// Join the body array into one string.
$message['body'] = implode("\n\n", $message['body']);
return $message;
}
Steps to reproduce
$context = [
'subject' => 'Whatever you like!',
'message' => Markup::create('<p><strong>Gimme</strong> some text!</p>'),
];
\Drupal::service('plugin.manager.mail')->mail('system', 'action_send_email', $user_mail, $langcode, [
'context' => $context
]);
Proposed resolution
Check if the message in the context is a MarkupInterface and rewrap the tokenized output.