Bon j'ai procédé autrement...
Pour ceux que ça intéresse : (si quelqu'un peut tester pour voir si ça fonctionne bien chez lui...)
dans ReCaptcha/Config/routing.xml j'ai ajouté :
<route id="customer.create.process" path="/register" methods="post">
<default key="_controller">ReCaptcha\Controller\CustomerController::createAction</default>
<default key="_view">register</default>
</route>
<route id="newsletter.process" path="/newsletter" methods="post">
<default key="_controller">ReCaptcha\Controller\NewsletterController::subscribeAction</default>
<default key="_view">newsletter</default>
</route>
<route id="contact.send" path="/contact" methods="post">
<default key="_controller">ReCaptcha\Controller\ContactController::sendAction</default>
<default key="_view">contact</default>
</route>
dans ReCaptcha/Controller j'ai ajouté 3 fichiers (issus du module Front) que j'ai modifié :
- CustomerController.php
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace ReCaptcha\Controller;
use ReCaptcha\ReCaptcha;
use Front\Front;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Thelia\Controller\Front\BaseFrontController;
use Thelia\Core\Event\Customer\CustomerCreateOrUpdateEvent;
use Thelia\Core\Event\Customer\CustomerEvent;
use Thelia\Core\Event\Customer\CustomerLoginEvent;
use Thelia\Core\Event\LostPasswordEvent;
use Thelia\Core\Event\Newsletter\NewsletterEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\Security\Authentication\CustomerUsernamePasswordFormAuthenticator;
use Thelia\Core\Security\Exception\AuthenticationException;
use Thelia\Core\Security\Exception\CustomerNotConfirmedException;
use Thelia\Core\Security\Exception\UsernameNotFoundException;
use Thelia\Core\Security\Exception\WrongPasswordException;
use Thelia\Form\CustomerLogin;
use Thelia\Form\Definition\FrontForm;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Log\Tlog;
use Thelia\Model\ConfigQuery;
use Thelia\Model\Customer;
use Thelia\Model\CustomerQuery;
use Thelia\Model\Newsletter;
use Thelia\Model\NewsletterQuery;
use Thelia\Tools\RememberMeTrait;
use Thelia\Tools\URL;
use ReCaptcha\Event\ReCaptchaCheckEvent;
use ReCaptcha\Event\ReCaptchaEvents;
/**
* Class CustomerController
* @package Thelia\Controller\Front
* @author Manuel Raynaud <manu@raynaud.io>
*/
class CustomerController extends BaseFrontController
{
use RememberMeTrait;
/**
* Create a new customer.
* On success, redirect to success_url if exists, otherwise, display the same view again.
*/
public function createAction()
{
if (! $this->getSecurityContext()->hasCustomerUser()) {
$customerCreation = $this->createForm(FrontForm::CUSTOMER_CREATE);
try {
$form = $this->validateForm($customerCreation, "post");
$checkCaptchaEvent = new ReCaptchaCheckEvent();
$this->dispatch(ReCaptchaEvents::CHECK_CAPTCHA_EVENT, $checkCaptchaEvent);
if ($checkCaptchaEvent->isHuman() == false) { throw new \Exception('Invalid reCAPTCHA'); }
$customerCreateEvent = $this->createEventInstance($form->getData());
$this->dispatch(TheliaEvents::CUSTOMER_CREATEACCOUNT, $customerCreateEvent);
$newCustomer = $customerCreateEvent->getCustomer();
// Newsletter
if (true === $form->get('newsletter')->getData()) {
$newsletterEmail = $newCustomer->getEmail();
$nlEvent = new NewsletterEvent(
$newsletterEmail,
$this->getRequest()->getSession()->getLang()->getLocale()
);
$nlEvent->setFirstname($newCustomer->getFirstname());
$nlEvent->setLastname($newCustomer->getLastname());
// Security : Check if this new Email address already exist
if (null !== $newsletter = NewsletterQuery::create()->findOneByEmail($newsletterEmail)) {
$nlEvent->setId($newsletter->getId());
$this->dispatch(TheliaEvents::NEWSLETTER_UPDATE, $nlEvent);
} else {
$this->dispatch(TheliaEvents::NEWSLETTER_SUBSCRIBE, $nlEvent);
}
}
if (ConfigQuery::isCustomerEmailConfirmationEnable() && ! $newCustomer->getEnable()) {
$response = $this->generateRedirectFromRoute('customer.login.view');
} else {
$this->processLogin($customerCreateEvent->getCustomer());
$cart = $this->getSession()->getSessionCart($this->getDispatcher());
if ($cart->getCartItems()->count() > 0) {
$response = $this->generateRedirectFromRoute('cart.view');
} else {
$response = $this->generateSuccessRedirect($customerCreation);
}
}
return $response;
} catch (FormValidationException $e) {
$message = $this->getTranslator()->trans(
"Please check your input: %s",
[
'%s' => $e->getMessage()
],
Front::MESSAGE_DOMAIN
);
} catch (\Exception $e) {
$message = $this->getTranslator()->trans(
"Sorry, an error occured: %s",
[
'%s' => $e->getMessage()
],
Front::MESSAGE_DOMAIN
);
}
Tlog::getInstance()->error(
sprintf(
"Error during customer creation process : %s. Exception was %s",
$message,
$e->getMessage()
)
);
$customerCreation->setErrorMessage($message);
$this->getParserContext()
->addForm($customerCreation)
->setGeneralError($message)
;
// Redirect to error URL if defined
if ($customerCreation->hasErrorUrl()) {
return $this->generateErrorRedirect($customerCreation);
}
}
}
/**
* Dispatch event for customer login action
*
* @param Customer $customer
*/
protected function processLogin(Customer $customer)
{
$this->dispatch(TheliaEvents::CUSTOMER_LOGIN, new CustomerLoginEvent($customer));
}
/**
* @param $data
* @return \Thelia\Core\Event\Customer\CustomerCreateOrUpdateEvent
*/
private function createEventInstance($data)
{
$customerCreateEvent = new CustomerCreateOrUpdateEvent(
isset($data["title"])?$data["title"]:null,
isset($data["firstname"])?$data["firstname"]:null,
isset($data["lastname"])?$data["lastname"]:null,
isset($data["address1"])?$data["address1"]:null,
isset($data["address2"])?$data["address2"]:null,
isset($data["address3"])?$data["address3"]:null,
isset($data["phone"])?$data["phone"]:null,
isset($data["cellphone"])?$data["cellphone"]:null,
isset($data["zipcode"])?$data["zipcode"]:null,
isset($data["city"])?$data["city"]:null,
isset($data["country"])?$data["country"]:null,
isset($data["email"])?$data["email"]:null,
isset($data["password"]) ? $data["password"]:null,
isset($data["lang_id"]) ? $data["lang_id"]:$this->getSession()->getLang()->getId(),
isset($data["reseller"])?$data["reseller"]:null,
isset($data["sponsor"])?$data["sponsor"]:null,
isset($data["discount"])?$data["discount"]:null,
isset($data["company"])?$data["company"]:null,
null,
isset($data["state"])?$data["state"]:null
);
return $customerCreateEvent;
}
}
- ContactController.php
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace ReCaptcha\Controller;
use ReCaptcha\ReCaptcha;
use Thelia\Controller\Front\BaseFrontController;
use Thelia\Core\Event\Contact\ContactEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Form\Definition\FrontForm;
use Thelia\Form\Exception\FormValidationException;
use Thelia\Log\Tlog;
use Thelia\Model\ConfigQuery;
use ReCaptcha\Event\ReCaptchaCheckEvent;
use ReCaptcha\Event\ReCaptchaEvents;
/**
* Class ContactController
* @package Thelia\Controller\Front
* @author Manuel Raynaud <manu@raynaud.io>
*/
class ContactController extends BaseFrontController
{
/**
* send contact message
*/
public function sendAction()
{
$contactForm = $this->createForm(FrontForm::CONTACT);
try {
$form = $this->validateForm($contactForm);
$checkCaptchaEvent = new ReCaptchaCheckEvent();
$this->dispatch(ReCaptchaEvents::CHECK_CAPTCHA_EVENT, $checkCaptchaEvent);
if ($checkCaptchaEvent->isHuman() == false) { throw new \Exception('Invalid reCAPTCHA'); }
$event = new ContactEvent($form);
$this->dispatch(TheliaEvents::CONTACT_SUBMIT, $event);
$this->getMailer()->sendSimpleEmailMessage(
[ ConfigQuery::getStoreEmail() => $event->getName() ],
[ ConfigQuery::getStoreEmail() => ConfigQuery::getStoreName() ],
$event->getSubject(),
'',
$event->getMessage(),
[],
[],
[ $event->getEmail() => $event->getName() ]
);
if ($contactForm->hasSuccessUrl()) {
return $this->generateSuccessRedirect($contactForm);
}
return $this->generateRedirectFromRoute('contact.success');
} catch (FormValidationException $e) {
$error_message = $e->getMessage();
}
Tlog::getInstance()->error(sprintf('Error during sending contact mail : %s', $error_message));
$contactForm->setErrorMessage($error_message);
$this->getParserContext()
->addForm($contactForm)
->setGeneralError($error_message)
;
// Redirect to error URL if defined
if ($contactForm->hasErrorUrl()) {
return $this->generateErrorRedirect($contactForm);
}
}
}
- NewsletterController.php
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace ReCaptcha\Controller;
use ReCaptcha\ReCaptcha;
use Front\Front;
use Symfony\Component\HttpFoundation\JsonResponse;
use Thelia\Controller\Front\BaseFrontController;
use Thelia\Core\Event\Newsletter\NewsletterEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Form\Definition\FrontForm;
use Thelia\Log\Tlog;
use Thelia\Model\Customer;
use Thelia\Model\NewsletterQuery;
use ReCaptcha\Event\ReCaptchaCheckEvent;
use ReCaptcha\Event\ReCaptchaEvents;
/**
* Class NewsletterController
* @package Thelia\Controller\Front
* @author Manuel Raynaud <manu@raynaud.io>, Franck Allimant <franck@cqfdev.fr>
*/
class NewsletterController extends BaseFrontController
{
public function subscribeAction()
{
$errorMessage = false;
$newsletterForm = $this->createForm(FrontForm::NEWSLETTER);
try {
$form = $this->validateForm($newsletterForm);
$checkCaptchaEvent = new ReCaptchaCheckEvent();
$this->dispatch(ReCaptchaEvents::CHECK_CAPTCHA_EVENT, $checkCaptchaEvent);
if ($checkCaptchaEvent->isHuman() == false) { throw new \Exception('Invalid reCAPTCHA'); }
$event = new NewsletterEvent(
$form->get('email')->getData(),
$this->getRequest()->getSession()->getLang()->getLocale()
);
/** @var Customer $customer */
if (null !== $customer = $this->getSecurityContext()->getCustomerUser()) {
$event
->setFirstname($customer->getFirstname())
->setLastname($customer->getLastname())
;
} else {
$event
->setFirstname($form->get('firstname')->getData())
->setLastname($form->get('lastname')->getData())
;
}
$this->dispatch(TheliaEvents::NEWSLETTER_SUBSCRIBE, $event);
// If a success URL is defined in the form, redirect to it, otherwise use the defaut view
if ($newsletterForm->hasSuccessUrl() && ! $this->getRequest()->isXmlHttpRequest()) {
return $this->generateSuccessRedirect($newsletterForm);
}
} catch (\Exception $e) {
$errorMessage = $e->getMessage();
Tlog::getInstance()->error(sprintf('Error during newsletter subscription : %s', $errorMessage));
$newsletterForm->setErrorMessage($errorMessage);
}
// If Ajax Request
if ($this->getRequest()->isXmlHttpRequest()) {
return new JsonResponse([
"success" => ($errorMessage) ? false : true,
"message" => ($errorMessage) ? $errorMessage : $this->getTranslator()->trans(
"Thanks for signing up! We'll keep you posted whenever we have any new updates.",
[],
Front::MESSAGE_DOMAIN
)
], ($errorMessage) ? 500 : 200);
}
$this->getParserContext()
->setGeneralError($errorMessage)
->addForm($newsletterForm);
// If an error URL is defined in the form, redirect to it, otherwise use the defaut view
if ($errorMessage && $newsletterForm->hasErrorUrl()) {
return $this->generateErrorRedirect($newsletterForm);
}
}
}
A priori... ça fait le job...
J'ai fait aussi d'autres modifications pour avoir plusieurs recaptcha sur une même page (newsletter mini) :
- ReCaptcha/Hook/FrontHook.php :
<?php
namespace ReCaptcha\Hook;
use ReCaptcha\ReCaptcha;
use Thelia\Core\Event\Hook\HookRenderEvent;
use Thelia\Core\Hook\BaseHook;
class FrontHook extends BaseHook
{
public function addRecaptchaCheck(HookRenderEvent $event)
{
$event->add("<input type=\"hidden\" name=\"g-recaptcha-response\">");
}
}
- ReCaptcha/templates/frontOffice/[theme]/recaptcha-js.html
<script src="https://www.google.com/recaptcha/api.js?render={loop type="module-config" name="site-key" module="ReCaptcha" variable="site_key"}{$VALUE}{/loop}"></script>
<script>
grecaptcha.ready(function (){
grecaptcha.execute('{loop type="module-config" name="site-key" module="ReCaptcha" variable="site_key"}{$VALUE}{/loop}', { action: 'forms' }).then(function (token) {
var recaptchaElements = document.getElementsByName('g-recaptcha-response');
for (var i = 0; i < recaptchaElements.length; i++) {
recaptchaElements[i].value = token;
}
});
});
</script>
et dans les différents forms j'ai ajouté
{hook name="recaptcha.check"}
Il faudrait peut être voir pour rajouter dans la configuration sur quel formulaire on veut activer ou non recaptcha... et remettre en place la gestion invisible... (là j'ai fait pour un recaptcha invisible)
Last edited by Elyos (30-04-2021 10:21:10)