Sending automated emails with PHP, Swiftmailer and Twig

I’m the one of hosts of a Coding Dojo in my city called Katayunos. Katayunos is the mix of the word Kata (coding kata) and “Desayuno” (breakfast in Spanish). A group of brave programmers meet together one Saturday morning and after having breakfast we pick one coding kata and we practise TDD and pair programming. It’s something difficult to explain to non-geek people (why the hell we wake up early one Saturday morning to do this) but if you are reading this post probably it sounds good:).

My work as host is basically pick the place and encourage people to join to the Coding Dojo. One way of doing this (besides twitter buzz) is take my address book and send one bulk email to all of them inviting to join us. I don’t like this kind of mails. They look like spam, so I prefer to send a personalized email. This email has a common part (the place location, the hour, the event description, …) and the personalized part. I can do it manually, the list isn’t so huge, but definitely that’s not cool. Because of that I have done a little script to perform this operation. I can do a simple PHP script but we are speaking about announcing a event about TDD, SOLID and things like that, so I must use the “right way”. Let’s start.

I manage my list of contacts within a spreadsheet. In this spreadsheet I have the name, the email and a one paragraph with the personalized part to each one of my contact. I can easily export this spreadsheet to a csv document like this:

[sourcecode]
Peter Parker, spiderman@gmail.com, "Lorem ipsum dolor sit amet, …"
Clark Kent, superman@gmail.com, "consectetur adipisicing elit, …"
Juan López Fernández, superlopez@gmail.com, "sed do eiusmod tempor incididunt .."
[/sourcecode]

So first of all I need to parse this file.

[sourcecode language=”php”]
class Parser
{
private $data;

public function createFromCsvFile($path)
{
$handle = fopen($path, "r");
while (($data = fgetcsv($handle)) !== false) {
$this->data[] = [
‘name’ => trim($data[0]),
’email’ => trim($data[1]),
‘body’ => isset($data[2]) ? trim($data[2]) : null,
];
}
}

public function getData()
{
return $this->data;
}
}
[/sourcecode]

Easy. Now I want to send this parsed array by email. Because of that I will include Swiftmailer in my composer.json file.

My email will also be one template and one personalized part. We will use Twig to manage the template.

[sourcecode language=”bash”]
"require": {
"swiftmailer/swiftmailer": "v5.0.2",
"twig/twig": "v1.13.2",
}
[/sourcecode]

Now we will create a class to wrap the needed code to send emails

[sourcecode language=”php”]
class Mailer
{
private $swiftMailer;
private $swiftMessage;

function __construct(Swift_Mailer $swiftMailer, Swift_Message $swiftMessage)
{
$this->swiftMailer = $swiftMailer;
$this->swiftMessage = $swiftMessage;
}

public function sendMessage($to, $body)
{
$this->swiftMessage->setTo($to);
$this->swiftMessage->setBody(strip_tags($body));
$this->swiftMessage->addPart($body, ‘text/html’);

return $this->swiftMailer->send($this->swiftMessage);
}
}
[/sourcecode]

Our Mailer class sends mails. Our Parser class parses one csv file. Now we need something to join those two classes: the Spammer class. Spammer class will take one parsed array and it will send one by one the mails using Mailer class.

[sourcecode language=”php”]
class Spammer
{
private $twig;
private $mailer;

function __construct(Twig_Environment $twig, Mailer $mailer)
{
$this->twig = $twig;
$this->mailer = $mailer;
}

public function sendEmails($data)
{
foreach ($data as $item) {
$to = $item[’email’];
$this->mailer->sendMessage($to, $this->twig->render(‘mail.twig’, $item));
}
}
}
[/sourcecode]

Ok with this three classes I can easily send my emails. This script is a console script and we also want pretty console colours and this kind of stuff. symfony/console to the rescue. But I’ve a problem now. I want to write one message when one mail is sent and another one when something wrong happens. If I want to do that I need to change my Spammer class. But my Spammer class does’t know anything about my console Command. If I inject the console command into my Spammer class I will violate the Demeter law, and that’s a sin. What can we do? Easy: The mediator pattern. We can write one implementation of mediator pattern but we also can use symfony/event-dispatcher, a well done implementation of this pattern. We change our Spammer class to:

[sourcecode language=”php”]
use Symfony\Component\EventDispatcher\EventDispatcher;

class Spammer
{
private $twig;
private $mailer;
private $dispatcher;

function __construct(Twig_Environment $twig, Mailer $mailer, EventDispatcher $dispatcher)
{
$this->twig = $twig;
$this->mailer = $mailer;
$this->dispatcher = $dispatcher;
}

public function sendEmails($data)
{
foreach ($data as $item) {
$to = $item[’email’];
try {
$this->mailer->sendMessage($to, $this->twig->render(‘mail.twig’, $item));
$this->dispatcher->dispatch(MailEvent::EVENT_MAIL_SENT, new MailEvent\Sent($to));
} catch (\Exception $e) {
$this->dispatcher->dispatch(MailEvent::EVENT_SENT_ERROR, new MailEvent\Error($to, $e));
}
}
}
}
[/sourcecode]

Now can easily build of console command class:

[sourcecode language=”php”]
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;

class SpamCommand extends Command
{
private $parser;
private $dispatcher;

protected function configure()
{
$this->setName(‘spam:run’)
->setDescription(‘Send Emails’);
}

protected function execute(InputInterface $input, OutputInterface $output)
{
$output->writeln("Sending mails …");
$this->dispatcher->addListener(MailEvent::EVENT_MAIL_SENT, function (MailEvent\Sent $event) use ($output) {
$output->writeln("<info>Mail sent to</info>: <fg=black;bg=cyan>{$event->getTo()}</fg=black;bg=cyan>");
}
);

$this->dispatcher->addListener(MailEvent::EVENT_SENT_ERROR, function (MailEvent\Error $event) use ($output) {
$output->writeln("<error>Error sending mail to</error>: <fg=black;bg=cyan>{$event->getTo()}</fg=black;bg=cyan> Error: " . $event->getException()->getMessage());
}
);

$this->spammer->sendEmails($this->parser->getData());
$output->writeln("End");
}

public function setSpammer(Spammer $spammer)
{
$this->spammer = $spammer;
}

public function setParser(Parser $parser)
{
$this->parser = $parser;
}

public function setDispatcher(EventDispatcher $dispatcher)
{
$this->dispatcher = $dispatcher;
}
}
[/sourcecode]

With all this parts we can build our script. Our classes are decoupled. That’s good but setting up the dependencies properly can be hard. Because of that we will use symfony/dependency-injection. With symfony DIC we can set up our dependency tree within a yaml file:

Our main services.yml
[sourcecode]
imports:
– resource: conf.yml
– resource: mail.yml
– resource: twig.yml

parameters:
base.path: .

services:
parser:
class: Parser
calls:
– [createFromCsvFile, [%mail.list%]]

mailer:
class: Mailer
arguments: [@swift.mailer, @swift.message]

spam.command:
class: SpamCommand
calls:
– [setParser, [@parser]]
– [setDispatcher, [@dispatcher]]
– [setSpammer, [@spammer]]

spammer:
class: Spammer
arguments: [@twig, @mailer, @dispatcher]

dispatcher:
class: Symfony\Component\EventDispatcher\EventDispatcher
[/sourcecode]

I like to separate the configuration files to reuse those files between projects and to make them more readable.

One for twig:

[sourcecode]
parameters:
twig.path: %base.path%/templates
twig.conf:
auto_reload: true

services:
twigLoader:
class: Twig_Loader_Filesystem
arguments: [%twig.path%]

twig:
class: Twig_Environment
arguments: [@twigLoader, %twig.conf%]
[/sourcecode]

another one for swiftmailer:

[sourcecode language=”xml”]
services:
swift.message:
class: Swift_Message
calls:
– [setSubject, [%mail.subject%]]
– [setFrom, [%mail.from.mail%: %mail.from.name%]]

