Using sfFormExtra Captcha on a Symfony based project

Posted on Categories:PHP, MySQL, Symfony

This post describes how to quickly implement a Captcha on a project that already uses sfFormExtra Plugin. Since sfFormExtra Plugin already has Captcha integrated, it is not necessary to install sfReCaptcha Plugin.

If you have installed sfFormExtra Plugin, you already have Captcha input widget at your disposal, and you can use it in your forms.
To integrate Captcha in a form add this to the form class:

# someForm.class.php
...
   $this->setWidget('captcha', new sfWidgetFormReCaptcha('public_key' => sfConfig::get('app_recaptcha_public_key')), array('required'=> false)));
   $this->setValidator('captcha', new sfValidatorReCaptcha(array('private_key' => sfConfig::get('app_recaptcha_private_key'))) );
...

Since Captcha widget does not render the input field like a normal sfWidgetFormInputText, you must catch the field that contains user’s captcha input, and pass it to the form, like this:

# your_action.class.php
...
      $captcha['recaptcha_challenge_field'] = $this->getRequestParameter('recaptcha_challenge_field');
      $captcha['recaptcha_response_field'] = $this->getRequestParameter('recaptcha_response_field');
 
      $data['captcha'] = $captcha;
...

So your action should look like something like this (I’m using my contact form as an example):

# your_action.class.php
...
public function executeContact(sfWebRequest $request)
{
    $this->form = new contactForm();
    $data = $request->getPostParameter('contact', false);
 
    if($data)
    {
      $captcha = array();
      $captcha['recaptcha_challenge_field'] = $this->getRequestParameter('recaptcha_challenge_field');
      $captcha['recaptcha_response_field'] = $this->getRequestParameter('recaptcha_response_field');
 
      $data['captcha'] = $captcha;
 
      //bind
      $this->form->bind($data);
 
      if($this->form->isValid())
      {
 
        try{
        $to = array('email' => $data['email'], 'fullname' => $data['name']);
        $params = array(
          'addr_to'=> $to,
          'text' => $this->getPartial($this->getModuleName() . '/sendNotificationText', array('obj'=>$data)),
          'html' => $this->getPartial($this->getModuleName() . '/sendNotificationHtml', array('obj'=>$data))
          );
        // Send contact email
        $mail = new KliksMailer('contact');
        $mail->quickSendMail($params, true);
 
        return 'ThankYou';
        }
        catch(Exception $e)
        {
          $this->getLogger()->err('Error while sending contact mail to: '.$data['email']);
          $this->getUser()->setFlash('mailer_error', 'Message was not sent. Please try again.');
          return sfView::SUCCESS;
        }
 
 
      }
    }
}