Как настроить SMTP программно

18

Предположим, у нас есть пустой сайт WP, и мы хотим программно настроить параметры SMTP в нашем плагине или теме. Какой самый простой способ сделать это без изменения основных файлов?

Евгений Мануйлов
источник

Ответы:

31

Прежде всего, если мы посмотрим на реализацию wp_mailфункции, мы увидим, что эта функция использует PHPMailerкласс для отправки электронных писем. Также мы можем заметить, что есть жестко закодированный вызов функции $phpmailer->IsMail();, который устанавливает использование mail()функции PHP . Это означает, что мы не можем использовать настройки SMTP с ним. Нам нужно вызвать isSMTPфункцию PHPMailerкласса. А также нам нужно установить наши настройки SMTP.

Для этого нам нужно получить доступ к $phpmailerпеременной. И вот мы приходим к phpmailer_initдействию, которое вызывается перед отправкой электронного письма. Таким образом, мы можем сделать то, что нам нужно, написав наш обработчик действий:

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();
}

И это все.

Евгений Мануйлов
источник
Хороший материал, Евгений, спасибо! Я думаю, что эти 10 строк кода могут заменить весь плагин SMTP ... (?)
brasofilo 13.12.12
@brasofilo спасибо! Я думаю, что он не может заменить плагин SMTP, потому что плагин позволяет настраивать параметры в админ-панели. Этот фрагмент представляет собой просто рекомендацию о том, «как программно изменить настройки электронной почты», не нарушая основные файлы или не перезаписывая wp_mailфункцию.
Евгений Мануйлов
2
Где этот код должен быть размещен? Я хочу, чтобы все мои темы использовали одни и те же SMTP-серверы.
Анжан
1
Очень странный WP не делает это проще, так как вы думаете, что это было бы обычным делом, чтобы изменить это.
Карсон Рейнке
1
это работает для меня, @JackNicholson, ты должен проверить это и со своей стороны.
Евгений Мануйлов
7

Дополнение к @EugeneManuilov ответа.

Настройки SMTP

По умолчанию их можно получить - как уже ответил @EugeneManuilov - во время обратного вызова, прикрепленного к do_action_ref_array(). Источник / ядро .

<?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

По умолчанию WordPress не дает никаких результатов отладки. Вместо этого он просто возвращает, FALSEесли произошла ошибка. Вот небольшой плагин, чтобы исправить это:

<?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()
        );
}

вместилище

Оба плагина доступны в этом Gist на GitHub , поэтому рассмотрите возможность проверить эти плагины, чтобы получить какие-либо обновления.

кайзер
источник
3

Другие ответы на этот пост, хотя и предоставляют работающее решение, не решают проблему безопасности хранения ваших учетных данных SMTP в файле плагина или functions.php. В некоторых случаях это может быть нормально, но лучшие практики требуют более безопасного хранения этой информации. На самом деле нет веских причин не следовать рекомендациям, когда дело касается защиты ваших учетных данных.

Некоторые предлагают сохранить его в БД в качестве опции, но также предоставляют те же проблемы безопасности в зависимости от количества административных пользователей на вашем сайте и того, должны ли эти пользователи видеть эти учетные данные для входа. Это также та же причина, чтобы не использовать плагин для этого.

Лучший способ сделать это - определить константы для информации phpmailer в вашем файле wp-config.php. На самом деле это обсуждалось как функция в Почтовом Компоненте , но в настоящее время не принято в качестве фактического усовершенствования. Но вы можете сделать это самостоятельно, добавив следующее в wp-config.php:

/**
 * Set the following constants in wp-config.php
 * These should be added somewhere BEFORE the
 * constant ABSPATH is defined.
 */
define( 'SMTP_USER',   'user@example.com' );    // Username to use for SMTP authentication
define( 'SMTP_PASS',   'smtp password' );       // Password to use for SMTP authentication
define( 'SMTP_HOST',   'smtp.example.com' );    // The hostname of the mail server
define( 'SMTP_FROM',   'website@example.com' ); // SMTP From email address
define( 'SMTP_NAME',   'e.g Website Name' );    // SMTP From name
define( 'SMTP_PORT',   '25' );                  // SMTP port number - likely to be 25, 465 or 587
define( 'SMTP_SECURE', 'tls' );                 // Encryption system to use - ssl or tls
define( 'SMTP_AUTH',    true );                 // Use SMTP authentication (true|false)
define( 'SMTP_DEBUG',   0 );                    // for debugging purposes only set to 1 or 2

Как только они определены в wp-config.php, их можно использовать где угодно с помощью определенной константы. Таким образом, вы можете использовать их в файле плагина или в вашем functions.php. (Определенный для OP, используйте файл плагина.)

/**
 * This function will connect wp_mail to your authenticated
 * SMTP server. Values are constants set in wp-config.php
 */
add_action( 'phpmailer_init', 'send_smtp_email' );
function send_smtp_email( $phpmailer ) {
    $phpmailer->isSMTP();
    $phpmailer->Host       = SMTP_HOST;
    $phpmailer->SMTPAuth   = SMTP_AUTH;
    $phpmailer->Port       = SMTP_PORT;
    $phpmailer->Username   = SMTP_USER;
    $phpmailer->Password   = SMTP_PASS;
    $phpmailer->SMTPSecure = SMTP_SECURE;
    $phpmailer->From       = SMTP_FROM;
    $phpmailer->FromName   = SMTP_NAME;
}

В этом посте есть немного больше подробностей, а на github - суть .

butlerblog
источник
Действительно хорошее решение!
Фил Хили
1
Небольшое дополнение: само собой разумеется, не храните учетные данные в управлении версиями. Вместо .envэтого используйте gitignored файл. Но никто, кто вкладывает что-то чувствительное, в wp-config.phpлюбом случае не использует контроль версий ...
jsphpl