Comment définir SMTP par programme

18

Supposons que nous ayons un site WP vierge et que nous voulons configurer les paramètres SMTP par programme dans notre plugin ou thème. Quelle est la façon la plus simple de le faire sans modifier les fichiers principaux?

Eugene Manuilov
la source

Réponses:

31

Tout d'abord, si nous regardons l'implémentation de la wp_mailfonction, nous verrons que cette fonction utilise la PHPMailerclasse pour envoyer des emails. Nous pourrions également remarquer qu'il existe un appel de fonction codé en dur $phpmailer->IsMail();, qui définit l'utilisation de la mail()fonction PHP . Cela signifie que nous ne pouvons pas utiliser les paramètres SMTP avec lui. Nous devons appeler la isSMTPfonction dePHPMailer classe. Et nous devons également définir nos paramètres SMTP également.

Pour y parvenir, nous devons avoir accès à la $phpmailervariable. Et ici, nous arrivons à l' phpmailer_initaction qui est appelée avant d'envoyer un e-mail. Nous pouvons donc faire ce dont nous avons besoin en écrivant notre gestionnaire d'actions:

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

Et c'est tout.

Eugene Manuilov
la source
Joli truc, Eugene, merci! Je suppose que ces 10 lignes de code peuvent remplacer un plugin SMTP entier ... (?)
brasofilo
@brasofilo thx! Je pense qu'il ne peut pas remplacer un plugin SMTP, car le plugin vous permet de configurer les paramètres dans le panneau d'administration. Cet extrait est simplement la meilleure pratique sur "comment modifier les paramètres de messagerie par programmation" sans casser les fichiers de base ou sans wp_mailfonction de réécriture .
Eugene Manuilov
2
Où ce code doit-il être placé? Je veux que tous mes thèmes utilisent les mêmes serveurs SMTP.
Anjan
1
WP très étrange ne rend pas cela plus facile car vous penseriez qu'il serait courant de le modifier.
Carson Reinke
1
cela fonctionne pour moi, @JackNicholson, vous devriez également le vérifier de votre côté.
Eugene Manuilov,
7

Ajout à la réponse @EugeneManuilov.

Paramètres SMTP

Par défaut, ceux-ci ne peuvent être définis - comme @EugeneManuilov l'a déjà répondu - que lors d'un rappel attaché à un do_action_ref_array(). Source / noyau .

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

Exceptions SMTP

Par défaut, WordPress ne vous donne aucune sortie de débogage. Au lieu de cela, il revient simplement FALSEsi une erreur s'est produite. Voici un petit plugin pour résoudre ce problème:

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

Dépôt

Les plugins sont tous deux disponibles dans ce Gist sur GitHub , alors pensez à vérifier ces plugins à partir de là pour récupérer les mises à jour.

kaiser
la source
3

Les autres réponses à ce message, tout en fournissant une solution de travail, ne résolvent pas le problème de sécurité du stockage de vos informations d'identification SMTP dans un fichier de plug-in ou functions.php. Dans certains cas, cela peut être acceptable, mais les meilleures pratiques dicteraient le stockage de ces informations de manière plus sécurisée. Il n'y a vraiment aucune bonne raison de ne pas suivre les meilleures pratiques en matière de protection de vos informations d'identification.

Certains suggèrent de l'enregistrer dans la base de données en option, mais offrent également les mêmes problèmes de sécurité selon le nombre d'utilisateurs administratifs de votre site et si ces utilisateurs devraient pouvoir voir ces informations de connexion. C'est aussi la même raison de ne pas utiliser de plugin pour cela.

La meilleure façon de le faire est de définir des constantes pour les informations phpmailer dans votre fichier wp-config.php. En fait, cela a été discuté en tant que fonctionnalité dans le composant Mail , mais n'a pas été accepté comme une amélioration réelle pour le moment. Mais vous pouvez le faire vous-même en ajoutant ce qui suit à 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

Une fois ceux-ci définis dans wp-config.php, ils peuvent être utilisés n'importe où en utilisant la constante définie. Vous pouvez donc les utiliser dans un fichier de plugin ou dans votre functions.php. (Spécifique à l'OP, utilisez un fichier de 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;
}

Il y a un peu plus de détails à ce sujet dans cet article et un résumé sur github ici .

butlerblog
la source
Une très bonne solution!
Phill Healey
1
Petit ajout: Inutile de dire que ne stockez pas les informations d'identification dans le contrôle de version. Utilisez plutôt un .envfichier gitignored . Mais personne qui met quelque chose de sensible dans wp-config.phputilise le contrôle de version, de toute façon…
jsphpl