我想知道是否可以在控制器 php 中专门检查 reCAPTCHA 的勾选。我想这样做,以便我可以设定一个条件,以便在用户没有勾选“我不是机器人”复选框的情况下显示错误消息。
我尝试做这样的事情:
contact.html.twig 文件
{% 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 文件
<?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['captcha'] == []) {
$this->addFlash('captcha', 'Si tu n\'es pas un robot, coche la case.');
} else {
$message = (new Email())
->from($contactFormData['email'])
->to('[email protected]')
->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()
]);
}
}
我注意到每种情况
$contactFormData['captcha'] == []
。
ReCaptchaValidationListener.php 文件
<?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.'));
}
}
}
是否有解决方案可以在我的控制器中写入此条件:如果提交表单时已勾选 reCAPTCHA 机器人?