swift.transport:
class: Swift_SmtpTransport
arguments: [%mail.smtp.host%, %mail.smtp.port%, %mail.smtp.encryption%]
calls:
– [setUsername, [%mail.smtp.username%]]
– [setPassword, [%mail.smtp.password%]]

swift.mailer:
class: Swift_Mailer
arguments: [@swift.transport]
[/sourcecode]

and the last one for the configuration parameters:

[sourcecode]
parameters:
mail.do.not.send.mails: false

mail.list: %base.path%/mailList.csv
mail.subject: mail subject
mail.from.name: My Name
mail.from.mail: my_email@mail.com

mail.smtp.username: my_smtp_username
mail.smtp.password: my_smtp_password
mail.smtp.host: smtp.gmail.com
mail.smtp.port: 465
mail.smtp.encryption: ssl
[/sourcecode]

Now we can build our script.

[sourcecode language=”php”]
use Symfony\Component\Console\Application;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . ‘/conf’));
$loader->load(‘services.yml’);

$container->setParameter(‘base.path’, __DIR__);

$application = new Application();
$application->add($container->get(‘spam.command’));
$application->run();
[/sourcecode]n

And that’s all. My colleagues of the next Katayuno will be invited in a “SOLID” way :).
Source code is available in my github account.

BTW: Do you want to organize one Katayuno in your city? It’s very easy. Feel free to contact me for further information.

Building a BDD framework with PHP

Do you know Jasmine, the BDD framework for JavaScript? This holidays I was looking for something like that in PHP and I didn’t found anything similar (please let me know if I’m wrong) (now I know a few of them thanks to Dave’s comment) . Because of that, and as an exercise, I hack a little bit building something similar for PHP.

I want to write as less code as I can (it’s only a proof of concept), so I will reuse the assertion framework or PHPUnit. As I’ve seen when studying Behat, we can use the assertion part as standalone functions. We only need to include vendor/phpunit/phpunit/PHPUnit/Framework/Assert/Functions.php file

Here you can see one example.
[sourcecode language=”php”]
class StringCalculator
{
public function add($string)
{
return (int)array_sum(explode(",", $string));
}
}

$stringCalculator = new StringCalculator;

describe("add mull returns zero", function () use ($stringCalculator) {
assertEquals(null, $stringCalculator->add(""));
});

describe("1,1 should return 2", function () use ($stringCalculator) {
assertEquals(2, $stringCalculator->add("1,1"));
});
[/sourcecode]

We also can use something similar than DataProvider in PHPUnit:

[sourcecode language=”php”]
describe("add number returns number", function ($expected, $actual, $message) use ($stringCalculator) {
assertEquals($expected, $stringCalculator->add($actual), $message);
}, [
[‘expected’ => 1, ‘actual’ => "1", ‘message’ => ‘add 1’],
[‘expected’ => 2, ‘actual’ => "2", ‘message’ => ‘add 1’],
[‘expected’ => 10, ‘actual’ => "10", ‘message’ => ‘add 10’],
]);
[/sourcecode]

And if we need mocks we can use Mockery, for example:

[sourcecode language=”php”]
class Temperature
{

public function __construct($service)
{
$this->_service = $service;
}

public function average()
{
$total = 0;
for ($i=0;$i<3;$i++) {
$total += $this->_service->readTemp();
}
return $total/3;
}
}

$service = m::mock(‘service’);

describe("testing mocks with mockery", function() use ($service) {
$service->shouldReceive(‘readTemp’)->andReturn(11, 12, 13);
$temperature = new Temperature($service);
assertEquals(12, $temperature->average(), "dummy message");
});
[/sourcecode]

I’ve created an small console application to run the test suites using symfony/console and symfony/finder components. We can run it with:

[sourcecode language=”bash”]
php ./bin/console.php texter:run ./tests
[/sourcecode]

Beware because this library is a proof of concept. There’re a lot of remaining things. What do you think?

Source code at github

The reason why singleton is a “problem” with PHPUnit

Singleton is a common design pattern. It’s easy to understand and we can easily implement it with PHP:

