Drupal - HTML mail without using modules
Without any module it is not possible to send HTML emails. This is because the default plugin the MailManager
class (which is a plugin manager) uses to effectively send emails contains the following code. (See PhpMail.php.)
public function format(array $message) {
// Join the body array into one string.
$message['body'] = implode("\n\n", $message['body']);
// Convert any HTML to plain-text.
$message['body'] = MailFormatHelper::htmlToText($message['body']);
// Wrap the mail body for sending.
$message['body'] = MailFormatHelper::wrapMail($message['body']);
return $message;
}
The comment clearly states: Convert any HTML to plain-text.
If you look at MailFormatHelper::htmlToText()
, you will see the code that is converting the HTML markup in plain text, in particular the following that changes any <a>
tag as you saw in your test email.
// Replace inline <a> tags with the text of link and a footnote.
// 'See <a href="https://www.drupal.org">the Drupal site</a>' becomes
// 'See the Drupal site [1]' with the URL included as a footnote.
static::htmlToMailUrls(NULL, TRUE);
$pattern = '@(<a[^>]+?href="([^"]*)"[^>]*?>(.+?)</a>)@i';
$string = preg_replace_callback($pattern, 'static::htmlToMailUrls', $string);
$urls = static::htmlToMailUrls();
$footnotes = '';
if (count($urls)) {
$footnotes .= "\n";
for ($i = 0, $max = count($urls); $i < $max; $i++) {
$footnotes .= '[' . ($i + 1) . '] ' . $urls[$i] . "\n";
}
}
You need a module that defines a new mail plugin using a different implementation of the format()
method and make the MailManager
class use it. As said in the documentation for MailManager::getInstance()
, the class uses the configuration in system.mail.interface. (The array returned from \Drupal::config('system.mail.interface')
.) In your example, an array value for custom_forward_formard (e.g. 'custom_forward_forward => 'custom_forward_mail'
, where custom_forward_mail is the plugin ID for the class implemented by your module) would do the trick.