Qual é a maneira mais fácil de definir programações SMTP programaticamente?

18

Suponha que tenhamos um site WP em branco e desejamos definir programações SMTP programaticamente em nosso plugin ou tema. Qual é a maneira mais fácil de fazer isso sem alterar os arquivos principais?

Eugene Manuilov
fonte

Respostas:

31

Primeiro de tudo, se dermos uma olhada na implementação da wp_mailfunção, veremos que essa função usa PHPMailerclasse para enviar e-mails. Também podemos notar que há uma chamada de função codificada $phpmailer->IsMail();, que define o uso da mail()função do PHP . Isso significa que não podemos usar configurações SMTP com ele. Precisamos chamar a isSMTPfunção de PHPMailerclasse. E também precisamos definir nossas configurações de SMTP também.

Para alcançá-lo, precisamos obter acesso à $phpmailervariável. E aqui chegamos à phpmailer_initação que é chamada antes de enviar um email. Assim, podemos fazer o que precisamos escrevendo nosso manipulador de ações:

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

E isso é tudo.

Eugene Manuilov
fonte
Coisas legais, Eugene, thx! Eu acho que essas 10 linhas de código podem substituir um plug-in SMTP inteiro ... (?)
brasofilo
@brasofilo thx! Eu acho que não pode substituir um plug-in SMTP, porque o plug-in permite que você defina as configurações no painel de administração. Esse snippet é apenas uma prática recomendada sobre "como alterar as configurações de email programaticamente" sem interromper os arquivos principais ou sem reescrever a wp_mailfunção.
Eugene Manuilov
2
Onde esse código deve ser colocado? Quero que todos os meus temas usem os mesmos servidores SMTP.
Anjan
1
O WP muito estranho não facilita isso, pois você pensaria que seria comum modificá-lo.
Carson Reinke
1
funciona para mim, @JackNicholson, você também deve verificar isso do seu lado.
Eugene Manuilov
7

Além da resposta @EugeneManuilov.

Configurações de SMTP

Por padrão, eles só podem ser configurados - como o @EugeneManuilov já respondeu - durante um retorno de chamada anexado a um do_action_ref_array(). Fonte / núcleo .

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

Exceções de SMTP

Por padrão, o WordPress não fornece nenhuma saída de depuração. Em vez disso, apenas retorna FALSEse ocorreu um erro. Aqui está um pequeno plugin para corrigir isso:

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

Repositório

Os plugins estão disponíveis neste Gist no GitHub , portanto, considere verificar esses plugins para obter atualizações.

kaiser
fonte
3

As outras respostas a esta postagem, embora ofereçam uma solução funcional, não abordam a questão da segurança de armazenar suas credenciais SMTP em um arquivo de plugin ou functions.php. Em alguns casos, isso pode ser bom, mas as práticas recomendadas determinariam o armazenamento dessas informações de maneira mais segura. Não há realmente um bom motivo para não seguir as práticas recomendadas quando se trata de proteger suas credenciais.

Alguns sugerem salvá-lo no banco de dados como uma opção, mas também fornecem os mesmos problemas de segurança, dependendo do número de usuários administrativos que seu site possui e se esses usuários devem poder ver essas credenciais de logon. Este também é o mesmo motivo para não usar um plugin para isso.

A melhor maneira de fazer isso é definir constantes para as informações do phpmailer no seu arquivo wp-config.php. Na verdade, isso foi discutido como um recurso no componente de email , mas não foi aceito como um aprimoramento real no momento. Mas você pode fazer isso adicionando o seguinte ao 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

Depois de definidos no wp-config.php, eles podem ser usados ​​em qualquer lugar usando a constante definida. Então você pode usá-los em um arquivo de plugin ou no seu functions.php. (Específico ao OP, use um arquivo de plug-in.)

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

Há um pouco mais de detalhes sobre isso neste post e uma essência no github aqui .

butlerblog
fonte
Uma solução realmente boa!
Phill Healey
1
Pequena adição: Escusado será dizer que não armazene credenciais no controle de versão. Use o .envarquivo gitignored . Mas ninguém que põe tudo em minúsculas wp-config.phpé usando o controle de versão, de qualquer maneira ...
jsphpl