Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Mail

Enviando
Emails

Enviando e-mails

Você vai enviar e-mails, como newsletters ou confirmações de pedidos? O Nette Framework fornece as ferramentas necessárias com uma API muito agradável. Vamos mostrar:

  • como criar um e-mail, incluindo anexos
  • como enviá-lo
  • como conectar e-mails e templates

Instalação

Baixe e instale a biblioteca usando o Composer:

composer require nette/mail

Criando um e-mail

Um e-mail é um objeto da classe Nette\Mail\Message. Vamos criá-lo assim:

$mail = new Nette\Mail\Message;
$mail->setFrom('Franta <franta@example.com>')
	->addTo('petr@example.com')
	->addTo('jirka@example.com')
	->setSubject('Confirmação do pedido')
	->setBody("Olá,\nseu pedido foi recebido.");

Todos os parâmetros inseridos devem estar em UTF-8.

Além de especificar o destinatário com o método addTo(), também é possível especificar o destinatário da cópia addCc(), ou o destinatário da cópia oculta addBcc(). Em todos esses métodos, incluindo setFrom(), podemos escrever o destinatário de três maneiras:

$mail->setFrom('franta@example.com');
$mail->setFrom('franta@example.com', 'Franta');
$mail->setFrom('Franta <franta@example.com>');

O corpo do e-mail escrito em HTML é passado pelo método setHtmlBody():

$mail->setHtmlBody('<p>Olá,</p><p>seu pedido foi recebido.</p>');

Você não precisa criar a alternativa de texto, o Nette a gerará automaticamente para você. E se o e-mail não tiver um assunto definido, ele tentará pegá-lo do elemento <title>.

Também é extraordinariamente fácil inserir imagens no corpo HTML. Basta passar o caminho onde as imagens estão fisicamente localizadas como segundo parâmetro, e o Nette as incluirá automaticamente no e-mail:

// adiciona automaticamente /path/to/images/background.gif ao e-mail
$mail->setHtmlBody(
	'<b>Olá</b> <img src="background.gif">',
	'/path/to/images',
);

O algoritmo que insere imagens procura por estes padrões: <img src=...>, <body background=...>, url(...) dentro do atributo HTML style e a sintaxe especial [[...]].

Enviar e-mails pode ser ainda mais fácil?

Um e-mail é como um cartão postal. Nunca envie senhas ou outras credenciais por e-mail.

Anexos

Claro, anexos podem ser inseridos no e-mail. O método addAttachment(string $file, ?string $content = null, ?string $contentType = null) é usado para isso.

// insere o arquivo /path/to/example.zip no e-mail com o nome example.zip
$mail->addAttachment('/path/to/example.zip');

// insere o arquivo /path/to/example.zip no e-mail chamado info.zip
$mail->addAttachment('info.zip', file_get_contents('/path/to/example.zip'));

// insere o arquivo example.txt no e-mail com o conteúdo "Olá John!"
$mail->addAttachment('example.txt', 'Olá John!');

Templates

Se você envia e-mails HTML, é natural escrevê-los no sistema de templates Latte. Como fazer isso?

$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',
	);

Arquivo email.latte:

<html>
<head>
	<meta charset="utf-8">
	<title>Confirmação do pedido</title>
	<style>
	body {
		background: url("background.png")
	}
	</style>
</head>
<body>
	<p>Olá,</p>

	<p>Seu pedido número {$orderId} foi recebido.</p>
</body>
</html>

O Nette insere automaticamente todas as imagens, define o assunto de acordo com o elemento <title> e gera uma alternativa de texto para o HTML.

Uso no Nette Application

Se você usa e-mails em conjunto com o Nette Application, ou seja, com presenters, pode querer criar links nos templates usando o atributo n:href ou a tag {link}. O Latte não os conhece por padrão, mas é muito fácil adicioná-los. O objeto Nette\Application\LinkGenerator pode criar links, e você pode acessá-lo pedindo para ser passado via injeção de dependência:

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

No template, criamos links da maneira que estamos acostumados. Todos os links criados através do LinkGenerator serão absolutos.

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

Enviando e-mail

Mailer é uma classe que garante o envio de e-mails. Implementa a interface Nette\Mail\Mailer e existem vários mailers pré-preparados disponíveis, que apresentaremos.

