Issue #1889644 by Berdir: Convert drupal_mail_system() to a MailFactory service to allow more flexible replacements.
parent
f37f7a1e9c
commit
4d783b7369
|
@ -487,6 +487,9 @@ services:
|
||||||
flood:
|
flood:
|
||||||
class: Drupal\Core\Flood\DatabaseBackend
|
class: Drupal\Core\Flood\DatabaseBackend
|
||||||
arguments: ['@database', '@request']
|
arguments: ['@database', '@request']
|
||||||
|
mail.factory:
|
||||||
|
class: Drupal\Core\Mail\MailFactory
|
||||||
|
arguments: ['@config.factory']
|
||||||
plugin.manager.condition:
|
plugin.manager.condition:
|
||||||
class: Drupal\Core\Condition\ConditionManager
|
class: Drupal\Core\Condition\ConditionManager
|
||||||
arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler']
|
arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler']
|
||||||
|
|
|
@ -200,98 +200,21 @@ function drupal_mail($module, $key, $to, $langcode, $params = array(), $from = N
|
||||||
/**
|
/**
|
||||||
* Returns an object that implements Drupal\Core\Mail\MailInterface.
|
* Returns an object that implements Drupal\Core\Mail\MailInterface.
|
||||||
*
|
*
|
||||||
* Allows for one or more custom mail backends to format and send mail messages
|
* @param string $module
|
||||||
* composed using drupal_mail().
|
|
||||||
*
|
|
||||||
* An implementation needs to implement the following methods:
|
|
||||||
* - format: Allows to preprocess, format, and postprocess a mail
|
|
||||||
* message before it is passed to the sending system. By default, all messages
|
|
||||||
* may contain HTML and are converted to plain-text by the
|
|
||||||
* Drupal\Core\Mail\PhpMail implementation. For example, an alternative
|
|
||||||
* implementation could override the default implementation and additionally
|
|
||||||
* sanitize the HTML for usage in a MIME-encoded e-mail, but still invoking
|
|
||||||
* the Drupal\Core\Mail\PhpMail implementation to generate an alternate
|
|
||||||
* plain-text version for sending.
|
|
||||||
* - mail: Sends a message through a custom mail sending engine.
|
|
||||||
* By default, all messages are sent via PHP's mail() function by the
|
|
||||||
* Drupal\Core\Mail\PhpMail implementation.
|
|
||||||
*
|
|
||||||
* The selection of a particular implementation is controlled via the config
|
|
||||||
* 'system.mail.interface', which is a keyed array. The default implementation
|
|
||||||
* is the class whose name is the value of 'default' key. A more specific match
|
|
||||||
* first to key and then to module will be used in preference to the default. To
|
|
||||||
* specify a different class for all mail sent by one module, set the class
|
|
||||||
* name as the value for the key corresponding to the module name. To specify
|
|
||||||
* a class for a particular message sent by one module, set the class name as
|
|
||||||
* the value for the array key that is the message id, which is
|
|
||||||
* "${module}_${key}".
|
|
||||||
*
|
|
||||||
* For example to debug all mail sent by the user module by logging it to a
|
|
||||||
* file, you might set the variable as something like:
|
|
||||||
*
|
|
||||||
* @code
|
|
||||||
* array(
|
|
||||||
* 'default' => 'Drupal\Core\Mail\PhpMail',
|
|
||||||
* 'user' => 'DevelMailLog',
|
|
||||||
* );
|
|
||||||
* @endcode
|
|
||||||
*
|
|
||||||
* Finally, a different system can be specified for a specific e-mail ID (see
|
|
||||||
* the $key param), such as one of the keys used by the contact module:
|
|
||||||
*
|
|
||||||
* @code
|
|
||||||
* array(
|
|
||||||
* 'default' => 'Drupal\Core\Mail\PhpMail',
|
|
||||||
* 'user' => 'DevelMailLog',
|
|
||||||
* 'contact_page_autoreply' => 'DrupalDevNullMailSend',
|
|
||||||
* );
|
|
||||||
* @endcode
|
|
||||||
*
|
|
||||||
* Other possible uses for system include a mail-sending class that actually
|
|
||||||
* sends (or duplicates) each message to SMS, Twitter, instant message, etc, or
|
|
||||||
* a class that queues up a large number of messages for more efficient bulk
|
|
||||||
* sending or for sending via a remote gateway so as to reduce the load
|
|
||||||
* on the local server.
|
|
||||||
*
|
|
||||||
* @param $module
|
|
||||||
* The module name which was used by drupal_mail() to invoke hook_mail().
|
* The module name which was used by drupal_mail() to invoke hook_mail().
|
||||||
* @param $key
|
* @param string $key
|
||||||
* A key to identify the e-mail sent. The final e-mail ID for the e-mail
|
* A key to identify the e-mail sent. The final e-mail ID for the e-mail
|
||||||
* alter hook in drupal_mail() would have been {$module}_{$key}.
|
* alter hook in drupal_mail() would have been {$module}_{$key}.
|
||||||
*
|
*
|
||||||
* @return Drupal\Core\Mail\MailInterface
|
* @return Drupal\Core\Mail\MailInterface
|
||||||
|
* An object that implements Drupal\Core\Mail\MailInterface.
|
||||||
*
|
*
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
|
*
|
||||||
|
* @see \Drupal\Core\Mail\MailFactory::get()
|
||||||
*/
|
*/
|
||||||
function drupal_mail_system($module, $key) {
|
function drupal_mail_system($module, $key) {
|
||||||
$instances = &drupal_static(__FUNCTION__, array());
|
return Drupal::service('mail.factory')->get($module, $key);
|
||||||
|
|
||||||
$id = $module . '_' . $key;
|
|
||||||
|
|
||||||
$configuration = Drupal::config('system.mail')->get('interface');
|
|
||||||
|
|
||||||
// Look for overrides for the default class, starting from the most specific
|
|
||||||
// id, and falling back to the module name.
|
|
||||||
if (isset($configuration[$id])) {
|
|
||||||
$class = $configuration[$id];
|
|
||||||
}
|
|
||||||
elseif (isset($configuration[$module])) {
|
|
||||||
$class = $configuration[$module];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$class = $configuration['default'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($instances[$class])) {
|
|
||||||
$interfaces = class_implements($class);
|
|
||||||
if (isset($interfaces['Drupal\Core\Mail\MailInterface'])) {
|
|
||||||
$instances[$class] = new $class();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Exception(t('Class %class does not implement interface %interface', array('%class' => $class, '%interface' => 'Drupal\Core\Mail\MailInterface')));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $instances[$class];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Core\Mail\MailFactory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Core\Mail;
|
||||||
|
|
||||||
|
use Drupal\Core\Config\ConfigFactory;
|
||||||
|
use Drupal\Component\Utility\String;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory for creating mail system objects.
|
||||||
|
*/
|
||||||
|
class MailFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config object for mail system configurations.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Config\Config
|
||||||
|
*/
|
||||||
|
protected $mailConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of already instantiated mail system objects.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $instances = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a MailFActory object.
|
||||||
|
*
|
||||||
|
* @param \Drupal\Core\Config\ConfigFactory $configFactory
|
||||||
|
* The configuration factory.
|
||||||
|
*/
|
||||||
|
public function __construct(ConfigFactory $configFactory) {
|
||||||
|
$this->mailConfig = $configFactory->get('system.mail');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an object that implements \Drupal\Core\Mail\MailInterface.
|
||||||
|
*
|
||||||
|
* Allows for one or more custom mail backends to format and send mail messages
|
||||||
|
* composed using drupal_mail().
|
||||||
|
*
|
||||||
|
* The selection of a particular implementation is controlled via the config
|
||||||
|
* 'system.mail.interface', which is a keyed array. The default
|
||||||
|
* implementation is the class whose name is the value of 'default' key. A
|
||||||
|
* more specific match first to key and then to module will be used in
|
||||||
|
* preference to the default. To specify a different class for all mail sent
|
||||||
|
* by one module, set the class name as the value for the key corresponding to
|
||||||
|
* the module name. To specify a class for a particular message sent by one
|
||||||
|
* module, set the class name as the value for the array key that is the
|
||||||
|
* message id, which is "${module}_${key}".
|
||||||
|
*
|
||||||
|
* For example to debug all mail sent by the user module by logging it to a
|
||||||
|
* file, you might set the variable as something like:
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* array(
|
||||||
|
* 'default' => 'Drupal\Core\Mail\PhpMail',
|
||||||
|
* 'user' => 'DevelMailLog',
|
||||||
|
* );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* Finally, a different system can be specified for a specific e-mail ID (see
|
||||||
|
* the $key param), such as one of the keys used by the contact module:
|
||||||
|
*
|
||||||
|
* @code
|
||||||
|
* array(
|
||||||
|
* 'default' => 'Drupal\Core\Mail\PhpMail',
|
||||||
|
* 'user' => 'DevelMailLog',
|
||||||
|
* 'contact_page_autoreply' => 'DrupalDevNullMailSend',
|
||||||
|
* );
|
||||||
|
* @endcode
|
||||||
|
*
|
||||||
|
* Other possible uses for system include a mail-sending class that actually
|
||||||
|
* sends (or duplicates) each message to SMS, Twitter, instant message, etc,
|
||||||
|
* or a class that queues up a large number of messages for more efficient
|
||||||
|
* bulk sending or for sending via a remote gateway so as to reduce the load
|
||||||
|
* on the local server.
|
||||||
|
*
|
||||||
|
* @param string $module
|
||||||
|
* The module name which was used by drupal_mail() to invoke hook_mail().
|
||||||
|
* @param string $key
|
||||||
|
* A key to identify the e-mail sent. The final e-mail ID for the e-mail
|
||||||
|
* alter hook in drupal_mail() would have been {$module}_{$key}.
|
||||||
|
*
|
||||||
|
* @return \Drupal\Core\Mail\MailInterface
|
||||||
|
* An object that implements Drupal\Core\Mail\MailInterface.
|
||||||
|
*
|
||||||
|
* @throws \Exception
|
||||||
|
*/
|
||||||
|
public function get($module, $key) {
|
||||||
|
$id = $module . '_' . $key;
|
||||||
|
|
||||||
|
$configuration = $this->mailConfig->get('interface');
|
||||||
|
|
||||||
|
// Look for overrides for the default class, starting from the most specific
|
||||||
|
// id, and falling back to the module name.
|
||||||
|
if (isset($configuration[$id])) {
|
||||||
|
$class = $configuration[$id];
|
||||||
|
}
|
||||||
|
elseif (isset($configuration[$module])) {
|
||||||
|
$class = $configuration[$module];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$class = $configuration['default'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($this->instances[$class])) {
|
||||||
|
$interfaces = class_implements($class);
|
||||||
|
if (isset($interfaces['Drupal\Core\Mail\MailInterface'])) {
|
||||||
|
$this->instances[$class] = new $class();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new \Exception(String::format('Class %class does not implement interface %interface', array('%class' => $class, '%interface' => 'Drupal\Core\Mail\MailInterface')));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this->instances[$class];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -15,6 +15,14 @@ interface MailInterface {
|
||||||
/**
|
/**
|
||||||
* Formats a message composed by drupal_mail() prior sending.
|
* Formats a message composed by drupal_mail() prior sending.
|
||||||
*
|
*
|
||||||
|
* Allows to preprocess, format, and postprocess a mail message before it is
|
||||||
|
* passed to the sending system. By default, all messages may contain HTML and
|
||||||
|
* are converted to plain-text by the Drupal\Core\Mail\PhpMail implementation.
|
||||||
|
* For example, an alternative implementation could override the default
|
||||||
|
* implementation and additionally sanitize the HTML for usage in a
|
||||||
|
* MIME-encoded e-mail, but still invoking the Drupal\Core\Mail\PhpMail
|
||||||
|
* implementation to generate an alternate plain-text version for sending.
|
||||||
|
*
|
||||||
* @param array $message
|
* @param array $message
|
||||||
* A message array, as described in hook_mail_alter().
|
* A message array, as described in hook_mail_alter().
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue