<?php
namespace App\Controller;
use App\Entity\Alert;
use App\Entity\Availabilities;
use App\Entity\EnumValues;
use App\Entity\FavoriteOffer;
use App\Entity\Guarantor;
use App\Entity\MD5HashCheck;
use App\Entity\MailingSearch;
use App\Entity\Offer;
use App\Entity\OfferImage;
use App\Entity\OfferTenantApplication;
use App\Entity\Page;
use App\Entity\User;
use App\Entity\WorkStatus;
use App\Form\ModalOfferType;
use App\Form\OfferType;
use App\Form\RegisterFormType;
use App\Form\SearchFrontFormType;
use App\Form\SignConventionType;
use App\Form\UpdatePasswordType;
use App\Repository\AgencyRepository;
use App\Repository\EnumValuesRepository;
use App\Repository\FavoriteOfferRepository;
use App\Repository\MailingSearchRepository;
use App\Repository\OfferRepository;
use App\Repository\OfferTenantApplicationRepository;
use App\Repository\UserRepository;
use App\Security\LoginFormAuthenticator;
use App\Service\CustomMailer;
use App\Service\CustomPdfGenerator;
use App\Service\FormLabelHydrater;
use App\Service\PhoneNumberHelper;
use App\Service\SearchParameterChecker;
use App\Service\Securizer;
use App\Service\SignConvention;
use Doctrine\DBAL\DBALException;
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\FrameworkBundle\Controller\createFormBuilder;
use Symfony\Bundle\FrameworkBundle\Controller\denyAccessUnlessGranted;
use Symfony\Bundle\FrameworkBundle\Controller\redirectToRoute;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\File\Exception\FileException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Type;
class BaseController extends AbstractController
{
public $parkingType;
public $buildingType;
public $constructionType;
public $nbrRooms;
public function __construct(FormLabelHydrater $hydrater, EnumValuesRepository $enumrepo)
{
$labels = $hydrater->getOfferLabels();
$this->nbrRooms = $enumrepo->findOneBy(['name' => 'nbrRooms'])->getData();
$this->buildingType = array_flip($labels['buildingType']);
$this->parkingType = array_flip($labels['parkingType']);
$this->constructionType = array_flip($labels['constructionType']);
}
/**
* @Route("/", name="homepage")
*/
public function index(OfferRepository $repo, Request $request)
{
$sums = $repo->getNbrOffersByDepartments();
$latests = $repo->getLatest();
$congratulations = $request->get('congratulations')??null;
//$buildingType = $enumrepo->findOneBy(['name' => 'buildingType'])->getData();
//$constructionType = $enumrepo->findOneBy(['name' => 'constructionType'])->getData();
return $this->render('base/index.html.twig', [
'controller_name' => 'BaseController',
'sums' => $sums,
'latests' => $latests,
'nbrRooms' => $this->nbrRooms,
'buildingType' => $this->buildingType,
'constructionType' => $this->constructionType,
'total' => array_sum($sums),
'show_free_estimate_modal' => true,
'congratulations' => $congratulations??null,
]);
}
/**
* @Route("/annonces/departement/{department}", name="list_offers_by_department")
*/
public function listOffersByDepartment($department = null, OfferRepository $repo, EnumValuesRepository $enumrepo)
{
if ($department == null && !in_array($department, ['75', '77', '78', '91', '92', '93', '94', '95']))
{
return $this->redirectToRoute('homepage');
}
$results = $repo->searchFrontSide(['departments' => [$department]]);
$latest = $repo->getLatest();
$sums = $repo->getNbrOffersByDepartments();
$buildingType = $enumrepo->findOneBy(['name' => 'buildingType'])->getData();
$nbrRoom = $enumrepo->findOneBy(['name' => 'nbrRooms'])->getData();
$constructionType = $enumrepo->findOneBy(['name' => 'constructionType'])->getData();
return $this->render('base/search_results.html.twig', [
'controller_name' => 'BaseController',
'results' => $results ?? [],
'latests' => $latest,
'sums' => $sums,
'buildingType' => $this->buildingType,
'nbrRoom' => $this->nbrRooms,
'departments' => $department,
'constructionType' => $this->constructionType,
]);
}
/**
* @Route("/resultats-recherche", name="search_results")
*/
public function searchResults(Request $request, EntityManagerInterface $manager, OfferRepository $repo, SessionInterface $session, EnumValuesRepository $enumrepo)
{
if ($session->has('searchParameters'))
{
$parameters = $session->get('searchParameters');
$session->remove('searchParameters');
}
$user = $this->getUser();
$results = $repo->searchFrontSide($parameters ?? null, FALSE, $user ? $user->getId() : null);
$buildingType = $enumrepo->findOneBy(['name' => 'buildingType'])->getData();
$nbrRoom = $enumrepo->findOneBy(['name' => 'nbrRooms'])->getData();
$constructionType = $enumrepo->findOneBy(['name' => 'constructionType'])->getData();
return $this->render('base/search_results.html.twig', [
'controller_name' => 'BaseController',
'buildingType' => $this->buildingType,
'buildingTypeParameter' => $parameters['buildingType'] ?? null,
'departments' => $parameters['departments'] ?? null,
'price' => $parameters['price'] ?? null,
'surface' => $parameters['surface'] ?? null,
'nbrRooms' => $parameters['nbrRooms'] ?? null,
'nbrRoom' => $this->nbrRooms,
'constructionType' => $this->constructionType,
'results' => $results ?? [],
]);
}
/**
* @Route("/annonce/{slug}", name="view_offer_profile")
public function viewOffer(Offer $offer = null)
{
if ($offer == null)
{
$this->addFlash('danger', 'Cette annonce n\'est plus disponible !');
return $this->redirectToRoute('homepage');
}
$user = $offer->getUser();
$values = $valuesRepo->findAllEnums();
// see App\Security\Voter\CheckMethodsAccessVoter
$this->denyAccessUnlessGranted('OWNER_OR_ADMIN', $user);
return $this->render('offer/view_offer.html.twig', [
'offer' => $offer,
'values' => $values,
]
);
} */
/**
* @Route("/save-parameters", name="save_parameters")
*/
public function saveParameters(Request $request, SessionInterface $session, SearchParameterChecker $checker)
{
// get search parameters from homepage, check it, put it in session, and redirect to search page
if ($request->isXmlHttpRequest() && isset($request->request))
{
$search = $request->request->get('searchParameters');
// lazy & ugly solution, doesn't mind
$login_route = $request->request->get('login_route_plz') ?? false;
$path = $login_route ? $this->generateUrl('login') : $this->generateUrl('search_results');
$parameters = $checker->checkParameters($search);
// if search is empty, it's cool, we just send ok status to trigger the redirection
if (empty($parameters))
{
$session->remove('searchParameters');
return new JsonResponse(['status' => 'ok', 'path' => $path]);
}
$session->set('searchParameters', $parameters);
return new JsonResponse(['status' => 'ok', 'path' => $path]);
}
return new JsonResponse(['status' => 'ko', 'error' => 'Not xmlhttp']);
}
/**
* @Route("/save-offer-session", name="save_offer_session")
*/
public function saveOfferSession(Request $request, SessionInterface $session, SearchParameterChecker $checker)
{
// get search parameters from homepage, check it, put it in session, and redirect to search page
if ($request->isXmlHttpRequest() && isset($request->request))
{
$offerId = $request->request->get('offerId');
// lazy & ugly solution, doesn't mind
$login_route = $request->request->get('login_route_plz') ?? false;
$path = $this->generateUrl('login');
$session->set('offerId', $offerId);
return new JsonResponse(['status' => 'ok', 'path' => $path, 'offerId' => $offerId]);
}
return new JsonResponse(['status' => 'ko', 'error' => 'Not xmlhttp']);
}
/**
* @Route("/set_favorite_offer", name="set_favorite_offer")
*/
public function setFavoriteOffer(Request $request, EntityManagerInterface $manager, FavoriteOfferRepository $repo)
{
if ($request->isXmlHttpRequest() && isset($request->request))
{
// get data
$userId = $request->get('userId');
$offerId = $request->get('offerId');
$tenant = $this->getDoctrine()->getRepository(User::class)->find($userId);
if ($tenant == null || $offerId == null)
return new JsonResponse(['status' => 'ko', 'error' => 'Impossible de trouver cette offre ou cet utilisateur avec les informations spécifiées.']);
$favorite = $repo->findOneBy(['offerId' => $offerId, 'userId' => $userId]);
if ($favorite == null)
$manager->persist(new FavoriteOffer($offerId, $userId));
else
$manager->remove($favorite);
$manager->flush();
// return users, please let me die a week or two
return new JsonResponse(['status' => 'ok']);
// go and take urself something to eat in the kitchen. A fruit, ffs, stop the sugar
}
return new JsonResponse(['error' => 'Not xmlhttp']);
}
/**
* @Route("/get-search-results", name="get_search_results")
*/
public function getSearchResults(Request $request, EntityManagerInterface $manager, OfferRepository $repo, SessionInterface $session, SearchParameterChecker $checker, EnumValuesRepository $enumrepo)
{
$enumRepo = $this->getDoctrine()->getRepository(EnumValues::class);
$buildingType = $enumRepo->findOneBy(['name' => 'buildingType'])->getData();
$offerRepo = $this->getDoctrine()->getRepository(Offer::class);
if ($request->isXmlHttpRequest() && isset($request->request))
{
$search = $request->request->get('searchParameters');
$parameters = $checker->checkParameters($search);
$nbrRoom = $enumrepo->findOneBy(['name' => 'nbrRooms'])->getData();
$constructionType = $enumrepo->findOneBy(['name' => 'constructionType'])->getData();
$user = $this->getUser();
// if search is empty, it's cool, we just dump everything we got
if (empty($parameters))
{
$results = $offerRepo->searchFrontSide(null, FALSE, $user ? $user->getId() : null);
$html = $this->renderView('partials/search/_search_results_container.html.twig', [
'buildingType' => $this->buildingType,
'constructionType' => $this->constructionType,
'buildingTypeParameter' => null,
'departments' => null,
'price' => null,
'surface' => null,
'nbrRooms' => null,
'results' => $results,
'nbrRoom' => $this->nbrRooms,
]);
return new JsonResponse(['status' => 'ok', 'html' => $html]);
}
$results = $offerRepo->searchFrontSide($parameters, FALSE, $user ? $user->getId() : null);
$html = $this->renderView('partials/search/_search_results_container.html.twig', [
'buildingType' => $this->buildingType,
'constructionType' => $this->constructionType,
'buildingTypeParameter' => $parameters['buildingType'] ?? null,
'departments' => $parameters['departments'] ?? null,
'price' => $parameters['price'] ?? null,
'surface' => $parameters['surface'] ?? null,
'nbrRooms' => $parameters['nbrRooms'] ?? null,
'results' => $results ?? [],
'nbrRoom' => $this->nbrRooms,
]);
return new JsonResponse(['status' => 'ok', 'html' => $html, 'dump' => $results, 'data' => $parameters]);
}
return new JsonResponse(['status' => 'ko', 'error' => 'Not xmlhttp']);
}
/**
* @Route("/inscription", name="register")
*/
public function register(Request $request, EntityManagerInterface $manager, UserPasswordEncoderInterface $encoder, GuardAuthenticatorHandler $guardHandler, LoginFormAuthenticator $authenticator, CustomMailer $mailer, Securizer $securizer, UserRepository $repo)
{
$user = $this->getUser();
if ($user != null && $securizer->isGranted($user, 'ROLE_LANDLORD'))
return $this->redirectToRoute('landlord_profile', ['id' => $user->getId()]);
else if ($user != null && $securizer->isGranted($user, 'ROLE_TENANT'))
return $this->redirectToRoute('tenant_profile', ['id' => $user->getId()]);
else if ($user != null && $securizer->isGranted($user, 'ROLE_ADMIN'))
return $this->redirectToRoute('admin_home');
/*else if ($user != null && $user->isGranted('ROLE_TENANT'))
return $this->redirectToRoute('tenant_profile', ['id' => $user->getId()]);*/
$user = new User();
$formFactory = $this->get('form.factory');
$form = $this->createForm(RegisterFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
{
//$isTenant flag utilisé pour conditionner l'envoie de mail d'activation
$isTenant = false;
$role = $form->get('roles')->getData() ? array('ROLE_TENANT') : array('ROLE_LANDLORD');
$user->setRoles($role);
// if user is Tenant, he must give additional data
if ($form->get('roles')->getData())
{
$user->setWorkStatus(new WorkStatus());
$user->setGuarantor(new Guarantor());
//Activation du compte du locataire
$user->setActivated(true);
$isTenant = true;
}
$hash = $encoder->encodePassword($user, $user->getPassword());
$user->setPassword($hash);
$manager->persist($user);
$manager->flush();
//sending activation mail
$email = $user->getEmail();
$id = $user->getId();
$d = new \DateTime();
$hash = md5($email.$d->format('Y-m-d\TH:i:s.u'));
$newActChk = new MD5HashCheck($id, $hash);
$manager->persist($newActChk);
while ($repo->findOneBy(['token' => $hash]) != null)
{
$d = new \DateTime();
$hash = md5($email.$d->format('Y-m-d\TH:i:s.u'));
}
$user->setToken($hash);
$manager->persist($user);
$manager->persist(new Availabilities($user->getId(), []));
$manager->flush();
// sending mail only for landlord
$messageFlash="Compte créé avec succès ! ";
if (!$isTenant){
$mailer->sendActivationLink($hash, $id, $email);
$messageFlash .= "Un email d'activation vous a été envoyé sur $email !";
}
$this->addFlash('success', $messageFlash);
// auto login after register success
return $guardHandler->authenticateUserAndHandleSuccess($user, $request, $authenticator, 'main');
}
return $this->render('register.html.twig', [
'controller_name' => 'BaseController',
'form' => $form->createView(),
]);
}
/**
* @Route("/changement-de-mot-de-passe/id={id}", name="update_password")
*/
public function updatePassword(User $user = null, Request $request, EntityManagerInterface $manager, UserPasswordEncoderInterface $encoder, Securizer $securizer)
{
if ($user == null)
return $this->redirectToRoute('homepage');
// see App\Security\Voter\CheckMethodsAccessVoter
$this->denyAccessUnlessGranted('OWNER_OR_ADMIN', $user);
$logged = $this->getUser();
// if we're trying to modify an admin password that is NOT our account and we are NOT super_admin, we fuck off
if ($securizer->isGranted($user, 'ROLE_ADMIN') && $securizer->isGranted($logged, 'ROLE_ADMIN_MASTER') && $user->getId() != $logged->getId())
{
$this->addFlash('danger', 'Vous n\'avez pas l\'autorité nécessaire pour cette opération !');
return $this->redirectToRoute('admin_homepage');
}
$form = $this->createForm(UpdatePasswordType::class, null);
$form->handleRequest($request);
$redirectPath = null;
$success = true;
if ($form->isSubmitted() && $form->isValid())
{
// if the old password is not valid, we create an error on this field and f*** off
if (!$encoder->isPasswordValid($user, $form['oldPassword']->getData()))
{
$form['oldPassword']->addError(new FormError('Mot de passe incorrect.'));
$success = false;
}
$password = $form['newPassword']->getData();
if (strcmp($password, $form['oldPassword']->getData()) == 0)
{
$form['newPassword']->addError(new FormError('Le nouveau mot de passe ne peut pas être identique à l\'ancien.'));
$success = false;
}
// password must contain lowercase, uppercase and number
if (!preg_match('@[A-Z]@', $password) || !preg_match('@[a-z]@', $password) || !preg_match('@[0-9]@', $password) || strlen($password) < 10)
{
$form['newPassword']->addError(new FormError('Le mot de passe doit avoir au minimum 10 caractères et contenir au moins une minuscule, une majuscule et un chiffre.'));
$success = false;
}
if ($success)
{
$newPassword = $encoder->encodePassword($user, $password);
$user->setPassword($newPassword);
$manager->persist($user);
$manager->flush();
}
$this->addFlash('success', 'Votre mot de passe a été modifié.');
if ($securizer->isGranted($user, 'ROLE_LANDLORD'))
$redirectPath = 'landlord_profile';
else if ($securizer->isGranted($user, 'ROLE_TENANT'))
$redirectPath = 'tenant_profile';
else if ($securizer->isGranted($user, 'ROLE_ADMIN'))
$redirectPath = 'admin_homepage';
}
if ($success == true && $redirectPath != null)
return $this->redirectToRoute($redirectPath, ['id' => $user->getId()]);
return $this->render('update_password.html.twig', [
'form' => $form->createView(),
'userId' => $user->getId(),
'user' => $user,
]);
}
/**
* @Route("/changement-de-mot-de-passe/key={hash}", name="reset_password")
* @ParamConverter("key", options={"mapping"={"hash"="hash"}})
*/
public function resetPassword(MD5HashCheck $key = null, Request $request, EntityManagerInterface $manager, UserPasswordEncoderInterface $encoder, UserRepository $repo)
{
$date = new \Datetime();
// key must exists, be 7 days old MAX and user must exists
if ($key == null || date_diff($key->getCreationDate(), $date)->format('d') > 7 || ($user = $repo->findOneBy(['id' => $key->getUserId()])) == null)
{
$this->addFlash('danger', 'Cet lien n\'est plus valide (plus de sept jours).');
return $this->$this->redirectToRoute('homepage');
}
// todo create a form with repetedtype, check it, hash it, update user, done
$form = $this->createForm(UpdatePasswordType::class, null, ['reset' => true]);
$form->handleRequest($request);
$redirectPath = null;
if ($form->isSubmitted() && $form->isValid())
{
$password = $form['newPassword']->getData();
// password must contain lowercase, uppercase and number
//if (!preg_match('@[A-Z]@', $password) || !preg_match('@[a-z]@', $password) || !preg_match('@[0-9]@', $password) || strlen($password) < 10)
if (strlen($password) < 10)
{
$form['newPassword']->addError(new FormError('Le mot de passe doit avoir au minimum 10 caractères.'));
return $this->render('reset_password.html.twig', ['form' => $form->createView()]);
}
$newPassword = $encoder->encodePassword($user, $password);
$user->setPassword($newPassword);
$manager->persist($user);
$manager->flush();
$this->addFlash('success', 'Votre mot de passe a été modifié.');
$redirectPath = 'login';
}
if ($redirectPath != null)
return $this->redirectToRoute($redirectPath);
return $this->render('reset_password.html.twig', [
'form' => $form->createView()
]);
}
/**
* @Route("/demande-changement-mot-de-passe", name="reset_password_request")
*/
public function sendResetPasswordMail(Request $request, UserRepository $repo, EntityManagerInterface $manager, CustomMailer $mailer)
{
$form = $this->createFormBuilder()
->add('email', EmailType::class, [
'label' => 'Renseignez votre adresse email',
'constraints' => [
new NotBlank([
'message' => "Veuillez renseigner votre email."
]),
new Email([
'mode' => 'html5',
'message' => "L'email {{ value }} n'est pas un email valide.",
]),
],
'required' => true,
'attr' => array('placeholder' => 'Adresse email*'),
])
->getForm();
$success = false;
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
{
$email = $form['email']->getData();
// wether or not the email was in our database, we send a happy message to fool our enemies.
$success = true;
$this->addFlash('success', 'Un email de réinitialisation vous a été envoyé sur '.$email.' !');
// password must contain lowercase, uppercase and number
if (($user = $repo->findOneBy(['email' => $email])) != null)
{
$d = new \DateTime();
$hash = md5($email.$d->format('Y-m-d\TH:i:s.u'));
$newActChk = new MD5HashCheck($user->getId(), $hash);
$manager->persist($newActChk);
$manager->flush();
// sending mail
//$mail = new CustomMailer($mailer, $this->get('twig'));
$mailer->sendResetPasswordLink($hash, $email);
}
}
if ($success)
return $this->redirectToRoute('login');
return $this->render('email_form.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/demande_activation/id={id}", name="activation_request")
*/
public function sendActivationMail(User $user = null, EntityManagerInterface $manager, CustomMailer $mailer, Securizer $securizer)
{
if ($user == null)
return $this->redirectToRoute('homepage');
// see App\Security\Voter\CheckMethodsAccessVoter
$this->denyAccessUnlessGranted('OWNER_OR_ADMIN', $user);
$id = $user->getId();
$email = $user->getEmail();
$d = new \DateTime();
$hash = md5($email.$d->format('Y-m-d\TH:i:s.u'));
$newActChk = new MD5HashCheck($id, $hash);
$manager->persist($newActChk);
$manager->flush();
// sending mail
$mailer->sendActivationLink($hash, $id, $email);
$this->addFlash('success', 'Un email d\'activation vous a été envoyé sur '.$email.' !');
if ($securizer->isGranted($user, 'ROLE_LANDLORD'))
return $this->redirectToRoute('landlord_profile', ['id' => $user->getId()]);
return $this->redirectToRoute('tenant_profile', ['id' => $user->getId()]);
}
/**
* @Route("/activation/key={hash}", name="activate_user")
* @ParamConverter("activationKey", options={"mapping"={"hash"="hash"}})
*/
public function activateUser(MD5HashCheck $activationKey = null, EntityManagerInterface $manager)
{
if ($activationKey == null)
{
$this->addFlash('danger', 'Cette clef n\'est pas valide.');
return $this->$this->redirectToRoute('homepage');
}
$user = $this->getDoctrine()->getRepository(User::class)->findOneById($activationKey->getUserId());
if ($user != null && $user->getActivated() != true)
{
$user->setActivated(true);
$manager->persist($user);
$manager->flush();
$this->addFlash('success', 'Votre profil a été activé !');
}
return $this->redirectToRoute('login');
}
/**
* @Route("/annonce/{slug}", name="view_offer_profile")
*/
public function viewOfferProfile(Offer $offer = null, EntityManagerInterface $manager, UserRepository $urepo, OfferRepository $orepo, SessionInterface $session, EnumValuesRepository $erepo, FavoriteOfferRepository $f, AgencyRepository $arepo)
{
if ($offer == null || $offer->getIsPublished() == false)
{
$this->addFlash('danger', 'Cette annonce n\'est plus disponible !');
return $this->redirectToRoute('homepage');
}
if ($session->has('offerId'))
$session->remove('offerId');
$nearest = $orepo->getNearest($offer->getDepartment(), $offer->getId());
$agency = $arepo->find($offer->getAgency());
$contractType = $erepo->findOneBy(['name' => 'contractType'])->getData();
$buildingType = $erepo->findOneBy(['name' => 'buildingType'])->getData();
$nbrRooms = $erepo->findOneBy(['name' => 'nbrRooms'])->getData();
$energyRating = $erepo->findOneBy(['name' => 'energyRating'])->getData();
$parkingType = $erepo->findOneBy(['name' => 'parkingType'])->getData();
$kitchenType = $erepo->findOneBy(['name' => 'kitchenType'])->getData();
$constructionType = $erepo->findOneBy(['name' => 'constructionType'])->getData();
$logged = $this->getUser();
$saved = $logged ? $f->findOneBy(['userId' => $logged->getId(), 'offerId' => $offer->getId()]) ? true : false : false;
return $this->render('base/view_offer_profile.html.twig', [
'offer' => $offer,
'nearest' => $nearest,
'contractType' => $contractType,
'buildingType' => $this->buildingType,
'nbrRooms' => $this->nbrRooms,
'energyRating' => $energyRating,
'parkingType' => $this->parkingType,
'kitchenType' => $kitchenType,
'constructionType' => $this->constructionType,
'saved' => $saved,
'agency' => $agency,
]
);
}
/**
* @Route("/visite/{md5slug}/{landlordId}", name="view_offer_profile_visit")
* @ParamConverter("landlord", options={"mapping"={"landlordId"="id"}})
*/
public function viewOfferProfileVisit(Offer $offer = null, User $landlord = null, EntityManagerInterface $manager, UserRepository $urepo, OfferRepository $orepo, EnumValuesRepository $erepo, AgencyRepository $arepo)
{
if ($offer == null || $offer->getIsPublished() == false)
{
$this->addFlash('danger', 'Cette annonce n\'est plus disponible !');
return $this->redirectToRoute('homepage');
}
if ($landlord != null && $landlord->getId() !== $offer->getUser()->getId())
{
$landlord = null;
}
$agency = $arepo->find($offer->getAgency());
$nearest = $orepo->getNearest($offer->getDepartment(), $offer->getId());
$contractType = $erepo->findOneBy(['name' => 'contractType'])->getData();
$buildingType = $erepo->findOneBy(['name' => 'buildingType'])->getData();
$nbrRooms = $erepo->findOneBy(['name' => 'nbrRooms'])->getData();
$energyRating = $erepo->findOneBy(['name' => 'energyRating'])->getData();
$parkingType = $erepo->findOneBy(['name' => 'parkingType'])->getData();
$kitchenType = $erepo->findOneBy(['name' => 'kitchenType'])->getData();
$constructionType = $erepo->findOneBy(['name' => 'constructionType'])->getData();
return $this->render('base/view_offer_profile_visit.html.twig', [
'agency' => $agency,
'offer' => $offer,
'nearest' => $nearest,
'contractType' => $contractType,
'buildingType' => $this->buildingType,
'nbrRooms' => $this->nbrRooms,
'energyRating' => $energyRating,
'parkingType' => $this->parkingType,
'kitchenType' => $kitchenType,
'constructionType' => $this->constructionType,
'landlord' => $landlord,
]
);
}
/**
* @Route("/page/{pageSlug}", name="page_display")
* @ParamConverter("page", options={"mapping"={"pageSlug"="slug"}})
*/
public function pageDisplay(Page $page = null)
{
if ($page == null)
throw $this->createNotFoundException('Cette page n\'existe pas.');
if ($page->getStatus() != 2 && !$this->isGranted('ROLE_ADMIN'))
return $this->redirectToRoute('homepage');
return $this->render($page->getTemplate().'.html.twig', [
'page' => $page,
'metadescription' => $page->getMetadescription(),
'title' => $page->getTitle(),
]);
}
function checkArray($array)
{
foreach($array as $value)
{
if(!is_int($value))
return false;
}
return true;
}
/**
* @Route("/create-mailing", name="create_mailing")
*/
public function createMailing(Request $request, EntityManagerInterface $manager, UserRepository $u, MailingSearchRepository $m, SessionInterface $session, SearchParameterChecker $checker, Securizer $securizer)
{
if ($request->isXmlHttpRequest() && isset($request->request))
{
// get data
// check data
$search = $request->request->get('searchParameters');
$parameters = $checker->checkParameters($search);
$session->set('searchParameters', $parameters);
$user = $this->getUser();
if ($user == null || !$securizer->isGranted($user, 'ROLE_TENANT'))
{
return new JsonResponse(['status' => 'ko', 'error' => 'login']);
}
$mailing = new MailingSearch();
$contractType = $parameters['contractType'];
$surface = $parameters['surface'];
$price = $parameters['price'];
$buildingType = $parameters['buildingType'] ?? null;
$nbrRooms = array_filter($parameters['nbrRooms'] ?? []);
$departments = $parameters['departments'] ?? null;
if (!empty($contractType) && is_int($contractType)) {
$mailing->setContractType($contractType);
}
if (!empty($price) && is_int($price)) {
$mailing->setPrice($price);
}
if (!empty($surface) && is_int($surface)) {
$mailing->setSurface($surface);
}
if (!empty($departments) && $this->checkArray($departments)) {
$mailing->setDepartments($departments);
}
if (!empty($nbrRooms) && $this->checkArray($nbrRooms)) {
$mailing->setNbrRooms($nbrRooms);
}
if (!empty($buildingType) && $this->checkArray($buildingType)) {
$mailing->setBuildingType($buildingType);
}
try {
$user->addMailing($mailing);
$manager->persist($user);
$manager->flush();
} catch (DBALException $e) {
return new JsonResponse(['status' => 'ko', 'error' => 'duplicate']);
}
return new JsonResponse(['status' => 'ok']);
}
return new JsonResponse(['status' => 'ko', 'error' => 'Not xmlhttp']);
}
/**
* @Route("/ajax-sign-conv/{id}", name="ajax_sign_conv")
*/
public function ajaxSignConvention(Offer $offer, SignConvention $signConventionService, Request $request)
{
if ($offer == null){
$this->addFlash('danger', "Cette annonce n'est plus disponible");
return $this->redirectToRoute('homepage');
}
$retour = $signConventionService->signConvention($offer, $request);
if (count($retour['erreur_bloquante']) > 0){
return $this->json(['status' => 'missingInfo2', 'errors' => $retour['erreur_bloquante']]);
}
if(isset($retour['errors']) && count($retour['errors'])>0){
foreach ($retour['errors'] as $error){
$this->addFlash($error['type'], $error['message']);
}
}
if($retour['status'] == 'success'){
$this->addFlash('success', 'Merci beaucoup 👍, vous venez de valider la convention de votre annonce avec succès 🎉 Nous allons des à présent, proposer votre bien à nos candidats et nous reviendrons vers vous pour l’organisation des visites');
$redirectUrl = $this->generateUrl('homepage', ['congratulations' => true]);
return $this->json(['status' => 'success', 'redirectUrl' => $redirectUrl]);
}else{
return $this->json(['status' => 'error', 'redirectUrl'=>$this->generateUrl('homepage')]);
}
}
private function getMask(array $strings):array
{
//mask de l'adresse email
list($nom, $domaineComplet) = explode('@', $strings['email']);
$nomVisible = substr($nom, 0, 2);
$nomMasque = str_repeat('*', max(1, strlen($nom) - 2));
$lastDotPos = strrpos($domaineComplet, '.');
if ($lastDotPos === false) {
// Pas d'extension : on masque tout
$domaineMasque = str_repeat('*', strlen($domaineComplet));
$extension = '';
} else {
$extension = substr($domaineComplet, $lastDotPos); // ex: ".fr"
$domaineMasque = str_repeat('*', $lastDotPos); // masque tout avant le ".fr"
}
$retour['email']=$nomVisible . $nomMasque . '@' . $domaineMasque . $extension;
//Mask du numéro de téléphone
$longueur = strlen($strings['phone']);
$subLength = ($strings['phone'][0]==='+')?4:2;
$debut = substr($strings['phone'], 0, $subLength);
$fin = substr($strings['phone'], -2);
$masque = str_repeat('*', $longueur - (2+$subLength));
$retour['phone']=$debut . $masque . $fin;
return $retour;
}
/**
* @Route("/confirm/{action}/{hash}", name="confir_user", requirements={"action":"sign|del", "key": "[A-Za-z0-9]+"})
*/
public function confirmUser($action, $hash, EntityManagerInterface $em, Request $request, SessionInterface $session):Response
{
$tentative = $session->get('tentative', 0);
if($tentative >=3){
$params = ['action'=>$action, 'hash'=>$hash, 'ERROR'=>1];
return $this->render('base/confirm_user.html.twig', $params);
}
if($hash == null){
$this->addFlash('danger', "⛔ Lien erroné, absence de hash !");
return $this->redirectToRoute('homepage');
}
//Vérification si le lien provient du mail ou de SMS
$origineLien = substr($hash, -1);
$hash = substr($hash, 0, -1);
$hashCheck = $em->getRepository(MD5HashCheck::class)->findOneBy(['hash' => $hash]);
if($hashCheck == null){
$this->addFlash('danger', "⛔ Cette hash n'existe pas");
return $this->redirectToRoute('homepage');
}
$offerId = $hashCheck->getUserId();
if($offerId == null){
$this->addFlash('danger', "⛔ Cette annonce n'est plus disponible");
return $this->redirectToRoute('homepage');
}
$user = $em->getRepository(Offer::class)->findOneBy(['id' => $offerId])->getUser();
$userMail = $user->getEmail();
$userPhone = $user->getPhone();
$masques = $this->getMask(['email' => $userMail, 'phone' => $userPhone]);
$params =['offerId'=> $offerId, 'action'=>$action, 'hash'=>$hash, 'ERROR'=>'', 'origineLien'=>$origineLien];
if($origineLien == 'M'){
//Le lien provient d'un mail
$params ['masqueMail'] = $masques['email'];
}elseif ($origineLien == 'S'){
//Le lien provient d'un SMS
$params['masquePhone'] = $masques['phone'];
}
return $this->render('base/confirm_user.html.twig', array_merge($params, ['ERROR'=>$request->query->get('ERROR', '')]));
}
/**
* @Route("/verif-user", name="verif_user")
*/
public function verifUser(Request $request, EntityManagerInterface $em, SessionInterface $session, PhoneNumberHelper $helper):Response
{
if($request->isMethod('POST')){
//récupération de la valeur saisie par l'utilisateur
$hash = $request->request->get('hash', false);
$offerId = $request->request->get('offerId', false);
$action = $request->request->get('action', false);
$origineLien = $request->request->get('origineLien', false);
//récupération de la valeur saisie par l'utilisateur
$email = $request->request->get('email', false);
$tel = $helper->normalizePhoneToE164($request->request->get('tel', false));
if(!$hash || !$offerId || !$action || !$origineLien || (!$email && !$tel)){
$this->addFlash('danger', '⛔ Accès refusé');
return $this->redirectToRoute('homepage');
}
$user = $em->getRepository(Offer::class)->findOneBy(['id' => $offerId])->getUser();
$userMail = $user->getEmail();
$userPhone = $helper->normalizePhoneToE164($user->getPhone());
$verifError = false;
if($email && $email !== $userMail){
$this->addFlash('danger', "⛔ L'adresse email saisie ne correspond pas à l'adresse email attendue !");
$verifError = true;
}elseif ($tel && $tel !== $userPhone){
$this->addFlash('danger', '⛔ Le numéro saisi ne correspond pas au numéro de téléphone attendu');
$verifError = true;
}
$tentative = $session->get('tentative', 0);
if ($verifError){
$tentative++;
$session->set('tentative', $tentative);
$params = ['action'=>$action, 'hash'=>$hash.$origineLien];
return $this->redirectToRoute('confir_user', $params);
}
switch ($action) {
case 'del':
return $this->redirectToRoute('del_conv', ['hash' => $hash]);
break;
case 'sign':
return $this->redirectToRoute('sign_offer', ['hash'=>$hash]);
break;
default:
$this->addFlash('danger', '⛔ Accès refusé');
return $this->redirectToRoute('homepage');
}
}
$this->addFlash('danger', '⛔ Accès refusé');
return $this->redirectToRoute('homepage');
}
/**
* @Route("/del_conv/key={hash}", name="del_conv")
*/
public function delConvention($hash, EntityManagerInterface $em, OfferTenantApplicationRepository $offerTenantApplicationRepo)
{
if ($hash == null)
{
$this->addFlash('danger', 'Pas de hash.');
return $this->redirectToRoute('homepage');
}
$hashCheck = $em->getRepository(MD5HashCheck::class)->findOneBy(['hash' => $hash]);
if ($hashCheck == null){
$this->addFlash('danger', 'Pas de hash.');
return $this->redirectToRoute('homepage');
}
$offer = $em->getRepository(Offer::class)->find($hashCheck->getUserId());
if ($offer == null || $offer->getIsSigned()){
$this->addFlash('danger', "Cette offre n'est plus disponible ou elle est déjà signée");
return $this->redirectToRoute('homepage');
}
$offer->setIsPublished(0);
$offer->setStatus(3);
$offerTenantApplicationRepo->disableAllOfferApplications($offer->getId());
$em->persist($offer);
$em->flush();
$this->addFlash('success', "🗑️ L'offre a bien été supprimée");
return $this->redirectToRoute('homepage');
}
/**
* @Route("/sign_conv/key={hash}", name="sign_offer")
*/
public function signConvention($hash, Request $request, EnumValuesRepository $valuesRepo, FormLabelHydrater $hydrater, SessionInterface $session)
{
// I had a perfectly working nice method, but no, I had to change it because the client is king.
if ($hash == null)
{
$this->addFlash('danger', 'Pas de hash.');
return $this->redirectToRoute('homepage');
}
$offerId = $this->getDoctrine()->getRepository(MD5HashCheck::class)->findOneBy(['hash' => $hash]);
if ($offerId == null)
{
$this->addFlash('danger', 'Pas de id.');
return $this->redirectToRoute('homepage');
}
$offer = $this->getDoctrine()->getRepository(Offer::class)->find($offerId->getUserId());
// if offer is already signed, what the hell are you doing here?
if ($offer == null )
{
$this->addFlash('danger', "⛔ L'accès a cette offre n'est plus disponible, pour plus d'information contacter l'agence");
return $this->redirectToRoute('homepage');
}
if($offer->getIsSigned() == true){
$this->addFlash('danger', "⛔ L'accès a cette offre n'est plus disponible. L'offre a déjà été validé. Pour plus d'information contacter l'agence");
return $this->redirectToRoute('homepage');
}
//Si l'offre est supprimée status = 3
if($offer->getStatus() == 3){
$this->addFlash('danger', "⛔ L'accès a cette offre n'est plus disponible. L'offre a déjà été supprimée. Pour plus d'information contacter l'agence");
return $this->redirectToRoute('homepage');
}
if($offer->getIsPublished() == true){
$this->addFlash('danger', "⛔ L'accès a cette offre n'est plus disponible. L'offre a déjà été publiée. Pour plus d'information contacter l'agence");
return $this->redirectToRoute('homepage');
}
$user = $offer->getUser();
if ($user == null)
{
$this->addFlash('danger', 'Impossible de trouver un propriétaire.');
return $this->redirectToRoute('homepage');
}
$values = $valuesRepo->findAllEnums();
$labels = $hydrater->getOfferLabels('flip');
$form = $this->createForm(SignConventionType::class, $offer);
$form->handleRequest($request);
$session->set('magic_access_offer_id', $offer->getId());
return $this->render('offer/sign_offer.html.twig', [
'form' => $form->createView(),
'formOffer' => $this->createForm(ModalOfferType::class, $offer)->createView(),
'offer' => $offer,
'user' => $user,
'values' => $values,
'labelHydrater' => $hydrater->getOfferLabels('flip'),
'offerDetailsLabels' => $hydrater->getOfferDetailsLabels(),
'nbrRooms' => $labels['nbrRooms'],
'heatingType' => $labels['heatingType'],
'allowUpdate' => true,
'ajaxSignConventionRoute' => $this->generateUrl('ajax_sign_conv', ['id'=>$offer->getId(),'hash'=> $hash]),
]
);
}
/**
* @Route("/ajax-edit-landlord-contact", name="ajax_edit_landlord_contact", methods={"POST"})
*/
public function ajaxEditLandlordContact(Request $request, OfferRepository $repo, EntityManagerInterface $em)
{
//cas d'accès par lien magique avec le hash
$session = $request->getSession();
$offer_id = $session->get('magic_access_offer_id');
if(!$offer_id) {
//cas d'accès par authentification
$offer_id = $request->request->get('offer_id');
}
$landLordContactInfo = $request->request->get('formOffer');
$offer = $repo->findOneBy(['id' => $offer_id]);
$form = $this->createForm(OfferType::class, $offer);
// On soumet uniquement les données envoyées sans supprimer les autres champs
$form->submit($landLordContactInfo, false);
if ($form->isSubmitted() && $form->isValid()) {
$em->flush();
return new JsonResponse(['status' => 'success']);
}
$errors = [];
foreach ($form->getErrors(true, false) as $error) {
$errors[] = $error->getMessage();
}
return new JsonResponse(['status' => 'error', 'message' => 'Form not valid', 'errors' => $errors], 400);
}
/**
* @Route("/partial-offer-contact/{id}", name="partial_offer_contact")
*/
public function getPartialOfferContact(Offer $offer): Response
{
return $this->render('partials/offer/_landlordContact.html.twig', [
'offer' => $offer,
'user' => $offer->getUser()
]);
}
/**
* @Route("/ajax-edit-offer-description", name="ajax_edit_offer_description", methods={"POST"})
*/
public function ajaxEditOfferDescription(Request $request, OfferRepository $repo, EntityManagerInterface $em)
{
$offer_id = $request->request->get('offer_id');
$offerDescription = $request->request->get('formOffer');
$offer = $repo->findOneBy(['id' => $offer_id]);
$form = $this->createForm(OfferType::class, $offer);
$form->submit($offerDescription, false);
if ($form->isSubmitted() && $form->isValid()) {
$em->flush();
return new JsonResponse(['status' => 'success']);
}
$errors = [];
foreach ($form->getErrors(true, false) as $error) {
$errors[] = $error->getMessage();
}
return new JsonResponse(['status' => 'error', 'message' => 'Form not valid', 'errors' => $errors], 400);
}
/**
* @Route("/partial-offer-description/{id}", name="partial_offer_description")
*/
public function getPartialOfferDescription(Offer $offer, FormLabelHydrater $formLabelHydrater): Response
{
return $this->render('partials/offer/_description.html.twig', [
'offer' => $offer,
'labelHydrater' => $formLabelHydrater->getOfferLabels('flip'),
'offerDetailsLabels' => $formLabelHydrater->getOfferDetailsLabels(),
]);
}
/**
* @Route("/ajax-edit-offer-address", name="ajax_edit_offer_address", methods={"POST"})
*/
public function ajaxEditOfferAddress(Request $request, OfferRepository $repo, EntityManagerInterface $em): JsonResponse
{
$offer_id = $request->request->get('offer_id');
$offerAddress = $request->request->get('formOffer');
$offer = $repo->findOneBy(['id' => $offer_id]);
$form = $this->createForm(OfferType::class, $offer);
$form->submit($offerAddress, false);
if ($form->isSubmitted() && $form->isValid()) {
$em->flush();
return new JsonResponse(['status' => 'success']);
}
$errors = [];
foreach ($form->getErrors(true, false) as $error) {
$errors[] = $error->getMessage();
}
return new JsonResponse(['status' => 'error', 'message' => 'Form not valid', 'errors' => $errors], 400);
}
/**
* @Route("/partial-offer-address/{id}", name="partial_offer_address")
*/
public function getPartialOfferAddress(Offer $offer): Response
{
return $this->render('partials/offer/_address.html.twig', [
'offer' => $offer
]);
}
/**
* @Route("/ajax-edit-offer-price", name="ajax_edit_offer_price", methods={"POST"})
*/
public function ajaxEditOfferPrice(Request $request, OfferRepository $repo, EntityManagerInterface $em): JsonResponse
{
$offer_id = $request->request->get('offer_id');
$offerPrice = $request->request->get('formOffer');
$offer = $repo->findOneBy(['id' => $offer_id]);
$form = $this->createForm(OfferType::class, $offer);
$form->submit($offerPrice, false);
if ($form->isSubmitted() && $form->isValid()) {
$em->flush();
return new JsonResponse(['status' => 'success']);
}
$errors = [];
foreach ($form->getErrors(true, false) as $error) {
$errors[] = $error->getMessage();
}
return new JsonResponse(['status' => 'error', 'message' => 'Form not valid', 'errors' => $errors], 400);
}
/**
* @Route("/partial-offer-price/{id}", name="partial_offer_price")
*/
public function getPartialOfferPrice(Offer $offer): Response
{
return $this->render('partials/offer/_price.html.twig', [
'offer' => $offer
]);
}
/**
* @Route("/ajax-reset-consumption-emission/{id}", name="ajax_reset_consumption_emission")
*/
public function ajaxResetConsumptionEmission(Offer $offer, EntityManagerInterface $em, Request $request):JsonResponse
{
$resetValue = $request->request->get('reset');
$offerDetails = $offer->getDetails();
$offerDetails->setEnergyConsumption($resetValue);
$offerDetails->setGhgEmission($resetValue);
$em->flush();
return new JsonResponse(['status' => 'success']);
}
/**
* @Route("/ajax-update-energy-consumption/{id}", name="ajax_update_energy_consumption")
*/
public function ajaxUpdateEnergyConsumption(Offer $offer, Request $request, EntityManagerInterface $em) : JsonResponse
{
$offerDetails = $offer->getDetails();
$offerDetails->setEnergyConsumption($request->request->get('consumption'));
$em->flush();
return new JsonResponse(['status' => 'success']);
}
/**
* @Route("/ajax-update-emission/{id}", name="ajax_update_emission")
*/
public function ajaxUpdateEmission(Offer $offer, Request $request, EntityManagerInterface $em) : JsonResponse
{
$offerDetails = $offer->getDetails();
$offerDetails->setGhgEmission($request->request->get('emission'));
$em->flush();
return new JsonResponse(['status' => 'success']);
}
/**
* @Route("/offer-image/remove/{id}", name="offer_remove_image", methods={"POST"})
*/
public function ajaxRemoveOfferImage(OfferImage $offerImage, Filesystem $filesystem, EntityManagerInterface $em):JsonResponse
{
if (!$offerImage) {
return new JsonResponse(['status' => 'error', 'message' => 'Image not found'], 404);
}
$filePath = $this->getParameter('kernel.project_dir').'/public'.$offerImage->getFullPath();
if ($filesystem->exists($filePath)) {
$filesystem->remove($filePath);
}
$em->remove($offerImage);
$em->flush();
return new JsonResponse(['status' => 'success']);
}
/**
* @Route("/partial-offer-images/{id}", name="partial_offer_images")
*/
public function getPartialOfferPhotos(Offer $offer)
{
return $this->render('partials/offer/_offerPhotos.html.twig', ['offer'=>$offer, 'allowUpdate' => true,]);
}
/**
* @Route("/offer/{id}/upload-image", name="offer_upload_image", methods={"POST"})
*/
public function uploadImage(Request $request, Offer $offer, EntityManagerInterface $em)
{
$uploadedFiles = $request->files->get('files');
if (!$uploadedFiles) {
return new JsonResponse(['status' => 'error', 'message' =>"Aucun fichier n'a été téléchargé."], 500);
}else {
//Modification pour avoir le path d'upload sous forme de /offer-images/yyyy/mm/file.extension
//préparation du path
$publicDirectory = $this->getParameter('kernel.project_dir').'/public';
$offerImagesDirectory = $this->getParameter('offer_images_directory').date('/Y/m');
$uploadDirectory = $publicDirectory.$offerImagesDirectory;
if(!is_dir($uploadDirectory)) {
mkdir($uploadDirectory, 0777, true);
}
foreach ($uploadedFiles as $file)
{
if ($file->isValid()) {
$newFilename = uniqid();
$fileExtension = $file->guessExtension();
try {
$file->move(
$uploadDirectory,
$newFilename . '.' . $fileExtension
);
// Créer une nouvelle instance de l'entité OfferImage
$offerImage = new OfferImage();
$offerImage->setFilename($offerImagesDirectory.'/'.$newFilename. '.' . $fileExtension);
$offerImage->setOffer($offer);
// Enregistre l'entité en base de données
$em->persist($offerImage);
$em->flush();
} catch (FileException $e) {
return new JsonResponse(['status' => 'error', 'message' => $e->getMessage()], 500);
}
}else {
return new JsonResponse(['status' => 'error', 'message' => 'Invalid file'], 400);
}
}
}
return new JsonResponse(['status' => 'success']);
}
/**
* @Route("/proprietaire/questionnaire/key={token};app={appId}", name="landlord_quizz")
* @ParamConverter("app", options={"mapping"={"appId"="id"}})
*/
public function landlordQuizz(User $landlord = null, OfferTenantApplication $app = null, Securizer $securizer, UserRepository $uRepo, AgencyRepository $aRepo, OfferRepository $oRepo, Request $request, CustomMailer $mailer)
{
if ($app == null || $landlord == null)
{
$this->addFlash('danger', 'Un problème a été rencontré avec cette application, le questionnaire est par conséquent inaccessible.');
return $this->redirectToRoute('homepage');
}
// Create user for login event
$token = new UsernamePasswordToken($landlord, $landlord->getPassword(), "main", $landlord->getRoles());
$this->get("security.token_storage")->setToken($token);
// Fire the login event
$event = new InteractiveLoginEvent($request, $token);
$dispatcher = new EventDispatcher();
$dispatcher->dispatch($event, "security.interactive_login");
if ($landlord->getId() != $app->getLandlordId())
{
$this->addFlash('danger', 'Vous n\'avez pas le droit d\'accéder à ce questionnaire.');
return $this->redirectToRoute('homepage');
}
$tenant = $uRepo->find($app->getTenantId());
$offer = $oRepo->find($app->getOfferId());
// check that we have the landlord, the tenant and the offer entities
if ($tenant == null || $offer == null)
{
$this->addFlash('danger', 'Un problème a été rencontré avec cette application, le questionnaire est par conséquent inaccessible.');
return $this->redirectToRoute('homepage');
}
$form = $this->createFormBuilder([])
->add('name', TextType::class, [
'label' => 'Nom du futur locataire',
'constraints' => [
new Type('string'),
new NotBlank([
'message' => "Veuillez renseigner le nom."
]),
],
'required' => true,
])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// data is an array with "name", "email", and "message" keys
$data = $form->getData();
$name = $data['name'];
$agencyMail = $aRepo->find($offer->getAgency())->getEmail();
$mailer->sendVisitSuccessful($landlord, $offer, $name, $agencyMail);
return $this->redirectToRoute('landlord_profile', ['id' => $landlord->getId()]);
}
return $this->render('landlord/landlord_quizz.html.twig', [
'landlordId' => $landlord->getId(),
'tenantId' => $tenant->getId(),
'offerId' => $offer->getId(),
'appId' => $app->getId(),
'form' => $form->createView(),
]);
}
/**
* @Route("/locataire/questionnaire/key={token};app={appId}", name="tenant_quizz")
* @ParamConverter("app", options={"mapping"={"appId"="id"}})
*/
public function tenantQuizz(User $tenant = null, OfferTenantApplication $app = null, Securizer $securizer, UserRepository $uRepo, AgencyRepository $aRepo, OfferRepository $oRepo, Request $request, CustomMailer $mailer)
{
if ($app == null || $tenant == null)
{
$this->addFlash('danger', 'Un problème a été rencontré avec cette application, le questionnaire est par conséquent inaccessible.');
return $this->redirectToRoute('homepage');
}
// Create user for login event
$token = new UsernamePasswordToken($tenant, $tenant->getPassword(), "main", $tenant->getRoles());
$this->get("security.token_storage")->setToken($token);
// Fire the login event
$event = new InteractiveLoginEvent($request, $token);
$dispatcher = new EventDispatcher();
$dispatcher->dispatch($event, "security.interactive_login");
if ($tenant->getId() != $app->getTenantId())
{
$this->addFlash('danger', 'Vous n\'avez pas le droit d\'accéder à ce questionnaire.');
return $this->redirectToRoute('homepage');
}
$landlord = $uRepo->find($app->getLandlordId());
$offer = $oRepo->find($app->getOfferId());
// check that we have the landlord, the tenant and the offer entities
if ($landlord == null || $offer == null)
{
$this->addFlash('danger', 'Un problème a été rencontré avec cette application, le questionnaire est par conséquent inaccessible.');
return $this->redirectToRoute('homepage');
}
$form = $this->createFormBuilder([])
->add('name', TextType::class, [
'label' => 'Nom du futur locataire',
'constraints' => [
new Type('string'),
new NotBlank([
'message' => "Veuillez renseigner le nom."
]),
],
'required' => true,
])
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// data is an array with "name", "email", and "message" keys
$data = $form->getData();
$name = $data['name'];
$agencyMail = $aRepo->find($offer->getAgency())->getEmail();
$mailer->sendVisitSuccessful($landlord, $offer, $name, $agencyMail);
return $this->redirectToRoute('tenant_profile', ['id' => $tenant->getId()]);
}
return $this->render('landlord/landlord_quizz.html.twig', [
'landlordId' => $landlord->getId(),
'tenantId' => $tenant->getId(),
'offerId' => $offer->getId(),
'appId' => $app->getId(),
'form' => $form->createView(),
]);
}
/**
* @Route("/mentions-legales", name="mentions_legales")
*/
public function mentionsLegales(): Response
{
return $this->render('pages/mentions-legales.html.twig');
}
/**
* @Route("/honoraires", name="honoraires")
*/
public function honoraires(): Response
{
return $this->render('pages/honoraires.html.twig');
}
/**
* @Route("/service-descriptif", name="service_descriptif")
*/
public function serviceDescriptif(): Response
{
return $this->render('pages/service-descriptif.html.twig');
}
}