ParticipationController.php 8.9 KB

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