How to add CAPTCHA to all Drupal Webforms
If you are building a website that has a lot of webforms, I'm sure you also want those webforms protected from spam. You can add the reCAPTCHA module to your site and then add each webform to the CAPTCHA settings, but that's kind of a pain if you have lots of webforms. Also, you don't want to bother authenticated users with CAPTCHA challenges, since you know they aren't spammers, so you'll want to add a permission that allows them to skip CAPTCHA. Luckily this is easy to do with a small amount of custom code.
This example is using the reCAPTCHA module which leverages Google's reCAPTCHA service, but should be easy to modify if you prefer to use a different spam protection module.
This assumes the following setup:
- You have downloaded and enabled reCAPTCHA and CAPTCHA
- You have configured CAPTCHA at admin/config/people/captcha to use reCAPTCHA as the default challenge type
- You have configured reCAPTCHA at admin/config/people/captcha/recaptcha with your API keys
- You have added the desired users to the Skip CAPTCHA permission at admin/people/permissions
If you wanted to protect one or two webforms, you could just add their machine names to the form protection list for CAPTCHA at admin/config/people/captcha. However, if you have lots of webforms, and new ones are being added by non-technical users, chances are they won't remember to add their new form or understand when you say something like 'machine name'.
This will require a small custom module. We'll call ours demo_webform, but you'll want to give it something more descriptive. Create your demo_webform.info and then your demo_webform.module file. This is the code in your .module file that will add the reCAPTCHA to all webforms, except for users who can skip the CAPTCHA challenge.
<?php /** * Implements hook_form_alter(). * * Add reCAPTCHA to all webforms so don't have to add each one by id. */ function demo_webform_form_alter(&$form, &$form_state, $form_id ){ // Check to see if it is any webform, regardless of ID // Also check to see if user has 'skip CAPTCHA' permissions if ((strstr($form_id, 'webform_client_form')) && !(user_access('skip CAPTCHA'))) { $form['my_captcha_element'] = array( '#type' => 'captcha', // default captcha type set at '#captcha_type' => 'default', ); } }
Let's break this down:
-
function demo_webform_form_alter(&$form, &$form_state, $form_id )
We're going to do a hook_form_alter, so we name it 'demo_webform' (our module name) + _form_alter -
if ((strstr($form_id, 'webform_client_form'))
Since we want to alter all webforms, we check the webform_id to see if it contains the string webform_client_form using the PHP strstr() function. To get the $form_id, we can add dpm($form_id); to our custom module, using the Devel module and dpm(). -
&& !(user_access('skip CAPTCHA'))
We also want to check if the user can skip CAPTCHA. If they can't (hence the '!') we will then apply the CAPTCHA challenge. We do this using the Drupal user_access function. -
$form['my_captcha_element'] = array( '#type' => 'captcha', // default captcha type set at '#captcha_type' => 'default', );
Add the CAPTCHA protection.
And that's it - pretty simple.