<?php
namespace App\Controller;
use App\Entity\User;
use DateTime;
use App\Form\RegistrationFormType;
use App\Form\UnsecureRegistrationFormType;
use App\Security\EmailVerifier;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mime\Address;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Contracts\Translation\TranslatorInterface;
use SymfonyCasts\Bundle\VerifyEmail\Exception\VerifyEmailExceptionInterface;
use App\Repository\ClientRepository;
use App\Repository\AvatarRepository;
use App\Repository\ClientProductRepository;
use App\Repository\DomainRepository;
use App\Repository\JobRepository;
use App\Repository\LocationRepository;
use App\Repository\ProductRepository;
use App\Repository\SubLocationRepository;
use App\Repository\UserRepository;
use App\Security\LoginFormAuthenticator;
use App\Security\LoginFormAuthenticatorUnsecure;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface;
class RegistrationController extends AbstractController
{
private $emailVerifier;
public function __construct(EmailVerifier $emailVerifier)
{
$this->emailVerifier = $emailVerifier;
}
/**
* @Route("/{clientSlug}/{clientSalt}/register", name="app_register")
*/
public function register($clientSlug, $clientSalt, Request $request, UserPasswordHasherInterface $userPasswordHasher, EntityManagerInterface $entityManager, ClientRepository $clientRepository, DomainRepository $domainRepository, LocationRepository $locationRepository, SublocationRepository $subLocationRepository, MailerInterface $mailer, AvatarRepository $avatarRepository, JobRepository $jobRepository, ClientProductRepository $clientProductRepository, UserAuthenticatorInterface $authenticator, LoginFormAuthenticator $loginAuthenticator, LoginFormAuthenticatorUnsecure $loginAuthenticatorUnsecure): Response
{
$client = $clientRepository->findOneBySlug($clientSlug);
$avatar = $avatarRepository->findOneById(13);
$jobs = $jobRepository->findByClient($client);
$locations = $locationRepository->findByClient($client);
$subLocations = $subLocationRepository->findByClient($client);
$user = new User();
if($client->isIsSecure() == true){
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$jobTitleData = $form->get('jobTitle')->getData();
if($client->isIsHiddenJobTitle() == false){
if($jobTitleData == ''){
$form->get('jobTitle')->addError(new FormError('Veuillez renseigner un poste.'));
return $this->render('registration/register.html.twig', [
'registrationForm' => $form->createView(),
'locations' => $locations,
'subLocations' => $subLocations,
'client' => $client,
'jobs' => $jobs,
'hiddenPassword' => $this->getParameter('app.generic_password')
]);
}
}
$clientLocationsCount = count($client->getLocations());
$locationData = $form->get('location')->getData();
if($clientLocationsCount > 0){
if($locationData == '' || $locationData == null){
$form->get('location')->addError(new FormError('Veuillez renseigner votre ' . $client->getLabelLocation() . '.'));
return $this->render('registration/register_unsecure.html.twig', [
'registrationForm' => $form->createView(),
'locations' => $locations,
'subLocations' => $subLocations,
'client' => $client,
'jobs' => $jobs,
'hiddenPassword' => $this->getParameter('app.generic_password')
]);
}
}
$clientSubLocationsCount = count($client->getSubLocations());
$subLocationData = $form->get('subLocation')->getData();
if($clientSubLocationsCount > 0){
if($subLocationData == '' || $subLocationData == null){
$form->get('subLocation')->addError(new FormError('Veuillez renseigner votre ' . $client->getLabelSubLocation() . '.'));
return $this->render('registration/register_unsecure.html.twig', [
'registrationForm' => $form->createView(),
'locations' => $locations,
'subLocations' => $subLocations,
'client' => $client,
'jobs' => $jobs,
'hiddenPassword' => $this->getParameter('app.generic_password')
]);
}
}
// Si le client = public
if($client->getId() == 1){
$user->setIsActive(true);
$user->setAvatar($avatar);
$user->setClient($client);
$user->setCreatedAt(new Datetime());
$user->setModifiedAt(new Datetime());
$user->setSalt($this->generateRandomString());
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
)
)
;
}else{
// Si count des noms de domaines du client > 0 : vérification de l'adresse email renseignée par l'utilisateur
$domainsCount = count($client->getDomains());
if($domainsCount > 0){
$userDomain = substr($form->get('email')->getData(), strpos($form->get('email')->getData(), "@") + 1);
$clientDomain = $domainRepository->findOneBy(['name' => $userDomain, 'client' => $client]);
if(!empty($clientDomain)){
$user->setIsActive(true);
$user->setAvatar($avatar);
$user->setClient($client);
$user->setCreatedAt(new Datetime());
$user->setModifiedAt(new Datetime());
$user->setSalt($this->generateRandomString());
// encode the plain password
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
)
);
}else{
$form->addError(new FormError('Veuillez renseigner votre adresse email professionnelle.'));
return $this->render('registration/register.html.twig', [
'registrationForm' => $form->createView(),
'locations' => $locations,
'subLocations' => $subLocations,
'client' => $client,
'jobs' => $jobs,
]);
}
}else{
$user->setIsActive(true);
$user->setAvatar($avatar);
$user->setClient($client);
$user->setCreatedAt(new Datetime());
$user->setModifiedAt(new Datetime());
$user->setSalt($this->generateRandomString());
// encode the plain password
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
)
);
}
}
$entityManager->persist($user);
$entityManager->flush();
// Mail de bienvenue
$welcomeEmail = (new TemplatedEmail())
->context([
'client' => $client
])
->from(new Address('no-reply@avisea.net', 'Ween'))
->to($user->getEmail())
->subject('Bienvenue sur Ween')
->htmlTemplate('email/welcome.html.twig')
;
$mailer->send($welcomeEmail);
// generate a signed url and email it to the user
$this->emailVerifier->sendEmailConfirmation('app_verify_email', $user,
(new TemplatedEmail())
->context(['client' => $client])
->from(new Address('no-reply@avisea.net', 'Ween'))
->to($user->getEmail())
->subject('Veuillez confirmer votre adresse email')
->htmlTemplate('registration/confirmation_email.html.twig')
);
return $this->redirectToRoute('app_login', ['clientSlug' => $client->getSlug(), 'clientSalt' => $client->getSalt(), 'fromRegister' => '1'], Response::HTTP_SEE_OTHER);
}
$content = $this->renderView('registration/register.html.twig', [
'registrationForm' => $form->createView(),
'locations' => $locations,
'subLocations' => $subLocations,
'jobs' => $jobs,
'client' => $client
]);
$viewWithCookie = $this->setCookie($client->getSlug(), $content);
return $viewWithCookie;
}else{
$secureClientProducts = $clientProductRepository->hasClientSecureProduct($client);
$form = $this->createForm(UnsecureRegistrationFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$jobTitleData = $form->get('jobTitle')->getData();
if($client->isIsHiddenJobTitle() == false){
if($jobTitleData == ''){
$form->get('jobTitle')->addError(new FormError('Veuillez renseigner un poste.'));
return $this->render('registration/register_unsecure.html.twig', [
'registrationForm' => $form->createView(),
'locations' => $locations,
'subLocations' => $subLocations,
'client' => $client,
'jobs' => $jobs,
'hiddenPassword' => $this->getParameter('app.generic_password')
]);
}
}
$clientLocationsCount = count($client->getLocations());
$locationData = $form->get('location')->getData();
if($clientLocationsCount > 0){
if($locationData == '' || $locationData == null){
$form->get('location')->addError(new FormError('Veuillez renseigner votre ' . $client->getLabelLocation() . '.'));
return $this->render('registration/register_unsecure.html.twig', [
'registrationForm' => $form->createView(),
'locations' => $locations,
'subLocations' => $subLocations,
'client' => $client,
'jobs' => $jobs,
'hiddenPassword' => $this->getParameter('app.generic_password')
]);
}
}
$clientSubLocationsCount = count($client->getSubLocations());
$subLocationData = $form->get('subLocation')->getData();
if($clientSubLocationsCount > 0){
if($subLocationData == '' || $subLocationData == null){
$form->get('subLocation')->addError(new FormError('Veuillez renseigner votre ' . $client->getLabelSubLocation() . '.'));
return $this->render('registration/register_unsecure.html.twig', [
'registrationForm' => $form->createView(),
'locations' => $locations,
'subLocations' => $subLocations,
'client' => $client,
'jobs' => $jobs,
'hiddenPassword' => $this->getParameter('app.generic_password')
]);
}
}
if($form->get('plainPassword')->getData() == 'hidden_pswrd'){
$domainsCount = count($client->getDomains());
if($domainsCount > 0){
$userDomain = substr($form->get('email')->getData(), strpos($form->get('email')->getData(), "@") + 1);
$clientDomain = $domainRepository->findOneBy(['name' => $userDomain, 'client' => $client]);
if(!empty($clientDomain)){
$user->setIsActive(true);
$user->setAvatar($avatar);
$user->setClient($client);
$user->setCreatedAt(new Datetime());
$user->setModifiedAt(new Datetime());
$user->setIsVerified(true);
$user->setSalt($this->generateRandomString());
// encode the plain password
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$this->getParameter('app.generic_password')
)
);
}else{
$form->addError(new FormError('Veuillez renseigner votre adresse email professionnelle.'));
return $this->render('registration/register_unsecure.html.twig', [
'registrationForm' => $form->createView(),
'locations' => $locations,
'subLocations' => $subLocations,
'client' => $client,
'jobs' => $jobs,
'hiddenPassword' => $this->getParameter('app.generic_password')
]);
}
}else{
$user->setIsActive(true);
$user->setAvatar($avatar);
$user->setClient($client);
$user->setCreatedAt(new Datetime());
$user->setModifiedAt(new Datetime());
$user->setIsVerified(true);
$user->setSalt($this->generateRandomString());
// encode the plain password
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$this->getParameter('app.generic_password')
)
);
}
}
$entityManager->persist($user);
$entityManager->flush();
$welcomeEmail = (new TemplatedEmail())
->context([
'client' => $client
])
->from(new Address('no-reply@avisea.net', 'Ween'))
->to($user->getEmail())
->subject('Bienvenue sur Ween')
->htmlTemplate('email/welcome.html.twig')
;
$mailer->send($welcomeEmail);
if($secureClientProducts === true){
$authenticator->authenticateUser(
$user,
$loginAuthenticatorUnsecure,
$request)
;
return $this->redirectToRoute('app_set_password', [], Response::HTTP_SEE_OTHER);
}else{
return $authenticator->authenticateUser(
$user,
$loginAuthenticator,
$request)
;
}
}
$content = $this->renderView('registration/register_unsecure.html.twig', [
'registrationForm' => $form->createView(),
'locations' => $locations,
'subLocations' => $subLocations,
'jobs' => $jobs,
'client' => $client,
'hiddenPassword' => $this->getParameter('app.generic_password')
]);
$viewWithCookie = $this->setCookie($client->getSlug(), $content);
return $viewWithCookie;
}
}
/**
* @Route("/verify/email", name="app_verify_email")
*/
public function verifyUserEmail(Request $request, TranslatorInterface $translator, UserRepository $userRepository): Response
{
$id = $request->get('id');
if (null === $id) {
return $this->redirectToRoute('app_register', array('client' => $request->attributes->get('client'), 'salt' => $request->attributes->get('salt')));
}
$user = $userRepository->find($id);
if (null === $user) {
return $this->redirectToRoute('app_register', array('client' => $request->attributes->get('client'), 'salt' => $request->attributes->get('salt')));
}
// validate email confirmation link, sets User::isVerified=true and persists
try {
$this->emailVerifier->handleEmailConfirmation($request, $user);
} catch (VerifyEmailExceptionInterface $exception) {
$this->addFlash('verify_email_error', $translator->trans($exception->getReason(), [], 'VerifyEmailBundle'));
return $this->redirectToRoute('app_register');
}
// @TODO Change the redirect on success and handle or remove the flash message in your templates
$this->addFlash('success', 'Votre email a été vérifié.');
return $this->redirectToRoute('app_login', array('clientSlug' => $user->getClient()->getSlug(), 'clientSalt' => $user->getClient()->getSalt()));
}
public function generateRandomString($length = 3) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[random_int(0, $charactersLength - 1)];
}
return $randomString;
}
public function setCookie($clientSlug, $content){
switch ($_ENV['ACTUAL_ENV']) {
case 'local':
$clientSlugCookie = new Cookie(
'clientSlug',
$clientSlug,
strtotime('+1 year'),
'/',
'plateform.localhost',
true,
true
);
break;
case 'demo':
$clientSlugCookie = new Cookie(
'clientSlug',
$clientSlug,
strtotime('+1 year'),
'/',
'demo.plateform.jobinlive.fr',
true,
true
);
break;
case 'preprod':
$clientSlugCookie = new Cookie(
'clientSlug',
$clientSlug,
strtotime('+1 year'),
'/',
'preprod.plateform.jobinlive.fr',
true,
true
);
break;
case 'prod':
$clientSlugCookie = new Cookie(
'clientSlug',
$clientSlug,
strtotime('+1 year'),
'/',
'app-ween.fr',
true,
true
);
break;
}
$response = new Response();
$response->setContent($content);
$response->headers->setCookie($clientSlugCookie);
return $response;
}
}