Problem/Motivation
The SymfonyMailer class that was added in #3165762: Add symfony/mailer into core does not properly handle multiple comma-separated email addresses in the $message['to'] variable that is produced by Drupal. It attempts to send the entire message['to'] string into the Symfony mailer to() method, which expects a single address.
This results in an exception like the following:
Symfony\Component\Mime\Exception\RfcComplianceException: Email "test1@example.com, test2.example.com" does not comply with addr-spec of RFC 2822. in Symfony\Component\Mime\Address-\>__construct() (line 54 of /opt/drupal/vendor/symfony/mime/Address.php).
The addTo() method should be used to add additional addresses, or we can use to(...$toAddresses) with an array.
Reference: https://symfony.com/doc/current/mailer.html#email-addresses
Drupal core's MailManagerInterface::mail expects a string $to parameter, so sending to multiple addresses requires formatting them as a comma-separated list (and that is the recommendation).
Reference: https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Mail%21Ma...
Steps to reproduce
1. Enable the Symfony mailer per the instructions in this change record: https://www.drupal.org/node/3369935
2. Trigger an email to be sent to multiple comma-separated addresses.
Proposed resolution
The SymfonyMailer class should parse $message['to'] into an array of addresses, and then use to(...$toAddresses) to pass them to Symfony mailer.
Remaining tasks
TBD
User interface changes
None.
API changes
None.
Data model changes
None.
Release notes snippet
TBD.
| Comment | File | Size | Author |
|---|
Issue fork drupal-3446368
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
m.stentaComment #3
m.stentaIt appears Symfony devs have explored possible solutions for this, although it is unclear if they implemented anything: https://github.com/symfony/symfony/issues/40205
Comment #4
m.stentaComment #5
m.stentaNotably, it appears the same exception was encountered in Drupal core in the past, but in a slightly different context: #3226117: Uncaught RfcComplianceException when email From name contains a comma
The exception comes from
Symfony\Component\Mime\AddressDrupal core uses
Addressto check that the "From" address inMailManagerin order to "Make sure the site-name is a RFC-2822 compliant 'display-name'":https://git.drupalcode.org/project/drupal/-/blob/f8ede99aabdf39e95aeb259...
But it does not check the "To" address(es) with
Addressat any point. Symfony mailer does, however, which is why this issue starts to happen once you start using Symfony mailer.Comment #6
m.stentaUpdated the description to include the full error message.
Comment #7
m.stentaComment #8
cilefen commentedWould it be more elegant or a better API for
$message['to']to contain either a string (one address) or an array (multiple addresses)?Comment #9
m.stenta@cilefen Yes that would be more elegant, but I think it would require much bigger changes to Drupal mail handling outside the scope of this specific
SymfonyMailerclass. So unfortunately, in order to fix this bug, we need to deal with the fact that$message['to']is a string, and figure out how to parse it into an array. As it stands right now,SymfonyMaileris broken when sending to multiple email addresses.Comment #10
cilefen commentedSo this is like a two-line fix.
Comment #11
m.stentaWell... based on the comments in the Symfony issue I linked to above, it may not be as simple as adding an
explode(). 😅@althaus says:
@javiereguiluz says:
@fabpot suggests he would be open to that approach:
But as far as I can tell this has not been done yet. So we are left with the problem, because Drupal core is starting with a string of multiple comma-separated addresses.
Comment #12
m.stentaWe could consider using imap_rfc822_parse_adrlist(), but it sounds like that has some problems, which is what prompted the Symfony issue...
Maybe it's the best way to start, and we could potentially leverage something better provided by Symfony in the future (if they ever implement it)?
Comment #13
m.stentaScratch that idea. It requires the
imapextension to be installed.Comment #14
m.stentaHere is a simple MR+patch that uses
str_getcsv()(instead ofexplode()), because it should ignore commas that are enclosed in double-quotes.str_getcsv()was also used in #3226117: Uncaught RfcComplianceException when email From name contains a comma...https://www.drupal.org/project/drupal/issues/3226117#comment-14192545
This might not work for all cases, but it's a first step to get the ball rolling at least. Needs tests too, of course.
Comment #16
znerol commentedThanks, I agree with the approach. Left a small note in the MR.
A simple test case could go into SymfonyMailerTest.php
Comment #18
dcam commentedI added a test. To do it I reconfigured
SymfonyMailerTest::testMail()so that it uses a provider. So expect a lot of changes related to that. That test was originally testing newline characters in the subject. That too was extracted to one of the test cases.Also, there's a PHP 8.4 deprecation for
str_getcsv(). To fix it we have to use named parameters so that we can specify the escape character. See https://www.php.net/manual/en/function.str-getcsv.php.Comment #19
znerol commentedThanks for taking this up. Adding a data provider is useful in this case I think. It needs some improvements in order to improve readability I think.
Comment #20
znerol commentedComment #21
m.stentaAttached is an updated patch that includes the PHP 8.4 fix described by @dcam in #18 above.
This patch does NOT include the test, and is only meant for applying patches via cweagans/composer-patches while we wait for this to be merged.
Comment #26
dcam commentedI made the suggested changes, but had to open a new branch and MR because I messed up the rebase.
Comment #27
znerol commentedThank you @dcam.
Comment #28
longwaveMR needs rebase.
Comment #29
dcam commentedRebased. Tests are passing. Re-setting to RTBC.
Comment #32
longwaveCommitted and pushed cbf36cb7238 to 11.x. Thanks!
Committed f1a6a0c and pushed to 11.3.x. Thanks!
Initially I was not going to backport this to 11.3.x but then I realised someone might still be using this even though the experimental mailer module is not included in 11.3.
Comment #35
m.stentaThank you @longwave!!
> someone might still be using this even though the experimental mailer module is not included in 11.3
I am that someone! And this was the last core patch I've been applying! :-D