0

I want to remove the Return-Path, Sender, and Reply-To headers from the sent emails. I am trying to achieve this using the following code, but the headers aren't removed from the email.

function mymodule_mail_alter(&$message) {
  unset($message['headers']['Return-Path']);
  unset($message['headers']['Sender']);
  unset($message['headers']['Reply-To']);
}

We are using default PHP mailer of Drupal 8 and the SMTP module . We are trying to fire the Test Mail via the SMTP module after entering credentials. But it seems we are not able to modify the headers from hook_mail_alter().

What am I doing wrong?

2
  • 2
    So much left unsaid ... such as what @Mail plugin(s) you're using.
    – anonymous
    Commented Aug 5, 2021 at 8:55
  • We are using default PHP mailer of Drupal 8 and the SMTP module . We are trying to fire the Test Mail via the SMTP module after entering credentials. But it seems we are not able to modify the headers from hook_mail_alter Commented Aug 5, 2021 at 9:46

3 Answers 3

1

The SMTP module always sets certain headers which cannot be unset. See the following lines from Drupal\smtp\Plugin\Mail\SMTPMailSystem:

$headers['Sender'] = $from;
$headers['Return-Path'] = $from;
$headers['Reply-To'] = $from;

This is to make it compatible with Drupal core which does the same from what I can tell.

For more control, you can use the module PHPMailer SMTP instead which explicitly unsets the Return-Path header to comply with RFC 5321.

It also makes no assumptions about which extra headers should be present (beyond the required ones) and only sets them if they are added elsewhere.

The following would work if the case of the headers match:

function mymodule_mail_alter(&$message) {
  unset($message['headers']['Sender']);
  unset($message['headers']['Reply-To']);
}

Alternatively, the following would unset headers regardless of case:

function mymodule_mail_alter(&$message) {
  $message['headers'] = array_change_key_case($message['headers']);
  unset($message['headers']['sender']);
  unset($message['headers']['reply-to']);
}

Disclaimer: I am the author of PHPMailer SMTP.

2

Removing the values from $message['headers'] isn't sufficient, as the plugin used to send emails could also use $message['Return-Path'], $message['Sender'], or $message['Reply-To'] value to build the email headers. The class that is used as default plugin to send emails, PhpMail uses the following code, but other plugins could use different code.

$site_mail = $this->configFactory->get('system.site')->get('mail');
$additional_headers = isset($message['Return-Path']) && ($site_mail === $message['Return-Path'] || static::_isShellSafe($message['Return-Path'])) ? '-f' . $message['Return-Path'] : '';
$mail_result = @mail($message['to'], $mail_subject, $mail_body, $mail_headers, $additional_headers);

Since the email plugin is used to send the email after the hook_mail_alter() implementations are invoked, and since the email plugin can add one of those headers to its discretion, there isn't any warranty the email is sent without those headers. Assuming the email plugin adds only those headers when $message or $message['headers'] contains a value for them, the following code should work.

function mymodule_mail_alter(&$message) {
  unset($message['Return-Path']);
  unset($message['Sender']);
  unset($message['Reply-To']);
  unset($message['headers']['Return-Path']);
  unset($message['headers']['Sender']);
  unset($message['headers']['Reply-To']);
}
1
  • 1
    I'd like to add that the RFC says headers are case insensitive, so for example "unset($message['headers']['Return-Path']);" is insufficient - the header key could be "return-Path", so your unset wouldn't do anything. Likewise, the @Mail plugin could be assuming a certain casing, so even if the plugin tried to respect your choice the case you use could trip it up. Bottom line is what apademo said above: "Since the email plugin is used to send the email after the hook_mail_alter() implementations are invoked ... there isn't any warranty the email is sent without those headers."
    – anonymous
    Commented Sep 14, 2021 at 0:01
-1

Use function hook_mail($key, &$message, $params) instead. Also, you would need additional $key I believe to distinguish for which functionality is the mail being sent.

Then this hook would be triggered when sending the mail manually:

$send = true;
$mailManager = \Drupal::service('plugin.manager.mail');
$result = $mailManager->mail($module, $key, $to, $langcode, $params, null, $send);

I would suggest using Swiftmailer, it omits all of the manual work.

2
  • I take the OP wants to remove those headers from every email. hook_mail() would not help with that.
    – apaderno
    Commented Aug 5, 2021 at 12:12
  • Even if the OP wanted to remove the Return-Path, Sender, and Reply-To headers from the email sent by a module the OP wrote, or by a specific module, this answer doesn't say how to achieve that.
    – apaderno
    Commented Aug 6, 2021 at 9:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.