SSL Labs ScoreSecurityHeaders.io ScoreHSTS Preloaded

Joomla Message Queue - Unleashed!

Recently, I was writing a Joomla extension that needed to send an email silently....very silently. Most developers would think - that isn't a problem, Joomla ships with the excellent and very flexible PHPMailer, so everything should be easy. Those developers overlook one flaw in the Joomla PHPMailer implementation - exceptions.

You see, when initiating PHPMailer - a developer has the flexibility to catch exceptions and do with them as he feels necessary. I said, when initiating PHPMailer - but that isn't how it's done in Joomla... oh no. In Joomla, a developer initiates an instance of JMailer by calling JFactory::getMailer(). When using JMailer, a developer has absolutely no control over the exceptions. Those exceptions go straight into the Joomla System Message Queue for display on the next page load. In my extension, this would be unacceptable. Under no circumstances is it allowed for a user to know when or if an email is sent by the system. So knowing that an error could potentially be displayed to a user meant letting the cat out of the bag - they would know that at least an email attempt was made.

Capturing those messages and disposing of them quietly became a quest of mine. A quest that led me down several paths until I was finally confronted with my own reflection... Or rather, the PHP Reflection classes! For those who aren't familiar with Reflection, it's an amazing set of tools that allow you to generally control every aspect of an object and much more. So much more that I've only scratched the surface of what it can do.

You might be wondering what I was attempting to do that required such control over an object. It begins with the Joomla JApplication object which holds system messages prior to them being delivered into the user session variables and finally to the user screen. The messages are stored as an array in the _messageQueue property of the JApplication object. It would have been very nice if that property was pubilc - but it is protected. As a Joomla developer, I'm allowed to read the system messages (JFactory::getApplication()->getMessageQueue();), I'm allowed to add to it (JFactory::getApplication()->enqueueMessage();), but I'm not allowed to take anything away from it. The solution is to make the property accessible using reflection.

Because I knew what the message was, it became very easy to find it. But removing it meant using Reflection to change the property so I could write to it. This is actually very easy using Reflection. This function takes a known error and removes it from the message queue.

<?php
function _killMessage($error) { $app = JFactory::getApplication(); $appReflection = new ReflectionClass(get_class($app)); $_messageQueue = $appReflection->getProperty('_messageQueue'); $_messageQueue->setAccessible(true); $messages = $_messageQueue->getValue($app); foreach($messages as $key=>$message) { if($message['message'] == $error) { unset($messages[$key]); } } $_messageQueue->setValue($app,$messages); }
?>

So, what's happening here is that a reflection object is made of the object which I want to manipulate. I then create a reflected property to mirror the property I want to manipulate. From here, I set the attributes I want to change in my mirrored property, then set the values I want to set, and then send those changes back to the original object. It's pretty sweet.

If you haven't heard of Reflection yet - you should do some exploring and open yourself to a new world of possibilities. Don't be caged by restrictive frameworks - unleash the possibilities.