[sourcecode language=”php”]
<?php
class Foo
{
static private $instance = NULL;

static public function getInstance()
{
if (self::$instance == NULL) {
self::$instance = new static();
}
return self::$instance;
}
}
[/sourcecode]

Maybe this pattern is not as useful as it is in J2EE world. With PHP everything dies within each request, so we cannot persist our instances between requests (without any persistent mechanism such as databases, memcached or external servers). But at least in PHP we can share the same instance, with this pattern, in our script. No matter were we are, we use Foo::getInstance() and we get our instance. It useful when we work, for example, with database connections and service containers.

If we work with TDD we most probably use PHPUnit. Imagine a simple script to test the instantiation of our Foo class
[sourcecode language=”php”]
class FooTest extends PHPUnit_Framework_TestCase
{
public function testGetInstance()
{
$this->assertInstanceOf(‘Foo’, Foo::getInstance());
}
}
[/sourcecode]

All is green. It works.

Imagine now we want to “improve” our Foo class and we want to create a counter:

[sourcecode language=”php”]
public function testCounter()
{
$foo = Foo::getInstance();
$this->assertEquals(0, $foo->getCounter());
$foo->incrementCounter();
$this->assertEquals(1, $foo->getCounter());
}
[/sourcecode]

Now our test fails, So we change our implementation of the class to pass the test and we add to Foo class

[sourcecode language=”php”]
private $counter = 0;

public function getCounter()
{
return $this->counter;
}

public function incrementCounter()
{
$this->counter++;
}
[/sourcecode]

It’s green again. We are using a singleton pattern to get the instance of the class and we are using TDD, so what’s the problem? I will show you with an example. Imagine we need to improve our Foo class and we want a getter to say if counter is even or not. We add a new test:

[sourcecode language=”php”]
public function testIsOdd()
{
$foo = Foo::getInstance();
$this->assertEquals(FALSE, $foo->counterIsOdd(), ‘0 is even’);
$foo->incrementCounter();
$this->assertEquals(TRUE, $foo->counterIsOdd(), ‘1 is uneven’);
}
[/sourcecode]

And we implement the code to pass the test again:

[sourcecode language=”php”]
public function counterIsOdd()
{
return $this->counter % 2 == 0 ? FALSE : TRUE;
}
[/sourcecode]

But it doesn’t work. Our test is red now. Why? The answer is simple. We are sharing the same instance of Foo class in both tests, so in the first one our counter start with 0 (the default value) but with the second one it start with 1, because the first test has changed the state of the instance (and we are reusing it).

This is a trivial example, but real world problems with this issue are a bit nightmare. Imagine, for example, that we use singleton pattern to get the database connection (a common usage of this pattern). Suddenly we break one test (because we have created a wrong SQL statement). Imagine we have a test suite with 100 assertions. We have broken one assertion (the second one, for example), and our PHPUnit script will say that we have 99 errors (the second one and all the following ones). That happens because our script can’t reuse the database connection (it’s broken in the second test). Too much garbage in the output of the PHPUnit script and that’s not agile.

How to solve it? We have two possible solutions. The first one is avoid singletons as a plague. We have alternatives such as dependency injection, but if we really want to use them (they are not forbidden, indeed) we need to remember to write one static function in our class to reset all our static states and call after each test. PHPUnit allow to execute something at the end of each test with tearDown() function. So we add to our test:

[sourcecode language=”php”]
class FooTest extends PHPUnit_Framework_TestCase
{

public function tearDown()
{
Foo::tearDown();
}
}
[/sourcecode]

And now we implement the tearDown function in our Foo Class
[sourcecode language=”php”]
public static function tearDown()
{
static::$instance = NULL;
}
[/sourcecode]

And all works again. All is green and green is cool, isn’t it? 🙂

Note: Take into account that “problem” is between quotes in the title. That’s beacause singleton is not a “real” problem. We can use it, it isn’t forbiden, but we need to realize the collateral effects that its usage can throw to our code.

