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.

Assume we have blank WP site and we want to setup SMTP settings programmatically in our plugin or theme. What's the easiest way to do it without changing core files?

share|improve this question

2 Answers 2

up vote 10 down vote accepted

First of all, if we take a look at implementation of wp_mail function, we will see that this function uses PHPMailer class to send emails. Also we could notice that there is hard coded function call $phpmailer->IsMail();, which sets to use PHP's mail() function. It means that we can't use SMTP settings with it. We need to call isSMTP function of PHPMailer class. And also we need to set our SMTP settings as well.

To achieve it we need to get access to $phpmailer variable. And here we come to phpmailer_init action which is called before sending an email. So we can do what we need by writing our action handler:

add_action( 'phpmailer_init', 'wpse8170_phpmailer_init' );
function wpse8170_phpmailer_init( PHPMailer $phpmailer ) {
    $phpmailer->Host = 'your.smtp.server.here';
    $phpmailer->Port = 25; // could be different
    $phpmailer->Username = 'your_username@example.com'; // if required
    $phpmailer->Password = 'yourpassword'; // if required
    $phpmailer->SMTPAuth = true; // if required
    // $phpmailer->SMTPSecure = 'ssl'; // enable if required, 'tls' is another possible value

    $phpmailer->IsSMTP();
}

And that's all.

share|improve this answer
    
Nice stuff, Eugene, thx! I guess this 10 lines of code can substitute an entire SMTP plugin...(?) –  brasofilo Dec 13 '12 at 11:59
    
@brasofilo thx! I think it can't substitute a SMTP plugin, because the plugin allows you to configure settings at admin panel. This snippet is just best practice about "how to change email settings programmatically" without breaking core files or without rewriting wp_mail function. –  Eugene Manuilov Dec 13 '12 at 12:40
    
Maybe a link to the core? Just found that we need to use this for SSL: $phpmailer->SMTPSecure = 'ssl';, or 'tls' if that's the case. ::: Again:, great stuff! –  brasofilo Jan 15 '13 at 10:24
    
@brasofilo yes, agree. Feel free to edit the answer if you want. Thanks for help. –  Eugene Manuilov Jan 15 '13 at 11:14
    
Where should this code be placed? I want to make all my themes use the same SMTP servers. –  Anjan Jan 10 at 14:43

Addition to @EugeneManuilov answer.

SMTP settings

By default those can only get - as @EugeneManuilov already answered - be set by during a callback attached to an do_action_ref_array(). Source/core.

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (WCM) PHPMailer SMTP Settings
 * Description: Enables SMTP servers, SSL/TSL authentication and SMTP settings.
 */

add_action( 'phpmailer_init', 'phpmailerSMTP' );
function phpmailerSMTP( $phpmailer )
{
    # $phpmailer->IsSMTP();
    # $phpmailer->SMTPAuth   = true;  // Authentication
    # $phpmailer->Host       = '';
    # $phpmailer->Username   = '';
    # $phpmailer->Password   = '';
    # $phpmailer->SMTPSecure = 'ssl'; // Enable if required - 'tls' is another possible value
    # $phpmailer->Port       = 26;    // SMTP Port - 26 is for GMail
}

SMTP Exceptions

Per default WordPress doesn't give you any debug output. Instead it just returns FALSE if an error occurred. Here's small plugin to fix this:

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (WCM) PHPMailer Exceptions & SMTP
 * Description: WordPress by default returns <code>FALSE</code> instead of an <code>Exception</code>. This plugin fixes that.
 */

add_action( 'phpmailer_init', 'WCMphpmailerException' );
function WCMphpmailerException( $phpmailer )
{
    if ( ! defined( 'WP_DEBUG' ) OR ! WP_DEBUG )
    {
        $phpmailer->SMTPDebug = 0;
        $phpmailer->debug = 0;
        return;
    }
    if ( ! current_user_can( 'manage_options' ) )
        return;

    // Enable SMTP
    # $phpmailer->IsSMTP();
    $phpmailer->SMTPDebug = 2;
    $phpmailer->debug     = 1;

    // Use `var_dump( $data )` to inspect stuff at the latest point and see
    // if something got changed in core. You should consider dumping it during the
    // `wp_mail` filter as well, so you get the original state for comparison.
    $data = apply_filters(
        'wp_mail',
        compact( 'to', 'subject', 'message', 'headers', 'attachments' )
    );

    current_user_can( 'manage_options' )
        AND print htmlspecialchars( var_export( $phpmailer, true ) );

    $error = null;
    try
    {
        $sent = $phpmailer->Send();
        ! $sent AND $error = new WP_Error( 'phpmailerError', $sent->ErrorInfo );
    }
    catch ( phpmailerException $e )
    {
        $error = new WP_Error( 'phpmailerException', $e->errorMessage() );
    }
    catch ( Exception $e )
    {
        $error = new WP_Error( 'defaultException', $e->getMessage() );
    }

    if ( is_wp_error( $error ) )
        return printf(
            "%s: %s",
            $error->get_error_code(),
            $error->get_error_message()
        );
}

Repository

The plugins are both available in this Gist on GitHub, so consider checking those plugins out from there to grab any updates.

share|improve this answer

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.