ninesurvey/src/ninesurvey-1.0/src/Controller/SurveyController.php

631 lines
24 KiB
PHP

<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\FormError;
use App\Form\CreateSurveyFlow;
use Ramsey\Uuid\Uuid;
use App\Entity\Survey;
use App\Entity\Option;
use App\Entity\Guest;
use App\Entity\Vote;
use App\Form\GuestType as GuestType;
use App\Form\SurveykeyType as SurveykeyType;
use App\Form\SurveystatusType as SurveystatusType;
class SurveyController extends AbstractController
{
public function list()
{
$guests=$this->getUser()->getGuests();
return $this->render('Survey/survey.html.twig', [
'useheader' => true,
'usesidebar' => false,
'guests' => $guests,
]);
}
public function submit(CreateSurveyFlow $flow)
{
$em = $this->getDoctrine()->getManager();
$key = Uuid::uuid4();
$survey = new Survey();
$survey->setUser($this->getUser());
$survey->setKey($key);
$survey->setPrivate(true);
$survey->setNotification(true);
$survey->setStatus(0);
$survey->setTonotifyclose(false);
$survey->setTonotifyopen(false);
$flow->bind($survey);
$form = $flow->createForm();
$return = $this->edit($flow,$form,$survey);
if($return) return $this->redirect($this->generateUrl('app_home'));
return $this->render('Survey/edit.html.twig',[
'useheader' => true,
'usesidebar' => false,
'form' => $form->createView(),
'flow' => $flow,
'survey' => $survey,
]);
}
public function update($id,CreateSurveyFlow $flow)
{
$em = $this->getDoctrine()->getManager();
$survey=$em->getRepository("App:Survey")->find($id);
// Construction de la chaine jsonoptions
$options=$em->getRepository("App:Option")->findBy(["survey"=>$survey],["date"=>"ASC"]);
$tbdates=[];
foreach($options as $option) {
$date=$option->getDate()->format("Y-m-d");
$hour=$option->getDate()->format("H : i");
if(!array_key_exists($date,$tbdates)) {
$tbdates[$date]=["date"=>$date,"hours"=>[]];
}
if(!in_array($hour,$tbdates[$date]["hours"])) array_push($tbdates[$date]["hours"],$hour);
}
$jsonoptions="[";
$i=0;
foreach($tbdates as $date) {
if($i>0) $jsonoptions.=",";
$jsonoptions.=json_encode($date);
$i++;
}
$jsonoptions.="]";
$survey->setJsonoptions($jsonoptions);
// Construction de la chaine jsonguests
$guests=$em->getRepository("App:Guest")->findBy(["survey"=>$survey],["email"=>"ASC"]);
$tbguests=[];
foreach($guests as $guest) {
array_push($tbguests,$guest->getEmail());
}
$survey->setJsonguests(json_encode($tbguests));
$flow->bind($survey);
$form = $flow->createForm();
$return = $this->edit($flow,$form,$survey);
if($return) return $this->redirect($this->generateUrl('app_home'));
return $this->render('Survey/edit.html.twig',[
'useheader' => true,
'usesidebar' => false,
'form' => $form->createView(),
'flow' => $flow,
'survey' => $survey,
'id' => $id,
]);
}
private function edit(CreateSurveyFlow &$flow,&$form,$survey)
{
$em = $this->getDoctrine()->getManager();
// On s'assure que le survey appartient bien à l'utilisateur
if($this->getUser()!=$survey->getUser()) {
return $this->redirect($this->generateUrl('app_home'));
}
if ($flow->isValid($form)) {
// Controle de validité étape options
if($flow->getCurrentStepNumber()=="2") {
$data=$form->getData();
$jsonoptions=$data->getJsonoptions();
if(!$jsonoptions||$jsonoptions=="[]") {
$form->addError(new FormError("Votre sondage doit comporter au minimum un horaire"));
}
$errors = $form->getErrors();
foreach( $errors as $error ) {
$this->get('session')->getFlashBag()->add("error", $error->getMessage());
}
}
// Controle de validité étape guests
if($flow->getCurrentStepNumber()=="3") {
$data=$form->getData();
if($survey->getPrivate()) {
$jsonguests=$data->getJsonguests();
if(!$jsonguests||$jsonguests=="[]") {
$form->addError(new FormError("Votre sondage doit comporter au minimum un invité"));
}
$errors = $form->getErrors();
foreach( $errors as $error ) {
$this->get('session')->getFlashBag()->add("error", $error->getMessage());
}
}
}
if($form->isValid($form)) {
$flow->saveCurrentStepData($form);
if ($flow->nextStep()) {
$form = $flow->createForm();
} else {
// Sauvegarde du sondage
$em->persist($survey);
// Sauvegarde des options
$data=$form->getData();
$jsonoptions=json_decode($data->getJsonoptions());
$tboptions=[];
foreach($jsonoptions as $date) {
foreach($date->hours as $hour ) {
$hour=str_replace(" ","",$hour);
$dateoption= new \DateTime($date->date." ".$hour);
array_push($tboptions,$dateoption);
$option=$em->getRepository("App:Option")->findOneBy(["date"=>$dateoption,"survey"=>$survey]);
if(!$option) {
$option=new Option();
$option->setDate($dateoption);
$option->setSurvey($survey);
$option->setChoiced(false);
$em->persist($option);
}
}
}
// Sauvegarde des invités
if($survey->getPrivate()) {
$data=$form->getData();
$jsonguest=json_decode($data->getJsonguests());
$tbguests=[];
// On ajoute le propriétaire du sondage en tant qu'invité si ce n'est pas le cas
if(!in_array($this->getUser()->getEmail(),$jsonguest)) array_push($jsonguest,$this->getUser()->getEmail());
foreach($jsonguest as $email) {
array_push($tbguests,$email);
$user=$em->getRepository("App:User")->findOneBy(["email"=>$email]);
$guest=$em->getRepository("App:Guest")->findOneBy(["email"=>$email,"survey"=>$survey]);
if(!$guest) {
$key = Uuid::uuid4();
$displayname=$email;
$tonotifyguest=true;
if($user) {
$displayname=$user->getDisplayname();
$tonotifyguest=($user!=$this->getUser());
}
$guest=new Guest();
$guest->setEmail($email);
$guest->setDisplayname($displayname);
$guest->setKey($key);
$guest->setSurvey($survey);
$guest->setTonotifyguest($tonotifyguest);
$guest->setTonotifyowner(false);
}
$guest->setUser($user);
$em->persist($guest);
}
// Suppression des invités obsolète
$guests=$survey->getGuests();
foreach($guests as $guest) {
if(!in_array($guest->getEmail(),$tbguests)) {
$em->remove($guest);
}
}
}
else {
// On ajoute qu'il arrive le propriétaire en tant qu'invité
$guest=$em->getRepository("App:Guest")->findOneBy(["email"=>$this->getUser()->getEmail(),"survey"=>$survey]);
if(!$guest) {
$key = Uuid::uuid4();
$guest=new Guest();
$guest->setEmail($this->getUser()->getEmail());
$guest->setDisplayname($this->getUser()->getDisplayname());
$guest->setKey($key);
$guest->setSurvey($survey);
$guest->setTonotifyguest(false);
$guest->setTonotifyowner(false);
}
$guest->setUser($this->getUser());
$em->persist($guest);
}
$em->flush();
$flow->reset();
return true;
}
}
}
return false;
}
public function delete($id,Request $request)
{
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
$survey=$em->getRepository("App:Survey")->find($id);
// On s'assure que le survey appartient bien à l'utilisateur
if($this->getUser()!=$survey->getUser()) {
return $this->redirect($this->generateUrl('app_home'));
}
// Suppression
$em->remove($survey);
$em->flush();
return $this->redirect($this->generateUrl('app_home'));
}
public function closeopen($id,$status,Request $request) {
// Initialisation de l'enregistrement
$em = $this->getDoctrine()->getManager();
$survey=$em->getRepository("App:Survey")->find($id);
// On s'assure que le survey appartient bien à l'utilisateur
if($this->getUser()!=$survey->getUser()) {
return $this->redirect($this->generateUrl('app_home'));
}
$modalclose=false;
$survey->setStatus($status);
if($status==1) {
$survey->setTonotifyclose(true);
$survey->setTonotifymessage("Bonjour,<br><br>Après sondage la date suivante a été retenue pour notre réunion : <b>".$survey->getTitle()."</b><br><br><strong>#DATE#</strong><br><br>Merci de votre présence.<br><br>Vous pouvez consulter les réponses au songage via le lien ci-après: <a href='#LINK#'>accéder au sondage</a><br><br>Cordialement<br>".$survey->getUser()->getDisplayname());
}
else {
$survey->setTonotifyopen(true);
$survey->setTonotifymessage("Bonjour,<br><br>Le sondage suivant a été réouvert : <b>".$survey->getTitle()."</b><br><br>Vous pouvez de nouveau répondre au songage via le lien ci-après: <a href='#LINK#'>accéder au sondage</a>.<br><br>Cordialement<br>".$survey->getUser()->getDisplayname());
}
// Création du formulaire
$form = $this->createForm(SurveystatusType::class,$survey,array("result"=>$survey->getResult(),"status"=>$status));
// Récupération des data du formulaire
$form->handleRequest($request);
// Sur validation
if ($form->get('submit')->isClicked() && $form->isValid()) {
$data = $form->getData();
// Pour chaque options du suvery les placer comme non choisie
$options=$em->getRepository("App:Option")->findBy(["survey"=>$survey]);
foreach($options as $option) {
$option->setChoiced(false);
$em->persist($option);
$em->flush();
}
// Placer l'option selectionné comme choisie
if($status==1) {
$isresult=$form->get("isresult")->getData();
$option=$em->getRepository("App:Option")->find($isresult);
if($option) {
$option->setChoiced(true);
$em->persist($option);
$em->flush();
}
}
$em->persist($data);
$em->flush();
// Retour à la liste
$modalclose=true;
}
return $this->render('Survey/status.html.twig',[
'useheader' => false,
'usesidebar' => false,
'form' => $form->createView(),
'modalclose' => $modalclose,
]);
}
public function byuserkey($key,Request $request)
{
$em = $this->getDoctrine()->getManager();
// Recherche de l'utilisateur dans le sondage
$guest = $em->getRepository("App:Guest")->findOneBy(["survey"=>$key,"user"=>$this->getUser()]);
if(!$guest) {
return $this->render('Response/nokey.html.twig',[
'useheader' => true,
'usesidebar' => false,
]);
}
$return = $this->vote($request,$form,$guest,"byuserkey");
if($return) return $this->redirect($this->generateUrl('app_home'));
return $this->render('Response/vote.html.twig',[
'useheader' => true,
'usesidebar' => false,
'guest' => $guest,
'form' => $form->createView(),
'by' => "byuserkey",
]);
}
public function byguestkey($key,Request $request)
{
$em = $this->getDoctrine()->getManager();
// Recherche de la clé d'invitation
$guest = $em->getRepository("App:Guest")->findOneBy(["key"=>$key]);
if(!$guest) {
return $this->render('Response/nokey.html.twig',[
'useheader' => true,
'usesidebar' => false,
]);
}
$this->vote($request,$form,$guest,"byguestkey");
return $this->render('Response/vote.html.twig',[
'useheader' => true,
'usesidebar' => false,
'guest' => $guest,
'form' => $form->createView(),
'by' => "byguestkey",
]);
}
public function bysurveykey($key,Request $request)
{
$em = $this->getDoctrine()->getManager();
// Recherche de la clé d'invitation
$survey = $em->getRepository("App:Survey")->findOneBy(["key"=>$key]);
if(!$survey) {
return $this->render('Response/nokey.html.twig',[
'useheader' => true,
'usesidebar' => false,
]);
}
// S'assurer que le sondage est public
if($survey->getPrivate()) {
return $this->render('Response/nokey.html.twig',[
'useheader' => true,
'usesidebar' => false,
]);
}
// Si la personne est déjà connectée : on génère une invitation et on le redirige via un accès user
if($this->getUser()) {
$guest = $em->getRepository("App:Guest")->findOneBy(["survey"=>$survey,"user"=>$this->getUser()]);
if(!$guest) {
$key = Uuid::uuid4();
$email=$this->getUser()->getEmail();
$displayname=$this->getUser()->getDisplayname();
$tonotifyguest=true;
$guest=new Guest();
$guest->setEmail($email);
$guest->setDisplayname($displayname);
$guest->setKey($key);
$guest->setSurvey($survey);
$guest->setTonotifyguest($tonotifyguest);
$guest->setTonotifyowner(false);
$guest->setUser($this->getUser());
$em->persist($guest);
$em->flush();
}
return $this->redirect($this->generateUrl('app_survey_byuserkey',["key"=>$survey->getId()]));
}
// Initialisation de l'enregistrement
$data = new Guest();
// Création du formulaire
$form = $this->createForm(SurveykeyType::class,$data);
// Récupération des data du formulaire
$form->handleRequest($request);
// S'assurer que la personne n'a pas déjà voté
// Si c'est le cas il ne devrait plus utiliser cette url
// On lui retourne l'url associé à son vote
if ($form->get('submit')->isClicked()) {
$data = $form->getData();
$email=$data->getEmail();
$guest=$em->getRepository("App:Guest")->findOneBy(["survey"=>$survey,"email"=>$email]);
if($guest) {
$guest->setTonotifyguest(true);
$em->persist($guest);
$em->flush();
// Initialiser l'erreur
$form->addError(new FormError("Une personne a déjà utiliser ce mail pour répondre au sondage.<br>Si vous êtes cette personne vous allez recevoir un mail vous indiquant l'url d'accès pour modifier ou visualiser votre réponse"));
$this->get('session')->getFlashBag()->clear();
$errors = $form->getErrors();
foreach( $errors as $error ) {
$request->getSession()->getFlashBag()->add("error", $error->getMessage());
}
}
}
if ($form->get('submit')->isClicked()&&$form->isValid()) {
$user=$em->getRepository("App:User")->findOneBy(["email"=>$email]);
$guest=$em->getRepository("App:Guest")->findOneBy(["email"=>$email,"survey"=>$survey]);
if(!$guest) {
$key = Uuid::uuid4();
$displayname=$data->getDisplayname();
$tonotifyguest=true;
$guest=new Guest();
$guest->setEmail($email);
$guest->setDisplayname($displayname);
$guest->setKey($key);
$guest->setSurvey($survey);
$guest->setTonotifyguest($tonotifyguest);
$guest->setTonotifyowner(false);
}
$guest->setUser($user);
$em->persist($guest);
$em->flush();
return $this->redirect($this->generateUrl('app_survey_byguestkey',["key"=>$guest->getKey()]));
}
return $this->render('Survey/bysurveykey.html.twig',[
'useheader' => false,
'usesidebar' => false,
'survey' => $survey,
'key' => $key,
'form' => $form->createView(),
]);
}
public function byloginkey($key,Request $request) {
$em = $this->getDoctrine()->getManager();
// Recherche de la clé d'invitation
$survey = $em->getRepository("App:Survey")->findOneBy(["key"=>$key]);
if(!$survey) {
return $this->render('Response/nokey.html.twig',[
'useheader' => true,
'usesidebar' => false,
]);
}
// S'assurer que le sondage est public
if($survey->getPrivate()) {
return $this->render('Response/nokey.html.twig',[
'useheader' => true,
'usesidebar' => false,
]);
}
// Si la personne est déjà connectée : on génère une invitation et on le redirige via un accès user
if($this->getUser()) {
$guest = $em->getRepository("App:Guest")->findOneBy(["survey"=>$survey,"user"=>$this->getUser()]);
if(!$guest) {
$key = Uuid::uuid4();
$email=$this->getUser()->getEmail();
$displayname=$this->getUser()->getDisplayname();
$tonotifyguest=true;
$guest=new Guest();
$guest->setEmail($email);
$guest->setDisplayname($displayname);
$guest->setKey($key);
$guest->setSurvey($survey);
$guest->setTonotifyguest($tonotifyguest);
$guest->setTonotifyowner(false);
$guest->setUser($this->getUser());
$em->persist($guest);
$em->flush();
}
return $this->redirect($this->generateUrl('app_survey_byuserkey',["key"=>$survey->getId()]));
}
return $this->render('Response/nokey.html.twig',[
'useheader' => true,
'usesidebar' => false,
]);
}
private function vote(&$request,&$form,&$guest,$by) {
$em = $this->getDoctrine()->getManager();
// Construction de la chaine jsonvotes
$options=$em->getRepository("App:Option")->findBy(["survey"=>$guest->getSurvey()],["date"=>"ASC"]);
$tbvotes=[];
foreach($options as $option) {
$id=$option->getId();
if(!array_key_exists($id,$tbvotes)) {
$tbvotes[$id]=["id"=>$id,"val"=>""];
}
$vote=$em->getRepository("App:Vote")->findOneBy(["guest"=>$guest,"option"=>$option]);
if($vote)
$tbvotes[$id]["val"]=(!is_null($vote->getVote())?$vote->getVote():"");
}
$jsonvotes="[";
$i=0;
foreach($tbvotes as $vote) {
if($i>0) $jsonvotes.=",";
$jsonvotes.=json_encode($vote);
$i++;
}
$jsonvotes.="]";
$guest->setJsonvotes($jsonvotes);
// Création du formulaire
$form = $this->createForm(GuestType::class,$guest,["status"=>$guest->getSurvey()->getStatus()]);
// Récupération des data du formulaire
$form->handleRequest($request);
// Si validation
if($guest->getSurvey()->getStatus()==0) {
if ($form->get('submit')->isClicked() && $form->isValid()) {
$data=$form->getData();
$jsonvotes=json_decode($data->getJsonvotes());
foreach($jsonvotes as $tovote) {
$option=$em->getRepository("App:Option")->find($tovote->id);
if($option) {
$vote=$em->getRepository("App:Vote")->findOneBy(["guest"=>$guest,"option"=>$option]);
if(!$vote) {
$vote= new Vote();
$vote->setGuest($guest);
$vote->setOption($option);
}
$vote->setVote($tovote->val==""?null:$tovote->val);
$em->persist($vote);
$em->flush();
}
}
// Si le vote n'est pas celui du propriétaire : on positionne le flag de notification du owner
if($guest->getUser()!=$guest->getSurvey()->getUser()) {
$guest->setTonotifyowner(true);
$em->persist($vote);
$em->flush();
}
if($by=="byuserkey") return true;
$this->get('session')->getFlashBag()->add("notice", "Votre vote a bien été prise en compte.<br>Vous pouvez à tout moment modifier votre vote via le lien qui vous a été transmis par mail.");
}
}
else
$this->get('session')->getFlashBag()->add("notice", "Ce sondage est clos, voici les résultats des votes");
return false;
}
}