Symfony 4 Form Validation BotDetect CAPTCHA Example
First Time Here?
Check the BotDetect Symfony 4 Captcha Quickstart for key integration steps.
Symfony Form Validation BotDetect CAPTCHA Example shows how to integrate CaptchaBundle in a form. We have also demonstrated how to create the ValidCaptcha
constraint in order to validate captcha code user submits.
The brief example is based around a contact form which sends email if user input is considered valid -– a likely real world scenario for Captcha protection integration.
Files for this example are:
/config/packages/captcha.php
/src/Form/Type/ContactType.php
/src/Entity/Contact.php
/src/Controllers/ContactController.php
/templates/contact/index.html.twig
Config - /config/packages/captcha.php
<?php if (!class_exists('CaptchaConfiguration')) { return; } // BotDetect PHP Captcha configuration options return [ // Captcha configuration for contact page 'ContactCaptcha' => [ 'UserInputID' => 'captchaCode', 'CodeLength' => CaptchaRandomization::GetRandomCodeLength(4, 6), 'ImageStyle' => ImageStyle::AncientMosaic, ], ];
In order to use the CaptchaBundle, we have defined Captcha configuration which will be used as a CaptchaType
in ContactType form. Detailed description of this approach is available in a BotDetect Symfony 4 integration guide.
Type - /src/Form/Type/ContactType.php
<?php namespace App\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\Extension\Core\Type\EmailType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextareaType; use Symfony\Component\Form\Extension\Core\Type\TextType; // Importing the CaptchaType class use Captcha\Bundle\CaptchaBundle\Form\Type\CaptchaType; class ContactType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('name', TextType::class) ->add('email', EmailType::class) ->add('subject', TextType::class) ->add('message', TextareaType::class) ->add('captchaCode', CaptchaType::class, array( 'captchaConfig' => 'ContactCaptcha', 'label' => 'Retype the characters from the picture' )) ->add('submit', SubmitType::class) ; } }
The above code uses the CaptchaType
to add Captcha to contact form. It is required to declare captchaConfig
option and assign it a captcha configuration variable defined in config/packages/captcha.php
file.
Entity - /src/Entity/Contact.php
<?php namespace App\Entity; use Symfony\Component\Validator\Constraints as Assert; use Captcha\Bundle\CaptchaBundle\Validator\Constraints as CaptchaAssert; class Contact { /** * @Assert\Length( * min = 2, * max = 10, * minMessage = "Your name must be at least {{ limit }} characters long", * maxMessage = "Your name cannot be longer than {{ limit }} characters" * ) */ protected $name; /** * @Assert\Email( * message = "The email '{{ value }}' is not a valid email.", * ) */ protected $email; /** * @Assert\Length( * min = 1, * max = 50, * minMessage = "Your subject must be at least {{ limit }} characters long", * maxMessage = "Your subject cannot be longer than {{ limit }} characters" * ) */ protected $subject; /** * @Assert\Length( * min = 2, * max = 255, * minMessage = "Your message must be at least {{ limit }} characters long", * maxMessage = "Your message cannot be longer than {{ limit }} characters" * ) */ protected $message; /** * @CaptchaAssert\ValidCaptcha( * message = "CAPTCHA validation failed, try again." * ) */ protected $captchaCode; public function getCaptchaCode() { return $this->captchaCode; } public function setCaptchaCode($captchaCode) { $this->captchaCode = $captchaCode; } public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } public function getEmail() { return $this->email; } public function setEmail($email) { $this->email = $email; } public function getSubject() { return $this->subject; } public function setSubject($subject) { $this->subject = $subject; } public function getMessage() { return $this->message; } public function setMessage($message) { $this->message = $message; } }
To validate the captchaCode
field in contact form, we have added the ValidCaptcha
constraint to Contact Entity.
Controller - /src/Controllers/ContactController.php
<?php namespace App\Controller; use App\Entity\Contact; use App\Form\Type\ContactType; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Component\HttpFoundation\Request; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; class ContactController extends AbstractController { /** * @Route("/contact") */ public function getForm(Request $request) { // create contact form $form = $this->createForm(ContactType::class, new Contact()); // initially, the message shown to the visitor is empty $message = ''; $form ->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { // Captcha validation passed // TODO: send email $message = 'Your message was sent successfully.'; } return $this->render('contact/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 $contactForm
object. Code above assigns a success message to the $message
variable which will be displayed on a contact page.
View - /templates/contact/index.html.twig
<!DOCTYPE html> <html> <head> <title>Symfony 4 Form Validation BotDetect CAPTCHA Example</title> </head> <body> <h2>Symfony 4 Form Validation 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.
Current BotDetect Versions
-
BotDetect ASP.NET CAPTCHA
2019-07-22v4.4.2 -
BotDetect Java CAPTCHA
2019-07-22v4.0.Beta3.7 -
BotDetect PHP CAPTCHA
2019-07-22v4.2.5