29

I have a dev, staging, and live server workflow set up on Pantheon. My site has a lot of rules that cause members to be e-mailed for various reasons. I sometimes need to work on these on my dev/staging sites but I've realized that, since they have the live data, sometimes users will receive additional or duplicate e-mails when I'm working on something.

Is there any easy way to turn off all e-mailing capability (preferably automatically to prevent me from forgetting) on a dev/staging server? Ideally, I'd like to disable e-mail via a custom module, since I already have steps in place for making sure a custom module is enabled on dev/staging.

5
  • 2
    None of the answers here are satisfactory. Changing the settings.php means that this will get pushed to production. Installing a module in Test and Dev means that it will get overwritten when you clone from Live. Some suggested code changes - seriously? A settings.local.php would work but was not mentioned. I have one in the local development site, but with a Git workflow this is not practical for the Pantheon environments because I have to switch to SFTP before I can get the file there or make updates. So, alas, innocent production users will continue to occasionally receive emails from test.
    – cdonner
    Sep 2, 2015 at 2:29
  • 3
    @cdonner Yes, seriously. There are many ways you can solve the knock-on issue you've succumbed to, all of them very straightforward. Personally I use git update-index --assume-unchanged sites/default/settings.php to keep settings.php from being pushed around different environments. Some people prefer some conditional logic which checked environment settings and includes different conf files based on environment (a la pretty much every other web framework in existence, in any language). The only limit here is one's imagination, it's basic PHP/git stuff, doesn't need to be added to the answers
    – Clive
    Sep 14, 2015 at 8:43
  • 1
    I respect your opinion, Clive. Here is the problem, though. If you have a big site where a large number of users can get a large number of emails from a test environment if one team member forgets to make an assume-unchanged git call before checking in, I as the person responsible for this would not want to rely on your method.
    – cdonner
    Sep 15, 2015 at 14:16
  • 1
    If you do choose to modify sites/default/settings.php, instead do git update-index --skip-worktree sites/default/settings.php. With --assume-unchanged, you lose the changes you made to settings.php if you do a git reset --hard. See stackoverflow.com/questions/13630849/…
    – user5072
    Jan 14, 2016 at 21:35
  • Couldn't you also put settings.php into your .gitignore? Dec 8, 2016 at 18:13

14 Answers 14

41

As another, quicker, option, you can add the following lines to your site's settings.php file (if you have the Devel module installed, which you certainly should if this is a dev site).

$conf['mail_system'] = array(
  'default-system' => 'DevelMailLog',
);

That will replace the default mail system with Devel's development mail system, which writes emails to a file log rather than sending them to a recipient. By default the files are stored in temporary://devel-mails, but you can alter that by setting another variable, eg.

$conf['devel_debug_mail_directory'] = '/path/to/folder';
1
13

Just a note to add another module to the "There is a module for that" list :

Reroute email intercepts all outgoing emails from a Drupal site and reroutes them to a predefined configurable email address.

I agree that this functionnality can easily be implemented with a few lines of code, but using this module, you could continue to receive emails to a predefined adress, with details on the original recipient, nice functionnality imho.

1
  • 3
    Reroute email also lets you put code in your settings.php file to enable/disable/change settings based on your hostname (or whatever if() statement you want to use), so you can have it automatically turn OFF on Production and ON on any other machine.
    – diamondsea
    Oct 2, 2015 at 19:50
11

Or you can use hook_mail_alter to redirect or prevent drupal mails:

/**
* Implements hook_mail_alter
*/
function yourmodule_mail_alter(&$message) {
  // set 'To' field to nothing, so Drupal won’t have any address
  $message['to'] = ''; 
}
2
  • 3
    This is essentially all Mail Redirect does; probably better just to write these few lines than to include a whole new module
    – Clive
    Jul 27, 2012 at 8:26
  • Not a good idea, this is they type of code that sneaks into your prod environment when you forget about it and git commit . or something similar.
    – Duncanmoo
    Aug 1, 2018 at 11:53
6

https://api.drupal.org/api/drupal/modules!system!system.api.php/function/hook_mail_alter/7

<?php
/**
 * Implements hook_mail_alter().
 */
function mymodule_mail_alter(&$message) {
  $message['send'] = FALSE; 
}
1
  • This is a better solution than the accepted answer. This stops the mail from being sent altogether, instead of just rerouting to a dummy address that still requires a send mail attempt. Jul 16, 2014 at 22:10
6

Drupal 8

For Drupal 8, you can turn on the Devel module mail handler through the configuration system.

With drush it would be:

