Nette Mail
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 parasslserá usadotimeout– timeout para a conexão SMTPpersistent– usar conexão persistenteclientHost– definir o cabeçalho Host do clientestreamOptions– 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 |