<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Mime\MimeTypes;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use App\Form\Type\UserType;
use App\Entity\Structure;
use App\Entity\Firm;
use App\Entity\Attachment;
use App\Entity\Activation;
use App\Entity\User;
use App\Repository\UserRepository;
use App\Security\Voter;
use App\Security\Roles;
use App\Security\RoleSwitcher;
use App\Service\TimetableManager;
use App\Exception\UserActivationException;
class DefaultController extends VicinAppController
{
/**
* @Route("/", name="index")
*/
public function index(Request $request)
{
$roleSwitcher = $request->getSession()->get('roleSwitcher');
if ($roleSwitcher !== null) {
$active = $roleSwitcher->getActiveRole();
if ($active !== null) {
switch($active) {
case RoleSwitcher::SUPER_ADMIN: return new RedirectResponse($this->generateUrl('superAdminFirms'));
case RoleSwitcher::ADMIN: return new RedirectResponse($this->generateUrl('adminStructures'));
case RoleSwitcher::USER: return new RedirectResponse($this->generateUrl('userStructures'));
}
}
}
if ($this->isGranted('ROLE_SUPER_ADMIN')) {
return new RedirectResponse($this->generateUrl('superAdminFirms'));
}
if ($this->isGranted('ROLE_ADMIN')) {
return new RedirectResponse($this->generateUrl('adminStructures'));
}
if ($this->isGranted('ROLE_USER')) {
return new RedirectResponse($this->generateUrl('userStructures'));
}
return $this->render('index.html.twig');
}
/**
* @Route("/clearSession", name="clearSession")
*/
public function clearSession(Request $request)
{
$request->getSession()->set('newTimetable',null);
}
/**
* @Route("/structures", name="structures")
*/
public function structures()
{
$structures = $this->doctrine->getRepository(Structure::class)->findAll();
return $this->render('default/structures.html.twig', array('entities'=>$structures));
}
/**
* @Route("/firms", name="firms")
*/
public function firms()
{
$structures = $this->doctrine->getRepository(Firm::class)->findAll();
return $this->render('default/firms.html.twig', array('entities'=>$structures));
}
/**
* @Route("/downloadAttachment/{id}", name="downloadAttachment", requirements={"id" = "\d+"})
*/
public function downloadAttachment(Request $request, Attachment $attachment, $id)
{
$this->denyAccessUnlessGranted(Voter::ATTACHMENT, $attachment);
$response = new Response(stream_get_contents($attachment->getContent()));
$mime = MimeTypes::getDefault()->getMimeTypes($attachment->getType());
if (! empty($mime)) $response->headers->set('Content-Type',$mime[0]);
$filename = $attachment->getFullName();
$response->headers->set('Content-Disposition',"attachment; filename=\"{$filename}\"");
$response->headers->set('Content-Length',$attachment->getSize());
return $response;
}
/**
* @Route("/activateUser/{token}", name="activateUser")
*/
public function activateUser(Request $request, $token, Activation $activation, UserPasswordHasherInterface $passwordHasher, TimetableManager $ttManager)
{
try {
if ($activation->isActivated()) throw new UserActivationException("L'attivazione è già avvenuta");
$user = $this->doctrine->getRepository(User::class)->findOneByEmail($activation->getEmail());
if ($user !== null) throw new UserActivationException("L'utente è già esistente");
$user = new User();
if ($activation->getHousingUnit() !== null) {
$user->setAddress($activation->getHousingUnit()->getAddress());
$user->setZipCode($activation->getHousingUnit()->getZipCode());
$user->setCity($activation->getHousingUnit()->getCity());
$user->setProvince($activation->getHousingUnit()->getProvince());
}
$user->setEmail($activation->getEmail());
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user->setEmail($activation->getEmail()); //just to be sure it's not been changed by user
$user->setActive(true);
$user->setAlerts(true);
if ($user->getPrivacyCheck()) $user->setPrivacy(new \DateTime());
$hashedPassword = $passwordHasher->hashPassword($user, $user->getPlainPassword());
$user->setPassword($hashedPassword);
$user->setRoles([Roles::USER]); //overwritten to admin if there is at least one activation as admin(*)
$em = $this->doctrine->getManager();
//$userRepo = $em->getRepository(User::class);
$em->persist($user);
$em->flush(); //I need to flush before adding the user to timetables otherwise he won't have an id
$this->handleUserActivation($user, $activation, $ttManager);
// check if more activations were present for same user
$more = $em->getRepository(Activation::class)->findByEmail($activation->getEmail());
foreach($more as $act) {
if ($act === $activation) continue; //skip the same one!
$this->handleUserActivation($user, $act, $ttManager);
}
$em->flush();
$request->getSession($request)->getFlashBag()->add('success', 'I dati sono stati salvati, ora puoi fare login con email e password');
return new RedirectResponse($this->generateUrl('app_login'));
}
} catch (UserActivationException $ex) {
$request->getSession($request)->getFlashBag()->add('warning', $ex->getMessage());
return new RedirectResponse($this->generateUrl('index'));
}
//$user->setPrivacyCheck(false); NON FUNZIONA!!
return $this->render('default/activateUser1.html.twig', array('form' => $form->createView(), 'email'=>$user->getEmail()));
}
private function handleUserActivation(User $user, Activation $activation, TimetableManager $ttManager) {
if ($activation->isAdmin()) {
$user->setRoles([Roles::ADMIN]); //see before (*)
/*
* WARNING: there may be more than one activations as admin, for different firms.
* As the first activation processed is the one the user is answering to, this one will be kept as the good one - if it is an admin activation
* If the user answered to a user activation and there are some admin activations, one of them will be randomly kept
*/
if ($user->getFirm() === null) {
$user->setFirm($activation->getFirm());
//if it's first admin for firm, he must be set as owner
$admins = $activation->getFirm()->getUsers();
if ($admins->isEmpty()) {
$user->setRoles([Roles::FIRM_OWNER]);
}
}
} else {
if ($activation->getOwner()) {
$activation->getHousingUnit()->addOwner($user);
$ttManager->newOwner($activation->getHousingUnit()->getStructure(), $user);
}
if ($activation->getTenant()) {
$activation->getHousingUnit()->addTenant($user);
$ttManager->newTenant($activation->getHousingUnit()->getStructure(), $user);
}
$activation->getFirm()->addLinkedUser($user);
}
$activation->setConfirmation(new \DateTime());
}
/**
* @Route("/reactivateUser/{token}", name="reactivateUser")
*/
public function reactivateUser(Request $request, $token)
{
$user = $this->doctrine->getRepository(User::class)->findOneByToken($token);
if ($user === null) throw new \Exception("Token non trovato");
$user->setActive(true);
$user->setToken(null);
$this->doctrine->getManager()->flush();
$this->addFlash('success', 'L\'account è stato riattivato, puoi fare login con email e password');
return new RedirectResponse($this->generateUrl('app_login'));
}
/**
* @Route("/inactiveUser/", name="inactiveUser")
*/
public function inactiveUser()
{
return $this->render('errors/inactiveUser.html.twig');
}
/**
* @Route("/endImpersonate/", name="endImpersonate")
*/
public function endImpersonate(Request $request)
{
$request->getSession()->set('roleSwitcher',null);
return new RedirectResponse($this->generateUrl('index',['_switch_user' => '_exit']));
}
}