<?php
namespace App\Controller\Main;
use App\Entity\Main\User;
use App\Entity\Main\UserRegistrationData;
use App\Events\Main\Registration\SecurityEvent;
use App\Events\Main\User\UserCreatedEvent;
use App\Events\Main\User\UserRegisteredEvent;
use App\EventSubscribers\Main\SecuritySubscriber;
use App\EventSubscribers\Main\UserSubscriber;
use App\Form\Main\UserSimpleRegistrationType;
use App\Services\TranslationManager;
use App\Services\UserManager;
use App\Services\ReferralProgramManager;
use App\Tools\Encryption;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
/**
* Controller managing the registration.
*
* @Route(
* condition="not (context.getHost() matches '%coaching_domain.host.regexp%')"
* )
*/
class RegistrationController extends AbstractController
{
use BrulafineControllerTrait;
/**
* @param RequestStack $requestStack
* @param ReferralProgramManager $referralProgramManager
* @param UserManager $serviceUserManager
* @param EventDispatcherInterface $dispatcher
* @param EntityManagerInterface $entityManager
* @return Response
* @throws \Exception
* @Route("/register", name="user_registration")
*/
public function registerAction(
RequestStack $requestStack,
ReferralProgramManager $referralProgramManager,
UserManager $serviceUserManager,
EventDispatcherInterface $dispatcher,
EntityManagerInterface $entityManager,
AuthorizationCheckerInterface $authorizationChecker,
Encryption $encrypter,
UserPasswordHasherInterface $userPasswordHasher
) {
$setup = $this->getSetup();
$request = $requestStack->getCurrentRequest();
$registerAsGuest = $request->request->get('register_as_guest');
if ($authorizationChecker->isGranted('ROLE_USER')) {
$url = $this->generateUrl('brulafine_user_compte');
if ($referralProgramManager->isReferralProgramEnabled($setup->getUser(), $setup->getSite())) {
$url = $this->generateUrl('brulafine_user_referral_program');
}
return $this->appendCookie(new RedirectResponse($url), $setup->getCookie());
}
$user = new User();
$user->setEnabled(true);
$session = $request->getSession();
$userRegistrationData = new UserRegistrationData();
$userRegistrationData->setCGU(true);
$email = $request->query->get('f_mail');
if (null === $email) {
$email = $session->get('f_mail');
}
if (isset($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) {
$userRegistrationData->setEmail($email);
$session->set('f_mail', $email);
}
$form = $this->createForm(UserSimpleRegistrationType::class, $userRegistrationData);
$form->handleRequest($request);
if (($form->isSubmitted() && $form->isValid()) || $registerAsGuest) {
$email = $userRegistrationData->getEmail();
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
if ($request->isXmlHttpRequest()) {
$res = [
'status' => 'error',
'message' => $this->get('translator')->trans( 'flashMessages.site.incorrectEmail', array(), TranslationManager::TRANSLATION_DOMAIN_FLASH),
'code' => 801,
'data' => ['email' => $email],
];
return $this->appendCookie(new JsonResponse($res, Response::HTTP_UNAUTHORIZED), $setup->getCookie());
}
$response = $this->render($this->getTemplatesDir() . '/Security/views/Registration/register.html.twig', [
'form' => $form->createView(),
'tracking' => $setup->getTracking(),
'site' => $setup->getSite(),
'submit_button' => $request->attributes->get('submit_button'),
]);
return $this->appendCookie($response, $setup->getCookie());
}
/** @var User $userExists */
$userExists = $entityManager->getRepository(User::class)->findOneByUsername($email);
if ($userExists && !$userExists->hasRole(User::ROLE_GUEST)) {
if ($request->isXmlHttpRequest()) {
$res = [
'status' => 'error',
'message' => $this->get('translator')->trans( 'flashMessages.site.emailAlreadyExists', array(), TranslationManager::TRANSLATION_DOMAIN_FLASH),
'code' => 802,
'data' => ['email' => $email],
];
return $this->appendCookie(new JsonResponse($res, Response::HTTP_UNAUTHORIZED), $setup->getCookie());
}
$response = $this->render($this->getTemplatesDir() . '/Security/views/Registration/register.html.twig', [
'form' => $form->createView(),
'tracking' => $setup->getTracking(),
'site' => $setup->getSite(),
'submit_button' => $request->attributes->get('submit_button'),
]);
return $this->appendCookie($response, $setup->getCookie());
}
if ($userExists && $userExists->hasRole(User::ROLE_GUEST) && $registerAsGuest) {
if ($request->isXmlHttpRequest()) {
$session->set(User::GUEST_USER_SESSION_KEY, $userExists->getId());
$res = [
'user' => $userExists->getId(),
'message' => 'User already has GUEST Account',
'email' => $email,
];
return $this->appendCookie(new JsonResponse($res), $setup->getCookie());
}
}
if ($userExists && $userExists->hasRole(User::ROLE_GUEST) && !$registerAsGuest) {
$userExists->removeRole(User::ROLE_GUEST);
$user = $userExists;
}
$password = $serviceUserManager->generatePassword();
$user->setEncryptedPassword($encrypter->encrypt($serviceUserManager->generatePassword()));
$user->setTracking($setup->getTracking());
$user->setEmail($form->getData()->getEmail());
$user->setPlainPassword($password);
$user->setPassword($userPasswordHasher->hashPassword($user, $user->getPlainPassword()));
$user->setUserIp($request->getClientIp());
$user->setUserAgent($request->headers->get('User-Agent', 'N/A'));
$user->setRegisteredFrom($setup->getSite());
if ($registerAsGuest) {
$user->addRole(User::ROLE_GUEST);
$user->setUserLocale($request->getLocale());
}
$dispatcher->dispatch(
new UserCreatedEvent($user, $request),
UserSubscriber::USER_CREATED
);
$request->attributes->set('user_plain_password', $password);
if (!$user->hasRole(User::ROLE_GUEST)) {
$dispatcher->dispatch(
new UserRegisteredEvent($setup->getTracking(), $user, $setup->getSite()),
UserSubscriber::REWARD_APPLYING
);
$url = $this->generateUrl('brulafine_user_compte');
if ($referralProgramManager->isReferralProgramEnabled($user, $setup->getSite())) {
$url = $this->generateUrl('brulafine_user_referral_program');
}
$response = new RedirectResponse($url);
$dispatcher->dispatch(
new SecurityEvent($user, $request, $response),
SecuritySubscriber::REGISTRATION_COMPLETED
);
}
if ($session->has('f_mail')) {
$session->remove('f_mail');
}
$res = [
'user' => $user->getId(),
'message' => 'User created',
'email' => $user->getEmail(),
];
if ($request->isXmlHttpRequest()) {
if ($registerAsGuest) {
$session->set(User::GUEST_USER_SESSION_KEY, $user->getId());
}
return $this->appendCookie(new JsonResponse($res), $setup->getCookie());
}
return $this->appendCookie($response, $setup->getCookie());
}
$errors = $form->getErrors(true, true);
if ($request->isXmlHttpRequest()) {
$data = [];
foreach ($form['email']->getErrors(true, true) as $error) {
$data['email'] = $error->getMessage();
}
$res = [
'status' => 'error',
'message' => $data['email'] ?? $this->get('translator')->trans( 'flashMessages.site.notValidEmail', array(), TranslationManager::TRANSLATION_DOMAIN_FLASH),
'code' => 801,
'data' => $data,
];
return $this->appendCookie(new JsonResponse($res, Response::HTTP_UNAUTHORIZED), $setup->getCookie());
}
$response = $this->render($this->getTemplatesDir() . '/Security/views/Registration/register.html.twig', [
'form' => $form->createView(),
'tracking' => $setup->getTracking(),
'site' => $setup->getSite(),
'submit_button' => $request->attributes->get('request')->attributes->get('submit_button'),
]);
return $this->appendCookie($response, $setup->getCookie());
}
}