Skip to content
Snippets Groups Projects
Commit b23b1ea7 authored by Adam Shepherd's avatar Adam Shepherd Committed by Adam Shepherd
Browse files

Issue #3315698 by AdamPS: Improve back-compatibility, call hook_mail_alter()

parent 5dc1f5d2
Branches
Tags 1.1.0-beta1
No related merge requests found
Showing
with 397 additions and 171 deletions
<?php
/**
* @file
* Documentation of Symfony Mailer back-compatibility hooks.
*/
/**
* Alters back-compatibility creation of an email.
*
* The parameters supplied are from the old mail manager interface. The altered
* values will be passed to the email factory.
*
* @param array $message
* A message array, as described in hook_mail_alter().
* @param \Drupal\Core\Config\Entity\ConfigEntityInterface|null $entity
* (optional) Entity. @see \Drupal\symfony_mailer\EmailInterface::getEntity()
*
* @see \Drupal\Core\Mail\MailManagerInterface::mail()
* @see \Drupal\symfony_mailer\EmailFactory
*/
function hook_mailer_bc_alter(array &$message, ?ConfigEntityInterface $entity) {
}
/**
* Alters back-compatibility creation of an email from a specific module.
*
* @param array $message
* A message array, as described in hook_mail_alter().
* @param \Drupal\Core\Config\Entity\ConfigEntityInterface|null $entity
* (optional) Entity. @see \Drupal\symfony_mailer\EmailInterface::getEntity()
*/
function hook_mailer_bc_MODULE_alter(array &$message, ?ConfigEntityInterface $entity) {
}
name: Symfony Mailer Back-compatibility
name: Symfony Mailer Override
type: module
description: 'Back-compatibility mapper for Symfony Mailer. Entirely replaces the default mail system, so that all Drupal emails will be sent via Symfony Mailer.'
description: 'Overrides email building for key core and contrib modules, improving features and integration with Symfony Mailer.'
core_version_requirement: ^9.1
package: Mail
dependencies:
......
<?php
/**
* @file
* Install, functions for the Symfony Mailer Back-compatibility module.
*/
/**
* Implements hook_requirements().
*/
function symfony_mailer_bc_requirements($phase) {
$requirements = [];
if ($phase === 'install') {
if (\Drupal::moduleHandler()->moduleExists('mailsystem')) {
$requirements['symfony_mailer_bc'] = [
'description' => t('Symfony Mailer Back-compatibility module cannot be installed because the Mail System module is installed and incompatible.'),
'severity' => REQUIREMENT_ERROR,
];
}
}
return $requirements;
}
......@@ -6,7 +6,6 @@
*/
use Drupal\Core\Form\FormStateInterface;
use Drupal\symfony_mailer\Annotation\EmailBuilder;
/**
* Implements hook_theme().
......@@ -22,28 +21,6 @@ function symfony_mailer_bc_theme($existing, $type, $theme, $path) {
return $hooks;
}
/**
* Implements hook_mailer_builder_info_alter().
*/
function symfony_mailer_bc_mailer_builder_info_alter(array &$email_builders) {
// Add EmailBuilder definitions for any implementations of hook_mail() that
// don't already have one, using LegacyEmailBuilder.
$module_handler = \Drupal::moduleHandler();
$mail_hooks = $module_handler->getImplementations('mail');
$missing = array_diff($mail_hooks, array_keys($email_builders));
foreach ($missing as $type) {
$params = [
'id' => $type,
'label' => $module_handler->getName($type),
'class' => "Drupal\symfony_mailer_bc\Plugin\EmailBuilder\LegacyEmailBuilder",
'provider' => $type,
];
$email_builders[$type] = (new EmailBuilder($params))->get();
}
}
/**
* Implements hook_module_implements_alter().
*/
......
......@@ -56,7 +56,8 @@ trait BaseEmailTrait {
*/
public function setAddress(string $name, $addresses) {
assert(isset($this->addresses[$name]));
if ($name == 'To') {
// See Mailer::doSend() for explanation of __disable_customize__.
if (($name == 'To') && !$this->getParam('__disable_customize__')) {
$this->valid(self::PHASE_BUILD);
}
$this->addresses[$name] = Address::convert($addresses);
......
<?php
namespace Drupal\symfony_mailer;
use Drupal\Component\Render\MarkupInterface;
/**
* Provides the legacy mailer helper service.
*/
class LegacyMailerHelper implements LegacyMailerHelperInterface {
/**
* List of headers for conversion to array.
*
* @var array
*/
protected const HEADERS = [
'From' => 'from',
'Reply-To' => 'reply-to',
'To' => 'to',
'Cc' => 'cc',
'Bcc' => 'bcc',
];
/**
* The mailer helper.
*
* @var \Drupal\symfony_mailer\MailerHelperInterface
*/
protected $mailerHelper;
/**
* Constructs the MailerHelper object.
*
* @param \Drupal\symfony_mailer\MailerHelperInterface $mailer_helper
* The mailer helper.
*/
public function __construct(MailerHelperInterface $mailer_helper) {
$this->mailerHelper = $mailer_helper;
}
/**
* {@inheritdoc}
*/
public function formatBody(array $body_array) {
foreach ($body_array as $part) {
if ($part instanceof MarkupInterface) {
$body[] = ['#markup' => $part];
}
else {
$body[] = [
'#type' => 'processed_text',
'#text' => $part,
];
}
}
return $body ?? [];
}
/**
* {@inheritdoc}
*/
public function emailToArray(EmailInterface $email, array $message) {
$message['subject'] = $email->getSubject();
if ($email->getPhase() >= EmailInterface::PHASE_POST_RENDER) {
$message['body'] = $email->getHtmlBody();
}
$headers = $email->getHeaders();
foreach (self::HEADERS as $name => $key) {
if ($headers->has($name)) {
$message['headers'][$name] = $headers->get($name)->getBodyAsString();
}
if ($key) {
$message[$key] = $message['headers'][$name] ?? NULL;
}
}
}
/**
* {@inheritdoc}
*/
public function emailFromArray(EmailInterface $email, array $message) {
$email->setSubject($message['subject']);
// Attachments.
$attachments = $message['params']['attachments'] ?? [];
foreach ($attachments as $attachment) {
$email->attachFromPath($attachment['filepath'], $attachment['filename'] ?? NULL, $attachment['filemime'] ?? NULL);
}
// Address headers.
foreach (self::HEADERS as $name => $key) {
$encoded = $message['headers'][$name] ?? $message[$key] ?? NULL;
if (isset($encoded)) {
$email->setAddress($name, $this->mailerHelper->parseAddress($encoded));
}
}
}
}
<?php
namespace Drupal\symfony_mailer;
/**
* Provides the legacy mailer helper service.
*/
interface LegacyMailerHelperInterface {
/**
* Formats a message body.
*
* Performs conversion of the message body as required by
* \Drupal\Core\Mail\MailInterface::format().
*
* @param array $body_array
* An array of body parts.
*
* @return string
* The body as a single formatted string.
*/
public function formatBody(array $body_array);
/**
* Fills a message array from an Email.
*
* @param \Drupal\symfony_mailer\EmailInterface $email
* The email to fill from.
* @param array $message
* The array to fill.
*/
public function emailToArray(EmailInterface $email, array $message);
/**
* Fills an Email from a message array.
*
* @param \Drupal\symfony_mailer\EmailInterface $email
* The email to fill.
* @param array $message
* The array to fill from.
*/
public function emailFromArray(EmailInterface $email, array $message);
}
<?php
namespace Drupal\symfony_mailer_bc;
namespace Drupal\symfony_mailer;
use Drupal\Core\Cache\CacheBackendInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
......@@ -9,8 +9,6 @@ use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Mail\MailManager;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\symfony_mailer\EmailFactoryInterface;
use Drupal\symfony_mailer\EmailInterface;
use Drupal\symfony_mailer\Processor\EmailBuilderManagerInterface;
/**
......@@ -18,19 +16,6 @@ use Drupal\symfony_mailer\Processor\EmailBuilderManagerInterface;
*/
class MailManagerReplacement extends MailManager implements MailManagerReplacementInterface {
/**
* List of headers for conversion to array.
*
* @var array
*/
protected const HEADERS = [
'From' => 'from',
'Reply-To' => 'reply-to',
'To' => 'to',
'Cc' => 'cc',
'Bcc' => 'bcc',
];
/**
* The email factory.
*
......@@ -45,6 +30,13 @@ class MailManagerReplacement extends MailManager implements MailManagerReplaceme
*/
protected $emailBuilderManager;
/**
* The legacy mailer helper.
*
* @var \Drupal\symfony_mailer\LegacyMailerHelperInterface
*/
protected $legacyHelper;
/**
* Constructs the MailManagerReplacement object.
*
......@@ -67,11 +59,14 @@ class MailManagerReplacement extends MailManager implements MailManagerReplaceme
* The email factory.
* @param \Drupal\symfony_mailer\Processor\EmailBuilderManagerInterface $email_builder_manager
* The email builder manager.
* @param \Drupal\symfony_mailer\LegacyMailerHelperInterface $legacy_helper
* The legacy mailer helper.
*/
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, LoggerChannelFactoryInterface $logger_factory, TranslationInterface $string_translation, RendererInterface $renderer, EmailFactoryInterface $email_factory, EmailBuilderManagerInterface $email_builder_manager) {
public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, LoggerChannelFactoryInterface $logger_factory, TranslationInterface $string_translation, RendererInterface $renderer, EmailFactoryInterface $email_factory, EmailBuilderManagerInterface $email_builder_manager, LegacyMailerHelperInterface $legacy_helper) {
parent::__construct($namespaces, $cache_backend, $module_handler, $config_factory, $logger_factory, $string_translation, $renderer);
$this->emailFactory = $email_factory;
$this->emailBuilderManager = $email_builder_manager;
$this->legacyHelper = $legacy_helper;
}
/**
......@@ -91,26 +86,17 @@ class MailManagerReplacement extends MailManager implements MailManagerReplaceme
// Create an email from the array. Always call the plug-in from the module
// name, not any variants.
$email = $this->emailBuilderManager->createInstance($module)->fromArray($this->emailFactory, $message);
$email = $this->emailBuilderManager->createInstance($message['module'])->fromArray($this->emailFactory, $message);
if ($send) {
$message['result'] = $email->send();
}
// Update the message array.
$message['subject'] = $email->getSubject();
$message['body'] = ($email->getPhase() >= EmailInterface::PHASE_POST_RENDER) ? $email->getHtmlBody() : $email->getBody();
$headers = $email->getHeaders();
foreach (self::HEADERS as $name => $key) {
if ($headers->has($name)) {
$message['headers'][$name] = $headers->get($name)->getBodyAsString();
}
if ($key) {
$message[$key] = $message['headers'][$name] ?? NULL;
}
else {
// We set 'result' to NULL, because FALSE indicates an error in sending.
$message['result'] = NULL;
}
$this->legacyHelper->emailToArray($email, $message);
return $message;
}
......
<?php
namespace Drupal\symfony_mailer_bc;
namespace Drupal\symfony_mailer;
use Drupal\Core\Mail\MailManagerInterface;
......
......@@ -173,19 +173,35 @@ class Mailer implements MailerInterface {
$this->changeTheme($theme_name);
}
// Determine langcode and account from the to address, if there is
// agreement.
$langcodes = $accounts = [];
foreach ($email->getTo() as $to) {
if ($loop_langcode = $to->getLangcode()) {
$langcodes[$loop_langcode] = $loop_langcode;
}
if ($loop_account = $to->getAccount()) {
$accounts[$loop_account->id()] = $loop_account;
$current_langcode = $this->languageManager->getCurrentLanguage()->getId();
if ($email->getParam('__disable_customize__')) {
// Undocumented setting for use from LegacyEmailBuilder only for
// back-compatibility. This may change without notice.
//
// By default, the language code and account are customized based on the
// recipient ('To' address). This setting disables customization, and
// leaves the language and account unchanged. Normally this is a bad idea
// and it can even expose private information from rendering an entity in
// the context of a privileged user.
$langcode = $current_langcode;
$account = $this->account;
}
else {
// Determine langcode and account from the to address, if there is
// agreement.
$langcodes = $accounts = [];
foreach ($email->getTo() as $to) {
if ($loop_langcode = $to->getLangcode()) {
$langcodes[$loop_langcode] = $loop_langcode;
}
if ($loop_account = $to->getAccount()) {
$accounts[$loop_account->id()] = $loop_account;
}
}
$langcode = (count($langcodes) == 1) ? reset($langcodes) : $this->languageManager->getDefaultLanguage()->getId();
$account = (count($accounts) == 1) ? reset($accounts) : User::getAnonymousUser();
}
$langcode = (count($langcodes) == 1) ? reset($langcodes) : $this->languageManager->getDefaultLanguage()->getId();
$account = (count($accounts) == 1) ? reset($accounts) : User::getAnonymousUser();
$email->customize($langcode, $account);
$must_switch_account = $account->id() != $this->account->id();
......@@ -194,7 +210,6 @@ class Mailer implements MailerInterface {
$this->accountSwitcher->switchTo($account);
}
$current_langcode = $this->languageManager->getCurrentLanguage()->getId();
$must_switch_language = $langcode !== $current_langcode;
if ($must_switch_language) {
......
<?php
namespace Drupal\symfony_mailer_bc\Plugin\EmailBuilder;
namespace Drupal\symfony_mailer\Plugin\EmailBuilder;
use Drupal\Component\Render\MarkupInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\symfony_mailer\EmailFactoryInterface;
use Drupal\symfony_mailer\EmailInterface;
use Drupal\symfony_mailer\Exception\SkipMailException;
use Drupal\symfony_mailer\MailerHelperInterface;
use Drupal\symfony_mailer\LegacyMailerHelperInterface;
use Drupal\symfony_mailer\Processor\EmailBuilderBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines the Legacy Email Builder plug-in that calls hook_mail().
* Defines the Legacy Email Builder plug-in that uses a message array.
*/
class LegacyEmailBuilder extends EmailBuilderBase implements ContainerFactoryPluginInterface {
/**
* The mailer helper.
* The legacy mailer helper.
*
* @var \Drupal\symfony_mailer\MailerHelperInterface
* @var \Drupal\symfony_mailer\LegacyMailerHelperInterface
*/
protected $mailerHelper;
protected $legacyHelper;
/**
* List of headers for conversion from array.
* The module handler.
*
* We omitted the To header, since it needs to be set in the build phase.
*
* @var array
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected const HEADERS = [
'From' => 'from',
'Reply-To' => 'reply-to',
'Cc' => 'cc',
'Bcc' => 'bcc',
];
protected $moduleHandler;
/**
* Constructor.
......@@ -46,12 +39,15 @@ class LegacyEmailBuilder extends EmailBuilderBase implements ContainerFactoryPlu
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\symfony_mailer\MailerHelperInterface $mailer_helper
* The mailer helper.
* @param \Drupal\symfony_mailer\LegacyMailerHelperInterface $legacy_helper
* The legacy mailer helper.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler to invoke the alter hook with.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, MailerHelperInterface $mailer_helper) {
public function __construct(array $configuration, $plugin_id, $plugin_definition, LegacyMailerHelperInterface $legacy_helper, ModuleHandlerInterface $module_handler) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->mailerHelper = $mailer_helper;
$this->legacyHelper = $legacy_helper;
$this->moduleHandler = $module_handler;
}
/**
......@@ -62,7 +58,8 @@ class LegacyEmailBuilder extends EmailBuilderBase implements ContainerFactoryPlu
$configuration,
$plugin_id,
$plugin_definition,
$container->get('symfony_mailer.helper')
$container->get('symfony_mailer.legacy_helper'),
$container->get('module_handler'),
);
}
......@@ -78,18 +75,8 @@ class LegacyEmailBuilder extends EmailBuilderBase implements ContainerFactoryPlu
*/
public function createParams(EmailInterface $email, array $legacy_message = NULL) {
assert($legacy_message != NULL);
$email->setParam('legacy_message', $legacy_message);
}
/**
* {@inheritdoc}
*/
public function build(EmailInterface $email) {
$message = $email->getParam('legacy_message');
$recipient = $message['to'] ?? NULL;
if (isset($recipient)) {
$email->setTo($this->mailerHelper->parseAddress($recipient, $message['langcode']));
}
$email->setParam('legacy_message', $legacy_message)
->setParam('__disable_customize__', TRUE);
}
/**
......@@ -103,57 +90,21 @@ class LegacyEmailBuilder extends EmailBuilderBase implements ContainerFactoryPlu
'headers' => [],
];
// Call hook_mail() on this module.
if (function_exists($function = $message['module'] . '_mail')) {
$function($message['key'], $message, $message['params']);
}
// Build the email by invoking hook_mail() on this module.
$args = [$message['key'], &$message, $message['params']];
$this->moduleHandler->invoke($message['module'], 'mail', $args);
if (isset($message['send']) && !$message['send']) {
throw new SkipMailException('Send aborted by hook_mail().');
}
// Invoke hook_mail_alter() to allow all modules to alter the resulting
// email.
$this->moduleHandler->alter('mail', $message);
$this->emailFromArray($email, $message);
}
/**
* Fills an Email from a message array.
*
* @param \Drupal\symfony_mailer\EmailInterface $email
* The email to fill.
* @param array $message
* The array to fill from.
*/
protected function emailFromArray(EmailInterface $email, array $message) {
$email->setSubject($message['subject']);
// Add attachments.
$attachments = $message['params']['attachments'] ?? [];
foreach ($attachments as $attachment) {
$email->attachFromPath($attachment['filepath'], $attachment['filename'] ?? NULL, $attachment['filemime'] ?? NULL);
}
// Add Address headers from message array to Email object.
// The "To" header will be set via build().
foreach (self::HEADERS as $name => $key) {
$encoded = $message['headers'][$name] ?? $message[$key] ?? NULL;
if (isset($encoded)) {
$email->setAddress($name, $this->mailerHelper->parseAddress($encoded));
}
if (!$message['send']) {
throw new SkipMailException('Send aborted by hook_mail().');
}
// Add the body to the Email object, as rendered by hook_mail.
foreach ($message['body'] as $part) {
if ($part instanceof MarkupInterface) {
$body[] = ['#markup' => $part];
}
else {
$body[] = [
'#type' => 'processed_text',
'#text' => $part,
];
}
}
$email->setBody($body ?? []);
// Fill the email from the message array.
$email->setBody($this->legacyHelper->formatBody($message['body']));
$this->legacyHelper->emailFromArray($email, $message);
}
}
<?php
namespace Drupal\symfony_mailer_bc;
namespace Drupal\symfony_mailer;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
......@@ -9,16 +9,19 @@ use Symfony\Component\DependencyInjection\Reference;
/**
* Modifies the mail manager service.
*/
class SymfonyMailerBcServiceProvider extends ServiceProviderBase {
class SymfonyMailerServiceProvider extends ServiceProviderBase {
/**
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container) {
$definition = $container->getDefinition('plugin.manager.mail');
$definition->setClass('Drupal\symfony_mailer_bc\MailManagerReplacement')
// Cancel any method calls, for example from mailsystem.
$definition->setClass('Drupal\symfony_mailer\MailManagerReplacement')
->addArgument(new Reference('email_factory'))
->addArgument(new Reference('plugin.manager.email_builder'));
->addArgument(new Reference('plugin.manager.email_builder'))
->addArgument(new Reference('symfony_mailer.legacy_helper'))
->setMethodCalls([]);
}
}
......@@ -7,6 +7,7 @@
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\symfony_mailer\Annotation\EmailBuilder;
/**
* Implements hook_theme().
......@@ -29,6 +30,28 @@ function symfony_mailer_theme_suggestions_email(array $variables) {
return array_slice($variables['email']->getSuggestions('email', '__'), 1);
}
/**
* Implements hook_mailer_builder_info_alter().
*/
function symfony_mailer_mailer_builder_info_alter(array &$email_builders) {
// Add EmailBuilder definitions for any implementations of hook_mail() that
// don't already have one, using LegacyEmailBuilder.
$module_handler = \Drupal::moduleHandler();
$mail_hooks = $module_handler->getImplementations('mail');
$missing = array_diff($mail_hooks, array_keys($email_builders));
foreach ($missing as $type) {
$params = [
'id' => $type,
'label' => $module_handler->getName($type),
'class' => "Drupal\symfony_mailer\Plugin\EmailBuilder\LegacyEmailBuilder",
'provider' => $type,
];
$email_builders[$type] = (new EmailBuilder($params))->get();
}
}
/**
* Prepares variables for email template.
*
......
......@@ -18,3 +18,6 @@ services:
symfony_mailer.helper:
class: Drupal\symfony_mailer\MailerHelper
arguments: ['@entity_type.manager', '@plugin.manager.email_adjuster', '@plugin.manager.email_builder', '@config.factory']
symfony_mailer.legacy_helper:
class: Drupal\symfony_mailer\LegacyMailerHelper
arguments: ['@symfony_mailer.helper']
<?php
namespace Drupal\symfony_mailer_bc_test\Form;
namespace Drupal\symfony_mailer_legacy_test\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
......@@ -8,9 +8,9 @@ use Drupal\Core\Mail\MailManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Test module form to send a test BC mail.
* Test module form to send a test legacy email.
*/
class BcTestMailForm extends FormBase {
class LegacyTestEmailForm extends FormBase {
/**
* The mail manager service.
......@@ -42,7 +42,7 @@ class BcTestMailForm extends FormBase {
* {@inheritdoc}
*/
public function getFormId() {
return 'symfony_mailer_bc_test_form';
return 'symfony_mailer_legacy_test_form';
}
/**
......@@ -52,7 +52,7 @@ class BcTestMailForm extends FormBase {
$form = [];
$form['submit'] = [
'#type' => 'submit',
'#value' => 'Send test mail',
'#value' => 'Send test email',
];
/** @var \Drupal\Core\Theme\ThemeManagerInterface $theme_manager */
$theme_manager = \Drupal::service('theme.manager');
......@@ -68,7 +68,7 @@ class BcTestMailForm extends FormBase {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->mailManager->mail('symfony_mailer_bc_test', 'bc_test', 'test@example.com', 'en');
$this->mailManager->mail('symfony_mailer_legacy_test', 'legacy_test', 'test@example.com', 'en');
}
}
name: Symfony Mailer BC Test
name: Symfony Mailer Legacy Email Test
type: module
package: Mail
hidden: true
core_version_requirement: ^9.1
dependencies:
- symfony_mailer:symfony_mailer
- symfony_mailer:symfony_mailer_bc
......@@ -2,35 +2,44 @@
/**
* @file
* Hook implementations for the Symfony Mailer BC test module.
* Hook implementations for the Symfony Mailer Legacy Email test module.
*/
/**
* Implements hook_mail().
*/
function symfony_mailer_bc_test_mail($key, &$message, $params) {
if ($key == 'bc_test') {
$message['subject'] = 'Backwards compatible mail sent via hook_mail().';
function symfony_mailer_legacy_test_mail($key, &$message, $params) {
if ($key == 'legacy_test') {
$message['subject'] = 'Legacy email sent via hook_mail().';
$message['body'][] = 'This email is sent via hook_mail().';
$message['body'][] = symfony_mailer_bc_test_add_template_to_body();
$message['body'][] = symfony_mailer_legacy_test_add_template_to_body();
$message['headers']['Cc'] = 'cc@example.com';
}
}
/**
* Implements hook_mail_alter().
*/
function symfony_mailer_legacy_test_mail_alter(&$message) {
if ($message['id'] == 'symfony_mailer_legacy_test_legacy_test') {
$message['body'][] = 'This email was altered via hook_mail_alter().';
}
}
/**
* Adds a rendered (Twig) template file to the body of the test email message.
*
* This mimics the logic implemented in Drupal Commerce, when sending the
* "commerce order receipt" mail.
*/
function symfony_mailer_bc_test_add_template_to_body() {
function symfony_mailer_legacy_test_add_template_to_body() {
/** @var \Drupal\Core\Theme\ThemeManagerInterface $theme_manager */
$theme_manager = \Drupal::service('theme.manager');
/** @var \Drupal\Core\Render\RendererInterface $renderer */
$renderer = \Drupal::service('renderer');
$current_theme = $theme_manager->getActiveTheme()->getName();
$template = [
'#theme' => 'bc_test_mail',
'#theme' => 'legacy_test_email',
'#current_theme' => $current_theme,
];
return $renderer->render($template);
......@@ -39,9 +48,9 @@ function symfony_mailer_bc_test_add_template_to_body() {
/**
* Implements hook_theme().
*/
function symfony_mailer_bc_test_theme() {
function symfony_mailer_legacy_test_theme() {
return [
'bc_test_mail' => [
'legacy_test_email' => [
'variables' => ['current_theme' => NULL],
],
];
......
symfony_mailer_bc_test.send:
path: '/admin/symfony_mailer_bc_test/send'
symfony_mailer_legacy_test.send:
path: '/admin/symfony_mailer_legacy_test/send'
defaults:
_form: 'Drupal\symfony_mailer_bc_test\Form\BcTestMailForm'
_title: 'Send BC test mail'
_form: 'Drupal\symfony_mailer_legacy_test\Form\LegacyTestEmailForm'
_title: 'Send legacy test email'
requirements:
_access: 'TRUE'
options:
......
<strong>This is the default BC test mail template.</strong>
<strong>This is the default legacy test email template.</strong>
<p>Rendered in theme: {{ current_theme }}</p>
<?php
namespace Drupal\Tests\symfony_mailer_bc\Functional;
use Drupal\Tests\symfony_mailer\Functional\SymfonyMailerTestBase;
namespace Drupal\Tests\symfony_mailer\Functional;
/**
* Test the Symfony Mailer Back-compatibility module.
*
* @group symfony_mailer
*/
class TestBcMail extends SymfonyMailerTestBase {
class TestLegacyEmail extends SymfonyMailerTestBase {
/**
* Modules to enable.
......@@ -18,9 +16,8 @@ class TestBcMail extends SymfonyMailerTestBase {
*/
protected static $modules = [
'symfony_mailer',
'symfony_mailer_bc',
'symfony_mailer_test',
'symfony_mailer_bc_test',
'symfony_mailer_legacy_test',
];
/**
......@@ -36,13 +33,13 @@ class TestBcMail extends SymfonyMailerTestBase {
}
/**
* Test sending a backwards compatible email rendered via hook_mail().
* Test sending a legacy email rendered via hook_mail().
*/
public function testSendBcMail() {
public function testSendLegacyEmail() {
$this->drupalLogin($this->adminUser);
// Trigger sending a backwards compatible email via hook_mail().
$this->drupalGet('admin/symfony_mailer_bc_test/send');
$this->submitForm([], 'Send test mail');
// Trigger sending a legacy email via hook_mail().
$this->drupalGet('admin/symfony_mailer_legacy_test/send');
$this->submitForm([], 'Send test email');
$this->readMail();
// Check email recipients.
......@@ -50,34 +47,36 @@ class TestBcMail extends SymfonyMailerTestBase {
$this->assertCc('cc@example.com', '');
// Check email contents.
$this->assertSubject("Backwards compatible mail sent via hook_mail().");
$this->assertSubject("Legacy email sent via hook_mail().");
$this->assertBodyContains("This email is sent via hook_mail().");
$this->assertBodyContains("This is the default BC test mail template.");
$this->assertBodyContains("This email was altered via hook_mail_alter().");
$this->assertBodyContains("This is the default legacy test email template.");
$this->assertBodyContains("Rendered in theme: stark");
}
/**
* Test sending a backwards compatible email with custom email body template.
* Test sending a legacy email with custom email body template.
*/
public function testSendBcMailWithTheme() {
public function testSendLegacyEmailWithTheme() {
$this->drupalLogin($this->adminUser);
// Switch the current default theme and admin theme, and test if template
// renders in the default theme instead of the admin theme, even though the
// admin theme is active when the mail gets triggered.
\Drupal::service('theme_installer')->install(['test_bc_mail_theme', 'stark']);
$themes = ['test_legacy_email_theme', 'stark'];
\Drupal::service('theme_installer')->install($themes);
$this->config('system.theme')
->set('default', 'test_bc_mail_theme')
->set('default', 'test_legacy_email_theme')
->set('admin', 'stark')
->save();
/** @var \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler */
$theme_handler = $this->container->get('theme_handler');
$this->assertTrue($theme_handler->themeExists('test_bc_mail_theme'));
$this->assertTrue($theme_handler->themeExists('test_legacy_email_theme'));
// Trigger sending a backwards compatible email via hook_mail().
$this->drupalGet('admin/symfony_mailer_bc_test/send');
// Trigger sending a legacy email via hook_mail().
$this->drupalGet('admin/symfony_mailer_legacy_test/send');
$this->assertSession()->pageTextContains('Current theme: stark');
$this->submitForm([], 'Send test mail');
$this->submitForm([], 'Send test email');
$this->readMail();
// Check email recipients.
......@@ -85,10 +84,11 @@ class TestBcMail extends SymfonyMailerTestBase {
$this->assertCc('cc@example.com', '');
// Check email contents.
$this->assertSubject("Backwards compatible mail sent via hook_mail().");
$this->assertSubject("Legacy email sent via hook_mail().");
$this->assertBodyContains("This email is sent via hook_mail().");
$this->assertBodyContains("This is the overridden BC test mail template.");
$this->assertBodyContains("Rendered in theme: test_bc_mail_theme");
$this->assertBodyContains("This email was altered via hook_mail_alter().");
$this->assertBodyContains("This is the overridden legacy test email template.");
$this->assertBodyContains("Rendered in theme: test_legacy_email_theme");
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment