TRAJOIN is an Application to Translate symfony documents Jointly.
home > 1.2/cookbook/en > email.txt
[1] Edit ↑TOPSending mails is a web developer's everyday task, and symfony 1.2 lets you do this easier than ever using Swift Mailer.
Swift Mailer is a well thought out, fully featured PHP5 object library that should cover all of your mailing needs.
: SwiftMailer is now up to version 4.x which is not available via svn. Check http://swiftmailer.org for details, and make the necessary adjustments below (pending documentation update).
It is available in a tagged SVN repository, so your project won't break just because the library is updated. It will be up to you to switch to a newer version.
Symfony's way to send emails from a project is very simple. You create a partial or a component that will render the e-mail content, and use Swift to send it in a flexible way.
If your project is already using svn, you can install it using the svn:externals property:
$ cd /path/to/symfony/project
$ mkdir -p lib/vendor
$ cd lib/vendor
$ svn propedit svn:externals .
Then add the following line:
swift http://swiftmailer.svn.sourceforge.net/svnroot/swiftmailer/tags/php5/3.3.3/lib/
And run:
$ svn update
If your project is not using SVN, you can still get this part as a subversion working copy by checking out the tag.
$ cd /path/to/symfony/project
$ mkdir -p lib/vendor
$ cd lib/vendor
$ svn checkout http://swiftmailer.svn.sourceforge.net/svnroot/swiftmailer/tags/php5/3.3.3/lib/ swift
Just clear your cache to force class autoloading resolution to be flushed, and you're done with the installation.
There is no mailer-specific configuration.
To keep your project flexible, you should use app.yml configuration file to keep hard-written e-mail addresses. This way, you can have different senders/receivers addresses depending on the environment you're on, and when one will need to change it, he won't have to dig all the project code. The place to change it will be just too obvious.
As of symfony 1.1 RC2, you can easily get rendered partials and components from an action:
$mailBody = $this->getPartial('mailBody', array('name' => 'John Doe'));
or
$mailBody = $this->getComponent('mail', 'mailBody', array('name' => 'John Doe'));
Then we send the mail rendered above using Swift:
try
{
// Create the mailer and message objects
$mailer = new Swift(new Swift_Connection_NativeMail());
$message = new Swift_Message('Mail\'s subject', $mailBody, 'text/html');
// Send
$mailer->send($message, $mailTo, $mailFrom);
$mailer->disconnect();
}
catch (Exception $e)
{
$mailer->disconnect();
// handle errors here
}
Some e-mail clients don't like HTML at all, so it's usually a good idea to provide your mail in both html and plain text.
try
{
// Create the mailer and message objects
$mailer = new Swift(new Swift_Connection_NativeMail());
$message = new Swift_Message('Test mail subject');
// Render message parts
$mailContext = array('name' => 'John Doe');
$message->attach(new Swift_Message_Part($this->getPartial('mail/mailHtmlBody', $mailContext), 'text/html'));
$message->attach(new Swift_Message_Part($this->getPartial('mail/mailTextBody', $mailContext), 'text/plain'));
// Send
$mailer->send($message, $mailTo, $mailFrom);
$mailer->disconnect();
}
catch (Exception $e)
{
$mailer->disconnect();
// handle errors there
}
When you create the Swift object, you can use a different Swift_Connection object.
mail() function.
public function __construct($server="localhost", $port=null, $encryption=null)
We'll see in a few how to use this to send a mail via a secure mail server, using gMail secure SMTP in occurence.
Swift_Connection object instances, and can even embed other Swift_Connection_Multi instances (even if the advantage of doing so might be a bit obscure)Swift_Connection_Multi by keeping track of down servers, and managing rotation of "alive" servers. How to use it is beyond the scope of this cookbook recipe, and you should refer to the Swift Mailer documentation.Why would you like to use a gmail account to send your emails?
Sent Mails, allowing easy debugWhat are the limitations?
Here is how to configure the Swift object:
$connection = new Swift_Connection_SMTP('smtp.gmail.com', 465, Swift_Connection_SMTP::ENC_SSL);
$connection->setUsername('romain@gmail.com');
$connection->setPassword('SuperSecurePassword');
$mailer = new Swift($connection);
To embed images in your mail, you need to get mail-dependant URLs from the embedded objects before rendering its content. Here's an example how you can do it.
// Create the mailer and message objects
$mailer = new Swift(new Swift_Connection_NativeMail());
$message = new Swift_Message('Test mail subject');
// Inline images
$images = array();
$images['symfony'] = new Swift_Message_Image(new Swift_File(sfConfig::get('sf_web_dir').'/images/symfony.gif'));
$images['swift'] = new Swift_Message_Image(new Swift_File(sfConfig::get('sf_web_dir').'/images/swift.jpg'));
$imageReferences = array();
foreach ($images as $name => $image)
{
$imageReferences[$name] = $message->attach($image);
}
// Render message parts
$mailContext = array('name' => 'John Doe', 'images' => $imageReferences);
$message->attach(new Swift_Message_Part($this->getPartial('mail/mailHtmlBody', $mailContext), 'text/html'));
$message->attach(new Swift_Message_Part($this->getPartial('mail/mailTextBody', $mailContext), 'text/plain'));
// Send
$mailer->send($message, $mailTo, $mailFrom);
$mailer->disconnect();
Now in your component/partial template you can easily display those attached pictures like this:
<img src="<?php echo $images['symfony']; ?>" alt="Symfony Project" />
<img src="<?php echo $images['swift']; ?>" alt="Swift Mailer" />
Wasn't that easy?
Attaching a document to a mail is as simple as you would expect it to be:
$message->attach(new Swift_Message_Attachment(new Swift_File($file), $filename, $mime_type));
You'll often want to have more than one recipient or carbon copies for a mail. This is done using the Swift_RecipientList class.
$recipients = new Swift_RecipientList();
$recipients->addTo($to);
$recipients->addCc($cc);
$recipients->addBcc($bcc);
If you're sending e-mails in a loop, don't forget to ->flush() your $recipients list, or you'll have a bad time explaining why someone received 500 copies of the same mailing list.
The process is exactly the same as doing it from an action, with one little
difference: You cannot use sfAction methods anymore.
You'll need to use get_partial() and get_component() functions in
PartialHelper instead of sfAction::getPartial() and
sfAction::getComponent() methods.
To load a helper from anywere in your application, you can use the following:sfProjectConfiguration::getActive()->loadHelpers(\"Partial\", \"Url\", \"MyHelper\");
The SwiftMailer website is a gold mine of documentation and tutorials.
Documentation