In a project, we've discovered some strange behavior of
Zend\Mail while trying to send a single message to multiple
bcc recipients. If addressed multiple
bcc (or even
cc) recipients, only the first one would get the message delivered by the mail server. It took us quite a long time to figure it out and found a solution.
Well, to understand what
Zend-Mail does in background let's assume a simple
Message object, like this:
Zend will create a
Message object and build the
Headers by the provided information. If you would print them by
$mail->getHeaders()->toString(), the result would look somehow like this:
The problem is, that each
bcc recipient stands in a separate line. This is the reason why our mail servers only addressed the first recipient of the list and ignored all others. We've tested this behavior with a Microsoft Exchange and two Linux servers. Each has ignored the additional recipients.
So, to solve this issue, it's needed to generate a proper mail header by
Zend\Mail. The real problem is, that Zend uses an abstract class for the generation of this and there is no way to change the generation of the header while build. It's hard-coded in there, at least until version 2.4.13. The only way (for now) is to create an own header class, used for
bcc representation, passed to the
Massage object later.
For this, I've created a new
Header\Bcc class in my modules
src folder and extended it by the original
\Zend\Mail\Header\Bcc class. Inside of the
Zend\Mail\Header\AbstractAddressList class there is a function, called
getFieldValue. This function is used to generate the header value as a
string. It would be possible to copy the whole function and change only the wrong part there. But as the function uses the
Headers::FOLDING constant to build the header, it's even possibile to use this for remove of the line-breaks from the result. This causes less code and this solution would even work on changes by updates in the future.
The only thing to be changed from now on, is the way the
bcc recipients will be added to the
Message object. Instead of using
addBcc functions, your new
Bcc class will be used and passed to the headers manually.
Once done, the headers will be correct and all recipients will get a copy of the mail. The same thing could be done with
cc recipients, which have the same problem by default.
Caution: If you use
$mail->setBcc() somewhere later in your project, the
Bcc class will be removed from the
Headers object and replaced by the original implementation. This causes the problem to stay there as before. Just remove all such function calls and use your own class!