Cómo configurar SMTP programáticamente

13 dic 2012, 10:48:08
Vistas: 55.1K
Votos: 23

Supongamos que tenemos un sitio WP en blanco y queremos configurar los ajustes de SMTP programáticamente en nuestro plugin o tema. ¿Cuál es la forma más sencilla de hacerlo sin modificar los archivos del núcleo?

0
Todas las respuestas a la pregunta 3
12
36

En primer lugar, si analizamos la implementación de la función wp_mail, veremos que esta utiliza la clase PHPMailer para enviar correos electrónicos. También podremos notar que hay una llamada de función codificada directamente $phpmailer->IsMail();, que configura el uso de la función mail() de PHP. Esto significa que no podemos usar configuraciones SMTP con ella. Necesitamos llamar a la función isSMTP de la clase PHPMailer. Además, también debemos configurar nuestros parámetros SMTP.

Para lograrlo, necesitamos acceder a la variable $phpmailer. Es aquí donde entra en juego la acción phpmailer_init, que se llama antes de enviar un correo electrónico. Por lo tanto, podemos hacer lo que necesitamos escribiendo nuestro manejador de acción:

add_action( 'phpmailer_init', 'wpse8170_phpmailer_init' );
function wpse8170_phpmailer_init( PHPMailer $phpmailer ) {
    $phpmailer->Host = 'tu.servidor.smtp.aqui';
    $phpmailer->Port = 25; // podría ser diferente
    $phpmailer->Username = 'tu_usuario@ejemplo.com'; // si es requerido
    $phpmailer->Password = 'tupassword'; // si es requerido
    $phpmailer->SMTPAuth = true; // si es requerido
    // $phpmailer->SMTPSecure = 'ssl'; // activar si es requerido, 'tls' es otro valor posible

    $phpmailer->IsSMTP();
}

Y eso es todo.

13 dic 2012 10:48:08
Comentarios

¡Buen material, Eugene, gracias! Supongo que estas 10 líneas de código pueden sustituir un plugin SMTP completo...(?)

brasofilo brasofilo
13 dic 2012 13:59:42

@brasofilo ¡gracias! Creo que no puede sustituir un plugin SMTP, porque el plugin te permite configurar los ajustes desde el panel de administración. Este fragmento es solo una buena práctica sobre "cómo cambiar los ajustes de correo electrónico programáticamente" sin romper los archivos del núcleo o sin reescribir la función wp_mail.

Eugene Manuilov Eugene Manuilov
13 dic 2012 14:40:07

¿Tal vez un enlace al núcleo? Acabo de descubrir que necesitamos usar esto para SSL: $phpmailer->SMTPSecure = 'ssl';, o 'tls' si ese es el caso. ::: De nuevo:, ¡material excelente!

brasofilo brasofilo
15 ene 2013 12:24:45

@brasofilo sí, estoy de acuerdo. Siéntete libre de editar la respuesta si lo deseas. Gracias por la ayuda.

Eugene Manuilov Eugene Manuilov
15 ene 2013 13:14:19

¿Dónde debería colocar este código? Quiero que todos mis temas usen los mismos servidores SMTP.

Anjan Anjan
10 ene 2014 16:43:23

@Anjan crea tu propio plugin.

Eugene Manuilov Eugene Manuilov
10 ene 2014 17:49:10

Es muy extraño que WordPress no facilite esto, ya que podrías pensar que sería común modificar este aspecto.

Carson Reinke Carson Reinke
30 abr 2015 16:14:49

Esto parece que ya no funciona.

Etienne Dupuis Etienne Dupuis
2 nov 2015 18:56:21

¿Alguien puede confirmar si esto aún funciona?

Jack Jack
9 nov 2015 13:51:22

Funciona para mí, @JackNicholson deberías verificarlo también en tu entorno.

Eugene Manuilov Eugene Manuilov
9 nov 2015 16:41:18

Usé este código pero WordPress envía mediante mail() de PHP. ¿Cómo forzar a WordPress a que envíe solo por SMTP? Cuando uso wp_mail("hossein@hashemiui.com", "test", "test"); no lo envía via SMTP

Hossein Hashemi Hossein Hashemi
28 ene 2017 01:55:48

En WordPress 5.5 hay una versión más reciente de PHPMailer. El código anterior mostrará un error. Cambia PHPMailer $phpmailer por \PHPMailer\PHPMailer\PHPMailer $phpmailer y todo volverá a funcionar.

Betty Betty
11 jun 2021 11:36:46
Mostrar los 7 comentarios restantes
0
11

Adición a la respuesta de @EugeneManuilov.

Configuración SMTP