O framework adiciona automaticamente um serviço do tipo Nette\Mail\Mailer ao contêiner DI, construído com base na configuração, e que você pode acessar pedindo para ser passado via injeção de dependência.

SendmailMailer

O mailer padrão é o SendmailMailer, que usa a função PHP mail. Exemplo de uso:

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

Se você quiser definir o returnPath e o servidor ainda o sobrescrever, use $mailer->commandArgs = '-fMeu@email.cz'.

SmtpMailer

Para enviar e-mails através de um servidor SMTP, use SmtpMailer.

$mailer = new Nette\Mail\SmtpMailer(
	host: 'smtp.gmail.com',
	username: 'franta@gmail.com',
	password: '*****',
	encryption: 'ssl',
);
$mailer->send($mail);

Os seguintes parâmetros adicionais podem ser passados para o construtor:

  • port – se não definido, o padrão 25 ou 465 para ssl será usado
  • timeout – timeout para a conexão SMTP
  • persistent – usar conexão persistente
  • clientHost – definir o cabeçalho Host do cliente
  • streamOptions – permite definir SSL context options para a conexão

FallbackMailer

Não envia e-mails diretamente, mas medeia o envio através de um conjunto de mailers. Se um mailer falhar, ele repete a tentativa com o próximo. Se o último também falhar, ele começa novamente do primeiro.

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

Como parâmetros adicionais no construtor, podemos especificar o número de repetições e o tempo de espera em milissegundos.

DKIM

DKIM (DomainKeys Identified Mail) é uma tecnologia para aumentar a confiabilidade dos e-mails, que também ajuda a detectar mensagens falsificadas. A mensagem enviada é assinada com a chave privada do domínio do remetente e esta assinatura é armazenada no cabeçalho do e-mail. O servidor do destinatário compara esta assinatura com a chave pública armazenada nos registros DNS do domínio. Se a assinatura corresponder, prova-se que o e-mail realmente veio do domínio do remetente e que não foi modificado durante a transmissão da mensagem.

Você pode configurar a assinatura de e-mail para o mailer diretamente na configuração. Se você não estiver usando injeção de dependência, ele é usado desta forma:

$signer = new Nette\Mail\DkimSigner(
	domain: 'nette.org',
	selector: 'dkim',
	privateKey: file_get_contents('../dkim/dkim.key'),
	passPhrase: '****',
);

$mailer = new Nette\Mail\SendmailMailer; // ou SmtpMailer
$mailer->setSigner($signer);
$mailer->send($mail);

Configuração

Visão geral das opções de configuração para Nette Mail. Se você não estiver usando todo o framework, mas apenas esta biblioteca, leia como carregar a configuração.

Para enviar e-mails, o mailer Nette\Mail\SendmailMailer é usado por padrão, que não é configurado posteriormente. No entanto, podemos mudá-lo para Nette\Mail\SmtpMailer:

mail:
	# usa SmtpMailer
	smtp: true       # (bool) o padrão é false

	host: ...        # (string)
	port: ...        # (int)
	username: ...    # (string)
	password: ...    # (string)
	timeout: ...     # (int)
	encryption: ...  # (ssl|tls|null) o padrão é null (tem alias 'secure')
	clientHost: ...  # (string) o padrão é $_SERVER['HTTP_HOST']
	persistent: ...  # (bool) o padrão é false

	# contexto para conexão com o servidor SMTP, o padrão é stream_context_get_default()
	context:
		ssl:         # visão geral das opções em https://www.php.net/manual/en/context.ssl.php
			allow_self_signed: ...
			...
		http:        # visão geral das opções em https://www.php.net/manual/en/context.http.php
			header: ...
			...

Usando a opção context › ssl › verify_peer: false, você pode desativar a verificação do certificado SSL. É altamente recomendável não fazer isso, pois a aplicação se tornará vulnerável. Em vez disso, adicione os certificados ao armazenamento.

Para aumentar a confiabilidade, podemos assinar e-mails usando a tecnologia DKIM:

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

Serviços DI

Estes serviços são adicionados ao contêiner DI:

Nome Tipo Descrição
mail.mailer Nette\Mail\Mailer classe que envia e-mails
mail.signer Nette\Mail\Signer Assinatura DKIM
versão: 4.0