Come impostare SMTP a livello di codice


18

Supponiamo di avere un sito WP vuoto e vogliamo configurare le impostazioni SMTP a livello di codice nel nostro plugin o tema. Qual è il modo più semplice per farlo senza cambiare i file core?

Risposte:


31

Prima di tutto, se diamo un'occhiata all'implementazione della wp_mailfunzione, vedremo che questa funzione usa la PHPMailerclasse per inviare e-mail. Inoltre, possiamo notare che esiste una chiamata di funzione con codice fisso $phpmailer->IsMail();, che imposta l'utilizzo della mail()funzione di PHP . Significa che non possiamo usare le impostazioni SMTP con esso. Dobbiamo chiamare la isSMTPfunzione di PHPMailerclasse. Inoltre, dobbiamo configurare anche le nostre impostazioni SMTP.

Per raggiungerlo dobbiamo avere accesso alla $phpmailervariabile. E qui arriviamo phpmailer_initall'azione che viene chiamata prima di inviare un'e-mail. Quindi possiamo fare ciò di cui abbiamo bisogno scrivendo il nostro gestore di azioni:

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

E questo è tutto.


Bella roba, Eugene, grazie! Immagino che queste 10 righe di codice possano sostituire un intero plug-in SMTP ... (?)
brasofilo,

@brasofilo thx! Penso che non possa sostituire un plug-in SMTP, perché il plug-in consente di configurare le impostazioni nel pannello di amministrazione. Questo frammento è solo la migliore pratica su "come modificare le impostazioni di posta elettronica a livello di codice" senza rompere i file core o senza la wp_mailfunzione di riscrittura .
Eugene Manuilov,

2
Dove dovrebbe essere collocato questo codice? Voglio fare in modo che tutti i miei temi utilizzino gli stessi server SMTP.
Anjan,

1
WP molto strano non lo rende più facile come si potrebbe pensare che sarebbe comune modificarlo.
Carson Reinke,

1
funziona per me, @JackNicholson dovresti verificarlo anche da te.
Eugene Manuilov

7

Aggiunta alla risposta @EugeneManuilov.

Impostazioni SMTP

Per impostazione predefinita, questi possono solo essere impostati, poiché @EugeneManuilov ha già risposto, durante un callback collegato a un do_action_ref_array(). Fonte / nucleo .

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

Eccezioni SMTP

Per impostazione predefinita, WordPress non fornisce alcun output di debug. Invece restituisce solo FALSEse si è verificato un errore. Ecco un piccolo plugin per risolvere questo problema:

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

deposito

I plug-in sono entrambi disponibili in questo Gist su GitHub , quindi considera di controllare quei plug-in da lì per ottenere eventuali aggiornamenti.


3

Le altre risposte a questo post, pur fornendo una soluzione funzionante, non affrontano il problema di sicurezza della memorizzazione delle credenziali SMTP in un file plug-in o funzioni.php. In alcuni casi potrebbe essere OK, ma le migliori pratiche imporrebbero di archiviare queste informazioni in modo più sicuro. Non c'è davvero un buon motivo per non seguire le migliori pratiche quando si tratta di proteggere le tue credenziali.

Alcuni suggerirebbero di salvarlo nel DB come opzione, ma forniscono anche gli stessi problemi di sicurezza a seconda del numero di utenti amministrativi che il tuo sito ha e se questi utenti dovrebbero essere in grado di vedere queste credenziali di accesso. Questo è anche lo stesso motivo per non utilizzare un plugin per questo.

Il modo migliore per farlo è definire le costanti per le informazioni di phpmailer nel tuo file wp-config.php. In realtà, questo è stato discusso come una funzionalità del componente Mail , ma al momento non è stato accettato come un effettivo miglioramento. Ma puoi farlo tu stesso aggiungendo quanto segue a 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

Una volta definiti in wp-config.php, possono essere usati ovunque usando la costante definita. Quindi potresti usarli in un file plugin o nelle tue funzioni.php. (Specifico per l'OP, utilizzare un 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;
}

C'è un po 'più di dettagli su questo in questo post e una sintesi su Github qui .


Un'ottima soluzione!
Phill Healey,

1
Piccola aggiunta: inutile dirlo, non archiviare le credenziali nel controllo versione. Utilizzare .envinvece il file gitignored . Ma nessuno che mette qualcosa di sensibile wp-config.phpsta usando il controllo versione, comunque ...
jsphpl
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.