Jak ustawić SMTP programowo


18

Załóżmy, że mamy pustą stronę WP i chcemy programowo skonfigurować ustawienia SMTP w naszej wtyczce lub motywie. Jak najłatwiej to zrobić bez zmiany podstawowych plików?

Odpowiedzi:


31

Po pierwsze, jeśli spojrzymy na implementację wp_mailfunkcji, zobaczymy, że ta funkcja używa PHPMailerklasy do wysyłania wiadomości e-mail. Zauważyliśmy również, że istnieje wywołanie funkcji zakodowane na stałe $phpmailer->IsMail();, które ustawia użycie mail()funkcji PHP . Oznacza to, że nie możemy używać z nim ustawień SMTP. Musimy wywołać isSMTPfunkcję PHPMailerklasy. Musimy również ustawić nasze ustawienia SMTP.

Aby to osiągnąć, musimy uzyskać dostęp do $phpmailerzmiennej. I tutaj dochodzimy do phpmailer_initdziałania, które jest wywoływane przed wysłaniem wiadomości e-mail. Możemy więc zrobić to, czego potrzebujemy, pisząc nasz moduł obsługi akcji:

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

I to wszystko.


Niezłe rzeczy, Eugene, dzięki! Myślę, że 10 wierszy kodu może zastąpić całą wtyczkę SMTP ... (?)
brasofilo,

@brasofilo thx! Myślę, że nie może zastąpić wtyczki SMTP, ponieważ wtyczka umożliwia konfigurację ustawień w panelu administracyjnym. Ten fragment kodu to po prostu najlepsza praktyka dotycząca „jak programowo zmieniać ustawienia poczty e-mail” bez uszkadzania podstawowych plików lub bez przepisywania wp_mail.
Eugene Manuilov,

2
Gdzie należy umieścić ten kod? Chcę, aby wszystkie moje motywy korzystały z tych samych serwerów SMTP.
Anjan

1
Bardzo dziwna WP nie ułatwia tego, ponieważ można by pomyśleć, że modyfikowanie tego byłoby powszechne.
Carson Reinke

1
to działa dla mnie, @JackNicholson, powinieneś to sprawdzić również na swoim końcu.
Eugene Manuilov,

7

Dodatek do odpowiedzi @EugeneManuilov.

Ustawienia SMTP

Domyślnie można je tylko - jak już odpowiedział @EugeneManuilov - ustawić w trakcie oddzwaniania dołączonego do do_action_ref_array(). Źródło / rdzeń .

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

Wyjątki SMTP

Domyślnie WordPress nie daje żadnych wyników debugowania. Zamiast tego po prostu zwraca, FALSEjeśli wystąpił błąd. Oto mała wtyczka, aby to naprawić:

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

Magazyn

Wtyczki są dostępne w tej Gist na GitHub , więc rozważ sprawdzenie tych wtyczek, aby pobrać aktualizacje.


3

Inne odpowiedzi na ten post, mimo że zapewniają działające rozwiązanie, nie rozwiązują problemu bezpieczeństwa przechowywania poświadczeń SMTP w pliku wtyczki lub funkcji. Php. W niektórych przypadkach może to być OK, ale najlepsze praktyki nakazują przechowywanie tych informacji w bardziej bezpieczny sposób. Naprawdę nie ma dobrego powodu, aby nie stosować najlepszych praktyk w zakresie ochrony danych uwierzytelniających.

Niektórzy sugerują zapisanie go jako opcję jako opcję, ale zapewnia to te same problemy bezpieczeństwa w zależności od liczby użytkowników administracyjnych Twojej witryny i tego, czy użytkownicy ci powinni widzieć te dane logowania. Jest to również ten sam powód, dla którego nie należy używać do tego wtyczki.

Najlepszym sposobem na to jest zdefiniowanie stałych dla informacji phpmailer w pliku wp-config.php. Zostało to omówione jako funkcja komponentu poczty , ale w tej chwili nie zostało zaakceptowane jako faktyczne ulepszenie. Ale możesz to zrobić samodzielnie, dodając następujące informacje do 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

Po ich zdefiniowaniu w wp-config.php można ich użyć w dowolnym miejscu, używając zdefiniowanej stałej. Możesz więc użyć ich w pliku wtyczki lub w pliku functions.php. (Specyficzne dla OP, użyj pliku wtyczki).

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

Jest trochę więcej szczegółów na ten temat w tym poście i streszczenie na github tutaj .


Naprawdę dobre rozwiązanie!
Phill Healey,

1
Mały dodatek: Nie trzeba dodawać, nie przechowuj poświadczeń w kontroli wersji. Zamiast .envtego użyj pliku gitignored . Ale i tak nikt, kto wp-config.php
włożyłby
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.