Symfony 2 Basic BotDetect CAPTCHA Example

Symfony Basic BotDetect CAPTCHA Example illustrates the most basic form of BotDetect PHP Captcha protection in Symfony MVC applications.

First Time Here?

Check the BotDetect Symfony2 Captcha Quickstart for key integration steps.

Alongside the Captcha image, the user is provided with an input field to retype the displayed characters, and a message stating the Captcha code validation result which is displayed after form submission.

The simple code showing Captcha validation result message should be replaced with more useful form processing code in a real world scenario.

Files for this ('bd-captcha-symfony2-examples') example are:

The files are available for download as a part of the BotDetect Captcha Symfony integration package.

Symfony2 Basic BotDetect Captcha validation screenshot

Config - /app/config/captcha.php

<?php if (!class_exists('CaptchaConfiguration')) { return; }

// BotDetect PHP Captcha configuration options

return [
  // Captcha configuration for example page
  'ExampleCaptcha' => [
    'UserInputID' => 'captchaCode',
    'ImageWidth' => 250,
    'ImageHeight' => 50,
  ],

];

In order to use the CaptchaBundle, we have defined Captcha configuration which will be used as a captcha field type in ExampleType form. Detailed description of this approach is available in a BotDetect Symfony2 integration guide.

Form Type - /src/AppBundle/Form/Type/ExampleType.php

<?php namespace AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

class ExampleType extends AbstractType
{
  public function buildForm(FormBuilderInterface $builder, array $options)
  {
    $builder
      ->add('captchaCode', 'captcha', array(
        'captchaConfig' => 'ExampleCaptcha',
        'label' => 'Retype the characters from the picture'
      ))
      ->add('submit', 'submit')
    ;
  }

  public function getName()
  {
    return 'basic';
  }
}

The above code uses the captcha field type to add Captcha to example form. It is required to declare captchaConfig option and assign it a captcha configuration key defined in app/config/captcha.php file.

Entity - /src/AppBundle/Entity/Example.php

<?php namespace AppBundle\Entity;

use Captcha\Bundle\CaptchaBundle\Validator\Constraints as CaptchaAssert;

class Example
{
  /**
   * @CaptchaAssert\ValidCaptcha(
   *      message = "CAPTCHA validation failed, try again."
   * )
   */
  protected $captchaCode;

  public function getCaptchaCode()
  {
    return $this->captchaCode;
  }

  public function setCaptchaCode($captchaCode)
  {
    $this->captchaCode = $captchaCode;
  }
}

To validate the captchaCode field in basic form, we have added the ValidCaptcha constraint to Example Entity.

Controller - /src/AppBundle/Controllers/ExampleController.php

<?php

namespace AppBundle\Controller;

use AppBundle\Entity\Example;
use AppBundle\Form\Type\ExampleType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class ExampleController extends Controller
{
  /**
   * @Route("/example")
   */
  public function getForm(Request $request)
  {
    // create example form
    $exampleForm = $this->createForm(new ExampleType(), new Example());

    // initially, the message shown to the visitor is empty
    $message = '';

    $exampleForm ->handleRequest($request);
    if ($exampleForm->isValid()) {
      // Captcha validation passed
      $message = 'CAPTCHA validation passed, human visitor confirmed!';
    }

    return $this->render('AppBundle:Example:example.html.twig', array(
      'form' => $exampleForm->createView(),
      'message' => $message
    ));
  }
}

When user submits a valid captcha code, isValid() returns true. Before redirecting user, it is possible to perform some actions using the $exampleForm object. Code above assigns a success message to the $message variable which will be displayed on a example page.

View - /src/AppBundle/Resources/views/Example/example.html.twig

<!DOCTYPE html>
<html>
<head>
  <title>Symfony2 Basic BotDetect CAPTCHA Example</title>
</head>

<body>
  <h2>Symfony2 Basic BotDetect CAPTCHA Example</h2>

  {# show message #}
  {% if message is not empty %}
    <p>{{ message }}</p>
  {% endif %}

  {{ form_start(form) }}
  {{ form_widget(form) }}
  {{ form_end(form) }}
</body>
</html>

The form has already been created, the next step is render it by using a set of forms helper functions, and to prints out a message (set in Controller) about Captcha validation success.