Problem/Motivation
Mimemail runs all email headers through UnstructuredHeader() which requires string input. This class is used for converting non-ASCII characters to an RFC compliant strings. The problem is that in Drupal 8 and newer, not all headers are required to be strings - some header values are objects for example.
Steps to reproduce
1. Create custom hook_mail implementation like so:
/**
* Implements hook_mail().
*/
function modulename_mail($key, &$message, $params) {
if ($key == 'message') {
// Set date header, which is expected to be DateTimeInterface.
// See: https://github.com/symfony/mime/blob/6.3/Header/Headers.php#L114
$message['headers']['Date'] = new DateTime();
// Set subject.
$message['subject'] = $params['subject'];
// Set body.
foreach ($params['body'] as $body_part) {
$message['body'][] = $body_part;
}
}
}
2. Send any email message using the above hook while using Drupal's default PHP mailer. The email will send fine and it will contain 'Date' header with the right value.
3. Now enable the mimemail for the above hook and try to send the email again.
4. You will get an error:
TypeError: Symfony\Component\Mime\Header\UnstructuredHeader::__construct(): Argument #2 ($value) must be of type string, DateTime given, called in \web\modules\contrib\mimemail\src\Utility\MimeMailFormatHelper.php on line 795 in Symfony\Component\Mime\Header\UnstructuredHeader->__construct() (line 23 of \vendor\symfony\mime\Header\UnstructuredHeader.php).
The error happens because Mimemail tries to run the Date header, which is an object "value", through function that operates on strings.
Proposed resolution
Apply the patch attached. It fixes the problem
| Comment | File | Size | Author |
|---|---|---|---|
| mimemail_unstructured_header_patch.patch | 1.15 KB | pawel.traczynski |
Issue fork mimemail-3408278
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
pawel.traczynski commentedComment #3
tr commentedWell no, an object is not a valid value for the message array. In the Drupal API this array is defined to be the same as the PHP mail() function arguments. What you should do in your hook is convert your date to a string.
Comment #4
pawel.traczynski commentedCould you test it without the mimemail module enabled, so just using Drupal Core PHP Mailer:
1. Send email with 'Date' email header set to DateTimeInterface
$message['headers']['Date'] = new DateTime();. The email will send correctly.2. Now send another email but this time set 'Date' header to any string date, like a result of date('r')
$message['headers']['Date'] = date('r');You will get this error:As you can see a DateTimeInterface object is expected, NOT a string.
So to summarize as a result, its possible to send email with 'Date' header using Drupal Core as it correctly handles it. But its not possible to send such email using MimeMail because of the bug that I have pointed outr in my patch.
Comment #5
pawel.traczynski commentedCan we have this resolved please?
Comment #6
pawel.traczynski commentedHow can I help further, despite the patch provided, to have this fixed? If you don't have time then add me as a maintainer and I will fix it.
Comment #7
joelpittet@pawel.traczynski starting a reply with
is not a great way to start a constructive discussion, I'd bet @TR stopped reading after that line... doesn't matter how correct you may or may not be.
I have an Merge Request here https://www.drupal.org/project/mimemail/issues/3257799#comment-15486431 that might inadvertently do what you are asking for, give it a try if you agree with the approach.
Comment #8
joelpittetA couple things on the issue correct: all patches should be applied against the dev branch, so changing the version to the dev branch. And since there is a patch on the issue it's good to have the status as "Needs Review" (also used to trigger tests to run against the patch)
Comment #9
pawel.traczynski commentedThanks @joelpittet. I found the first reply starting with "Well, no" to not be good start of a constructive conversation either but I see the point. I have provided patch and solution. Has it been integrated into the module?
Comment #10
mark_fullmerI was able to reproduce the problem, following the method outlined above, on the latest version of this module. The recently-merged #3257799: RfcComplianceException: RFC 2822 Return-Path does not prevent the error.
I'm not opposed to adding this skip logic, as it will not adversely affect any values sent as a string, but I would point out that while it may bypass the Symfony problem, depending on the mailer being used, there may still be a problem. For example, if sites are using the default phpmailer used by mimemail, they will get a downstream error:
Converting this to a merge request to show passing tests...
Comment #11
mark_fullmerComment #13
mark_fullmer