<?php
namespace Aviatur\CustomerBundle\Controller;
// namespace FOS\UserBundle\Controller;
use FOS\UserBundle\CompatibilityUtil;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use Aviatur\AgencyBundle\Entity\Agency;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Aviatur\GeneralBundle\Entity\FosUserUser;
use Aviatur\CustomerBundle\Exception\ValidateException;
use Aviatur\GeneralBundle\Services\AviaturErrorHandler;
use FOS\UserBundle\Controller\RegistrationController as BaseRegistrationController;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Psr\Container\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Doctrine\Persistence\ManagerRegistry;
class RegistrationController extends BaseRegistrationController
{
protected $eventDispatcher;
protected $formFactory;
protected $userManager;
protected $tokenStorage;
protected $managerRegistry;
public function __construct(
EventDispatcherInterface $eventDispatcher,
FactoryInterface $formFactory,
UserManagerInterface $userManager,
TokenStorageInterface $tokenStorage,
ContainerInterface $container,
ManagerRegistry $managerRegistry
) {
parent::__construct($eventDispatcher, $formFactory, $userManager, $tokenStorage);
$this->eventDispatcher = $eventDispatcher;
$this->formFactory = $formFactory;
$this->userManager = $userManager;
$this->tokenStorage = $tokenStorage;
$this->container = $container;
$this->managerRegistry = $managerRegistry;
}
public function registerAction(Request $request, RouterInterface $router = null, AviaturErrorHandler $errorHandler = null): Response
{
try {
$user = $this->userManager->createUser();
$user->setEnabled(true);
$em = $this->managerRegistry->getManager();
$domain = $request->getSession()->get('domain');
$agencyId = $request->getSession()->get('agencyDataInfo')['agency_id'] ?? $request->getSession()->get('agencyId');
$agency = $this->getDoctrine()
->getRepository(Agency::class)
->find($agencyId);
$captchaParameter = $em->getRepository(\Aviatur\GeneralBundle\Entity\Parameter::class)
->findOneByName('aviatur_captcha');
if (!$captchaParameter) {
throw new \Exception("No se encontró el parámetro de reCAPTCHA.");
}
$captchaData = json_decode($captchaParameter->getValue(), true);
$agenciesList = $captchaData['Agencies'] ?? [];
$validateCaptcha = in_array($domain, $agenciesList);
$secretKey = $validateCaptcha ? $captchaData['Keys']['RECAPTCHA_SECRET_KEY'] : null;
$siteKey = $validateCaptcha ? $captchaData['Keys']['RECAPTCHA_SITE_KEY'] : null;
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch($event, FOSUserEvents::REGISTRATION_INITIALIZE);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $this->formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($validateCaptcha) {
$recaptchaResponse = $request->request->get('g-recaptcha-response');
if (empty($recaptchaResponse)) {
return $this->redirect($errorHandler->errorRedirectNoEmail('', 'Error en el reCAPTCHA', 'Por favor, complete el CAPTCHA.'));
}
$verifyUrl = 'https://www.google.com/recaptcha/api/siteverify';
$params = [
'secret' => $secretKey,
'response' => $recaptchaResponse,
'remoteip' => $request->getClientIp(),
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $verifyUrl);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
$resultJson = json_decode($result);
if (!$resultJson->success) {
return $this->redirect($errorHandler->errorRedirectNoEmail('', 'Error en el reCAPTCHA', 'Por favor, confirme que no es un robot.'));
}
}
if ($form->isValid()) {
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch($event, FOSUserEvents::REGISTRATION_SUCCESS);
$user->setAgency($agency);
$user->setCreatedAt(new \DateTime());
$this->userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$this->eventDispatcher->dispatch(new FilterUserResponseEvent($user, $request, $response), FOSUserEvents::REGISTRATION_COMPLETED);
return $response;
}
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch($event, FOSUserEvents::REGISTRATION_FAILURE);
if (null !== $response = $event->getResponse()) {
return $response;
}
}
return $this->render('@FOSUser/Registration/register.html.twig', [
'form' => $form->createView(),
'siteKey' => $siteKey,
'validateCaptcha' => $validateCaptcha
]);
} catch (ValidateException $e) {
$message = 'Información incompleta o inconsistente: ' . $e->getMessage();
$redirectError = $errorHandler->errorRedirect($router->generate('homepage'), 'Error de Registro', $message);
return new RedirectResponse($redirectError);
} catch (\Exception $e) {
$message = 'Error en el sistema: ' . $e->getMessage();
$redirectError = $errorHandler->errorRedirect($router->generate('homepage'), 'Error de Registro', $message);
return new RedirectResponse($redirectError);
}
}
/**
* Tell the user to check their email provider.
*/
public function checkEmailAction(Request $request): Response
{
$email = $request->getSession()->get('fos_user_send_confirmation_email/email');
if (empty($email)) {
return new RedirectResponse($this->generateUrl('fos_user_registration_register'));
}
$request->getSession()->remove('fos_user_send_confirmation_email/email');
$user = $this->userManager->findUserByEmail($email);
if (null === $user) {
return new RedirectResponse($this->container->get('router')->generate('fos_user_security_login'));
}
return $this->render('@FOSUser/Registration/check_email.html.twig', [
'user' => $user,
]);
}
/**
* Receive the confirmation token from user email provider, login the user.
*
* @param string $token
*/
public function confirmAction(Request $request, $token): Response
{
$userManager = $this->userManager;
$user = $userManager->findUserByConfirmationToken($token);
if (null === $user) {
return new RedirectResponse($this->container->get('router')->generate('fos_user_security_login'));
}
$user->setConfirmationToken(null);
$user->setEnabled(true);
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch($event, FOSUserEvents::REGISTRATION_CONFIRM);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$this->eventDispatcher->dispatch(new FilterUserResponseEvent($user, $request, $response), FOSUserEvents::REGISTRATION_CONFIRMED);
return $response;
}
/**
* Tell the user his account is now confirmed.
*/
public function confirmedAction(Request $request): Response
{
$user = $this->getUser();
if (!is_object($user) || !$user instanceof UserInterface) {
throw new AccessDeniedException('This user does not have access to this section.');
}
return $this->render('@FOSUser/Registration/confirmed.html.twig', [
'user' => $user,
'targetUrl' => $this->getTargetUrlFromSession($request->getSession()),
]);
}
private function getTargetUrlFromSession(SessionInterface $session): ?string
{
$token = $this->tokenStorage->getToken();
if (method_exists($token, 'getFirewallName')) {
$firewallName = $token->getFirewallName();
} elseif (method_exists($token, 'getProviderKey')) {
// BC with Symfony 5.x
$firewallName = $token->getProviderKey();
} else {
return null;
}
$key = sprintf('_security.%s.target_path', $firewallName);
if ($session->has($key)) {
return $session->get($key);
}
return null;
}
}