Symfony 4 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 Symfony 4 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 example are:

Symfony 4 Basic BotDetect Captcha validation screenshot

Config - /config/packages/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 CaptchaType in ExampleType form. Detailed description of this approach is available in a BotDetect Symfony 4 integration guide.

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

<?php

namespace App\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
// Importing the CaptchaType class
use Captcha\Bundle\CaptchaBundle\Form\Type\CaptchaType;

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

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

Entity - /src/Entity/Example.php

<?php namespace App\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 example form, we have added the ValidCaptcha constraint to Example Entity.

Controller - /src/Controllers/ExampleController.php

<?php

namespace App\Controller;

use App\Entity\Example;
use App\Form\Type\ExampleType;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

class ExampleController extends AbstractController
{
  /**
   * @Route("/example")
   */
  public function getForm(Request $request)
  {
    // create contact form
    $form = $this->createForm(ExampleType::class, new Example());
    
    // initially, the message shown to the visitor is empty
    $message = '';

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

    return $this->render('example/index.html.twig', array(
      'form' => $form->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 - /templates/example/index.html.twig

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

<body>
  <h2>Symfony 4 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.