Was ist der einfachste Weg, um SMTP-Einstellungen programmgesteuert einzurichten?

18

Angenommen, wir haben eine leere WP-Site und möchten die SMTP-Einstellungen programmgesteuert in unserem Plugin oder Theme einrichten. Was ist der einfachste Weg, ohne die Kerndateien zu ändern?

Eugene Manuilov
quelle

Antworten:

31

Wenn wir uns zunächst die Implementierung der wp_mailFunktion ansehen , werden wir feststellen, dass diese Funktion die PHPMailerKlasse zum Senden von E-Mails verwendet. Wir konnten auch feststellen, dass es einen fest codierten Funktionsaufruf gibt $phpmailer->IsMail();, der die Verwendung der PHP- mail()Funktion einstellt . Dies bedeutet, dass wir keine SMTP-Einstellungen verwenden können. Wir müssen die isSMTPFunktion der PHPMailerKlasse aufrufen . Und wir müssen auch unsere SMTP-Einstellungen vornehmen.

Um dies zu erreichen, müssen wir Zugriff auf $phpmailerVariable erhalten. Und hier kommen wir zum phpmailer_initHandeln, das vor dem Versenden einer E-Mail aufgerufen wird. Wir können also tun, was wir brauchen, indem wir unseren Action-Handler schreiben:

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

Und das ist alles.

Eugene Manuilov
quelle
Nettes Zeug, Eugene, danke! Ich denke, diese 10 Codezeilen können ein ganzes SMTP-Plugin
ersetzen
@brasofilo Danke! Ich denke, es kann kein SMTP-Plugin ersetzen, da Sie mit dem Plugin Einstellungen im Admin-Bereich konfigurieren können. Dieses Snippet ist nur eine bewährte Methode zum "programmgesteuerten Ändern von E-Mail-Einstellungen", ohne Kerndateien zu beschädigen oder die wp_mailFunktion zum erneuten Schreiben zu verwenden.
Eugene Manuilov
2
Wo soll dieser Code platziert werden? Ich möchte, dass alle meine Designs dieselben SMTP-Server verwenden.
Anjan
1
Sehr seltsames WP macht dies nicht einfacher, da Sie denken, es wäre üblich, dies zu ändern.
Carson Reinke
1
es funktioniert bei mir, @JackNicholson du solltest es auch an deinem Ende überprüfen.
Eugene Manuilov
7

Zusatz zu @EugeneManuilov Antwort.

SMTP-Einstellungen

Standardmäßig können diese nur - wie @EugeneManuilov bereits beantwortet hat - durch einen an eine angehängten Rückruf gesetzt werden do_action_ref_array(). Quelle / Kern .

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

Standardmäßig gibt WordPress keine Debug-Ausgabe aus. Stattdessen wird nur zurückgegeben, FALSEwenn ein Fehler aufgetreten ist. Hier ist ein kleines Plugin, um dies zu beheben:

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

Die Plugins sind beide in diesem Gist auf GitHub verfügbar. Überprüfen Sie daher die Plugins von dort aus, um Aktualisierungen zu erhalten.

Kaiser
quelle
3

Bei den anderen Antworten auf diesen Beitrag handelt es sich zwar um eine funktionierende Lösung, es geht jedoch nicht um das Sicherheitsproblem beim Speichern Ihrer SMTP-Anmeldeinformationen in einer Plug-in-Datei oder in functions.php. In einigen Fällen mag dies in Ordnung sein, aber die Best Practices schreiben eine sicherere Speicherung dieser Informationen vor. Es gibt wirklich keinen guten Grund, sich beim Schutz Ihrer Anmeldeinformationen nicht an bewährte Methoden zu halten.

Einige schlagen vor, es als Option in der Datenbank zu speichern, bieten jedoch auch die gleichen Sicherheitsprobleme, abhängig von der Anzahl der administrativen Benutzer auf Ihrer Site und davon, ob diese Benutzer diese Anmeldeinformationen sehen können sollen. Dies ist auch der gleiche Grund, kein Plugin dafür zu verwenden.

Der beste Weg, dies zu tun, besteht darin, Konstanten für die phpmailer-Informationen in Ihrer wp-config.php-Datei zu definieren. Dies wurde in der E-Mail-Komponente bereits als Feature erörtert , wurde jedoch zu diesem Zeitpunkt noch nicht als eigentliche Verbesserung akzeptiert. Sie können dies jedoch selbst tun, indem Sie der Datei wp-config.php Folgendes hinzufügen:

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

Sobald diese in wp-config.php definiert sind, können sie mit der definierten Konstante überall verwendet werden. Sie können diese also in einer Plugin-Datei oder in Ihrer functions.php verwenden. (Verwenden Sie für das OP eine Plugin-Datei.)

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

Es gibt ein wenig mehr Details dazu in diesem Beitrag und einen Überblick über Github hier .

Butlerblog
quelle
Eine wirklich gute Lösung!
Phill Healey
1
Kleiner Zusatz: Es ist unnötig zu erwähnen, dass Anmeldeinformationen nicht in der Versionskontrolle gespeichert werden. Verwenden Sie .envstattdessen gitignored file. Aber niemand, der etwas Sensibles in wp-config.phpdie Versionskontrolle steckt , benutzt sowieso ...
jsphpl