How to use PHPmailer in a function in WordPress

I have a function in the WordPress functions.php file that searches for a condition in user meta and sends an email to a user based on what it finds. I currently use wp_mail() to send the email, and that works. However, I want to use the included PHPMailer class to do this so that I can send the messages via SMTP.

I thought I had a solution here: https://codex.wordpress.org/Plugin_API/Action_Reference/phpmailer_init, however, this seems to only apply to system generated messages, not for custom messages.

At this point I'm just guessing, but I tried this, with no luck (WP stops loading right at this point, no error message):

function my_function() {
    //if things are found send an email
    global $phpmailer;
    $phpmailer-IsSMTP();
    $phpmailer-Host = 'smtp.google.com';
    $phpmailer-Port = '587';
    $phpmailer-SMTPSecure = 'tls';
    $phpmailer-SMTPAuth = true;
    $phpmailer-Username = '[email protected]';
    $phpmailer-Password = '11111111';

    $phpmailer-addAddress('[email protected]', 'Joe User');
    $phpmailer-setFrom('[email protected]', 'Mailer');
    $phpmailer-addReplyTo('[email protected]', 'Information');
    $phpmailer-isHTML(true);
    $phpmailer-Subject = 'Here is the subject';
    $phpmailer-Body    = 'This is the HTML message body bin bold!/b';              
    $phpmailer-send();
    // Email sent; function over
}

FYI, I call this function in the header. I'm not adding it as an action because I want to control where it is used.

Is there a way to access the PHPMailer class directly from my function? I suppose i could load PHPMailer separately, but that seems silly.

Topic phpmailer wp-mail functions Wordpress

Category Web


require 'wp-includes/class-phpmailer.php'; fixed my problem, but I used a code to create a pdf and then send it in the same way.


There's no need to use the PHPMailer class in place of wp_mail(). wp_mail() is a essentially a wrapper for the class. It just makes an easier way of packaging and sending the message.

You can access the PHPMailer elements when it is initialized in order to have wp_mail() send through SMTP instead of the web server.

You said you're not adding as an action to control where it's used, but that's precisely what an action hook is for - it allows you to hook exactly where you want it, when you want it.

In this case, all of those PHPMailer elements need to be set when PHPMailer is initialized. There's an action hook for that - phpmailer_init

You can define your settings when PHPMailer is initialized using that hook:

add_action( 'phpmailer_init', 'send_smtp_email' );
function send_smtp_email( $phpmailer ) {
    $phpmailer->isSMTP();
    $phpmailer->Host       = 'smtp.google.com';
    $phpmailer->Port       = '587';
    $phpmailer->SMTPSecure = 'tls';
    $phpmailer->SMTPAuth   = true;
    $phpmailer->Username   = '[email protected]';
    $phpmailer->Password   = '11111111';
    $phpmailer->From       = '[email protected]';
    $phpmailer->FromName   = 'From Name';
    $phpmailer->addReplyTo('[email protected]', 'Information');
}

You want your message in HTML. You could set that in wp_mail()'s header argument, but you can/should use the wp_mail_content_type filter for that;

add_filter( 'wp_mail_content_type','set_my_mail_content_type' );
function set_my_mail_content_type() {
    return "text/html";
}

With your setup properly done, now you're all set to use wp_mail() to send your message and you can do it anywhere - I recommend hooking this function to something that makes sense - such as 'template_redirect' so you do it before headers are sent downstream:

function my_function() {

    $to = '[email protected]';
    $subject = 'Here is the subject';
    $message = 'This is the HTML message body <b>in bold!</b>';              

    wp_mail( $to, $subject, $message );

}

Update: Alternate (Contained) Method:

So, extending what was outlined above, suppose some these settings are not what you ordinarily want for every firing of wp_mail() and that you only wanted these settings for a specific email.

You still would need to break out the settings and hook them appropriately (otherwise they will not process at the right time). Noting that the phpmailer_init and wp_mail_content_type hooks are hit when wp_mail() is being run, you could set those hooks within your primary function, run your email, then remove them so you're back to the default.

function send_smtp_email( $phpmailer ) {
    $phpmailer->isSMTP();
    $phpmailer->Host       = 'smtp.google.com';
    $phpmailer->Port       = '587';
    $phpmailer->SMTPSecure = 'tls';
    $phpmailer->SMTPAuth   = true;
    $phpmailer->Username   = '[email protected]';
    $phpmailer->Password   = '11111111';
    $phpmailer->From       = '[email protected]';
    $phpmailer->FromName   = 'From Name';
    $phpmailer->addReplyTo('[email protected]', 'Information');
}

function set_my_mail_content_type() {
    return "text/html";
}

function my_function() {

    $to = '[email protected]';
    $subject = 'Here is the subject';
    $message = 'This is the HTML message body <b>in bold!</b>'; 

    add_filter( 'wp_mail_content_type','set_my_mail_content_type' );
    add_action( 'phpmailer_init', 'send_smtp_email' );

    wp_mail( $to, $subject, $message );

    remove_filter( 'wp_mail_content_type','set_my_mail_content_type' )
    remove_action( 'phpmailer_init', 'send_smtp_email' );

}

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.