Sending emails is a very common task in web applications. Signup forms, contact forms, newsletters are among the most used features, but the email send task itself can be a little slow to the eyes of the user. Symfony2 provides us with the tools to send the emails to a buffer, and sending them when the time is proper eliminating the perception of having a lag time. Symfony integrates SwiftMailer through the SwiftMailerBundle.

When you send an email, the mailer communicates with a remote server in charge of receiving the message and of delivering it to the recipient. This process can cause your form to submit slowly as it depends on how fast the mail server responds.

Spooling allows us to decouple the application execution line from the process of the sending one, two, or as many emails as we need. By sending emails this way our application won’t get stuck with background tasks thus improving the user experience of your users.

A simple example of how important setting up Swiftmailer correctly is would be on a Signup form where a confirmation email is sent after the user submits their information. Now suppose there is a communication error between the mailer and the remote server, producing an exception from the mailer. This would be a really bad first impression for this user. Spooling prevents this sort of error.

Configuration

All we need to do is configure the SwiftMailerBundle by adding a few lines to the config.yml file.

# app/config/config.yml
swiftmailer:
    spool:
        type: file
        path: %kernel.root_dir%/spool

Every email sent by your application will now be stored in the spool located in /path/to/project/app/spool.

Sending the messages

Now that we have the emails in the spool, we are ready to sent them. In order to do so, you need to run the following command:

$ php app/console swiftmailer:spool:send

Emails are environment dependent, so we need to specify the environment on the command by adding the option --env=prod, since Symfony2 runs its commands in the dev environment by default.

Cronjob

A good way to process all the messages in buffer, is to set a cronjob running every minute or every two minutes. Sent messages are removed from the buffer, so you don’t have to worry about sending a message twice.

VPS

If you are a VPS user, you have to add the following lines to the crontab:

# /etc/crontab
...
*/2 * * * * root php /path/to/project/app/console --env=prod swiftmailer:spool:send

This way the email buffer will be processed every two minutes.

Shared Hosting

For Shared Hosting users is a little different, but still easy. You have to follow these steps to process the buffer every two minutes:

  1. Head to the Scheduled Tasks sections
  2. Select your user
  3. Click on Schedule New Task
  4. Configure your task as you can see in the screenshot
  5. Click Ok to finalize

Now, our mailer sends the emails in a background process, completely transparent for the user.

You can find more information about this in the Symfony Cookbook