Different wp_mail_from and wp_mail_from_name for specific situations

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:

Read More
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.

Related posts

Leave a Reply

1 comment

  1. 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.