Symfony 2 Form Validation BotDetect CAPTCHA Example
First Time Here?
Check the BotDetect Symfony2 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 ('bd-captcha-symfony2-examples') example are:
/app/config/captcha.php
/src/AppBundle/Form/Type/ContactType.php
/src/AppBundle/Entity/Contact.php
/src/AppBundle/Controllers/ContactController.php
/src/AppBundle/Resources/views/Contact/contact.html.twig
All files are available for download as a part of the BotDetect Captcha Symfony integration package.
Config - /app/config/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 captcha
field type in ContactType form. Detailed description of this approach is available in a BotDetect Symfony2 integration guide.
Type - /src/AppBundle/Form/Type/ContactType.php
<?php namespace AppBundle\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; class ContactType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('name', 'text') ->add('email', 'email') ->add('subject', 'text') ->add('message', 'textarea') ->add('captchaCode', 'captcha', array( 'captchaConfig' => 'ContactCaptcha', 'label' => 'Retype the characters from the picture' )) ->add('submit', 'submit') ; } public function getName() { return 'contact'; } }
The above code uses the captcha
field type to add Captcha to contact form. It is required to declare captchaConfig
option and assign it a captcha configuration variable defined in app/config/captcha.php
file.
Entity - /src/AppBundle/Entity/Contact.php
<?php namespace AppBundle\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/AppBundle/Controllers/ContactController.php
<?php namespace AppBundle\Controller; use AppBundle\Entity\Contact; use AppBundle\Form\Type\ContactType; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Symfony\Component\HttpFoundation\Request; use Symfony\Bundle\FrameworkBundle\Controller\Controller; class ContactController extends Controller { /** * @Route("/contact") */ public function getForm(Request $request) { // create contact form $contactForm = $this->createForm(new ContactType(), new Contact()); // initially, the message shown to the visitor is empty $message = ''; $contactForm ->handleRequest($request); if ($contactForm->isValid()) { // Captcha validation passed // TODO: send email $message = 'Your message was sent successfully.'; } return $this->render('AppBundle:Contact:contact.html.twig', array( 'form' => $contactForm->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 - /src/AppBundle/Resources/views/Contact/contact.html.twig
<!DOCTYPE html> <html> <head> <title>Symfony2 Form Validation BotDetect CAPTCHA Example</title> </head> <body> <h2>Symfony2 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