Por defecto, como ya respondió @EugeneManuilov, solo se pueden configurar mediante un callback adjunto a un do_action_ref_array(). Fuente/núcleo.

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (WCM) Configuración SMTP de PHPMailer
 * Description: Habilita servidores SMTP, autenticación SSL/TSL y configuración SMTP.
 */

add_action( 'phpmailer_init', 'phpmailerSMTP' );
function phpmailerSMTP( $phpmailer )
{
    # $phpmailer->IsSMTP();
    # $phpmailer->SMTPAuth   = true;  // Autenticación
    # $phpmailer->Host       = '';
    # $phpmailer->Username   = '';
    # $phpmailer->Password   = '';
    # $phpmailer->SMTPSecure = 'ssl'; // Activar si es necesario - 'tls' es otro valor posible
    # $phpmailer->Port       = 26;    // Puerto SMTP - 26 es para GMail
}

Excepciones SMTP

Por defecto WordPress no proporciona ninguna salida de depuración. En su lugar, simplemente devuelve FALSE si ocurre un error. Aquí hay un pequeño plugin para solucionar esto:

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (WCM) Excepciones PHPMailer & SMTP
 * Description: WordPress por defecto devuelve <code>FALSE</code> en lugar de una <code>Exception</code>. Este plugin corrige eso.
 */

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;

    // Habilitar SMTP
    # $phpmailer->IsSMTP();
    $phpmailer->SMTPDebug = 2;
    $phpmailer->debug     = 1;

    // Usa `var_dump( $data )` para inspeccionar datos en el último punto y ver
    // si algo ha cambiado en el núcleo. Deberías considerar volcarlo durante el
    // filtro `wp_mail` también, para obtener el estado original para comparación.
    $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()
        );
}

Repositorio

Ambos plugins están disponibles en este Gist en GitHub, así que considera descargarlos desde allí para obtener actualizaciones.

22 jun 2013 13:17:17
2

Las otras respuestas a esta publicación, aunque proporcionan una solución funcional, no abordan el problema de seguridad de almacenar tus credenciales SMTP en un archivo de plugin o functions.php. En algunos casos puede estar bien, pero las mejores prácticas indicarían almacenar esta información de forma más segura. Realmente no hay una buena razón para no seguir las mejores prácticas cuando se trata de proteger tus credenciales.

Algunos sugerirían guardarlas en la base de datos como opción, pero esto también presenta los mismos problemas de seguridad dependiendo del número de usuarios administrativos que tenga tu sitio y si esos usuarios deberían poder ver estas credenciales de acceso. Esta es también la misma razón para no usar un plugin para esto.

La mejor manera de hacer esto es definir constantes para la información de phpmailer en tu archivo wp-config.php. Esto ha sido discutido como una característica en el componente Mail, pero no ha sido aceptado como una mejora real hasta ahora. Pero puedes hacerlo tú mismo añadiendo lo siguiente a wp-config.php:

/**
 * Define las siguientes constantes en wp-config.php
 * Estos deben añadirse en algún lugar ANTES de que
 * se defina la constante ABSPATH.
 */
define( 'SMTP_USER',   'user@example.com' );    // Nombre de usuario para autenticación SMTP  
define( 'SMTP_PASS',   'smtp password' );       // Contraseña para autenticación SMTP
define( 'SMTP_HOST',   'smtp.example.com' );    // El hostname del servidor de correo
define( 'SMTP_FROM',   'website@example.com' ); // Dirección de correo remitente SMTP  
define( 'SMTP_NAME',   'e.g Website Name' );    // Nombre remitente SMTP
define( 'SMTP_PORT',   '25' );                  // Número de puerto SMTP - normalmente 25, 465 o 587
define( 'SMTP_SECURE', 'tls' );                 // Sistema de encriptación a usar - ssl o tls
define( 'SMTP_AUTH',    true );                 // Usar autenticación SMTP (true|false)  
define( 'SMTP_DEBUG',   0 );                    // Solo para depuración, establecer a 1 o 2

Una vez definidas en wp-config.php, se pueden usar en cualquier lugar mediante la constante definida. Así que podrías usarlas en un archivo de plugin o en tu functions.php. (Específicamente para el OP, usa un archivo de plugin).

/**
 * Esta función conectará wp_mail a tu servidor SMTP
 * autenticado. Los valores son constantes definidas en 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;
}

Hay un poco más de detalle sobre esto en esta publicación y un gist en github aquí.

10 ago 2017 18:57:05
Comentarios

¡Una solución realmente buena!

Phill Healey Phill Healey
8 sept 2017 21:14:04

Pequeño añadido: Ni que decir tiene, no almacenes credenciales en el control de versiones. Usa mejor un archivo .env ignorado por git. Pero vamos, quien mete información sensible en wp-config.php no está usando control de versiones de todas formas…

jsphpl jsphpl
29 ago 2018 18:32:52