Caution: You are browsing the legacy symfony 1.x part of this website.

Como enviar um email

1.2
Symfony version
1.1
Language

Visão Geral

Enviar emails é uma tarefa comum para todos os desenvolvedores web, e o symfony 1.1 torna esta tarefa mais fácil do que nunca usando o Swift Mailer.

O Swift Mailer é uma poderosa biblioteca PHP5 totalmente orientada a objetos, que irá satisfazer 120% das suas necessidades de email.

Ela está disponível em um diretório SVN separado, e por isso o seu projeto não irá ter problemas só porque voce decidiu atualizar a biblioteca. É voce quem decide se quer atualizar para uma versão mais nova.

A forma de enviar emails pelo symfony é muito simples. Voce cria um partial ou um componente que irá manipular o conteúdo do email, e usar o Swift para enviá-lo de uma forma bastante flexível.

Instalando

Se o seu projeto já estiver usando SVN, voce pode instalá-lo usando o comando svn:externals:

$ cd /path/to/symfony/project
$ mkdir -p lib/vendor
$ svn propedit svn:externals .

E depois adicione a seguinte linha:

swift http://swiftmailer.svn.sourceforge.net/svnroot/swiftmailer/tags/php5/3.3.3/lib/

Se o seu projeto não estiver usando SVN, voce ainda pode baixá-lo pelo subversion usando os seguintes comandos:

$ cd /path/to/symfony/project
$ mkdir -p lib/vendor
$ svn checkout http://swiftmailer.svn.sourceforge.net/svnroot/swiftmailer/tags/php5/3.3.3/lib/ swift

Depois disso, limpe o cache para forçar o symfony a enxergar os novos diretórios que foram criados, e pronto!

Configuração

Não há configuração específica de email.

Para manter o seu projeto flexível, voce deve utilizar o arquivo de configuração app.yml para inserir os endereços de email. Desse modo, voce pode ter vários remetentes/destinatários de acordo com o ambiente(environment) que voce estiver trabalhando. E caso alguém precise alterá-los, não será necessário vasculhar todo o código do projeto. O lugar onde fazer a alteração será bastante óbvio.

Gerando o e-mail

A partir do symfony 1.1, voce pode pegar facilmente o conteudo de partials ou componentes a partir de uma ação:

$corpoDoEmail = $this->getPartial('mailBody', array('name' => 'Vitor Mello'));

ou

$corpoDoEmail = $this->getComponent('mail', 'mailBody', array('name' => 'Vitor Mello'));

Enviar um e-mail HTML

Agora, vamos enviar o email acima usando o Swift:

try
{
  // Criar a mensagem e o objeto que irá enviar os emails
  $mailer = new Swift(new Swift_Connection_NativeMail());
  $mensagem = new Swift_Message('Assunto do Email', $corpoDoEmail, 'text/html');
 
  // Enviar
  $mailer->send($mensagem, $destinatario, $remetente);
  $mailer->disconnect();
}
catch (Exception $e)
{
  $mailer->disconnect();
 
  // tratar os erros aqui
}

Enviando um e-mail em várias partes

Alguns clientes de email não gostam muito de HTML, por isso é uma boa idéia enviar seus emails tanto em HTML como em texto puro.

try
{
  // Criar a mensagem e o objeto que irá enviar os emails
  $mailer = new Swift(new Swift_Connection_NativeMail());
  $mensagem = new Swift_Message('Assunto do email de testes');
 
  // Montar as várias partes do email
  $contextoDoEmail = array('name' => 'Vitor Mello');
  $mensagem->attach(new Swift_Message_Part($this->getPartial('mail/mailHtmlBody', $contextoDoEmail), 'text/html'));
  $mensagem->attach(new Swift_Message_Part($this->getPartial('mail/mailTextBody', $contextoDoEmail), 'text/plain'));
 
  // Enviar
  $mailer->send($mensagem, $destinatario, $remetente);
  $mailer->disconnect();
}
catch (Exception $e)
{
  $mailer->disconnect();
 
  // tratar erros aqui
}

Usando diferentes configurações de conexão