Runtime Classes. A experiment with PHP and Object Oriented Programming

Last week I was thinking about creation of a new type of classes. PHP classes but created dynamically at run time. When this idea was running through my head I read the following article and I wanted to write something similar. Warning: Probably that it is something totally useless, but I wanted to create a working prototype (and it was fun to do it 😉 ). Let’s start:

We are going to crate something like this:

[sourcecode language=”php”]
class Human
{
private $name;
function __construct($name)
{
$this->name = $name;
}

function hello()
{
return "{$this->name} says hello";
}
}

$gonzalo = new Human(‘Gonzalo’);
$peter = new Human(‘Peter’);

echo $gonzalo->hello(); // outputs: Gonzalo says hello
echo $peter->hello(); // outputs: Peter says hello
[/sourcecode]

but without using class statement, adding the constructor and hello method dinamically.

[sourcecode language=”php”]
function testSimpleUsage()
{
$human = HClass::define()
->fct(HClass::__construct, function($self, $name) {$self->name = $name;})
->fct(‘hello’, function($self) {
return "{$self->name} says hello";
});

$gonzalo = $human->create(‘Gonzalo’);
$peter = $human->create(‘Peter’);

$this->assertEquals("Gonzalo says hello", $gonzalo->hello());
$this->assertEquals("Peter says hello", $peter->hello());
}
[/sourcecode]

I also want to test undefinded functions with an exception:

[sourcecode language=”php”]
function testCallingUndefinedFunctions()
{
$human = HClass::define()
->fct(HClass::__construct, function($self, $name) {$self->name = $name;})
->fct(‘hello’, function($self) {
return "{$self->name} says hello";
});

$gonzalo = $human->create(‘Gonzalo’);
$this->setExpectedException(‘Exception’, "ERROR Method ‘goodbye’ does not exits");
$gonzalo->goodbye();
}
[/sourcecode]

And simple inheritance too
[sourcecode language=”php”]
function testInheritance()
{
$human = HClass::define()
->fct(HClass::__construct, function($self, $name) {$self->name = $name;})
->fct(‘hello’, function($self) {
return "{$self->name} says hello";
});

$shyHuman = HClass::define($human)
->fct(‘hello’, function($self) {
return "{$self->name} is shy and don’t says hello";
});

$gonzalo = $human->create(‘Gonzalo’);
$peter = $shyHuman->create(‘Peter’);

$this->assertEquals("Gonzalo says hello", $gonzalo->hello());
$this->assertEquals("Peter is shy and don’t says hello", $peter->hello());
}
[/sourcecode]

Now we are going to create dinamically functions:

[sourcecode language=”php”]
function testDinamicallyFunctionCreation()
{
$human = HClass::define()
->fct(HClass::__construct, function($self, $name) {$self->name = $name;})
->fct(‘hello’, function($self) {
return "{$self->name} says hello";
});

$gonzalo = $human->create(‘Gonzalo’);
$this->assertEquals("Gonzalo says hello", $gonzalo->hello());

try {
$gonzalo->goodbye();
} catch (Exception $e) {
$this->assertEquals("ERROR Method ‘goodbye’ does not exits", $e->getMessage());
}

$human->fct(‘goodbye’, function($self) {
return "{$self->name} says goodbye";
});

$this->assertEquals("Gonzalo says goodbye", $gonzalo->goodbye());
}
[/sourcecode]

And that’s it. It works. probably with PHP5.4 we can drop the “$self” variable. It’s an ugly trick to pass the real instance of the class to the callback, thanks to the “Added closure $this support back” feature added in the new version of PHP. But at least now we need to it.

And now another turn the screw. Let’s try to create the FizzBuzz kata with those “Runtime Classes”. I will create two versions of FizzBuzz. Here you can see my implementation of both versions with “standard” PHP. Whith a simple class, and another one with Two classes and Dependency Injection. Now using the experiment:

