Problem/Motivation
On a site with translation enabled, when on the language that is not default, emails cannot be sent as the following error is raised:
The website encountered an unexpected error. Please try again later.
Error: Cannot use object of type Drupal\Core\StringTranslation\TranslatableMarkup as array in Drupal\Component\Utility\Unicode::truncateBytes() (line 263 of core/lib/Drupal/Component/Utility/Unicode.php).
Drupal\Component\Utility\Unicode::truncateBytes(Object, 47) (Line: 619)
Drupal\Component\Utility\Unicode::mimeHeaderEncode(Object, 1) (Line: 257)
Drupal\Core\Mail\MailManager->doMail('webform', 'contact_email_confirmation', 'example@gmail.com', 'hi', Array, 'Test', 1) (Line: 174)
Drupal\Core\Mail\MailManager->Drupal\Core\Mail\{closure}() (Line: 582)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 175)
Drupal\Core\Mail\MailManager->mail('webform', 'contact_email_confirmation', 'example@gmail.com', 'hi', Array, 'Test') (Line: 1022)
Drupal\webform\Plugin\WebformHandler\EmailWebformHandler->sendMessage(Object, Array) (Line: 721)
Drupal\webform\Plugin\WebformHandler\EmailWebformHandler->postSave(Object, , NULL) (Line: 2196)
Drupal\webform\Entity\Webform->invokeHandlers('postSave', Object, , NULL) (Line: 944)
...
In my case, this happens when submitting a webform in Hindi which tries to send a confirmation email to the user who submitted it.
The website has 2 languages, en as default and hi (hindi) as the other.
The error is only raised when submitting the form when on the Hindi version of the site.
Proposed resolution
I dug a bit and found that the problem resides in the doMail function of the MailManager manager class found in the core Mail module.
The call to $headers['From'] = Unicode::mimeHeaderEncode($site_config->get('name'), TRUE) . ' <' . $site_mail . '>'; raises the error as it happens that $site_config->get('name') does not always return a string. In my case it returns a TranslatableMarkup object.
my proposed solution is to detect when such a class is returned and call its getUntranslatedString() function when it happens.
Code extract:
// On sites with translations, the site name can come back as TranslatableMarkup
// instead of a simple string, so when this happens, we need to make it into
// a string first before passing it to mimeHeaderEncode.
$site_config_name = (get_class($site_config->get('name')) == "Drupal\Core\StringTranslation\TranslatableMarkup") ?
$site_config->get('name')->getUntranslatedString() : $site_config->get('name');
// Headers are usually encoded in the mail plugin that implements
// \Drupal\Core\Mail\MailInterface::mail(), for example,
// \Drupal\Core\Mail\Plugin\Mail\PhpMail::mail(). The site name must be
// encoded here to prevent mail plugins from encoding the email address,
// which would break the header.
$headers['From'] = Unicode::mimeHeaderEncode($site_config_name, TRUE) . ' <' . $site_mail . '>';
Remaining tasks
I need this to be reviewed by people who understand this module and its behaviour in general. I think my proposed solution would not break anything but I think a better way of doing it must exist.
| Comment | File | Size | Author |
|---|---|---|---|
| #3 | 2982908-error-email-sent-on-translated-site.patch | 1.52 KB | tguilpain |
Comments
Comment #2
tguilpain commentedComment #3
tguilpain commentedInitial patch.
Comment #4
cilefen commentedComment #7
allella commentedComment #8
allella commentedThe issue at https://www.drupal.org/project/drupal/issues/2745039#comment-12665783
would seem to be related because that suggests fixes for quoting ASCII-only site names, which is necessary to avoid breaking for sites with commas, VS not quoting MIME-encoded site names, which is against the mime-encoded RFC.
Comment #12
krzysztof domański