Envío de correos electrónicos
¿Va a enviar correos electrónicos, como boletines o confirmaciones de pedidos? Nette Framework proporciona las herramientas necesarias con una API muy agradable. Le mostraremos:
- cómo crear un correo electrónico, incluidos los archivos adjuntos
- cómo enviarlo
- cómo combinar correos electrónicos y plantillas
Instalación
Descargue e instale la biblioteca usando Composer:
composer require nette/mail
Creación de un correo electrónico
El correo electrónico es un objeto de la clase Nette\Mail\Message. Lo creamos así:
$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
->addTo('petr@example.com')
->addTo('jirka@example.com')
->setSubject('Confirmación de pedido')
->setBody("Hola,\nsu pedido ha sido recibido.");
Todos los parámetros especificados deben estar en UTF-8.
Además de especificar el destinatario con el método addTo()
, también puede especificar el destinatario de la
copia addCc()
o el destinatario de la copia oculta addBcc()
. En todos estos métodos, incluido
setFrom()
, podemos escribir la dirección de tres maneras:
$mail->setFrom('franta@example.com');
$mail->setFrom('franta@example.com', 'Franta');
$mail->setFrom('Franta <franta@example.com>');
El cuerpo del correo electrónico escrito en HTML se pasa usando el método setHtmlBody()
:
$mail->setHtmlBody('<p>Hola,</p><p>su pedido ha sido recibido.</p>');
No necesita crear la alternativa de texto, Nette la generará automáticamente por usted. Y si el correo electrónico no tiene
un asunto establecido, intentará tomarlo del elemento <title>
.
También es extraordinariamente fácil insertar imágenes en el cuerpo HTML. Simplemente pase la ruta donde se encuentran físicamente las imágenes como segundo parámetro, y Nette las incluirá automáticamente en el correo electrónico:
// agrega automáticamente /path/to/images/background.gif al correo electrónico
$mail->setHtmlBody(
'<b>Hola</b> <img src="background.gif">',
'/path/to/images',
);
El algoritmo que inserta imágenes busca estos patrones: <img src=...>
,
<body background=...>
, url(...)
dentro del atributo HTML style
y la sintaxis especial
[[...]]
.
¿Puede ser aún más fácil enviar correos electrónicos?
Un correo electrónico es como una postal. Nunca envíe contraseñas u otras credenciales por correo electrónico.
Adjuntos
Por supuesto, se pueden adjuntar archivos al correo electrónico. El método
addAttachment(string $file, ?string $content = null, ?string $contentType = null)
se utiliza para esto.
// inserta el archivo /path/to/example.zip en el correo electrónico con el nombre example.zip
$mail->addAttachment('/path/to/example.zip');
// inserta el archivo /path/to/example.zip en el correo electrónico llamado info.zip
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));
// inserta el archivo example.txt en el correo electrónico con el contenido "Hola John!"
$mail->addAttachment('example.txt', 'Hola John!');
Plantillas
Si envía correos electrónicos HTML, es natural escribirlos en el sistema de plantillas Latte. ¿Cómo hacerlo?
$latte = new Latte\Engine;
$params = [
'orderId' => 123,
];
$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
->addTo('petr@example.com')
->setHtmlBody(
$latte->renderToString('/path/to/email.latte', $params),
'/path/to/images',
);
Archivo email.latte
:
<html>
<head>
<meta charset="utf-8">
<title>Confirmación de pedido</title>
<style>
body {
background: url("background.png")
}
</style>
</head>
<body>
<p>Hola,</p>
<p>Su pedido número {$orderId} ha sido recibido.</p>
</body>
</html>
Nette inserta automáticamente todas las imágenes, establece el asunto según el elemento <title>
y genera
una alternativa de texto al HTML.
Uso en Nette Application
Si utiliza correos electrónicos junto con Nette Application, es decir, con presenters, es posible que desee crear enlaces en
las plantillas utilizando el atributo n:href
o la etiqueta {link}
. Latte no los conoce de forma nativa,
pero es muy fácil agregarlos. El objeto Nette\Application\LinkGenerator
puede crear enlaces, y puede obtenerlo
pidiéndolo mediante inyección de
dependencias:
use Nette;
class MailSender
{
public function __construct(
private Nette\Application\LinkGenerator $linkGenerator,
private Nette\Bridges\ApplicationLatte\TemplateFactory $templateFactory,
) {
}
private function createTemplate(): Nette\Application\UI\Template
{
$template = $this->templateFactory->createTemplate();
$template->getLatte()->addProvider('uiControl', $this->linkGenerator);
return $template;
}
public function createEmail(): Nette\Mail\Message
{
$template = $this->createTemplate();
$html = $template->renderToString('/path/to/email.latte', $params);
$mail = new Nette\Mail\Message;
$mail->setHtmlBody($html);
// ...
return $mail;
}
}
En la plantilla, creamos enlaces como estamos acostumbrados. Todos los enlaces creados a través de LinkGenerator serán absolutos.
<a n:href="Presenter:action">Enlace</a>
Envío de un correo electrónico
Mailer es una clase que se encarga de enviar correos electrónicos. Implementa la interfaz Nette\Mail\Mailer y hay varios mailers predefinidos disponibles, que presentaremos.
El framework agrega automáticamente un servicio de tipo Nette\Mail\Mailer
al contenedor DI basado en la configuración, al que puede acceder pidiéndolo mediante inyección de dependencias.
SendmailMailer
El mailer predeterminado es SendmailMailer, que utiliza la función PHP mail. Ejemplo de uso:
$mailer = new Nette\Mail\SendmailMailer;
$mailer->send($mail);
Si desea establecer returnPath
y su servidor sigue sobrescribiéndolo, use
$mailer->commandArgs = '-fMuj@email.cz'
.
SmtpMailer
Para enviar correo a través de un servidor SMTP, se utiliza SmtpMailer
.
$mailer = new Nette\Mail\SmtpMailer(
host: 'smtp.gmail.com',
username: 'franta@gmail.com',
password: '*****',
encryption: 'ssl',
);
$mailer->send($mail);
Se pueden pasar los siguientes parámetros adicionales al constructor:
port
– si no se establece, se utiliza el predeterminado 25 o 465 parassl
timeout
– tiempo de espera para la conexión SMTPpersistent
– usar conexión persistenteclientHost
– establecer la cabecera Host del clientestreamOptions
– permite establecer opciones de contexto SSL para la conexión
FallbackMailer
No envía correos electrónicos directamente, sino que media el envío a través de un conjunto de mailers. Si un mailer falla, repite el intento con el siguiente. Si el último también falla, comienza de nuevo desde el primero.
$mailer = new Nette\Mail\FallbackMailer([
$smtpMailer,
$backupSmtpMailer,
$sendmailMailer,
]);
$mailer->send($mail);
Como parámetros adicionales en el constructor, podemos especificar el número de reintentos y el tiempo de espera en milisegundos.
DKIM
DKIM (DomainKeys Identified Mail) es una tecnología para aumentar la confiabilidad de los correos electrónicos, que también ayuda a detectar mensajes falsificados. El mensaje enviado se firma con la clave privada del dominio del remitente y esta firma se almacena en la cabecera del correo electrónico. El servidor del destinatario compara esta firma con la clave pública almacenada en los registros DNS del dominio. Si la firma coincide, se demuestra que el correo electrónico realmente proviene del dominio del remitente y que no se modificó durante la transmisión del mensaje.
Puede configurar la firma de correos electrónicos para el mailer directamente en la configuración. Si no utiliza la inyección de dependencias, se utiliza de esta manera:
$signer = new Nette\Mail\DkimSigner(
domain: 'nette.org',
selector: 'dkim',
privateKey: file_get_contents('../dkim/dkim.key'),
passPhrase: '****',
);
$mailer = new Nette\Mail\SendmailMailer; // o SmtpMailer
$mailer->setSigner($signer);
$mailer->send($mail);
Configuración
Resumen de las opciones de configuración para Nette Mail. Si no utiliza todo el framework, sino solo esta biblioteca, lea cómo cargar la configuración.
Para enviar correos electrónicos, se utiliza de forma predeterminada el mailer Nette\Mail\SendmailMailer
, que no
se configura más. Sin embargo, podemos cambiarlo a Nette\Mail\SmtpMailer
:
mail:
# usa SmtpMailer
smtp: true # (bool) predeterminado es false
host: ... # (string)
port: ... # (int)
username: ... # (string)
password: ... # (string)
timeout: ... # (int)
encryption: ... # (ssl|tls|null) predeterminado es null (tiene alias 'secure')
clientHost: ... # (string) predeterminado es $_SERVER['HTTP_HOST']
persistent: ... # (bool) predeterminado es false
# contexto para la conexión al servidor SMTP, predeterminado es stream_context_get_default()
context:
ssl: # resumen de opciones en https://www.php.net/manual/en/context.ssl.php
allow_self_signed: ...
...
http: # resumen de opciones en https://www.php.net/manual/en/context.http.php
header: ...
...
Con la opción context › ssl › verify_peer: false
, puede desactivar la verificación de certificados SSL.
Desaconsejamos encarecidamente hacer esto, ya que la aplicación se volverá vulnerable. En su lugar, agregue los certificados al almacén.
Para aumentar la confiabilidad, podemos firmar los correos electrónicos utilizando la tecnología DKIM:
mail:
dkim:
domain: myweb.com
selector: lovenette
privateKey: %appDir%/cert/dkim.priv
passPhrase: ...
Servicios DI
Estos servicios se agregan al contenedor DI:
Nombre | Tipo | Descripción |
---|---|---|
mail.mailer |
Nette\Mail\Mailer | clase que envía correos electrónicos |
mail.signer |
Nette\Mail\Signer | firma DKIM |