- Issue created by @adamps
- last update
over 1 year ago Custom Commands Failed - @adamps opened merge request.
- 🇬🇧United Kingdom catch
3) Module code for sending emails
Modules should change to use the new API as soon as possible, creating an Email Builder. Code for the old API can be removed.Change code that calls MailManagerInterface::mail() to instead call MailerInterface.
Put code from hook_mail() into EmailBuilderInterface::build() if unrelated to config or config() if related to config.
If the new API uses a different ID or different params, implement EmailBuilderInterface::legacyMail() to perform the conversion.This looks to me like once modules have templates and an e-mail builder that they'd be able to remove their hook_mail() implementations, but the MR isn't doing that - is that because they need to have duplicates (hook_mail() + templates) or is it an oversight in the MR?.
- 🇬🇧United Kingdom adamps
Thanks @catch, you ask a very good question. Of course you know the BC requirements for Core much better than I do. What I have done is to think carefully about how they apply to a migration strategy from the old mail system to the new one - see ✨ Migration strategy for moving to Symfony Mailer Active .
Eventually of course we would delete
hook_mail()
implementations. However I believe we need to keep them for now.- Module developers can choose when to switch from the old mail sending API (
MailManagerInterface
) to the new one (MailerInterface
). - Sites can choose when to switch from the mail system with old transports (
@Mail
plug-ins), hooks (hook_mail_alter()
) and email contents to the new ones. - We don't know what in order these switches will take place.
When we commit this issue, that means Core modules switch to the new API for sending mails. We don't need 'if (new mail system)' or any code calling
MailManagerInterface
. However we must keep the same contents of emails sent and still callhook_mail_alter()
with an old style$message
array.1) With this patch, the new mailer implementing
MailerInterface
) callsMailManagerInterface
. The two interfaces are quite close, we just need to callEmailBuilder::prepare()
to find$to, $langcode, $reply
. The mail manager will of course callhook_mail()
so we need to keep it.2) The alternative is to cut out the old mail manager entirely. We would call
EmailBuilder::build()
then convert theEmailInterface
to a$message
. The problem is that the email contents won't be identical. For update mails, we've upgraded the body to HTML. For simplenews the$message
array contains many non-standard parameters and the email contents will likely be quite different using the new API. And the new mail system will fix bugs of the old one that we are currently postponing because it's non-BC. - Module developers can choose when to switch from the old mail sending API (
- 🇨🇭Switzerland berdir Switzerland
@catch: For now, this is just to explore how the API that modules use will look like. see the meta issue for BC discussions.
- 🇬🇧United Kingdom catch
Of course you know the BC requirements for Core much better than I do.
Ha I usually know what the requirements are, but knowing how to meet them is the tricky bit.
Started writing a comment but then realised it should probably be on ✨ Migration strategy for moving to Symfony Mailer Active so posting over there instead.
- last update
over 1 year ago Custom Commands Failed - 🇬🇧United Kingdom adamps
I thought some more. I feel we have two important motivations/ideas:
1) Building an email is done with a 'pipeline' of multiple phases. This is a pattern that exists many times in Drupal already. A form class has build, validate and submit. Rendering a page includes rendering some entities which calls view() but the processing and rendering is deferred until later, which can include a preRender callback. So the building code needs a structure to participate in the different stages.
2) The act of sending email is a good example of a service. It should expose a clear interface without being forced to fit a structure that's not appropriate. There might be one function on the interface or many, and each could have arbitrary parameters. Each call to a function might send zero, one or many emails.
===
Good news is that we can have both: the user module can implements both
EmailBuilderInterface
andUserMailerInterface
. Not only that, we could use the same class to implement both. We can have a @Mailer plug-in, implementingEmailBuilderInterface
, plus an implementation-specific mailer interface.Code that wants to send an email can write:
Drupal::mailer('user')->mail('password_reset', $account);
In Drupal.php:
public static function mailer(string $id) { return static::getContainer()->get('plugin.manager.mailer')->createInstance($id); }
Thoughts??
- last update
over 1 year ago Custom Commands Failed