My name is  
Jurgens du Toit.
Systems Developer.
Problem Solver.

About Me

Technology and Solving Problems are my passion. I'm a South African that loves my wife, life, and coding.

I'm writing a book!

The Logstash Config Guide

Buy it now on Leanpub

20 December 2012

Setting up the Swiftmailer Spooler

By Jurgens du Toit

The Swiftmailer library comes with a nifty feature where mails can be spooled to disk and sent later asynchronously instead of mailing them immediately. This results in quicker response times from your scripts, and by extension happier users. This post will explain how to set it up outside of the Symfony 2 framework.

Spooling the Mail

Swiftmailer defines a number of Transports with which mails can be sent. A common one is the Swift_SmtpTransport. To spool mails, we’ll use the Swift_SpoolTransport for the initial sending, and then still use Swift_SmtpTransport for the background sending. The following comes (with some changes) from a post in the Swiftmailer Google Group:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
// Setup the spooler, passing it the name of the folder to spool to
$spool = new Swift_FileSpool(__DIR__ . "/spool");
// Setup the transport and mailer
$transport = Swift_SpoolTransport::newInstance($spool);
$mailer = Swift_Mailer::newInstance($transport);

// Create a message
$message = Swift_Message::newInstance('Excellent Subject')
    ->setFrom(array('sende...@domain.com' => 'John Doe'))
    ->setTo(array([email protected]'))
    ->setBody('spool messages !!!');

 // Send the message
$result = $mailer->send($message);

echo "SPOOLED $result emails";

This will spool the email to specified folder instead of sending it. At this stage, the actual sending of the mail hasn’t happened yet. You will need to flush the spooled messages using a cron or background script that calls the flashQueue method to do that.

Sending the Mail

The background script will use the Swift_SmtpTransport to send the spooled mails:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
//create an instance of the spool object pointing to the right position in the filesystem
$spool = new Swift_FileSpool(__DIR__."/spool");

//create a new instance of Swift_SpoolTransport that accept an argument as Swift_FileSpool
$transport = Swift_SpoolTransport::newInstance($spool);

//now create an instance of the transport you usually use with swiftmailer
//to send real-time email
$realTransport = Swift_SmtpTransport::newInstance(
    "smtp.gmail.com",
    "465",
    "ssl"
)
    ->setUsername("username")
    ->setPassword("password");

$spool = $transport->getSpool();
$spool->setMessageLimit(10);
$spool->setTimeLimit(100);
$sent = $spool->flushQueue($realTransport);

echo "SENT $result emails";

And that’s it. All that’s left now is to call the background script periodically using something like cron.

blog comments powered by Disqus