Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm wondering how to create differents wp_mail_from and wp_mail_from_name for specific actions that use the built-in mail system in Wordpress.

For example, when a new comment comes, notify the user using this:

function comments_new_mail_from($old) {return 'comments@example.com';}
function comments_new_mail_from_name($old) {return 'Comments at Example.com';}
add_filter('wp_mail_from', 'comments_new_mail_from');
add_filter('wp_mail_from_name', 'comments_new_mail_from_name');

But when a new user registers, use:

function users_new_mail_from($old) {return 'users@example.com';}
function users_new_mail_from_name($old) {return 'Users at Example.com';}
add_filter('wp_mail_from', 'users_new_mail_from');
add_filter('wp_mail_from_name', 'users_new_mail_from_name');

I want to do this to figure out the way to do this properly and avoid any problems with plugins using the built-in mail system that Wordpress have.

share|improve this question
add comment

1 Answer

up vote 2 down vote accepted

There are two ways:

  1. Inspect the original value, and if it specific for this case return a specific new value.

  2. Chain the filters: register the mail filter only on specific hooks. So you have to find a hook that happens before wp_mail() is called.

Simple example, not tested, just a guide:

// change mod mails for new comments
add_filter( 'pre_option_moderation_notify', array ( 'WPSE_Mail_Filter', 'init' ) );
// new user registration
add_filter( 'load-user-new.php', array ( 'WPSE_Mail_Filter', 'init' ) );

class WPSE_Mail_Filter
{
    protected static $new_mail = NULL;
    protected static $new_name = NULL;

    public static function init( $input = NULL )
    {
        if ( 'pre_option_moderation_notify' === current_filter() )
        {
            self::$new_mail = 'comments@example.com';
            self::$new_name = 'Comments at Example.com';
        }

        if ( 'load-user-new.php' === current_filter() )
        {
            self::$new_mail = 'users@example.com';
            self::$new_name = 'Users at Example.com';
        }

        // add more cases
        // then check if we set a new value:

        if ( ! empty ( self::$new_mail ) )
            add_filter( 'wp_mail_from', array ( __CLASS__, 'filter_email' ) );

        if ( ! empty ( self::$new_name ) )
            add_filter( 'wp_mail_from_name', array ( __CLASS__, 'filter_name' ) );

        // we do not change anything here.
        return $input;
    }

    public static function filter_name( $name )
    {
        remove_filter( current_filter(), array ( __CLASS__, __FUNCTION__ ) );
        return self::$new_name;
    }

    public static function filter_email( $email )
    {
        remove_filter( current_filter(), array ( __CLASS__, __FUNCTION__ ) );
        return self::$new_mail;
    }
}

The difficult part is finding the proper hook.

For example when a new comment has been written, the function wp_notify_moderator() is called. There is no really good hook in that function, but it calls …

if ( 0 == get_option( 'moderation_notify' ) )

… early. That again fires the hook pre_option_moderation_notify, and that is where we can start our filter. You have to search through the core code to find the best start hook for all cases, but usually there is always something.

share|improve this answer
    
I've checked and for the comments, the function is wp_notify_moderator.. but I can't figure out yet how to apply this to your code. Can you help me? –  Sydney Beau Apr 11 '13 at 19:09
    
@SydneyBeau See my update. I have added an explanation how I found that hook. –  toscho Apr 11 '13 at 19:14
1  
You call add_filter() for a filter that runs before the mail is sent. Do not edit core files. Try my code as I have written it here in a separate plugin. I haven’t tested it, but it should work. –  toscho Apr 11 '13 at 19:39
1  
Thank you very much! Your code finally helped me to figure out how to do this in a very nice way. Just be aware that I've made some fixes to your untested code. if ( ! empty ( self::$new_name ) ) add_filter( 'wp_mail_from_name', array ( __CLASS__, 'filter_name' ) ); and public static function filter_email( $email ) { remove_filter( current_filter(), array ( __CLASS__, __FUNCTION__ ) ); return self::$new_mail; } –  Sydney Beau Apr 11 '13 at 20:06
1  
@SydneyBeau Please fix my post; you get reputation for that. :) –  toscho Apr 12 '13 at 2:51
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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