Integrate any captcha plugin into any custom Joomla! form

First published January 24, 2015
7196 hits -

I came upon a problem on a component that offered captcha integration. I could load the standard reCaptcha plugin packaged with the Joomla! framework but none of the custom captcha plugins I wanted to feed it to.

Looking around on the internet, I reviewed a few articles on how to integrate the captcha plugins into a custom form. The solutions I have found were similar to the code this custom component had implemented.

I could not figure out why those solutions could ONLY work with the standard reCaptcha plugin. Until I dug into the code...

Here is the solution that is usually presented for Joomla 2.5:

$dispatcher = JDispatcher::getInstance();
$dispatcher->trigger('onInit', 'dynamic_recaptcha_1');
<div id="dynamic_recaptcha_1"></div>

Add this code to any form and you get reCaptcha fully integrated (provided that the reCaptcha plugin is the ONLY/LAST one enabled AND the public and private keys are filled at the plugin level).

In order to allow any other captcha plugin to work with that solution, a few modifications are necessary.

$reCaptchaName = 'name'; // the name of the captcha plugin - retrieved from the custom component's parameters
JPluginHelper::importPlugin('captcha', $reCaptchaName); // will load the plugin selected, not all of them - we need to know what plugin's events we need to trigger
// $dispatcher = JDispatcher::getInstance(); // Joomla 2.5
$dispatcher = JEventDispatcher::getInstance(); // Joomla 3
$dispatcher->trigger('onInit', 'dynamic_recaptcha_1');
$output = $dispatcher->trigger('onDisplay', array($reCaptchaName, 'dynamic_recaptcha_1', 'class="some_class"'));
echo $output[0];

The first solution 'magically' worked with reCaptcha because the reCaptcha plugin's onDisplay event just outputs code similar to <div id="dynamic_recaptcha_1"></div>. Therefore, triggering onDisplay could be omitted as long as that 'div' was added manually.

But any captcha plugin with more extensive code in the onDisplay event would never show anything...