How to configure a php mail library (like Drupal 7 phpmailer) to use the correct server

Goal

To send mail, using a third party PHP library, In a Drupal environment.

Assumptions

  • This is for Drupal 7, and its phpmailer.module. However, the concepts may apply to any PHP app that needs SMTP mail server details provided to it during configuration.
  • You have admin access to your Drupal site.
  • You have write access to your sites settings.php (by way of git deployments).
  • You have read the initial docs on sending email from Platform.sh environments, and taken notes that you need to explicitly enable emails on dev environments if needed.

Problems

  • Mail doesn’t send, because I’m using an advanced library.
  • Test emails are not delivered.
  • Watchdog reports, or drush wd-show shows messages like

Error sending e-mail
SMTP Error: SMTP connect() failed.

By default, using mail() on a Platform.sh environment is already configured to just work, as

The PHP runtime is configured to send email automatically via the assigned SendGrid sub-account.

However, if using additional mail libraries like SwiftMailer, Drupals smtp.module or phpmailer.module, the basic PHP mail() is deliberately bypassed, and additional SMTP settings are exposed, and must now be configured by you.

Steps

If using Drupal 7 phpmailer:

1. Check the settings

At the admin page found at
/admin/config/system/phpmailer
check the Primary SMTP server. It should not be localhost.

It may need to be set to whatever the value of the Platform.sh-provided environment variable PLATFORM_SMTP_HOST is for your hosting environment. This may be different depending on region or plan. Platform.sh-provided variables.

Hint: you can see the environment variables available to your runtime by visiting your phpinfo page at /admin/reports/status/php - though it’s also available by ssh-ing in also.
platform ssh ‘echo PLATFORM_SMTP_HOST is $PLATFORM_SMTP_HOST’

Copy that host value (an IP) into your Primary SMTP server setting at /admin/config/system/phpmailer. The SMTP port should remain 25.

Test that mail works by entering your email address in the Test Configuration section when you save.

2. Configure these settings in your settings.php file, not just the UI

For protection against database overwrites, and to ensure the settings remain correct if you have to move servers around, it can be better to copy this environment variable out of the live environment, and into Drupals configuration settings directly.

Inspecting the settings ( drush vget smtp ) tells us that the configuration key we need to update is smtp_host.

Edit your sites settings.php or equivalent, and add a line like:

$conf['smtp_host'] = getenv('PLATFORM_SMTP_HOST');

Test email sending works.

Conclusion

The mail delivery subsystem is now configured to send mail using the named server explicitly. If things change, the correct SMTP server should be updated also.

As noted earlier, the default behaviour with no special mail handling subsystem, is expected to work automatically. It’s only the more configurable ones that may have incorrect placeholders, or may require you to provide a value explicitly.

1 Like

For Drupal 8, the process will be the same, but the syntax of configuration settings overrides will be different.

  • First explore the modules settings via the Drupal UI, and try setting it manually to whatever the value of $PLATFORM_SMTP_HOST is for your environment. Test that.

  • Second, Edit your sites settings.php or equivalent, and add a line like:

$config['mailmodule.settings']['smtp_host'] = getenv('PLATFORM_SMTP_HOST');

And you’ll be done.

Check your chosen modules README or instructions for the actual syntax!

Example: Drupal 8 Swiftmailer 8.2

The module README tells you how to set
"Configuration Overrides "
which would need to be:

$config['swiftmailer.transport']['smtp_host'] = getenv('PLATFORM_SMTP_HOST');
$config['swiftmailer.transport']['smtp_port'] = 25

Example: Drupal 8 SMTP module

Configs are seen at /admin/config/system/smtp but it’s better to set these from the environment level in your settings.php like so:

$config['smtp.settings']['smtp_host'] = getenv('PLATFORM_SMTP_HOST');

To find out other config values you may want to set, investigate the output of drush config:get smtp.settings

Should probably be this now:

$config['smtp.settings']['smtp_host'] = gethostbyname(getenv('PLATFORM_SMTP_HOST'));

But in actuality, you don’t need to set Host and Port to be set.

$mail = new PHPMailer(true);
$mail->setFrom('from@yourdomain.com', 'Mailer');
$mail->addAddress('to@someone.com', 'Their Name');     //Add a recipient
$mail->Subject = 'Test email phpmailer.php';
$mail->Body = 'these are testmails in the body thingy';
$mail->send();