[sourcecode language=”php”]
function testFizzBuzz()
{
$fizzBuzz = HClass::define()
->fct(‘run’, function($self, $elems = 100) {
list($fizz, $buzz) = array(‘Fizz’, ‘Buzz’);
return array_map(function ($element) use ($fizz, $buzz) {
$out = array();
if ($element % 3 == 0 || strpos((string) $element, ‘3’) !== false ) {
$out[] = $fizz;
}
if ($element % 5 == 0 || strpos((string) $element, ‘5’) !== false ) {
$out[] = $buzz;
}
return (count($out) > 0) ? implode(”, $out) : $element;
}, range(0, $elems-1));
});
$fizzBuzz = $fizzBuzz->create();
$arr = $fizzBuzz->run();

$this->assertEquals(count($arr), 100);
$this->assertEquals($arr[1], 1);
$this->assertEquals($arr[3], ‘Fizz’);
$this->assertEquals($arr[4], 4);
$this->assertEquals($arr[5], ‘Buzz’);
$this->assertEquals($arr[6], ‘Fizz’);
$this->assertEquals($arr[20], ‘Buzz’);
$this->assertEquals($arr[13], ‘Fizz’);
$this->assertEquals($arr[15], ‘FizzBuzz’);
$this->assertEquals($arr[53], ‘FizzBuzz’);
}
[/sourcecode]

[sourcecode language=”php”]
function testAnotherFizzBuzzImplementationWithDependencyInjection()
{
$fizzBuzz = HClass::define();
$fizzBuzz->fct(HClass::__construct, function($self, $fizzBuzzElement) {
$self->fizzBuzzElement = $fizzBuzzElement;
});
$fizzBuzz->fct(‘run’, function($self, $elems = 100) {
$out = array();
foreach (range(1, $elems) as $elem) {
$out[$elem] = $self->fizzBuzzElement->render($elem);
}
return $out;
});

$fizzBuzzElement = HClass::define()
->fct(‘render’, function($self, $element) {
list($fizz, $buzz) = array(‘Fizz’, ‘Buzz’);
$out = array();
if ($element % 3 == 0 || strpos((string) $element, ‘3’) !== false ) {
$out[] = $fizz;
}

if ($element % 5 == 0 || strpos((string) $element, ‘5’) !== false ) {
$out[] = $buzz;
}
return (count($out) > 0) ? implode(”, $out) : $element;
});

$fbe = $fizzBuzzElement->create();

$this->assertEquals($fbe->render(1), 1);

$this->assertEquals($fbe->render(2), 2);
$this->assertEquals($fbe->render(3), ‘Fizz’);
$this->assertEquals($fbe->render(4), 4);
$this->assertEquals($fbe->render(5), ‘Buzz’);
$this->assertEquals($fbe->render(6), ‘Fizz’);
$this->assertEquals($fbe->render(20), ‘Buzz’);
$this->assertEquals($fbe->render(13), ‘Fizz’);
$this->assertEquals($fbe->render(15), ‘FizzBuzz’);
$this->assertEquals($fbe->render(53), ‘FizzBuzz’);

$fb = $fizzBuzz->create($fbe);
$arr = $fb->run();

$this->assertEquals(count($arr), 100);
$this->assertEquals($arr[1], 1);
$this->assertEquals($arr[3], ‘Fizz’);
$this->assertEquals($arr[4], 4);
$this->assertEquals($arr[5], ‘Buzz’);
$this->assertEquals($arr[6], ‘Fizz’);
$this->assertEquals($arr[20], ‘Buzz’);
$this->assertEquals($arr[13], ‘Fizz’);
$this->assertEquals($arr[15], ‘FizzBuzz’);
$this->assertEquals($arr[53], ‘FizzBuzz’);
}
[/sourcecode]

And that’s all. As I said before probably this “Hybrid Classes” or “Runtime Classes” (I don’t know how to name them) are totally useless, but it’s fun to do it.

[sourcecode language=”bash”]
phpunit HclassTest.php
PHPUnit 3.4.5 by Sebastian Bergmann.

……

Time: 0 seconds, Memory: 5.00Mb

OK (6 tests, 39 assertions)
[/sourcecode]

Full code on github