Like every product, Natural Load Testing needs to send some mail, having written and re-written a bunch of different blocks of mail code over the years, I wanted to come up with something that would work now, and continue to serve us well into the future.

Basic Requirements:

  • Send multipart/mime mail, so the emails can look “more official” than plain text for the average customer. Users reading mail in plain text still get something nice.
  • Easy to send a custom email with a block or two of text in that format. This way we can leverage our system to send system notifications and updates, without any additional coding.
  • Easy to customize templates for automated messages like new account sign ups, expiry, and the like.

Last night I went back to use the code for the first time in months, always the true test of code, and it worked well!

How it works

I’m using the Zend_Mail class within my Lithium based application to send the multipart/mime emails. Writing my own mime handler would have been foolish, and it would have been wrong. It’s a great class, and I was happy to leverage it. Integrating it with Lithium ended up being a bit trickier than I was expecting, my class in /libraries starts like this:

namespace app\libraries;use lithium\core\Libraries; use Zend_Mail; use Zend_Mail_Transport_Sendmail; Libraries::add(“Zend”, array( “prefix” => “Zend_”, “path” => “/var/www/phpLibraries/Zend”, “bootstrap” => “Loader/Autoloader.php”, “loader” => array(“Zend_Loader_Autoloader”, “autoload”), “transform” => function($class) { return str_replace(“_”, “/”, $class) . “.php”; } ));

Past that the class itself is also very brief:

class wlmailer{ public $mail, $htmlMail, $plainMail, $options; public function __construct() { require_once(’Zend/Mail.php’); $this->mail = new Zend_Mail(); $tr = new Zend_Mail_Transport_Sendmail(’-fsupport@wondernetwork.com’); Zend_Mail::setDefaultTransport($tr); $this->mail = new Zend_Mail(’utf-8’); } public function basic($options) { $template = “beta.html”; extract($options); $mail = include(’…/app/libraries/mailTemplates/’ . $template); $this->htmlMail = $mail[’html’]; $this->plainMail = $mail[’plain’]; $this->options = $options; } public function send() { $this->mail->setBodyText($this->plainMail, ‘UTF-8’); $this->mail->setBodyHtml($this->htmlMail, ‘UTF-8’); $this->mail->setFrom(’support@wondernetwork.com’, ‘Natural Load Testing’); $this->mail->addTo($this->options[’to’], $this->options[’name’]); $this->mail->addBcc(“paul@wondernetwork.com”, “Paul Reinheimer”); $this->mail->setSubject($this->options[’subject’]); $this->mail->send(); } }

Upon construction the class creates an instance of Zend_Mail, configures it to set the appropriate return path using the -f switch, and selects UTF-8 for the character set for outgoing mail.

I called the next method basic as I’d initially thought I’d end up with several classes, but it ended up being all I needed. It accepts parameters in the $options array, and uses extract() to pull all the key value pairs in the array into the current scope. That done it includes the indicated template (defaulting to ‘beta.html’) which uses various tokens like $name, $email, $password etc to construct the message, and defines two copies of the message, a plain text and an HTML version. Those message versions are saved in public properties, so the calling class could manipulate them as required.

I’m leveraging the HTML Email Boilerplate template in my HTML emails, it’s fantastic. The format of the included template is something like this:

<?php $html = <<<HTML <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”> … <p>Hi {$name}, <br> We think you’re super, just thought we’d give you a heads up.</p> <p>paul & will</p> … HTML; $plain = <<<PLAIN Hi {$name}, We think you’re super, just thought we’d give you a heads up. paul & will PLAIN; return array(’html’ => $html, ‘plain’ => $plain);

Finally, when I want to send a message, it’s all invoked something like this:

$mail = new wlmailer(); $mailOptions = array( “subject” => “Natural Load Testing - Welcome (From: {$session[’display_name’]})”, “to” => $data[’email’], “template” => “coworkeradd.html”, “name” => $data[’display_name’], “username” => $data[’username’], “password” => $data[’password’], “coworker” => $session[’display_name’] ); $mail->basic($mailOptions); $mail->send();

As you can see the usual template of beta.html is overridden here to select the coworkeradd.html template.

Final Thoughts

I’m not going to argue that this is the best way to handle mail, but it is working really well for us. I generally consider being happy with code months after you write it to be a pretty effective test; this passed with flying colours. I still need to add a few more things on the front end, to make it easy to leverage this to mail individual customers, or groups of customers individually, but that’s not far off.


Comments »

No Trackbacks
No comments

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
Standard emoticons like :-) and ;-) are converted to images.
 

Hi, I’m Paul Reinheimer, a developer working on the web.

I wrote a book titled Professional Web APIs with PHP back in 2006, and am currently working in Biomedical Informatics for a major public health company.

I’m working on a project to help developers called WonderProxy which has proxies all over the world. Working on GeoIP development? Now you can finally test properly! We've also released Global Ping Statistics for expected ping times between cities, as well as a Load Testing Tool to measure your site's ability to handle load. Our most recent site checking tool is Where's it Up? which checks your sites availability globally, returning HTTP, DNS, and Traceroute details

My hobbies are cycling, photography, travel, and engaging Allison Moore in intelligent discourse. I frequently write about PHP and other related technologies.

I co-founded:

WonderNetwork Logo

Search