Change record status: 
Project: 
Introduced in branch: 
8.x
Introduced in version: 
8.x
Description: 

Mail backends are now annotated plugins, and can be discovered and implemented via the new plugin.manager.mail service.

drupal_mail_service() has been removed

The earlier mail.factory service has been removed, and its functionality has been merged into plugin.manager.mail.

Furthermore, the config setting system.mail.interface, which identifies the mail plugin used for a particular message, now takes plugin IDs as values rather than class names.

Creating a mail plugin

To provide a new mail backend in a custom module named mymodule, you must implement Drupal\Core\Mail\MailInterface within the \Drupal\mymodule\Plugin\Mail namespace, and annotate the class:

namespace Drupal\mymodule\Plugin\Mail;

use Drupal\Core\Mail\MailInterface;

/**
 * A custom mail backend.
 *
 * @Mail(
 *   id = "mymodule_mailer",
 *   label = @Translation("My custom mailer"),
 *   description = @Translation("An example mail plugin implementation.")
 * )
 */
class MymoduleMailer implements MailInterface {
  public function format(array $message) {
    // ...
  }
  public function mail(array $message) {
    // ...
  }
}

See the API documentation for MailInterface for implementation details.

Retrieving mail plugins

Previously in Drupal 8, there was no way to retrieve a list of MailInterface classes. Now, you can use the plugin.manager.mail service:

// Get a keyed array of mail plugin definitions.
$definitions = \Drupal::service('plugin.manager.mail')->getDefinitions();

// Get a single definition by plugin ID.
$plugin_id = 'php_mail';
$definition = \Drupal::service('plugin.manager.mail')->getDefinition($plugin_id);

// Create an instance of a specific mail plugin.
$plugin_id = 'php_mail';
$mailer = \Drupal::service('plugin.manager.mail')->createInstance($plugin_id);

Mail plugin selection

The Drupal 8 config setting system.mail.interface is a keyed array that maps the message ID to the mail plugin it should use. The values used in this array are now plugin IDs.

Before in Drupal 8

\Drupal::config('system.mail')->set('interface.default', 'Drupal\Core\Mail\Plugin\Mail\PhpMail')->save();

After

\Drupal::config('system.mail')->set('interface.default', 'php_mail')->save();
Impacts: 
Module developers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done