Quando voce instancia a classe Swift, voce pode utilizar diferentes objetos do tipo Swift_Connection.

  • Swift_Connection_NativeMail é o driver de conexão que irá utilizar a funcão mail, nativa do PHP.

  • Swift_Connection_SMTP envia os emails através de um servidor SMTP. O construtor pede tres parametros, todos opcionais:

    public function __construct($server="localhost", $port=null, $encryption=null)

    Veremos daqui a pouco como usar este driver para enviar emails através de um servidor SMTP seguro, como o Gmail, por exemplo.

  • Swift_Connection_Sendmail utiliza o binário sendmail para o envio de emails. Voce pode especificar o caminho para ele no próprio construtor.

  • Swift_Connection_Multi é o primeiro driver especial, que pode ser usado para combinar mais de um driver de conexão. Ele irá automaticamente tentar um outro driver de conexão, caso o servidor SMTP esteja fora do ar ao tentar enviar o email, por exemplo. O construtor irá receber um array de instancias do objeto Swift_Connection, que podem, inclusive, conter outras instancias do Swift_Connection_Multi (embora a razão de fazer isto seja um pouco obscura).

  • Swift_Connection_Rotator é o último, que faz um pouco mais do que o Swift_Connection_Multi: ele guarda uma lista dos servidores que estão inacessíveis, e faz uma rotação entre os servidores que estão ativos. O modo de usá-lo vai alem do escopo desse documento, e voce deve procurar maiores informações na própria documentação do Documentação do Swift.

Usando os servidores SMTP do Gmail

Por que alguém iria querer usar uma conta do gmail para enviar emails?

  • Voce não precisará configurar e administrar um servidor SMTP
  • Seus emails não serão vistos como spam pelos usuários do hotmail (ou similares)
  • Voce ganha uma cópia carbono de todos os emails enviados, na pasta Emails Enviados

Quais são as limitações?

  • Voce necessita de uma conta no gmail (é de graça!)
  • As negociações entre SMTP e SSL demoram um pouco mais do que usar apenas SMTP.
  • Voce não pode enviar emails a partir de um email aleatório (mas voce pode adicionar um novo endereço Enviar Email Como nas suas configurações de conta)

Veja como configurar um objeto do Swift:

$connection = new Swift_Connection_SMTP('smtp.gmail.com', 465, Swift_Connection_SMTP::ENC_SSL);
$connection->setUsername('[email protected]');
$connection->setPassword('SuperSecurePassword');
 
$mailer = new Swift($connection);

Embutindo imagens

Para embutir imagens no seu email, voce precisar gerar algumas URLs a partir dos objetos anexados antes de exibir seu conteudo. Veja um exemplo de como fazer isto:

// Criar a mensagem e o objeto que irá enviar os emails
$mailer = new Swift(new Swift_Connection_NativeMail());
$mensagem = new Swift_Message('Assunto do email de Testes');
 
// Inline images
$images = array();
$images['symfony'] = new Swift_Message_Image(new Swift_File(sfConfig::get('sf_web_dir').'/legacy/images/symfony.gif'));
$images['swift']   = new Swift_Message_Image(new Swift_File(sfConfig::get('sf_web_dir').'/legacy/images/swift.jpg'));
 
$imageReferences = array();
foreach ($images as $name => $image)
{
  $imageReferences[$name] = $message->attach($image);
}
 
// Montar as várias partes do email
$mailContext = array('name' => 'Vitor Mello', 'images' => $imageReferences);
$mensagem->attach(new Swift_Message_Part($this->getPartial('mail/mailHtmlBody', $mailContext), 'text/html'));
$mensagem->attach(new Swift_Message_Part($this->getPartial('mail/mailTextBody', $mailContext), 'text/plain'));
 
// Send
$mailer->send($mensagem, $destinatario, $remetente);
$mailer->disconnect();

No seu partial/componente voce pode incluir facilmente as imagens embutidas da seguinte maneira:

<img src="<?php echo $images['symfony']; ?>" alt="Symfony Project" />
<img src="<?php echo $images['swift']; ?>" alt="Swift Mailer" />

Fácil, fácil, não?

Anexos

Felizmente, anexar um arquivo a um email é tão simples quanto gostaríamos que fosse:

$message->attach(new Swift_Message_Attachment(new Swift_File($file), $filename, $mime_type));

Listas de Destinatários

Na maioria da vezes, voce pode querer enviar o mesmo email para mais de uma pessoa, ou mesmo incluir outras pessoas como cópias carbono. Voce pode fazer isso facilmente usando a classe Swift_RecipientList.

$destinatarios = new Swift_RecipientList();
$destinatarios->addTo($to);
$destinatarios->addCc($cc);
$destinatarios->addBcc($bcc);

Se voce estiver enviando emails em um loop, não se esqueça de usar o método ->flush() na sua lista de $destinatarios, ou voce vai ter um trabalhão pra explicar porque alguém recebeu 500 cópias de uma newsletter.

Enviando emails a partir de uma tarefa (task)

O processo é exatamente igual à maneira como voce faria a partir de uma ação, com uma pequena diferença: Voce não pode mais utilizar os métodos da sfAction.

Voce precisará utilizar as funções get_partial() e get_component() contidas no PartialHelper ao invés dos métodos sfAction::getPartial() e sfAction::getComponent.

Documentação adicional

O site do SwiftMailer é uma mina de ouro de documentação e tutoriais.