I'd like to know if it's possible to check the ticking of a reCAPTCHA specifically in a Controller php. I want to do it so that I can make a condition in order to display an error message in case user did not tick the "I am not a robot" checkbox.
I tried to do something like this :
contact.html.twig file
{% trans_default_domain 'contact' %}
{% extends 'base.html.twig' %}
{% block main %}
{{ form_start(form, {'attr' : {'id' : 'contactform', 'novalidate' : 'novalidate'}} ) }}
{{ form_widget(form.name) }}
{{ form_label(form.name, 'contact.name' | trans ) }}
{{ form_widget(form.email) }}
{{ form_label(form.email, 'contact.email' | trans ) }}
{{ form_widget(form.message) }}
{% for message in app.flashes('captcha') %}
<p class="text-danger">{{ 'contact.error.captcha' | trans }}</p>
{% endfor %}
{{ form_widget(form.save, {'label': 'contact.send' | trans } ) }}
{{ form_end(form) }}
<script>
function renderReCaptcha(widget) {
var form = widget.closest('form');
var widgetType = widget.getAttribute('data-type');
var widgetParameters = {
'sitekey': '{{ gg_recaptcha_site_key }}'
};
if (widgetType == 'invisible') {
widgetParameters['callback'] = function () {
form.submit()
};
widgetParameters['size'] = "invisible";
}
var widgetId = grecaptcha.render(widget, widgetParameters);
if (widgetType == 'invisible') {
bindChallengeToSubmitButtons(form, widgetId);
}
}
function bindChallengeToSubmitButtons(form, reCaptchaId) {
getSubmitButtons(form).forEach(function (button) {
button.addEventListener('click', function (e) {
e.preventDefault();
grecaptcha.execute(reCaptchaId);
});
});
}
function getSubmitButtons(form) {
var buttons = form.querySelectorAll('button, input');
var submitButtons = [];
for (var i= 0; i < buttons.length; i++) {
var button = buttons[i];
if (button.getAttribute('type') == 'submit') {
submitButtons.push(button);
}
}
return submitButtons;
}
</script>
{% endblock %}
ContactController.php file
<?php
namespace App\Controller\Front;
use App\Form\Front\ContactType;
use Symfony\Component\Mime\Email;
use App\Repository\UserRepository;
use App\Form\Front\ContactFromUserType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class ContactController extends AbstractController
{
#[Route('/contact', name: 'contact')]
public function contact(
Request $request,
UserRepository $userRepository,
MailerInterface $mailer): Response
{
$form = $this->createForm(ContactType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$contactFormData = $form->getData();
if ($contactFormData['g-recaptcha-response'] == "") {
$this->addFlash('captcha', 'Si tu n\'es pas un robot, coche la case.');
} else {
$message = (new Email())
->from($contactFormData['email'])
->to('contact@mail.com')
->subject('Message d\'un visiteur !')
->text(
'"'.$contactFormData['message'].'"'.\PHP_EOL.\PHP_EOL.
$contactFormData['name'].' - '.$contactFormData['email'],
'text/plain'
);
$mailer->send($message);
}
}
return $this->render('front/home/contact.html.twig', [
'form' => $form->createView()
]);
}
}
ReCaptchaValidationListener.php file
<?php
namespace App\Form\EventListener;
use ReCaptcha\ReCaptcha;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\HttpFoundation\Request;
class ReCaptchaValidationListener implements EventSubscriberInterface
{
private $reCaptcha;
public function __construct(ReCaptcha $reCaptcha)
{
$this->reCaptcha = $reCaptcha;
}
public static function getSubscribedEvents()
{
return [
FormEvents::POST_SUBMIT => 'onPostSubmit'
];
}
public function onPostSubmit(FormEvent $event)
{
$request = Request::createFromGlobals();
$result = $this->reCaptcha
->setExpectedHostname($request->getHost())
->verify($request->request->get('g-recaptcha-response'), $request->getClientIp());
if (!$result->isSuccess()) {
$event->getForm()->addError(new FormError('The captcha is invalid. Please try again.'));
}
}
}
Is there a solution to write this condition in my controller : if reCAPTCHA robot has been ticked when form is submitted ?