Nette Documentation Preview

syntax
Envío de correos electrónicos
*****************************

<div class=perex>

¿Va a enviar correos electrónicos como boletines o confirmaciones de pedidos? Nette Framework proporciona las herramientas necesarias con una API muy agradable. Se lo mostraremos:

- cómo crear un correo electrónico, incluyendo archivos adjuntos
- cómo enviarlo
- cómo combinar correos electrónicos y plantillas

</div>


Instalación .[#toc-installation]
================================

Descargue e instale el paquete utilizando [Composer |best-practices:composer]:

```shell
composer require nette/mail
```


Creación de correos electrónicos .[#toc-creating-emails]
========================================================

El correo electrónico es un objeto [api:Nette\Mail\Message]:

```php
$mail = new Nette\Mail\Message;
$mail->setFrom('John <john@example.com>')
	->addTo('peter@example.com')
	->addTo('jack@example.com')
	->setSubject('Order Confirmation')
	->setBody("Hello, Your order has been accepted.");
```

Todos los parámetros deben estar codificados en UTF-8.

Además de especificar destinatarios con el método `addTo()`, también puede especificar el destinatario de la copia con `addCc()`, o el destinatario de la copia oculta con `addBcc()`. Todos estos métodos, incluido `setFrom()`, aceptan destinatarios de tres formas:

```php
$mail->setFrom('john.doe@example.com');
$mail->setFrom('john.doe@example.com', 'John Doe');
$mail->setFrom('John Doe <john.doe@example.com>');
```

El cuerpo de un correo electrónico escrito en HTML se pasa mediante el método `setHtmlBody()`:

```php
$mail->setHtmlBody('<p>Hello,</p><p>Your order has been accepted.</p>');
```

No tiene que crear un texto alternativo, Nette lo generará automáticamente por usted. Y si el correo electrónico no tiene un asunto definido, se tomará del elemento `<title>` elemento.

Las imágenes también pueden insertarse muy fácilmente en el cuerpo HTML de un correo electrónico. Basta con pasar 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:

```php
// automatically adds /path/to/images/background.gif to the email
$mail->setHtmlBody(
	'<b>Hello</b> <img src="background.gif">',
	'/path/to/images',
);
```

El algoritmo de incrustación de imágenes admite los siguientes 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?

Los correos electrónicos son como postales. Nunca envíes contraseñas u otras credenciales por correo electrónico. .[tip]


Archivos adjuntos .[#toc-attachments]
-------------------------------------

Por supuesto, puedes adjuntar archivos al correo electrónico. Utilice la dirección `addAttachment(string $file, ?string $content = null, ?string $contentType = null)`.

```php
// inserts the file /path/to/example.zip into the email under the name example.zip
$mail->addAttachment('/path/to/example.zip');

// inserts the file /path/to/example.zip into the email under the name info.zip
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));

// attaches new example.txt file contents "Hello John!"
$mail->addAttachment('example.txt', 'Hello John!');
```


Plantillas .[#toc-templates]
----------------------------

Si envías correos electrónicos HTML, es una gran idea escribirlos en el sistema de plantillas [Latte |latte:]. ¿Cómo hacerlo?

```php
$latte = new Latte\Engine;
$params = [
	'orderId' => 123,
];

$mail = new Nette\Mail\Message;
$mail->setFrom('John <john@example.com>')
	->addTo('jack@example.com')
	->setHtmlBody(
		$latte->renderToString('/path/to/email.latte', $params),
		'/path/to/images',
	);
```

Archivo `email.latte`:

```latte
<html>
<head>
	<meta charset="utf-8">
	<title>Order Confirmation</title>
	<style>
	body {
		background: url("background.png")
	}
	</style>
</head>
<body>
	<p>Hello,</p>

	<p>Your order number {$orderId} has been accepted.</p>
</body>
</html>
```

Nette inserta automáticamente todas las imágenes, establece el asunto según el elemento `<title>` y genera un texto alternativo para el cuerpo HTML.


Uso en la aplicación Nette .[#toc-using-in-nette-application]
-------------------------------------------------------------

Si utiliza correos electrónicos junto con Nette Application, es decir, presentadores, es posible que desee crear enlaces en las plantillas utilizando el atributo `n:href` o la etiqueta `{link}`. Latte básicamente no los conoce, pero es muy fácil añadirlos. La creación de enlaces puede hacer objeto `Nette\Application\LinkGenerator`, que se obtiene al pasarlo usando [inyección de dependencia |dependency-injection:passing-dependencies].

```php
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, el enlace se crea como en una plantilla normal. Todos los enlaces creados sobre LinkGenerator son absolutos:

```latte
<a n:href="Presenter:action">Link</a>
```


Envío de correos electrónicos .[#toc-sending-emails]
====================================================

Mailer es la clase responsable del envío de correos electrónicos. Implementa la interfaz [api:Nette\Mail\Mailer] y existen varios mailers listos para usar que presentaremos a continuación.

El framework añade automáticamente un servicio `Nette\Mail\Mailer` basado en la [configuración |#Configuring] al contenedor DI, que se obtiene pasándolo mediante [inyección de dependencias |dependency-injection:passing-dependencies].


SendmailMailer .[#toc-sendmailmailer]
-------------------------------------

El mailer por defecto es SendmailMailer que utiliza la función PHP [php:mail]. Ejemplo de uso:

```php
$mailer = new Nette\Mail\SendmailMailer;
$mailer->send($mail);
```

Si desea configurar `returnPath` y el servidor sigue sobrescribiéndolo, utilice `$mailer->commandArgs = '-fmy@email.com'`.


SmtpMailer .[#toc-smtpmailer]
-----------------------------

Para enviar correo a través del servidor SMTP, utilice `SmtpMailer`.

```php
$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 usará el valor por defecto 25 o 465 para `ssl`
* `timeout` - tiempo de espera para la conexión SMTP
* `persistent` - utilizar conexión persistente
* `clientHost` - designación del cliente
* `streamOptions` - permite establecer "opciones de contexto SSL":https://www.php.net/manual/en/context.ssl.php para la conexión


FallbackMailer .[#toc-fallbackmailer]
-------------------------------------

No envía correos electrónicos, sino que los envía a través de un conjunto de mailers. Si un mailer falla, repite el intento en el siguiente. Si falla el último, vuelve a empezar desde el primero.

```php
$mailer = new Nette\Mail\FallbackMailer([
	$smtpMailer,
	$backupSmtpMailer,
	$sendmailMailer,
]);
$mailer->send($mail);
```

Otros parámetros del constructor incluyen el número de repeticiones y el tiempo de espera en milisegundos.


DKIM .[#toc-dkim]
=================

DKIM (DomainKeys Identified Mail) es una tecnología de correo electrónico de confianza 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. Al cotejar la firma, se demuestra que el correo electrónico procede realmente del dominio del remitente y que el mensaje no ha sido modificado durante su transmisión.

Puede configurar el mailer para firmar el correo electrónico en [la configuración |#Configuring]. Si no utiliza la inyección de dependencia, se utiliza de la siguiente manera:

```php
$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 de .[#toc-configuring]
====================================

Visión general de las opciones de configuración para el Nette Mail. Si no está utilizando todo el framework, sino sólo esta librería, lea [cómo cargar la |bootstrap:] configuración.

Por defecto, el mailer `Nette\Mail\SendmailMailer` se utiliza para enviar correos electrónicos, que no se configura más. Sin embargo, podemos cambiarlo a `Nette\Mail\SmtpMailer`:

```neon
mail:
	# use SmtpMailer
	smtp: true       # (bool) defaults to false

	host: ...        # (string)
	port: ...        # (int)
	username: ...    # (string)
	password: ...    # (string)
	timeout: ...     # (int)
	encryption: ...  # (ssl|tls|null) defaults to null (has alias 'secure')
	clientHost: ...  # (string) defaults to $_SERVER['HTTP_HOST']
	persistent: ...  # (bool) defaults to false

	# context for connecting to the SMTP server, defaults to stream_context_get_default()
	context:
		ssl:         # all options at https://www.php.net/manual/en/context.ssl.php
			allow_self_signed: ...
			...
		http:        # all options at https://www.php.net/manual/en/context.http.php
			header: ...
			...
```

Puede desactivar la autenticación de certificados SSL utilizando la opción `context › ssl › verify_peer: false`. Se **recomienda encarecidamente** no hacer esto ya que hará que la aplicación sea vulnerable. En su lugar, "añadir certificados al almacén de confianza":https://www.php.net/manual/en/openssl.configuration.php.

Para aumentar la confianza, podemos firmar los correos electrónicos utilizando [la tecnología DKIM |https://blog.nette.org/es/firmar-correos-electronicos-con-dkim]:

```neon
mail:
	dkim:
		domain: myweb.com
		selector: lovenette
		privateKey: %appDir%/cert/dkim.priv
		passPhrase: ...
```


Servicios DI .[#toc-di-services]
================================

Estos servicios se añaden al contenedor DI:

| Nombre | Tipo | Descripción
|-----------------------------------------------------
| `mail.mailer` | [api:Nette\Mail\Mailer] | [Clase de envío de correo |#Sending Emails]electrónico
| `mail.signer` | [api:Nette\Mail\Signer] | [Firma DKIM |#DKIM]


{{leftbar: nette:@menu-topics}}

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. Se lo mostraremos:

  • cómo crear un correo electrónico, incluyendo archivos adjuntos
  • cómo enviarlo
  • cómo combinar correos electrónicos y plantillas

Instalación

Descargue e instale el paquete utilizando Composer:

composer require nette/mail

Creación de correos electrónicos

El correo electrónico es un objeto Nette\Mail\Message:

$mail = new Nette\Mail\Message;
$mail->setFrom('John <john@example.com>')
	->addTo('peter@example.com')
	->addTo('jack@example.com')
	->setSubject('Order Confirmation')
	->setBody("Hello, Your order has been accepted.");

Todos los parámetros deben estar codificados en UTF-8.

Además de especificar destinatarios con el método addTo(), también puede especificar el destinatario de la copia con addCc(), o el destinatario de la copia oculta con addBcc(). Todos estos métodos, incluido setFrom(), aceptan destinatarios de tres formas:

$mail->setFrom('john.doe@example.com');
$mail->setFrom('john.doe@example.com', 'John Doe');
$mail->setFrom('John Doe <john.doe@example.com>');

El cuerpo de un correo electrónico escrito en HTML se pasa mediante el método setHtmlBody():

$mail->setHtmlBody('<p>Hello,</p><p>Your order has been accepted.</p>');

No tiene que crear un texto alternativo, Nette lo generará automáticamente por usted. Y si el correo electrónico no tiene un asunto definido, se tomará del elemento <title> elemento.

Las imágenes también pueden insertarse muy fácilmente en el cuerpo HTML de un correo electrónico. Basta con pasar 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:

// automatically adds /path/to/images/background.gif to the email
$mail->setHtmlBody(
	'<b>Hello</b> <img src="background.gif">',
	'/path/to/images',
);

El algoritmo de incrustación de imágenes admite los siguientes 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?

Los correos electrónicos son como postales. Nunca envíes contraseñas u otras credenciales por correo electrónico.

Archivos adjuntos

Por supuesto, puedes adjuntar archivos al correo electrónico. Utilice la dirección addAttachment(string $file, ?string $content = null, ?string $contentType = null).

// inserts the file /path/to/example.zip into the email under the name example.zip
$mail->addAttachment('/path/to/example.zip');

// inserts the file /path/to/example.zip into the email under the name info.zip
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));

// attaches new example.txt file contents "Hello John!"
$mail->addAttachment('example.txt', 'Hello John!');

Plantillas

Si envías correos electrónicos HTML, es una gran idea escribirlos en el sistema de plantillas Latte. ¿Cómo hacerlo?

$latte = new Latte\Engine;
$params = [
	'orderId' => 123,
];

$mail = new Nette\Mail\Message;
$mail->setFrom('John <john@example.com>')
	->addTo('jack@example.com')
	->setHtmlBody(
		$latte->renderToString('/path/to/email.latte', $params),
		'/path/to/images',
	);

Archivo email.latte:

<html>
<head>
	<meta charset="utf-8">
	<title>Order Confirmation</title>
	<style>
	body {
		background: url("background.png")
	}
	</style>
</head>
<body>
	<p>Hello,</p>

	<p>Your order number {$orderId} has been accepted.</p>
</body>
</html>

Nette inserta automáticamente todas las imágenes, establece el asunto según el elemento <title> y genera un texto alternativo para el cuerpo HTML.

Uso en la aplicación Nette

Si utiliza correos electrónicos junto con Nette Application, es decir, presentadores, es posible que desee crear enlaces en las plantillas utilizando el atributo n:href o la etiqueta {link}. Latte básicamente no los conoce, pero es muy fácil añadirlos. La creación de enlaces puede hacer objeto Nette\Application\LinkGenerator, que se obtiene al pasarlo usando inyección de dependencia.

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, el enlace se crea como en una plantilla normal. Todos los enlaces creados sobre LinkGenerator son absolutos:

<a n:href="Presenter:action">Link</a>

Envío de correos electrónicos

Mailer es la clase responsable del envío de correos electrónicos. Implementa la interfaz Nette\Mail\Mailer y existen varios mailers listos para usar que presentaremos a continuación.

El framework añade automáticamente un servicio Nette\Mail\Mailer basado en la configuración al contenedor DI, que se obtiene pasándolo mediante inyección de dependencias.

SendmailMailer

El mailer por defecto es SendmailMailer que utiliza la función PHP mail. Ejemplo de uso:

$mailer = new Nette\Mail\SendmailMailer;
$mailer->send($mail);

Si desea configurar returnPath y el servidor sigue sobrescribiéndolo, utilice $mailer->commandArgs = '-fmy@email.com'.

SmtpMailer

Para enviar correo a través del servidor SMTP, utilice 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 usará el valor por defecto 25 o 465 para ssl
  • timeout – tiempo de espera para la conexión SMTP
  • persistent – utilizar conexión persistente
  • clientHost – designación del cliente
  • streamOptions – permite establecer opciones de contexto SSL para la conexión

FallbackMailer

No envía correos electrónicos, sino que los envía a través de un conjunto de mailers. Si un mailer falla, repite el intento en el siguiente. Si falla el último, vuelve a empezar desde el primero.

$mailer = new Nette\Mail\FallbackMailer([
	$smtpMailer,
	$backupSmtpMailer,
	$sendmailMailer,
]);
$mailer->send($mail);

Otros parámetros del constructor incluyen el número de repeticiones y el tiempo de espera en milisegundos.

DKIM

DKIM (DomainKeys Identified Mail) es una tecnología de correo electrónico de confianza 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. Al cotejar la firma, se demuestra que el correo electrónico procede realmente del dominio del remitente y que el mensaje no ha sido modificado durante su transmisión.

Puede configurar el mailer para firmar el correo electrónico en la configuración. Si no utiliza la inyección de dependencia, se utiliza de la siguiente 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 de

Visión general de las opciones de configuración para el Nette Mail. Si no está utilizando todo el framework, sino sólo esta librería, lea cómo cargar la configuración.

Por defecto, el mailer Nette\Mail\SendmailMailer se utiliza para enviar correos electrónicos, que no se configura más. Sin embargo, podemos cambiarlo a Nette\Mail\SmtpMailer:

mail:
	# use SmtpMailer
	smtp: true       # (bool) defaults to false

	host: ...        # (string)
	port: ...        # (int)
	username: ...    # (string)
	password: ...    # (string)
	timeout: ...     # (int)
	encryption: ...  # (ssl|tls|null) defaults to null (has alias 'secure')
	clientHost: ...  # (string) defaults to $_SERVER['HTTP_HOST']
	persistent: ...  # (bool) defaults to false

	# context for connecting to the SMTP server, defaults to stream_context_get_default()
	context:
		ssl:         # all options at https://www.php.net/manual/en/context.ssl.php
			allow_self_signed: ...
			...
		http:        # all options at https://www.php.net/manual/en/context.http.php
			header: ...
			...

Puede desactivar la autenticación de certificados SSL utilizando la opción context › ssl › verify_peer: false. Se recomienda encarecidamente no hacer esto ya que hará que la aplicación sea vulnerable. En su lugar, añadir certificados al almacén de confianza.

Para aumentar la confianza, 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 añaden al contenedor DI:

Nombre Tipo Descripción
mail.mailer Nette\Mail\Mailer Clase de envío de correoelectrónico
mail.signer Nette\Mail\Signer Firma DKIM