Cara mengatur SMTP secara terprogram

18

Asumsikan kita memiliki situs WP kosong dan kami ingin mengatur pengaturan SMTP secara terprogram dalam plugin atau tema kami. Apa cara termudah untuk melakukannya tanpa mengubah file inti?

Eugene Manuilov
sumber

Jawaban:

31

Pertama-tama, jika kita melihat implementasi wp_mailfungsi, kita akan melihat bahwa fungsi ini menggunakan PHPMailerkelas untuk mengirim email. Kita juga bisa melihat bahwa ada panggilan fungsi kode keras $phpmailer->IsMail();, yang mengatur untuk menggunakan mail()fungsi PHP . Itu berarti bahwa kita tidak dapat menggunakan pengaturan SMTP dengannya. Kita perlu memanggil isSMTPfungsi PHPMailerkelas. Dan juga kita perlu mengatur pengaturan SMTP kita juga.

Untuk mencapainya kita perlu mendapatkan akses ke $phpmailervariabel. Dan di sini kita phpmailer_initbertindak yang dipanggil sebelum mengirim email. Jadi kita dapat melakukan apa yang kita butuhkan dengan menulis penangan tindakan kita:

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 = '[email protected]'; // 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();
}

Dan itu saja.

Eugene Manuilov
sumber
Barang bagus, Eugene, thx! Saya kira 10 baris kode ini dapat menggantikan seluruh plugin SMTP ... (?)
brasofilo
@brasofilo thx! Saya pikir itu tidak dapat menggantikan plugin SMTP, karena plugin memungkinkan Anda untuk mengonfigurasi pengaturan di panel admin. Cuplikan ini hanya praktik terbaik tentang "cara mengubah pengaturan email secara terprogram" tanpa merusak file inti atau tanpa wp_mailfungsi penulisan ulang .
Eugene Manuilov
2
Di mana kode ini ditempatkan? Saya ingin membuat semua tema saya menggunakan server SMTP yang sama.
Anjan
1
WP yang sangat aneh tidak membuat ini lebih mudah karena Anda akan berpikir itu akan menjadi umum untuk memodifikasi ini.
Carson Reinke
1
ini berfungsi untuk saya, @JackNicholson Anda harus memeriksanya juga.
Eugene Manuilov
7

Tambahan untuk jawaban @EugeneManuilov.

Pengaturan SMTP

Secara default mereka hanya bisa mendapatkan - sebagai @EugeneManuilov sudah menjawab - diatur oleh selama callback melekat pada do_action_ref_array(). Sumber / inti .

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

Pengecualian SMTP

Per default WordPress tidak memberikan Anda hasil debug. Alih-alih hanya mengembalikan FALSEjika terjadi kesalahan. Ini plugin kecil untuk memperbaikinya:

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

Gudang

Plugin keduanya tersedia di GistHub ini pada GitHub , jadi pertimbangkan untuk mengecek plugin tersebut dari sana untuk mendapatkan pembaruan.

kaisar
sumber
3

Jawaban lain untuk posting ini, sambil memberikan solusi yang berfungsi, jangan mengatasi masalah keamanan menyimpan kredensial SMTP Anda dalam file plugin atau functions.php. Dalam beberapa kasus mungkin OK, tetapi praktik terbaik akan menentukan penyimpanan informasi ini dengan cara yang lebih aman. Sebenarnya tidak ada alasan bagus untuk tidak mengikuti praktik terbaik ketika datang untuk melindungi kredensial Anda.

Beberapa menyarankan menyimpannya ke DB sebagai opsi, tetapi juga menyediakan masalah keamanan yang sama tergantung pada jumlah pengguna administratif yang dimiliki situs Anda dan apakah pengguna tersebut harus dapat melihat kredensial login ini. Ini juga alasan yang sama untuk tidak menggunakan plugin untuk ini.

Cara terbaik untuk melakukannya adalah dengan mendefinisikan konstanta untuk info phpmailer di file wp-config.php Anda. Ini sebenarnya telah dibahas sebagai fitur di Komponen Email , tetapi belum diterima sebagai perangkat tambahan aktual saat ini. Tapi Anda bisa melakukannya sendiri dengan menambahkan yang berikut ke 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',   '[email protected]' );    // 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',   '[email protected]' ); // 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

Setelah ini didefinisikan dalam wp-config.php, mereka dapat digunakan di mana saja dengan menggunakan konstanta yang didefinisikan. Jadi Anda bisa menggunakannya di file plugin atau di functions.php Anda. (Khusus untuk OP, gunakan file plugin.)

/**
 * 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;
}

Ada sedikit lebih detail tentang ini di posting ini dan intisari tentang github di sini .

butlerblog
sumber
Solusi yang sangat bagus!
Phill Healey
1
Tambahan kecil: Tidak perlu dikatakan, jangan menyimpan kredensial dalam kontrol versi. Gunakan .envfile gitignored sebagai gantinya. Tapi tak seorang pun yang menempatkan sesuatu yang sensitif wp-config.phpmenggunakan kontrol versi, bagaimanapun ...
jsphpl