ParticipationController.php 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <?php
  2. namespace App\Controller;
  3. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Component\HttpFoundation\Response;
  6. use Symfony\Component\HttpFoundation\JsonResponse;
  7. use Symfony\Component\Routing\Requirement\Requirement;
  8. use Symfony\Component\Routing\Attribute\Route;
  9. use Doctrine\ORM\EntityManagerInterface;
  10. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  11. use Symfony\Component\Mime\Address;
  12. use Symfony\Component\Mailer\MailerInterface;
  13. use Symfony\Component\Mime\Email;
  14. use App\Entity\Slot;
  15. use App\Entity\Party;
  16. use App\Entity\Event;
  17. use App\Entity\Participation;
  18. use App\Repository\SlotRepository;
  19. use App\Repository\ParticipationRepository;
  20. use App\Form\ParticipationType;
  21. final class ParticipationController extends AbstractController
  22. {
  23. #[Route('/cancel/{id}', name: 'app_participation_cancel', requirements: ['id' => Requirement::UUID_V7], methods: ['GET', 'POST'])]
  24. public function cancel(?Participation $participation, Request $request, EntityManagerInterface $manager, ParticipationRepository $repository): Response
  25. {
  26. if (!$participation) {
  27. // TGCM, ça ressemble à un UUID, mais y'a rien derrière
  28. $this->addFlash('danger', 'Participation inexistante !');
  29. return $this->redirectToRoute('app_main');
  30. }
  31. $redirectPath = 'app_main';
  32. $user = $this->getUser();
  33. if ($user && $user->getEmail() == $participation->getParticipantEmail()) {
  34. // L'utilisateur qui annule est connecté, la page de redirection est sa liste de parties
  35. $redirectPath = 'app_profile_participations';
  36. }
  37. // TODO: prendre en charge l'annulation en une fois de réservations de groupe
  38. // Détecter si d'autres réservations avec la même adresse mail existent -> présnter dans un tableau annexe
  39. $otherParticipations = $repository->findAllByEmail($participation->getParticipantEmail());
  40. if (count($otherParticipations)>1) {
  41. // Plusieurs participations avec la même adresse sur cette partie... OUI, MAIS C'EST PAS LE BON REPO !!!! IL FAUT BRIDER AUX PARTIES !!!!
  42. }
  43. $form = $this->createFormBuilder(FormType::class)->getForm();
  44. $form->handleRequest($request);
  45. if ($form->isSubmitted() && $form->isValid()) {
  46. $game = $participation->getParty()->getGame()->getName();
  47. $gameDate = $participation->getParty()->getStartOn();
  48. $gameDate->setTimezone(new \DateTimeZone($_ENV['APP_TZ']));
  49. $gameDateStr = $gameDate->format('d/m/y H:i');
  50. $manager->remove($participation);
  51. $manager->flush();
  52. $this->addFlash('info', 'Votre participation à '.$game.' du '.$gameDateStr.' a bien été annulée.');
  53. return $this->redirectToRoute($redirectPath);
  54. }
  55. return $this->render('participation/cancel.html.twig' , [
  56. 'form' => $form,
  57. 'participation' => $participation,
  58. 'redirectPath' => $redirectPath,
  59. ]);
  60. }
  61. #[Route('/cancel/{id}/direct', name: 'app_participation_cancel_direct', requirements: ['id' => Requirement::UUID_V7], methods: ['GET', 'POST'])]
  62. public function cancelByAdmin(?Participation $participation, Request $request, EntityManagerInterface $manager): Response
  63. {
  64. if (!$this->isGranted('ROLE_MANAGER')) {
  65. $this->addFlash('danger', 'Seuls les gestionnaires et les admins sont autorisés à utiliser cette fonction.');
  66. return $this->redirectToRoute('app_main');
  67. }
  68. if (!$participation) {
  69. // TGCM, ça ressemble à un UUID, mais y'a rien derrière
  70. $this->addFlash('danger', 'Participation inexistante !');
  71. return $this->redirectToRoute('app_main');
  72. }
  73. $manager->remove($participation);
  74. $manager->flush();
  75. $referer = $request->headers->get('referer');
  76. return $this->redirect($referer);
  77. }
  78. // afficher les détails d'une partie à partir d'un slot et permettre l'inscription
  79. #[Route('/party/participation/{id}', name: 'app_participation', requirements: ['id' => '\d+'], methods: ['GET', 'POST'])]
  80. public function partiticipation(?Slot $slot, Request $request, SlotRepository $slotRepository, EntityManagerInterface $manager, MailerInterface $mailer): Response
  81. {
  82. $party = $slot->getParty();
  83. if (!$party) {
  84. $this->addFlash('danger', 'Aucune partie associée à ce slot !');
  85. $referer = $request->headers->get('referer');
  86. return $this->redirect($referer);
  87. }
  88. $user=$this->getUser();
  89. // Si un utilisateur est connecté et que ce n'est ni un admin, ni un gestionnaire, ni le MJ de cette partie
  90. if ($user) {
  91. $roles = $user->getRoles();
  92. // Gestionnaire ou admin -> annuler l'user
  93. if (in_array("ROLE_MANAGER", $roles) || in_array("ROLE_ADMIN", $roles)) {
  94. $user = null;
  95. } elseif (in_array("ROLE_STAFF", $roles) && $party->getGamemaster() == $user->getLinkToGamemaster()) {
  96. $user = null;
  97. }
  98. }
  99. // Préparation du formulaire de participation
  100. $participation = new Participation();
  101. $participation->setParty($party);
  102. if ($user) {
  103. $participation->setParticipantName($user->getFullName());
  104. $participation->setParticipantEmail($user->getEmail());
  105. $participation->setParticipantPhone($user->getPhone());
  106. }
  107. $form = $this->createForm(ParticipationType::class, $participation);
  108. // Traitement des entrées du formulaire
  109. $form->handleRequest($request);
  110. if ($form->isSubmitted() && $form->isValid()) {
  111. // Récupérer le tableau des accompagnant.e envoyé
  112. $partyMore = $request->request->all('party_more');
  113. // Garder uniquement les noms non vides
  114. $partyMore = array_filter($partyMore, fn($name) => trim($name) !== '');
  115. // Réindexer pour avoir un tableau propre (0, 1, 2, ...)
  116. $partyMore = array_values($partyMore);
  117. // On contrôle qu'il y a encore de la place, sinon -> erreur
  118. if ($party->getSeatsLeft() < 1) {
  119. if ($party->getSeatsLeft() > 0) {
  120. $this->addFlash('danger', 'Il n\'y a pas assez de places pour vous accueillir sur cette partie.');
  121. } else {
  122. $this->addFlash('danger', 'Il n\'y a plus de places pour vous accueillir sur cette partie.');
  123. }
  124. } else {
  125. $reservationsCounter = 1;
  126. // On enregistre dans la base
  127. $manager->persist($participation);
  128. $manager->flush();
  129. // Envoyer un mail
  130. // Maintenant uniquement pour avoir l'ID
  131. $email = (new TemplatedEmail())
  132. ->from(new Address($_ENV['CONTACT_EMAIL'], $_ENV['CONTACT_NAME']))
  133. ->to((string) $participation->getParticipantEmail())
  134. ->subject('Votre réservation pour '.$party->getGame()->getName())
  135. ->htmlTemplate('participation/booking.email.html.twig')
  136. ->textTemplate('participation/booking.email.txt.twig')
  137. ->context([
  138. 'participation' => $participation,
  139. ]);
  140. $mailer->send($email);
  141. // On traite les accompagnant.e.s
  142. foreach ($partyMore as $companion) {
  143. $newParticipation = new Participation;
  144. $newParticipation->setParty($participation->getParty());
  145. $newParticipation->setParticipantName($companion);
  146. $newParticipation->setParticipantEmail($participation->getParticipantEmail());
  147. $newParticipation->setParticipantPhone($participation->getParticipantPhone());
  148. $manager->persist($newParticipation);
  149. $manager->flush();
  150. $email = (new TemplatedEmail())
  151. ->from(new Address($_ENV['CONTACT_EMAIL'], $_ENV['CONTACT_NAME']))
  152. ->to((string) $participation->getParticipantEmail())
  153. ->subject('Votre réservation pour '.$party->getGame()->getName())
  154. ->htmlTemplate('participation/booking.email.html.twig')
  155. ->textTemplate('participation/booking.email.txt.twig')
  156. ->context([
  157. 'participation' => $newParticipation,
  158. ]);
  159. $mailer->send($email);
  160. $reservationsCounter++;
  161. }
  162. // On informe
  163. if ($reservationsCounter > 1) {
  164. $this->addFlash('success', $reservationsCounter.' réservations enregistrées.');
  165. } else {
  166. $this->addFlash('success', 'Réservation enregistrée.');
  167. }
  168. }
  169. //$this->redirectToRoute('app_main_booking', ['id' => $party->getEvent()->getId()]);
  170. $referer = $request->headers->get('referer');
  171. return $this->redirect($referer);
  172. }
  173. // Affichage de la modale
  174. return $this->render('participation/_modal.add.html.twig', [
  175. 'party' => $party,
  176. 'slot' => $slot,
  177. 'form' => $form,
  178. 'pathController' => 'app_participation'
  179. ]);
  180. }
  181. }