If you have a WordPress site, you've no doubt received email messages from
"WordPress". If you've also registered with other WordPress based sites, you've
probably received more emails, all from WordPress, though the emails were from
a variety of sites. Obviously, site owners do not know how to alter this default setting
so that messages from their site can be uniquely identified. There's very little excuse
for this, it's quite easy to change this, though it does involve a small amount of coding.
(OK, that's actually a decent excuse) The necessary coding can be mostly cut and paste from right here.
And while we're at it, we'll look at all the other things
you can do to change how WordPress does emails.
From Name
Getting WordPress emails to use a From: name of your choosing doesn't get much easier. (at least until
WordPress developers decide to put the option on an admin screen) Copy the following snippet to your
theme's (or better yet,
child theme's) functions.php
file. Edit the code to contain the name of your
choosing, then upload the file to your server. Job done!
function bcw_from_name() {
return "Your Site's Name Here"; // or whatever you want emails to be From:
}
add_filter('wp_mail_from_name', 'bcw_from_name');
Naming Conventions
Always avoid using plain English words alone when naming variables, functions, classes, etc.
Doing so increases the chance of name collisions with other plugins or themes. On the
other hand, names that reflect what the function does or what a variable value
represents, etc. is good practice. Obscure names make code hard to read and maintain.
So go ahead and use descriptive plain English names, but always prefix the names with
a unique identifier. For random code snippets, I use the "bcw" prefix, from my screen
name "bcworkz". It's common practice for a prefix to be the initials or first few letters
of the plugin or theme to which the named element belongs. So if you want to name a
function that changes the from name in your plugin called "Awesome
WordPress Hacks",
the actual function name might be "awh_change_name".
How does this code work? It uses a fundamental technique to hack WordPress known as
'hooks'. The
add_filter()
call registers our callback function bcw_from_name() so it is called any time
WordPress needs an email From: name. WordPress then uses what ever value is returned
from the callback.
From Address
The default From: email address of wordpress@yourdomain.com might be acceptable to you,
but if not, changing the From: address is just as easy as changing the From: name. Do
the same thing you did for the From: name above with the snippet below, except this time
enter the return email address.
function bcw_from_email() {
return 'YourEmail@yourdomain.com';
}
add_filter('wp_mail_from', 'bcw_from_email');
Caution
Some host mail servers will not forward mail if the domain's name record does not point
to the hosted server. In other words, if your hosted site's domain is mysite.com,
the mail server will happily forward messages from myemail@mysite.com but may reject
your messages if the From: address is myemail@yahoo.com because yahoo.com is not a domain
hosted on the host's servers.
Check with your hosting provider or simply do some careful testing before implementing this
code and forgetting about it.
You can do much more with WordPress emails than change the From: fields. In fact, the
possibilities are wide open. Anything you can do with email can be done in WordPress.
There are a number of filters you can hook into to alter the various parameters involved
with sending an email message. There is also an action hook with which you can alter
any aspect of the mailer object. Finally, most of the WordPress functions that send
notifications such as new user registration are pluggable. Pluggable functions can be
redefined by your plugin or child theme. Your redefined version will be used in place of
the default version. (Normally in PHP, attempting to redefine a function causes a fatal error.)
It's a good idea to test any email hacks by sending email messages to yourself before
letting such messages go out to users. Otherwise you have no idea if your hacks were
executed correctly. It's all too easy to make some silly mistake causing the whole
thing to fail. The following is a simple script that replaces the To: field of any
WordPress email with that of your own email address for testing. The add_filter()
line is currently commented out so that the script is non-operational. Simply remove the
double slash // to enable the script and reinsert again to disable. (Upload to
your server each time of course) It becomes a sort of switch for any time you need to
test mail functions.
Any mail filters you add will be applied to all calls to wp_mail(). If you add any
filters to handle a specific wp_mail() call, you should immediately remove those
same filters after the call to avoid corrupting other calls that should not have your
filters applied. Example:
add_filter('wp_mail_content_type', 'bcw_set_html_content_type');
wp_mail( $multiple_to_recipients, 'The subject', '<p>The <em>HTML</em> message</p>');
// Reset content-type to avoid conflicts— http://core.trac.wordpress.org/ticket/23578
remove_filter('wp_mail_content_type', 'bcw_set_html_content_type');
function bcw_set_html_content_type() {
return 'text/html';
}
'wp_mail_from_name' 'wp_mail_from'
These two filters were covered in the first section of this article, there's little else
to say about them.
'wp_mail'
This filter gives you the ability to alter any of the parameters passed to the
wp_mail()
function. Here is a typical wp_mail() call with default parameter names:
The parameters are compacted into an array and passed to your filter callback, thus each
parameter becomes the key in the passed array. You may change them as desired before
returning the array. Review the above linked reference and the following examples for more
information on how to use each parameter. You will see $headers is used to specify
From:, Cc:, and Bcc: fields, the other parameters are self explanatory.
Since arrays are typically easier to work with than strings, most examples here convert
any existing string parameters to an array before adding new elements.
Example code to include 2 file attachments if Subject: has the word "attached":
function bcw_add_attachment( $parms ) {
if ( stripos( $parms['subject'], 'attached')) {
//convert any possible delimited string format to array
if ( !is_array( $parms['attachments']))
$parms['attachments'] = array_filter( array_map('trim',
preg_split("/[\n\r\t,]+/", $parms['attachments'])));
$parms['attachments'][] = WP_CONTENT_DIR . '/uploads/2013/11/sample1.jpg';
$parms['attachments'][] = WP_CONTENT_DIR . '/uploads/2013/11/sample2.jpg';
}
return $parms;
}
add_filter('wp_mail', 'bcw_add_attachment');
Explanation of the array_filter — array_map — preg_split sequence. The string
is supposed to be newline separated, but there's a chance it may be return, comma, or
tab separated as well. We use a
RegExp
to split up the string regardless of the delimiter used. The split up string is returned
as an array with each string fragment as an element. This array is then fed to the
array_map() function to trim off any leading or trailing spaces left over from
the splitting process. The trimmed elements could still contain empty strings after
this, especially if the string fragments were separated by Windows style line feeds
"\r\n". Using array_filter() without a callback removes all empty strings.
In the following examples, assume the $emails array is structured like so:
The .com in the above array definition is intentionally misspelled in order to foil email address
scraper bots.
Example code to add Bcc: addresses to an email message:
function bcw_add_attachment( $parms ) {
//assume $emails is a global array of valid email data
global $emails;
//convert any possible string content to an array
if ( !is_array( $parms['headers']))
$parms['headers'] = array_filter( array_map('trim', explode(',', $parms['headers'])));
foreach ( $emails as $email ) {
$parms['headers'][] = "Bcc: {$email['address']}";
}
return $parms;
}
add_filter('wp_mail', 'bcw_add_attachment');
At the time of this writing, WordPress only passes single email addresses as the $to
parameter, so adding additional addresses can be done by simply concatenating a comma and
another address to the $mail['to'] value. WordPress makes individual calls to
wp_mail() in a loop anytime there is more than one recipient. In such a case,
it's overkill to convert the existing value to an array. You could thus add the $emails
array of addresses like so:
//assume $emails is an array of valid email addresses and
// $parms was the passed parameters from wp_mail()
foreach ( $emails as $email ) {
$parms['to'] .= ",{$email['address']}"
}
In order to future-proof your script and be compatible with other plugins, you should still
assume the value could be any one of the valid formats: an array, a single address, or a
comma delimited list (with and/or without spaces, extra commas, etc.) and account for
all possibilities before adding addresses.
//assume $emails is an array of valid email addresses and
// $parms was the passed parameters from wp_mail()
if ( !is_array( $parms['to']))
$parms['to'] = array_filter( array_map('trim', explode(',', $parms['to'])));
foreach ( $emails as $email ) {
$parms['to'][] = $email['address'];
}
The functions used to split up any string format are similar to the attachments example
above, except a comma delimited string is the only acceptable format, so we can use the
more efficient explode() instead of the more flexible preg_split() used
for attachments. If $emails had been a simple one dimensional array of email
addresses, we could have simply merged the converted array and $emails instead of
running a foreach loop.
Most mail servers have limits on the number of recipients or the character count of the list,
as well as attachment size limits and possibly other restrictions. These limitations must be
considered when adding large lists or files.
For what it's worth, the other fields also default to a string, except $attachments
which is an empty array by default but may have a CRLF (\r\n) separated list string from some other
filter hook. Of course, $subject and $message must be a string but other
parameters could be either a string or an array.
'wp_mail_content_type'
This filter allows you to change the mime type from the default 'text/plain' to any
other valid mime type. The one type most people might want to use is 'text/html'
for formatted text, but you can set it to anything you need. When you alter the default
by adding your callback to this filter, you must then remove your callback after you've
made the wp_mail() call to avoid conflicts with system calls that require
the default content type. The
introductory example
of this section illustrates this technique.
'wp_mail_charset'
The charset of emails is set by default to that of the blog, usually UTF-8, but you can
use this filter to set the charset to any valid charset string. If you change it from
that of the blog, you must then ensure the message string uses the encoding specified. The functions
mb_convert_encoding() or
iconv()
can be used for changing encodings. As mentioned earlier, you should remove your
filter callback when you're done using it to avoid conflicts with other system
mail functions.
All the above filters are invoked by the wp_mail() function. The
pluggable functions
also have several filters that you can hook on to. Their filters are listed with each function below. to Contents
Actions
'phpmailer_init'
Your last chance to alter the $phpmailer object before the Send() method is called,
passing the message on to the mail server. The object is passed by reference to your action callback
so you have complete, direct control of the email configuration via this action.
PHPMailer
PHPMailer is a GPL licensed email
transfer class used by WordPress. On the initial call to wp_mail(), a global $phpmailer
object is created. wp_mail() causes $wpmailer to use PHP's mail()
function to send email. This (and anything else about the class object) can be changed by hooking
the 'phpmailer_init' action and changing the PHPMailer object passed by reference.
Pluggables
(mail related)
You can define your own pluggable function of the same name and it will be used instead of the
core version. With all the other ways you can change how things work via action and filter hooks
there is little reason to create you own version, but you can if you do happen to have a reason.
These are the email related pluggable functions and the filters available to tweak the data
without wholesale redefinition of the entire function.
If you do find the need to redefine a function, it's a good idea to retain any apply_filters()
calls that are still applicable to maintain maximum compatibility with other plugins the user
may have installed.
While you could redefine this function, there is rarely any need since you can change most
aspects of what this function does with the following filters.
While you could redefine this function, there is rarely any need since you can change most
aspects of what this function does with the following filters.
Change Password wp_password_change_notification()
This function has no filters or actions to hook, though it calls wp_mail() which does.
New User wp_new_user_notification()
This function has no filters or actions to hook, though it calls wp_mail() which does.
Send Email wp_mail()
Techniques to change how this function works via actions and filters have been covered.
If that's not enough, this function is pluggable as well. If you do plug in your own version,
you'd be well advised to continue to use the PHPMailer class, or lacking that,
at least some other mail library such as
SwiftMailer or
Zend/Mail.
Correctly using PHP's mail() function directly to generate email in full compliance
with all standards is exceedingly difficult. Let one of these libraries do it for you. to Contents «Back