Using Zend to Add ReCaptcha to Contact Form

Over the past few weeks, spammers have been inundating the QuickBase Contact Us form with automated spam. This has been quite a nuisance for the folks at QuickBase who read and respond to these contact form submissions.

recaptcha

In response to the complaints of spam, it was suggested that we add a captcha to the for – so today, I added the captcha using Zend_Captcha_ReCaptcha, a plugin that is included in the Zend Framework. Here’s how it’s done:

Create a reCAPTCHA account & Generate Keys

Create an account here: http://www.google.com/recaptcha

Once there, generate some keys for your domain(s). I created keys for our production domain and my local testing url.

Add the keys to the app config and registry

In your application.ini file, you’ll want to add the keys for production and your staging environment.

----------------------- ReCaptcha ------------------------
recaptcha.pubkey = "YOUR-KEY-HERE"
recaptcha.privkey = "YOUR-KEY-HERE"

[staging : production]
recaptcha.publickey = "YOUR-KEY-HERE"
recaptcha.privatekey = "YOUR-KEY-HERE"

Add Keys to the registry

In your bootloader.php, typically in the _init method, add the keys to the registry.

protected function _initAutoload() {
  $this->options = $this->getOptions();
  Zend_Registry::set('config.recaptcha', $this->options['recaptcha']);

Add the Zend_Form_Recaptcha Form Element to your form

In your form class, you need to setup a recaptcha service using Zend_Service_ReCaptcha. It is here that you pass in the registry values for your Recaptcha public and private keys. It is also here that you can specify timeout and the theme to use.

class MyApplication_Forms_ContactUs extends Zend_Form {
  public function __construct() {
   // Other Form Stuff Here
   // Captcha $recaptchaKeys = Zend_Registry::get('config.recaptcha');
   $recaptcha = new Zend_Service_ReCaptcha($recaptchaKeys['publickey'], $recaptchaKeys['privatekey'], NULL, array('theme' => 'clean'));

    $captcha = new Zend_Form_Element_Captcha('captcha',
      array('label' => 'Type the characters you see in the picture below.',
            'captcha' => 'ReCaptcha',
            'captchaOptions' => array(
              'captcha' => 'ReCaptcha',
              'service' => $recaptcha)
      )
    );

    $this->addElements(array($captcha, $submit));
    //Other Form Stuff Here - Like a Submit Button, etc)
  }
}

Add the form to your controller & view

$this->view->form = new MyApplication_Forms_ContactUs();

if ($this->getRequest()->isPost() && $this->view->form->isValid($this->_getAllParams())) {
//Yay - The captcha and all other form rules were validated
}
else {
  var_dump($this->_getAllParams());
}

Echo captcha in the view:

$this->form->captcha = $form

That’s really about it. Because you’re creating the captcha as an extension of Zend_Form_Element, it will run through the form validator class that Zend provides. This means that errors returned from the captcha service will be handled and decorated just like any other errors with your form.

Published byJosh McGinnis

Josh is a software engineer, leader, startup advisor for the LA Chamber of Commerce and consultant residing in the Los Angeles area. Josh is passionate about helping entrepreneurs and businesses reach their maximum potential.

11 Comments

  • d

    August 28, 2010 at 9:11 pm Reply

    Can you change the color of the code box? I cannot read black.

    • Joshua McGinnis

      August 29, 2010 at 1:18 pm Reply

      Yes, you can change the color of the theme. Look at lines 10-11 under adding ReCaptcha to a form. You’ll see:

      $recaptcha = new Zend_Service_ReCaptcha($recaptchaKeys[‘publickey’], $recaptchaKeys[‘privatekey’],
      NULL, array(‘theme’ => ‘clean’));

      Here, I’m passing in ‘clean’ as the theme I wish to use. You can also pass in any of the other themes available. For a list of themes, see:
      http://wiki.recaptcha.net/index.php/Theme

  • Makki

    September 3, 2010 at 10:42 am Reply

    Hi Joshua McGinnis,

    I followed all the above steps but when ever i submit the form i got the invalid captcha error. When i looked at the response of recaptcha->verify() it was like that

    Zend_Http_Response Object ( [version:protected] => 1.0 [code:protected] => 404 [message:protected] => Not Found [headers:protected] => Array ( [Connection] => close [Server] => nginx [Date] => Fri, 03 Sep 2010 10:41:04 GMT [Content-type] => text/html [Content-length] => 162 ) [body:protected] =>
    404 Not Found
    nginx
    )

    ==================
    Please help me in that. Thanks

    • Joshua McGinnis

      September 3, 2010 at 2:24 pm Reply

      It sounds like you might not be posting the form to the right location. For example, if you’re action is set to /controller/non-existent-action, you will get a 404 exception. You need to set the form to the controller and action that will be responsible for processing the form’s data.

      • Makki

        September 16, 2010 at 9:43 am Reply

        Thanks for your reply, sorry i was away for quite a long time. i was working on other task. Now let me present you the whole picture. when i open the url (http://mrc.localhost/white-label) i got that enquiry form where the recaptcha feature is implemented. actually i am routing (white-label) to businessPages/whiteLabel, so in that case i set the action for form as “white-label”. so whenever i try to submit i got captcha value is wrong and in error code i got 404 – Not Found — nginx.

        Please help me.

  • London

    September 6, 2010 at 4:20 pm Reply

    Would it be possible to use this class if not the site is not using Zend Framework?

  • Matt

    February 20, 2011 at 1:56 am Reply

    Great post Joshua! Had recaptcha up in minutes. Thanks…

  • Matrix

    June 10, 2011 at 12:52 pm Reply

    Hello, so i have the same thing as you , but in my submit form, i do have the reCaptcha that appears correctly , but just benath it i got a text input field, when i check where it comes from it says id=captcha, so when i add $captcha element , i get the recaptcha and input field. How to avoid this please ?
    (sorry for the bad english).

  • Muhammad

    September 19, 2011 at 2:23 pm Reply

    thanks man this tutorial helps alot….

  • Michal Walkowiak

    November 6, 2012 at 5:19 am Reply

    Very nice one! One thing – it should be: $recaptchaKeys[‘pubkey’], $recaptchaKeys[‘privkey’] in the form to be correct (you just typed wrong key names passed from registry)

Post a Comment