WPLift is supported by its audience. When you purchase through links on our site, we may earn an affiliate commission.

The WPLift Guide to Pluggable Functions Part 2: Logging emails with wp_mail

Last Updated on November 16th, 2018

Published on August 8th, 2013

Share This Article

This is the second of 3 posts that walk us through Pluggable Functions in WordPress. In our first post we were introduced to pluggable functions. We walked through how we could make use of them in our themes to let other developers override theme functions and in our plugins to override core WordPress functions like wp_mail.

Today we’re going to do something a bit more fancy with wp_mail than just shut it down. Simply turning off wp_mail solved our issue with emailing site users during development from development domains, but it really doesn’t help us know what’s going on with our WordPress install.

Are those receipt emails getting sent? Do they have the correct information in them? We have no way of knowing unless we log the emails that are getting sent.

Quick word on filters

For a simple site and a quick test you can use the wp_mail filter to change who an email get’s sent to. You can see an example below.

[sourcecode language=”php”]<?php
* Changes the ‘to’ email field in wp_mail so it always goes to the address specified
* @since 1.0
* @author WP Theme Tutorial, Curtis McHale
function wptt_change_to_address( $mail_array ){

$mail_array[‘to’] = ‘[email protected]’;

return $mail_array;

} // wptt_change_to_address
add_filter( ‘wp_mail’, ‘wptt_change_to_address’, 10, 1 );

That bit of code would simply make every email coming out of WordPress go to the email address you specify. While it works I don’t want a whole bunch of extra email in my inbox. Further if you’re building plugins for wide release and want to have some type of error reporting, getting a bunch of emails is simply not maintainable.

So we’re going to plug wp_mail and log all our emails in the WordPress admin.

Article Continues Below

Plugging and logging wp_mail

Now we’re going to walk through a plugin I have on Github called WPTT Basic Email Logging. I’m not going to cover the entire plugin, just the wp_mail portion. If you’d like to see the whole plugin explained you can visit this post.

For those that aren’t going to read the post, I’ve added a special class call WP_Logging that builds us an easy way to log anything in a WordPress custom post type. We’re going to take our code from last time and use the helper methods in WP_Logging to add a post to our site instead of sending an email.

Here is all the code, but the part to focus on is where we use function_exists to check if wp_mail is defined. The DEVELOPMENT constant just allows us to only capture emails on development environments. I go in to more detail about that in the linked post above.

To log emails you need the whole plugin, not just the piece I’m showing here.

[sourcecode language=”php”]<?php
Plugin Name: WPTT Email Logging
Plugin URI: https://wpthemetutorial.com
Description: Stops all emails going out from WordPress and logs them.
Version: 1.0
Author: WP Theme Tutorial, Curtis McHale
Author URI: https://wpthemetutorial.com
License: GPLv2 or later

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

require_once( plugin_dir_path( __FILE__ ) . ‘WP_Logging.php’ );

* Changes the default WP_Logging CPT items so that the default is to show
* them in the WordPress admin.
* @since 1.0
* @author SFNdesign, Curtis McHale
function wptt_email_logg_cpt_mods( $args ){

Article Continues Below

$args[‘public’] = true;

return $args;

} // wptt_email_logg_cpt_mods
if ( defined( ‘DEVELOPMENT’ ) && DEVELOPMENT ){
add_filter( ‘wp_logging_post_type_args’, ‘wptt_email_logg_cpt_mods’ );

if ( ! function_exists( ‘wp_mail’ ) && defined( ‘DEVELOPMENT’ ) && DEVELOPMENT ){

function wp_mail( $to, $subject, $message, $headers = ”, $attachments = array() ){
global $post;

if ( ! is_object( $post ) ) $post_id = null;

$log_data = array(
‘post_title’ => ‘Logged WordPress email to ‘ . $to . ”,
‘post_content’ => $message,
‘post_parent’ => $post_id,
‘log_type’ => ‘event’,

$log_meta = array(
‘to’ => $to,
‘subject’ => $subject,
‘message’ => $message,
‘headers’ => $headers,
‘attachments’ => $attachments,
‘current_user’ => wp_get_current_user(),
‘post_object’ => $post,

WP_Logging::insert_log( $log_data, $log_meta );
} // wp_mail

} // if

Article Continues Below

If you remember from our last post we just inserted the wp_mail function and did nothing with it. In our example above we now make sure that we pass through all the wp_mail parameters and log them.

Our first array defines the post_title, post_content, post_parent (mostly useful in the case of logging ecommerce transactions), and log_type. WP_Logging gives us 2 log types, error and event. An email is an event (typically not an error) so we just use the default event.

Our second array captures as much information as we can get. I want to have all the raw values of our parametrs and the post object and I want to know who the current user was when we caputered the email. If you’re tracking a bug, you typically can’t have too much information about it.

Logging the email will now add a new post to our WP_Logging custom post type which you can see an example of below.


Currently WP_Logging doesn’t provide a full UI so we’d only see the post title and post content, but in most scenarios that’s going to be enough information to confirm that our email was sent and has the proper content.

Use this where?

So this is cool and all, but where can we use it? I’ve used logging of wp_mail when I was building a system for students to book appointments with coaches. I needed to sort out a bunch of content in the email (usernames, times for calls, notes on calls) and I didn’t want to send all those emails. So I made sure I had the content right and then I sent 3 or 4 emails to test that WordPress was sending them properly.

Wrapping up and next time

After today I hope you can understand how pluggable functions can be used with this practical example. Next time we’re going to look at a few other pluggable functions with the goal of logging more information in WordPress. We’ll track password changes and new user notifications, to build a bit of a breadcrumb of what happens in our WordPress install.

About The Author

Curtis has been building WordPress sites for 5 years and specializes in eCommerce and Membership sites. You can find more of his writing on his personal site at Curtis McHale or his WordPress tutorials at WP Theme Tutorial. When not up to his elbows in WordPress you can find him hanging out with his wife and daughter.