How to send an email with symfony 1.3/1.4 and Gmail

One nice feature coming with symfony 1.3 & 1.4  is an embedded mail system based on Swift Mailer 4.1

Providing a mail system into symfony’s core has been a wide debate since symfony 1.0. The 1st stable version of the framework was coming with an unperfect but operational way of sending emails based on phpMailer. Thus, following the decoupling philosophy, this feature was removed on symfony 1.1 and 1.2. The old 1.0 email system is actually still supported through sfCompat10Plugin but it’s now a deprecated module and has completely disappear on symfony 1.4.

With the recent handover of Swift Mailer by Fabien Potencier, a natural synergy between symfony and Swift Mailer has been initiated. Swift Mailer still could be used on any PHP projects  but will also come as the default mailing system of symfony 1.3 & 1.4.

Let’s play with it a little, using a Gmail account…

Disclaimer : I assume you already know some basics of symfony. I must recommend you to learn Jobeet tutorial if you get lost starting this quick how-to.

Part 1: The configuration side

The mailer configuration is application-based (frontend, backend etc.) and can be set differently for each environment (prod, dev, test etc.) of your project.

All the configuration has to be done on the factories.yml file. There, you can set two aspects of the mailer : the delivery strategy and the transport of the messages.

The delivery strategy

The delivery strategy is defined by the delivery_strategy option. This one allows the following values :

  • realtime: sending the message directly
  • spool: using a queue
  • single_address: sending emails to a specific address (on a dev environment)
  • none: no email is sent (useful on a test environment)

Don’t forget to fill a delivery_address option if you plan to use single_address mode.

The transport

Swift Mailer supports 3 transports (or way of sending messages) modes :

  • SMTP: allows authentification and encryption (uses Swift_SmtpTransport class)
  • Sendmail: using a local MTA such as Sendmail
  • Mail: similar as PHP native mail() function

Example


#/myproject/apps/frontend/config/factories.yml
prod:
  mailer:
    param:
      delivery_strategy: realtime

test:
  mailer:
    param:
      delivery_strategy:  none 

dev:
  mailer:
    param:
      delivery_strategy:  single_address
      delivery_address:  your_email    

all:
  mailer:
    param:
      transport:
        class: Swift_SmtpTransport
        param:
          host:       smtp.gmail.com
          port:       465
          encryption: ssl
          username: your_gmail_account
          password: your_gmail_password

This example is quite explicit. A common smtp transport has been set for each environment (under the « all » section). Note that Gmail SMTP servers need to be called through port 465 using ssl encryption.

Thanks to configuration cascade mechanism, each environment can use this transport differently :

  • on test environment, no messages are sent but emails are logged and sfTesterMailer can be used on functional tests.
  • dev environment sends emails to a unique address (e.g. the developer’s one)
  • prod environment is set to work on real conditions : messages are consciously sent to their recipients

With anything correctly set, let’s now compose and send messages.

Part 2: The message side

Unlike the symfony 1.0 mail mechanism, composing and sending a message methods are supported by the context not by the controller. However, accessing to the mailer on an action is possible through the proxy method sfAction::getMailer(). So, on an action, symfony mailer can be accessed this way:

$this->getMailer()

elsewhere the mailer can be retrieved that way:

sfContext::getInstance()->getMailer();

Just compose and send
sfMailer comes with a very quick and simple method to send emails.

$this->getMailer()->composeAndSend('from@example.com', 'to@example.com', 'Subject', 'Body');

Complex messages

If you need to create more complex messages, sfMailer class gives access to all SwiftMailer great functionalities such as multipart emails, attachments, multi-recipients etc.
Consider the following example with a multipart message.


#/myproject/apps/frontend/modules/mymodule/actions.class.php

public function executeSend($request)
{
...
    $message = $this->getMailer()->compose();
    $message->setSubject($params['subject']);
    $message->setTo($params['to']));
    $message->setFrom($params['from']);

    $html = $this->getPartial('mymodule/myTemplateHtml',$params);
    $message->setBody($html, 'text/html');
    $text = $this->getPartial('mymodule/myTemplateTxt',$params);
    $message->addPart($text, 'text/plain');    

    $this->getMailer()->send($message);
...
}

Please note that the previous example is not complete, assuming that $params is an array of data which can come from the database or a form. One good practice would be refactoring this mailer piece of code on a protected method outside the action method or more likely on a reusable custom library.

That’s all for today. Don’t hesitate taking a look to sfMailer class and Swift Mailer documentation to know more about all the new mail capabilities available on symfony.

Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Twitter

13 Responses to “How to send an email with symfony 1.3/1.4 and Gmail”

  1. Bonjour,

    Bon article merci.

    Quelques remarques: une petite erreur ici: $message->addPart(text, ‘text/plain’);

    il faut remplacer text par $text.

    Ensuite, lorsque je fais un addPart, mon partial HTML est remplacé par le texte dans mon mail alors que je peux lire les mails en HTML.
    Je me demande si le addPart fait le même choix que le faisait le « attach » utilisé dans symfony 1.2.

    En tous cas merci ça m’a bien aidé ;)

  2. merci pour ton commentaire, j’ai corrigé la typo de $message->addPart($text, ‘text/plain’).

    Je n’ai pas rencontré le problème que tu mentionnes avec la version html du mail. Peut-être s’agit-il plutôt d’un problème lié à ton client. Concernant le multipart, tu peux jeter un coup d’oeil à la doc SwiftMailer sur le sujet.

  3. Savez-vous si les mails envoyés avec une methode spool/Doctrine sont conservé après l’envoi.
    Est-il simple de surcharger la classe doctrine pour avoir d’autre membres relatifs à l’email qui va être envoyé ?

    Merci

  4. A vrai dire je n’ai pas encore utilisé la gestion de la file de mails par Doctrine via la classe Swift_DoctrineSpool.
    Théoriquement, ce mode enregistre la file d’attente (et le contenu des mails) dans une base de données.
    Si les messages ne sont pas conservés après envoi, j’imagine qu’il est possible de passer par la configuration ou la surcharge de la classe Swift_DoctrineSpool pour éviter leur suppression.
    Je ne comprends pas très bien votre deuxième question.

  5. symfony 1.3/1.4 and Gmail for thanx.

  6. this is perfect! thanks for share.

  7. merci!

  8. Hey mate, thanks for this post!

  9. Merci ce post est très utile

  10. francois Greze Says:
    octobre 12th, 2010 at 14:03

    Bonjour,
    petit merci au passage sur ton blog :)
    FG

  11. I just found your blog via Yahoo answers, a really good read, thanks.

  12. Your blog is great! This blog really caught my eye when I was searching around. Thanks for sharing it.

  13. [...] This is how to use “Swift Mailer” (http://swiftmailer.org) . Update : This is a very good article: http://www.metulo.net/how-to-send-an-email-with-symfony-and-gmail [...]

Leave a Reply

metulo.net also edits Rural house for sale on Spain  metulo.net tambien hace Casa rural en venta  metulo.net edite aussi Gîte rural en vente en Espagne