<?php
namespace App\Controller;
use App\Entity\Address;
use App\Entity\Farm;
use App\Entity\FarmProducer;
use App\Entity\Organization;
use App\Entity\Producer;
use App\Entity\Profile;
use App\Entity\User;
use App\Form\CheckUserType;
use App\Form\FarmType;
use App\Form\OrganizationType;
use App\Form\ProducerType;
use App\Form\ProfileType;
use App\Form\UserType;
use App\Form\PasswordType;
use App\Form\RecaptchaType;
use App\Form\RecoverPasswordType;
use App\Repository\AddressRepository;
use App\Repository\UserRepository;
use App\Service\EmailService;
use App\Service\TokenGenerator;
use App\Service\UserService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Karser\Recaptcha3Bundle\Validator\Constraints\Recaptcha3Validator;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\Mime\Email;
use Twig\Environment;
class SecurityController extends AbstractController
{
public $recaptcha;
private $translator;
private $tokenGenerator;
public function __construct(TranslatorInterface $translator, TokenGenerator $tokenGenerator)
{
$this->translator = $translator;
$this->tokenGenerator = $tokenGenerator;
}
/**
* @Route("/login", name="app_login")
*/
public function login(AuthenticationUtils $authenticationUtils, UserRepository $userRepository): Response
{
$error = $authenticationUtils->getLastAuthenticationError();
$lastUsername = $authenticationUtils->getLastUsername();
$email = trim($lastUsername ?? '');
$user = null;
if ($email) {
$user = $userRepository->createQueryBuilder('u')
->where('LOWER(u.email) = :email')
->setParameter('email', mb_strtolower($email))
->getQuery()
->getOneOrNullResult();
}
if ($user && $this->isGranted('ROLE_USER')) {
return $this->redirectToRoute('app_dashboard');
}
return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
/**
* @Route("/logout", name="app_logout")
*/
public function logout()
{
throw new \Exception('This method can be blank - it will be intercepted by the logout key on your firewall');
}
/**
* @Route("/register", name="app_register")
*/
public function register(
Request $request,
UserService $userService,
AddressRepository $addressRepository,
Recaptcha3Validator $recaptcha3Validator,
EmailService $emailService,
Environment $twig,
UserPasswordHasherInterface $userPasswordHasher
): Response
{
$em = $this->getDoctrine()->getManager();
$user = new User;
$userForm = $this->createForm(UserType::class, $user);
$userForm->handleRequest($request);
$producer = new Producer;
$producerForm = $this->createForm(ProducerType::class, $producer);
$producerForm->handleRequest($request);
$organization = new Organization;
$organizationForm = $this->createForm(OrganizationType::class, $organization);
$organizationForm->handleRequest($request);
$farm = new Farm;
$farmForm = $this->createForm(FarmType::class, $farm);
$farmForm->handleRequest($request);
$profile = new Profile();
$profileForm = $this->createForm(ProfileType::class, $profile);
$profileForm->handleRequest($request);
$passwordForm = $this->createForm(PasswordType::class, $user);
$passwordForm->handleRequest($request);
$recaptchaForm = $this->createForm(RecaptchaType::class, $user);
$recaptchaForm->handleRequest($request);
// dd( $recaptcha3Validator );
// $score = $recaptcha3Validator->getLastResponse()->getScore();
if ( $userForm->isSubmitted()
and $userForm->isValid()
and $organizationForm->isValid()
and $producerForm->isValid()
and $farmForm->isValid()
and $profileForm->isValid()
and $recaptchaForm->isValid()
and $passwordForm->isValid())
{
$producer->setUser($user);
$producer->setOrganization($organization);
/* buscamos entonces por Google Id */
/* en producer */
$addressGid = $producerForm->get('address')->getData();
if ( ! $address = $addressRepository->findOneBy(['location' => $addressGid]) ) {
$address = new Address();
$address->setLocation( $addressGid );
$address->setAddress( $addressGid );
$em->persist( $address );
/* DEBUG: muy ineficiente arreglar */
}
$producer->setAddress( $address );
/* en organization */
$addressGid = $organizationForm->get('address')->getData();
if ( ! ( $address = $addressRepository->findOneBy(['location' => $addressGid]) ) ) {
$address = new Address();
$address->setLocation( $addressGid );
$address->setAddress( $addressGid );
$em->persist( $address );
/* DEBUG: muy ineficiente arreglar */
}
$organization->setAddress( $address );
/* en farm */
$addressGid = $farmForm->get('address')->getData();
if ( ! ( $address = $addressRepository->findOneBy(['location' => $addressGid]) ) ) {
$address = new Address();
$address->setLocation( $addressGid );
$address->setAddress( $addressGid );
$em->persist( $address );
/* DEBUG: muy ineficiente arreglar */
}
$farm->setAddress( $address );
$farm->setOrganization($organization);
$farm->setProducer($producer);
$farmProducer = new FarmProducer();
$farmProducer->setFarm( $farm );
$farmProducer->setProducer( $producer );
$farm->addFarmProducer($farmProducer);
$userFormOrganization = $userForm->has('organization')
? $userForm->get('organization')->getData()
: null;
if (!$userFormOrganization || !$organization) {
$this->addFlash('error', "Error al crear el usuario: es necesario que el usuario tenga una organización" );
return $this->redirectToRoute('app_register');
}
$user->setOrganization($userFormOrganization ?? $organization);
$user->setRoles(['ROLE_USER', 'ROLE_MANAGER']);
$user->setUserType($organizationForm->get('userType')->getData());
$hashedPassword = $userPasswordHasher->hashPassword($user, $user->getPassword());
$user->setPassword($hashedPassword);
$profile->setDefaultAnimalSpecie($profileForm->get('defaultAnimalSpecie')->getData());
$fullName = $profile->getFullName();
if ( $user->isIsOrganization() ) {
$organization->setName( $fullName );
$organization->setBusinessName( $fullName );
}
if ( $organization->isIsProducer() ) {
$name = $organization->getName();
$businessName = $organization->getBusinessName();
$address = $organization->getAddress();
$cuit = $organization->getCuit();
$phone = $organization->getPhone();
$producer->setName( $name );
$producer->setSurname( '' );
$producer->setBusinessName( $businessName );
$producer->setAddress( $address );
$producer->setCuit( $cuit );
$producer->setPhone( $phone );
}
$token = $this->tokenGenerator->generateToken();
$user->setConfirmationToken( $token );
/* todos los persists, de haber un nuevo objeto agregarlo aca */
foreach( [$profile, $farm, $farmProducer, $organization, $producer, $user ] as $obj ) {
$em->persist( $obj );
}
$em->flush();
$sendEmail = false;
$automaticRegistration = false;
/* para debug sin mandar email */
/* se usa para que muestre el email en lugar de mandarlo */
if ( $automaticRegistration ) {
$email = new Email();
$content = $twig->render('emails/registration.html.twig', [
'email' => $email,
'user' => $user,
'token' => $token
]);
if ( $sendEmail ) {
return new Response( $emailService->sendRegistrationToken($user, $content) );
}
} else {
$content = $twig->render('emails/manual_registration.html.twig');
}
return new Response( $content );
}
/* return response */
return $this->render('security/register.html.twig', [
'user' => $user,
'userForm' => $userForm->createView(),
'producerForm' => $producerForm->createView(),
'organizationForm' => $organizationForm->createView(),
'farmForm' => $farmForm->createView(),
'profileForm' => $profileForm->createView(),
'passwordForm' => $passwordForm->createView(),
'recaptchaForm' => $recaptchaForm->createView(),
]);
}
/**
* @Route("/registration_acceptance/{token}", name="app_registration_acceptance", methods={"GET"})
*/
public function registrationAcceptance( UserRepository $userRepository, $token)
{
$user = $userRepository->findOneBy(['confirmationToken' => $token]);
if ( $user && $token === $user->getConfirmationToken())
{
$user->setEnabled( true );
$em = $this->getDoctrine()->getManager();
$em->persist($user);
$em->flush();
/* esto hace que entre directamente, por ahora no
*
return $guardAuthenticatorHandler->authenticateUserAndHandleSuccess(
$user,
$request,
$authenticator,
'main'
);
*/
}
return $this->render('security/registration_success.html.twig', [
'user' => $user,
]);
}
/**
* @Route("/password_reset", name="app_password_reset_request", methods={"GET","POST"})
*/
public function passwordResetRequest(Request $request, UserService $userService, EmailService $emailService, TokenGenerator $tokenGenerator): Response
{
$form = $this->createForm(CheckUserType::class);
$form->handleRequest($request);
$passwordForm = $this->createForm(PasswordType::class);
$passwordForm->handleRequest($request);
if ( $form->isSubmitted() && $form->isValid()) {
$user = $userService->findOneBy(array('email' => $form->getData()['email']));
if ($user) {
$userService->update($user);
$emailService->sendPasswordRequest($user);
$this->addFlash('success',$this->translator->trans('Password.resetPasswordEmail') . $user->getEmail() );
return $this->redirectToRoute('app_login');
// para probar sin email
/* return $this->render('emails/password_reset_request.html.twig', [
'userForm' => $userForm->createView(),
'message' => "Se ha enviado un correo a " . $user->getEmail(),
'user' => $user,
'token' => $user->getConfirmationToken()
]);*/
} else {
$form->addError(new FormError('No se encontró usuario'));
}
}
return $this->render('security/password_reset_request.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/password_reset/{token}", name="app_password_reset_confirm", )
*/
public function passwordReset(Request $request, $token, UserService $userService, UserPasswordHasherInterface $passwordHasher): Response
{
/** @var User $user */
$user = $userService->findUserByConfirmationToken($token);
if (!$user) {
$checkUserForm = $this->createForm(CheckUserType::class);
$checkUserForm->addError(new FormError('userNotFound'));
return $this->render('security/password_reset_request.html.twig', array(
'form' => $checkUserForm->createView(),
));
}
$form = $this->createForm(PasswordType::class);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if($form->isValid()) {
$newEncodedPassword = $passwordHasher->hashPassword($user, $form->get('password')->getData());
$user->setPassword($newEncodedPassword);
$userService->update($user);
$this->addFlash('success', $this->translator->trans('Password.resetSuccess'));
return $this->redirectToRoute('app_login');
}
else {
$this->addFlash('error', $this->translator->trans('Password.resetError'));
}
}
return $this->render('security/password_reset_confirm.html.twig', array(
'form' => $form->createView(),
));
}
/**
* @Route("/password_reset_success", name="app_password_reset", methods={"POST"})
*/
public function passwordResetSuccess(Request $request, UserPasswordHasherInterface $hasher, UserService $userService): Response
{
$newPassword = $request->get('password');
$token = $request->get('token');
/** @var User $user */
$user = $userService->findUserByConfirmationToken($token);
$user->setPassword($hasher->hashPassword($user, $newPassword));
$user->setConfirmationToken(null);
$user->setPasswordRequestedAt(null);
$this->getDoctrine()->getManager()->flush();
return $this->render('security/password_reset_success.html.twig', []);
}
}