drush -y pm-enable devel
drush -y config-set system.mail interface.default devel_mail_log
2
  • 2
    You can also set this per environment in settings.local.php: $config['system.mail']['interface']['default'] = 'devel_mail_log'; Feb 4, 2016 at 1:25
  • 1
    To specify the log dir then it's $config['devel.settings']['debug_mail_directory'] = 'temporary://my-directory';.
    – leymannx
    Jan 7, 2019 at 14:53
4

I usually use Reroute Email module for this case. It can reroute all email from dev to certain email. The email sent also specify where this email should be sent to.

3

I think that Mail Redirect module is perfect for you :) Another dirty way is install the SMTP module and set a wrong smtp ;)

2
  • Is it possible to use this module and still be able to test Mail functionality ?
    – GoodSp33d
    Jul 27, 2012 at 8:01
  • Yes, because the system sends email to chosen email address
    – arrubiu
    Jul 27, 2012 at 8:12
3

This will work without devel and is safe in all three environments.

Add this in settings.php. Copy it and change the environment to test for Test.

// Stop email on dev.
if (isset($_SERVER['PANTHEON_ENVIRONMENT']) &&
  $_SERVER['PANTHEON_ENVIRONMENT'] === 'dev') {
  // @see MYMODULE_mail_alter().
  $conf['development_environment'] = TRUE;
}

Then in mymodule:

function MYMODULE_mail_alter(&$message) {
  if(variable_get('development_environment', FALSE)) {
    // First: Prevent the mail from being sent.
    $message['send'] = FALSE;

    // Next: Log the mail so it can be debugged if necessary
    watchdog('Development Env', 'The following email was not sent: !message', array('!message' => '<pre>' . print_r($message, TRUE) . '</pre>'));
  }
}

Credit for the mail alter idea goes to http://www.jaypan.com/tutorial/preventing-emails-being-sent-drupal-7-development-environment.

1
  • Note that this could be an access bypass vulnerability. On a pass reset email the hashed pass and reset link will be sent to watchdog, for one example.
    – awolfey
    Jan 25, 2016 at 1:57
2

So you could put this in your settings.php or settings.local.php if you have specific ones for dev, staging & production.

if(module_exists('devel')) {
  // Use Devel's maillog
  $conf['mail_system'] = array( 
    'default-system' => 'DevelMailLog',
  );
  // To set custom path 
  // $conf['devel_debug_mail_directory'] = '/path/to/folder';
} 
elseif (module_exists('mail_redirect')) {
  // Enable email rerouting.
  $conf['reroute_email_enable'] = 1;
  // Space, comma, or semicolon-delimited list of email addresses to pass
  // through. Every destination email address which is not on this list will be  
  // rerouted to the first address on the list.
  $conf['reroute_email_address'] = "[email protected]";
  // Enable inserting a message into the email body when the mail is being
  // rerouted.
  $conf['reroute_email_enable_message'] = 1;
}
2

Here is the documentation page for this: https://www.drupal.org/docs/develop/local-server-setup/managing-mail-handling-for-development-or-testing

Another way to can do this that I haven't seen mentioned yet here would be to put this on your settings.php file:

// Prevent sending emails, store it in Drupal within the state system.
// Use drush sget system.test_mail_collector or
// \Drupal::state()->get('system.test_mail_collector', []); to see emails sent.
// @see \Drupal\Core\Mail\Plugin\Mail\TestMailCollector
$config['system.mail']['interface']['default'] = 'test_mail_collector';

This way you work around having to depend on an third party module.

This is what core does to test mail functionality, which is pretty nice, have a look at \Drupal\Core\Test\AssertMailTrait if you're curious.

1

Assuming that you are using the Mailsystem module, just go to admin/config/system/mailsystem and select DevelMailLog.

1

Set-up your SMTP to localhost and install MailCatcher (GitHub) which catches any message sent to it to display in a web interface.

Installation

  1. gem install mailcatcher
  2. mailcatcher
  3. Configure your sendmail_path in PHP to:

    sendmail_path = /usr/bin/env catchmail -f [email protected]
    

    or in Apache configuration:

    php_admin_value sendmail_path "/usr/bin/env catchmail -f [email protected]"
    
  4. Go to http://localhost:1080/

  5. Send mail through smtp://localhost:1025

In Drush you can do like:

php -d sendmail_path="$(which catchmail)" drush.php some-command
1

if you do not want to touch Drupal configs, setup MailHog on your server to catch all the e-mails coming out of your application.

-1

Enable SMTP Authentication Support module and you can directly turn off your SMTP Mail Server at admin/config/system/smtp.

Your Answer

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

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