<?php
namespace App\Controller;
use App\Entity\Answer;
use App\Entity\Question;
use App\Entity\Rank;
use App\Entity\Respondent;
use App\Entity\User;
use App\Form\AnswerType;
use App\Form\RespondentType;
use App\Form\UserType;
use App\Service\EmailService;
use App\Service\ResultsService;
use Doctrine\Persistence\ManagerRegistry;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
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;
class QuestionnaireController extends AbstractController
{
private $doctrine;
private $requestStack;
private $passwordHasher;
private $resultsService;
private $emailService;
public function __construct(
ManagerRegistry $doctrine,
RequestStack $requestStack,
UserPasswordHasherInterface $passwordHasher,
ResultsService $resultsService,
EmailService $emailService
)
{
$this->doctrine = $doctrine;
$this->requestStack = $requestStack;
$this->passwordHasher = $passwordHasher;
$this->resultsService = $resultsService;
$this->emailService = $emailService;
}
/**
* Affiche la page d'intro du questionnaire : formulaire profil du répondent en session
* @Route("/questionnaire/intro", name="questionnaire_start")
*/
public function start(Request $request): Response
{
$session = $this->requestStack->getSession();
$respondentSlug = $session->get('respondentSlug');
// Initialisation du Respondent (si l'id n'est pas trouvé, on crée un nouveau)
$respondent = null;
$user = null;
if($respondentSlug){
$respondent = $this->doctrine->getRepository(Respondent::class)->findOneBySlug($respondentSlug);
}
// Si aucun Respondent n'est trouvé, créer un nouveau Respondent
if (null === $respondent) {
$respondent = new Respondent();
$user = new User();
} else {
// Si un Respondent est trouvé, récupérer l'utilisateur lié
$user = $respondent->getUser();
}
$form = $this->createForm(UserType::class, $user, [
'respondent' => $respondent
]);
$postedData = $request->request->all();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->doctrine->getManager();
$existingUser = $this->doctrine->getRepository(User::class)->findOneBy(['email' => $user->getEmail()]);
if(null !== $existingUser){
$user = $existingUser;
} else {
$user->setPassword($this->passwordHasher->hashPassword($user, 'password'));
}
// Si le Respondent est nouveau, on peut l'initialiser ici
if(null === $respondent->getStartTime()){
$respondent->setStartTime(new \DateTimeImmutable());
}
// affecter le rank au respondent
$rank = $form->get('rank')->getData();
$respondent->setRank($rank);
// si le respondent n'est pas dans la liste de user on l'ajoute
if (!$user->getRespondents()->contains($respondent)) {
$user->addRespondent($respondent);
$respondent->setUser($user);
}
$entityManager->persist($respondent);
$entityManager->persist($user);
$entityManager->flush();
// Sauvegarder dans la session l'id du Respondent
$session->set('respondentSlug', $respondent->getSlug());
// Redirection vers le questionnaire du rank
return $this->redirectToRoute('questionnaire_answer', [
'slug' => $respondent->getSlug(),
'position' => 1,
'questionnaire' => $respondent->getRank()->getId()]);
}
return $this->render('questionnaire/start.html.twig', [
'form' => $form->createView()
]);
}
/**
* Affiche la question en position $position pour le répondant en session
* @Route("/questionnaire/repondre/{slug}/{position}/{questionnaire}", name="questionnaire_answer")
* @ParamConverter("respondent", class="App\Entity\Respondent", options={"mapping": {"slug": "slug"}})
*/
public function answer(Request $request, Respondent $respondent, $position = null, $questionnaire = 1): Response
{
$question = $this->doctrine->getRepository(Question::class)->findOneBy([
'position' => $position,
'questionnaire' => $questionnaire
]);
$nbTotalQuestions = $this->doctrine->getRepository(Question::class)->count([]);
$answer = $this->doctrine->getRepository(Answer::class)->findOneByQuestionAndRespondant($question, $respondent);
if(null === $answer){
$answer = new Answer();
$answer->setRespondent($respondent);
}
$form = $this->createForm(AnswerType::class, $answer, ['question' => $question]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$entityManager = $this->doctrine->getManager();
$entityManager->persist($answer);
$entityManager->flush();
if($position == $nbTotalQuestions){
$respondent->setEndTime(new \DateTimeImmutable());
$entityManager->persist($respondent);
$entityManager->flush();
// on save là et pas dans le results pr save une seule fois
$resultsTraining = $this->resultsService->calculateResultsTraining($respondent);
$trainings = $this->resultsService->getTrainings($respondent, $resultsTraining);
$this->resultsService->saveRespondentTrainings($respondent, $trainings);
// puis on lui envoi le resultat
$this->emailService->sendResultatsEmail($respondent);
return $this->redirectToRoute('results', [
'slug' => $respondent->getSlug()
]);
}
return $this->redirectToRoute('questionnaire_answer', [
'slug' => $respondent->getSlug(),
'position' => $position+1,
'questionnaire' => $respondent->getRank()->getId()
]);
}
return $this->render('questionnaire/question.html.twig', [
'question' => $question,
'position' => $position,
'nbTotalQuestions' => $nbTotalQuestions,
'form' => $form->createView(),
'respondent' => $respondent
]);
}
}