src/Controller/ApplicationController.php line 403

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Content;
  4. use App\Entity\Event;
  5. use App\Entity\Invitee;
  6. use App\Entity\Lineup;
  7. use App\Entity\News;
  8. use App\Entity\Purchase;
  9. use App\Entity\Sponsor;
  10. use App\Entity\Stage;
  11. use App\Form\InviteeType;
  12. use App\Form\PurchaseEmailType;
  13. use App\Form\PurchaseLoginType;
  14. use App\Repository\ArtistRepository;
  15. use App\Repository\ContentRepository;
  16. use App\Repository\FaqRepository;
  17. use App\Repository\FoodRepository;
  18. use App\Repository\InviteeRepository;
  19. use App\Repository\LineupRepository;
  20. use App\Repository\NewsRepository;
  21. use App\Repository\PurchaseRepository;
  22. use App\Repository\SponsorRepository;
  23. use App\Repository\StageRepository;
  24. use App\Service\PurchaseHelper;
  25. use App\Service\TicketTailorApi;
  26. use Doctrine\Persistence\ManagerRegistry;
  27. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  28. use Symfony\Component\Form\FormInterface;
  29. use Symfony\Component\HttpFoundation\Cookie;
  30. use Symfony\Component\HttpFoundation\RedirectResponse;
  31. use Symfony\Component\HttpFoundation\Request;
  32. use Symfony\Component\HttpFoundation\Response;
  33. use Symfony\Component\Routing\Annotation\Route;
  34. class ApplicationController extends AbstractController
  35. {
  36.     private array $orders = [];
  37.     private ManagerRegistry $doctrine;
  38.     private ?Event $currentEvantevent;
  39.     private ?FormInterface $shareForm null;
  40.     private PurchaseHelper $purchaseHelper;
  41.     public function __construct(ManagerRegistry $doctrinePurchaseHelper $purchaseHelper)
  42.     {
  43.         $this->doctrine $doctrine;
  44.         $this->purchaseHelper $purchaseHelper;
  45.         $this->currentEvantevent $this->doctrine->getRepository(Event::class)->findOneBy(['state'=>Event::STATE_ACTIVE]);
  46.     }
  47.     /**
  48.      * @Route("/", name="feapp_landing")
  49.      * @Route("/ticket_login", name="feapp_landing_login")
  50.      */
  51.     public function landing(
  52.         Request $request,
  53.         PurchaseHelper $helper,
  54.         PurchaseRepository $repository,
  55.         InviteeRepository $inviteeRepository,
  56.         TicketTailorApi $api,
  57.         Purchase $purchase=null
  58.     ): Response
  59.     {
  60.         if ($request->get('_route')=='feapp_landing_login') {
  61.             $request->getSession()->set('login_session',true);
  62.             $request->cookies->remove('no_ticket');
  63.         } else {
  64.             if ($this->validSession($requesttrue)) {
  65.                 return $this->redirectToRouteClearNoTicket($request'feapp_home');
  66.             } else {
  67.                 return $this->anonymousLogin($request);
  68.             }
  69.         }
  70.         $new false;
  71.         if (!$purchase) {
  72.             $purchase = new Purchase();
  73.             $new true;
  74.         } elseif ($request->get('_route')=='upgrade_landing_email') {
  75.             $purchase->setCampaignClickedAt(new \DateTimeImmutable());
  76.             $this->doctrine->getManager()->persist($purchase);
  77.             $this->doctrine->getManager()->flush();
  78.         }
  79.         $form $this->createForm(PurchaseEmailType::class, $purchase);
  80.         $form->handleRequest($request);
  81.         if ($form->isSubmitted() && $form->isValid()) {
  82.             $_email $purchase->getEmail();
  83.             if (!$new) {
  84.                 $this->doctrine->getManager()->refresh($purchase);
  85.             }
  86.             unset($purchase);
  87.             $_purchase $repository->findOneBy([
  88.                 'email'=>$_email,
  89.                 'event'=>$this->currentEvantevent
  90.             ]);
  91.             if (!$_purchase) {
  92.                 $_purchase $api->getOrderByEmail($form->get('email')->getData(), $this->currentEvantevent->getTicketTailorEventId());
  93.             }
  94.             if ($_purchase) {
  95.                 $helper->generateLoginCode($_purchase);
  96.                 $this->doctrine->getManager()->persist($_purchase);
  97.                 $this->doctrine->getManager()->flush();
  98.                 $helper->sendAppLoginCode($_purchase);
  99.                 $this->addFlash('info''Please check your '.$_purchase->getEmail().' email for security code.');
  100.                 return $this->redirectToRouteClearNoTicket($request'feapp_login',['id'=>$_purchase->getId()]);
  101.             }
  102.             // No purchases. Look for invitations
  103.             $_invitation $inviteeRepository->findOneBy(['email'=>$form->get('email')->getData()]);
  104.             if ($_invitation) {
  105.                 $helper->generateLoginCode($_invitation);
  106.                 $this->doctrine->getManager()->persist($_invitation);
  107.                 $this->doctrine->getManager()->flush();
  108.                 $helper->sendAppLoginCode($_invitation);
  109.                 $this->addFlash('info''Please check your '.$form->get('email')->getData().' email for security code.');
  110.                 return $this->redirectToRouteClearNoTicket($request'feapp_login',['id'=>$_invitation->getPurchase()->getId()]);
  111.             }
  112.             $this->addFlash('warning''We were not able to find your order. Please check information you provided.');
  113.         }
  114.         if (!$request->cookies->has('no_ticket')) {
  115.             $response = new Response();
  116.             $response->headers->clearCookie('no_ticket');
  117.         } else {
  118.             $response null;
  119.         }
  120.         return $this->render(
  121.             'feSecurity/landing.html.twig',
  122.             [
  123.                 'form'=>$form->createView(),
  124.                 'event'=>$this->currentEvantevent
  125.             ],
  126.             $response
  127.         );
  128.     }
  129.     /**
  130.      * @Route("/app/anonymous-login", name="feapp_login_anonymously", methods={"POST"})
  131.      */
  132.     public function anonymousLogin(Request $request): Response
  133.     {
  134.         $request->getSession()->remove('order');
  135.         $request->getSession()->remove('login_session');
  136.         $request->cookies->remove('anonymos-visitor');
  137.         $cookie Cookie::create('no_ticket')
  138.             ->withValue('lowdefest')
  139.             ->withExpires(new \DateTime('+3 hours'))
  140.             ->withSecure(true);
  141.         $response = new RedirectResponse($this->generateUrl('feapp_home', [],Response::HTTP_SEE_OTHER));
  142.         $response->headers->setCookie($cookie);
  143.         return $response;
  144.     }
  145.     /**
  146.      * @Route("/app/resync-tickets", name="feapp_resync_tickets", methods={"POST"})
  147.      */
  148.     public function resyncTickets(Request $requestTicketTailorApi $api): Response
  149.     {
  150.         if (!$this->validSession($request)) {
  151.             $this->addFlash('warning','You session expired. Please login once more.');
  152.             return $this->redirectToRoute('feapp_landing');
  153.         }
  154.         if (count($this->orders['purchased'])) {
  155.             $api->getOrderByEmail($this->orders['purchased'][0]->getEmail(), $this->currentEvantevent->getTicketTailorEventId());
  156.             $this->addFlash('success''You tickets are in sync with TicketTailor.');
  157.         } else {
  158.             $this->addFlash('warning''No tickets were found in your session.');
  159.         }
  160.         return $this->redirectToRoute('feapp_home');
  161.     }
  162.     /**
  163.      * @Route("/app/{id}/login", name="feapp_login")
  164.      * @Route("/app/{id}/login/{code}", name="feapp_login_code")
  165.      */
  166.     public function login(Request $requestPurchase $purchase$code ''): Response
  167.     {
  168.         if ( !$purchase->isValidInviteeLoginCode() ) {
  169.             $this->addFlash('warning''You login request has been expired. Please request the new login code.');
  170.             return $this->redirectToRoute('feapp_landing_login');
  171.         }
  172.         $formPurchase = clone $purchase;
  173.         $formPurchase->setLoginCode($code);
  174.         $form $this->createForm(PurchaseLoginType::class, $formPurchase);
  175.         $form->handleRequest($request);
  176.         if ($form->isSubmitted() && $form->isValid()) {
  177.             if ( $loginObject $purchase->checkLoginCode($formPurchase->getLoginCode()) ) {
  178.                 $request->getSession()->set('order', [
  179.                     'email'=>$loginObject->getEmail(),
  180.                     'event'=>($loginObject instanceof Purchase)?$loginObject->getEvent()->getId():$loginObject->getPurchase()->getEvent()->getId()
  181.                 ]);
  182.                 $request->getSession()->remove('login_session');
  183.                 $loginObject->setLoginCodeExpireAt(null);
  184.                 $this->doctrine->getManager()->persist($loginObject);
  185.                 $this->doctrine->getManager()->flush();
  186.                 return $this->redirectToRoute('feapp_home');
  187.             }  else {
  188.                 $this->addFlash('danger''Invalid login code. Please check your email for a valid login code.');
  189.             }
  190.         }
  191.         return $this->render('feSecurity/login.html.twig', [
  192.             'form'=>$form->createView(),
  193.             'event'=>$this->currentEvantevent
  194.         ]);
  195.     }
  196.     /**
  197.      * @Route("/app", name="feapp_home")
  198.      */
  199.     public function home(
  200.         Request $request,
  201.         ArtistRepository $repository
  202.     ): Response
  203.     {
  204.         if (!$this->validSession($request)) {
  205.             $this->addFlash('warning','You session expired. Please login once more.');
  206.             return $this->redirectToRoute('feapp_landing');
  207.         }
  208.         return $this->render('feHome.html.twig', [
  209.             //'artists' => $repository->getRandom(3),
  210.             'artists' => $repository->getRandom(25$this->currentEvantevent),
  211.             'content' => $this->doctrine->getRepository(Content::class)->findBy(['event'=>$this->currentEvantevent],['position'=>'ASC']),
  212.             'event' => $this->currentEvantevent,
  213.         ]);
  214.     }
  215.     /**
  216.      * @Route("/app/news", name="feapp_news")
  217.      */
  218.     public function news(Request $requestNewsRepository $newsRepository): Response
  219.     {
  220.         if (!$this->validSession($request)) {
  221.             $this->addFlash('warning','You session expired. Please login once more.');
  222.             return $this->redirectToRoute('feapp_landing');
  223.         }
  224.         return $this->render('news.html.twig', [
  225.             'news' => $newsRepository->findCurrentNews(new \DateTimeImmutable(),  $this->currentEvantevent),
  226.             'event'=>$this->currentEvantevent,
  227.         ]);
  228.     }
  229.     /**
  230.      * @Route("/app/news/{id}", name="feapp_news_details")
  231.      */
  232.     public function newsDetails(Request $requestNews $article): Response
  233.     {
  234.         if (!$this->validSession($request)) {
  235.             $this->addFlash('warning','You session expired. Please login once more.');
  236.             return $this->redirectToRoute('feapp_landing');
  237.         }
  238.         return $this->render('newsDetails.html.twig', [
  239.             'article' => $article,
  240.             'event'=>$this->currentEvantevent,
  241.         ]);
  242.     }
  243.     /**
  244.      * @Route("/app/artists", name="feapp_artists")
  245.      */
  246.     public function artists(Request $requestArtistRepository $repository): Response
  247.     {
  248.         if (!$this->validSession($request)) {
  249.             $this->addFlash('warning','You session expired. Please login once more.');
  250.             return $this->redirectToRoute('feapp_landing');
  251.         }
  252.         return $this->render('artists.html.twig', [
  253.             'artists' => $repository->findByEvent($this->currentEvantevent),
  254.             'event'=>$this->currentEvantevent,
  255.         ]);
  256.     }
  257.     /**
  258.      * @Route("/app/stages", name="feapp_stages")
  259.      */
  260.     public function stages(Request $requestStageRepository $repository): Response
  261.     {
  262.         if (!$this->validSession($request)) {
  263.             $this->addFlash('warning','You session expired. Please login once more.');
  264.             return $this->redirectToRoute('feapp_landing');
  265.         }
  266.         return $this->render('stages.html.twig', [
  267.             'stages' => $repository->findByEvent($this->currentEvantevent),
  268.             'event'=>$this->currentEvantevent,
  269.         ]);
  270.     }
  271.     /**
  272.      * @Route("/app/lineup", name="feapp_lineup")
  273.      * @Route("/app/lineup/{id}", name="feapp_lineup_stage")
  274.      */
  275.     public function lineup(
  276.         Request $request,
  277.         StageRepository $repository,
  278.         LineupRepository $luRepository,
  279.         Stage $stage=null
  280.     ): Response
  281.     {
  282.         if (!$this->validSession($request)) {
  283.             $this->addFlash('warning','You session expired. Please login once more.');
  284.             return $this->redirectToRoute('feapp_landing');
  285.         }
  286.         return $this->render('lineup.html.twig', [
  287.             'stages' => $repository->findByEvent($this->currentEvantevent),
  288.             'stage' => $stage,
  289.             'lineups' => $luRepository->getRecordsByStage($stage$this->currentEvantevent),
  290.             'event'=>$this->currentEvantevent,
  291.         ]);
  292.     }
  293.     /**
  294.      * @Route("/app/faqs", name="feapp_faqs")
  295.      */
  296.     public function faqs(
  297.         Request $request,
  298.         FaqRepository $repository
  299.     ): Response
  300.     {
  301.         if (!$this->validSession($request)) {
  302.             $this->addFlash('warning','You session expired. Please login once more.');
  303.             return $this->redirectToRoute('feapp_landing');
  304.         }
  305.         return $this->render('faqs.html.twig', [
  306.             'faqs'=>$repository->findAll(),
  307.             'event'=>$this->currentEvantevent,
  308.         ]);
  309.     }
  310.     /**
  311.      * @Route("/app/sponsors", name="feapp_sponsors")
  312.      */
  313.     public function sponsors(
  314.         Request $request,
  315.         SponsorRepository $repository
  316.     ): Response
  317.     {
  318.         if (!$this->validSession($request)) {
  319.             $this->addFlash('warning','You session expired. Please login once more.');
  320.             return $this->redirectToRoute('feapp_landing');
  321.         }
  322.         return $this->render('sponsors.html.twig', [
  323.             'sponsors'=>$repository->findAllSponsors($this->currentEvantevent),
  324.             'event'=>$this->currentEvantevent,
  325.         ]);
  326.     }
  327.     /**
  328.      * @Route("/app/local_busines_partners", name="feapp_partners")
  329.      */
  330.     public function businessPartners(
  331.         Request $request,
  332.         SponsorRepository $repository
  333.     ): Response
  334.     {
  335.         if (!$this->validSession($request)) {
  336.             $this->addFlash('warning','You session expired. Please login once more.');
  337.             return $this->redirectToRoute('feapp_landing');
  338.         }
  339.         return $this->render('partners.html.twig', [
  340.             'sponsors'=>$repository->findAllPartners($this->currentEvantevent),
  341.             'event'=>$this->currentEvantevent,
  342.         ]);
  343.     }
  344.     /**
  345.      * @Route("/app/sponsors/{id}", name="feapp_sponsors_details")
  346.      */
  347.     public function sponsorDetails(
  348.         Request $request,
  349.         Sponsor $sponsor
  350.     ): Response
  351.     {
  352.         if (!$this->validSession($request)) {
  353.             $this->addFlash('warning','You session expired. Please login once more.');
  354.             return $this->redirectToRoute('feapp_landing');
  355.         }
  356.         return $this->render('sponsorDetails.html.twig', [
  357.             'sponsor' => $sponsor,
  358.             'event'=>$this->currentEvantevent,
  359.         ]);
  360.     }
  361.     protected function getUpcoming()
  362.     {
  363.         if ((new \DateTimeImmutable())>$this->currentEvantevent->getStartAt()) {
  364.             return $this->getDoctrine()->getRepository(Lineup::class)->getGlobalUpcoming(new \DateTimeImmutable('+1 hour'));
  365.         }
  366.         return [];
  367.     }
  368.     protected function getOnAir()
  369.     {
  370.         if ((new \DateTimeImmutable())>$this->currentEvantevent->getStartAt()) {
  371.             return $this->getDoctrine()->getRepository(Lineup::class)->getGlobalOnAir();
  372.         }
  373.         return [];
  374.     }
  375.     protected function validSession(Request $requestbool $noGuests false): bool
  376.     {
  377.         $template = [
  378.             'purchased'=>[],
  379.             'invited'=>[],
  380.         ];
  381.         if (
  382.             $request->getSession()->has('order')
  383.         ) {
  384.             $s $request->getSession()->get('order');
  385.             if (isset($s['email']) && isset($s['event'])) {
  386.                 $event $this->doctrine->getRepository(Event::class)->find($s['event']);
  387.                 $this->orders $this->purchaseHelper->getAllAvailablePurchases($s['email'], $event);
  388.                 if (count($this->orders['purchased']) || count($this->orders['invited'])) {
  389.                     return true;
  390.                 }
  391.             }
  392.         } elseif ($request->cookies->has('no_ticket') && !$noGuests) {
  393.             $this->orders $template;
  394.             return true;
  395.         }
  396.         $this->orders $template;
  397.         return false;
  398.     }
  399.     /**
  400.      * @Route("/app/directions", name="feapp_directions")
  401.      */
  402.     public function directionsMap(
  403.         Request $request
  404.     ): Response
  405.     {
  406.         if (!$this->validSession($request)) {
  407.             $this->addFlash('warning','You session expired. Please login once more.');
  408.             return $this->redirectToRoute('feapp_landing');
  409.         }
  410.         return $this->render('sponsors.html.twig', [
  411.             'event'=>$this->currentEvantevent,
  412.         ]);
  413.     }
  414.     /**
  415.      * @Route("/app/taxi", name="feapp_taxi")
  416.      */
  417.     public function bookTaxi(
  418.         Request $request,
  419.         ContentRepository $repository
  420.     ): Response
  421.     {
  422.         if (!$this->validSession($request)) {
  423.             $this->addFlash('warning','You session expired. Please login once more.');
  424.             return $this->redirectToRoute('feapp_landing');
  425.         }
  426.         return $this->render('taxi.html.twig', [
  427.             'content'=>$repository->get('taxi'),
  428.             'event'=>$this->currentEvantevent,
  429.         ]);
  430.     }
  431.     /**
  432.      * @Route("/app/directions", name="feapp_directions")
  433.      */
  434.     public function directions(
  435.         Request $request,
  436.         ContentRepository $repository
  437.     ): Response
  438.     {
  439.         if (!$this->validSession($request)) {
  440.             $this->addFlash('warning','You session expired. Please login once more.');
  441.             return $this->redirectToRoute('feapp_landing');
  442.         }
  443.         return $this->render('directions.html.twig', [
  444.             'content'=>$repository->get('directions'),
  445.             'event'=>$this->currentEvantevent,
  446.         ]);
  447.     }
  448.     /**
  449.      * @Route("/app/about-lowdefest", name="feapp_about")
  450.      */
  451.     public function adout(
  452.         Request $request,
  453.         ContentRepository $repository
  454.     ): Response
  455.     {
  456.         if (!$this->validSession($request)) {
  457.             $this->addFlash('warning','You session expired. Please login once more.');
  458.             return $this->redirectToRoute('feapp_landing');
  459.         }
  460.         return $this->render('cms.html.twig', [
  461.             'content'=>$repository->get('about'),
  462.             'event'=>$this->currentEvantevent,
  463.         ]);
  464.     }
  465.     /**
  466.      * @Route("/app/about-lowde-music-trust", name="feapp_about_trust")
  467.      */
  468.     public function aboutTrust(
  469.         Request $request,
  470.         ContentRepository $repository
  471.     ): Response
  472.     {
  473.         if (!$this->validSession($request)) {
  474.             $this->addFlash('warning','You session expired. Please login once more.');
  475.             return $this->redirectToRoute('feapp_landing');
  476.         }
  477.         return $this->render('cms.html.twig', [
  478.             'content'=>$repository->get('about-trust'),
  479.             'event'=>$this->currentEvantevent,
  480.         ]);
  481.     }
  482.     /**
  483.      * @Route("/app/food-and-bars", name="feapp_food")
  484.      */
  485.     public function foodAndBars(
  486.         Request $request,
  487.         FoodRepository $repository
  488.     ): Response
  489.     {
  490.         if (!$this->validSession($request)) {
  491.             $this->addFlash('warning','You session expired. Please login once more.');
  492.             return $this->redirectToRoute('feapp_landing');
  493.         }
  494.         return $this->render('food.html.twig', [
  495.             'content'=>$repository->findByEvent($this->currentEvantevent),
  496.             'event'=>$this->currentEvantevent,
  497.         ]);
  498.     }
  499.     protected function render(string $view, array $parameters = [], Response $response null): Response
  500.     {
  501.         if (!$this->shareForm) {
  502.             $invitee = new Invitee();
  503.             $this->shareForm $this->createForm(InviteeType::class, $invitee);
  504.         }
  505.         $shared = [
  506.             'orders'=>$this->orders,
  507.             'upcoming' => $this->getUpcoming(),
  508.             'onAir' => $this->getOnAir(),
  509.             'shareForm' => $this->shareForm->createView(),
  510.             'currentEvent' => $this->currentEvantevent,
  511.         ];
  512.         return parent::render($viewarray_merge($shared$parameters), $response);
  513.     }
  514.     /**
  515.      * @Route("/app/share/{id}", name="feapp_share_ticket", methods={"POST"})
  516.      */
  517.     public function addInvitation(Request $requestPurchase $purchaseManagerRegistry $doctrine): Response
  518.     {
  519.         if (!$this->validSession($request)) {
  520.             $this->addFlash('warning','You session expired. Please login once more.');
  521.             return $this->redirectToRoute('feapp_landing');
  522.         }
  523.         foreach ($this->orders['invited'] as $order) {
  524.             if ($order->getId()==$purchase->getId()) {
  525.                 $this->addFlash(
  526.                     'danger',
  527.                     'You can share only your own tickets',
  528.                 );
  529.                 return $this->redirectToRoute('feapp_home');
  530.             }
  531.         }
  532.         $invitee = new Invitee();
  533.         $this->shareForm $this->createForm(InviteeType::class, $invitee);
  534.         $this->shareForm->handleRequest($request);
  535.         if ($this->shareForm->isSubmitted() && $this->shareForm->isValid()) {
  536.             $purchase->addInvitee($invitee);
  537.             $doctrine->getManager()
  538.                 ->persist($purchase);
  539.             $doctrine->getManager()->flush();
  540.             $this->addFlash(
  541.                 'success',
  542.                 'You shared your ticket with '.$invitee->getEmail()
  543.             );
  544.             $this->purchaseHelper->sendSharedTickets($invitee);
  545.         }
  546.         return $this->redirectToRoute('feapp_home');
  547.     }
  548.     /**
  549.      * Returns a RedirectResponse to the given route with the given parameters.
  550.      */
  551.     protected function redirectToRouteClearNoTicket(Request $requeststring $route, array $parameters = [], int $status 302): RedirectResponse
  552.     {
  553.         $response = new RedirectResponse($this->generateUrl($route$parameters), $status);
  554.         if (!$request->cookies->has('no_ticket')) {
  555.             $response->headers->clearCookie('no_ticket');
  556.         }
  557.         return $response;
  558.     }
  559.     /**
  560.      * @Route("/app/pages/{slug}", name="feapp_page", methods={"GET"})
  561.      */
  562.     public function genericContent(
  563.         Request $request,
  564.         ContentRepository $repository
  565.     ): Response
  566.     {
  567.         $content $repository->findOneBy(
  568.             [
  569.                 'code'=>$request->get('slug'),
  570.                 'event'=>$this->currentEvantevent,
  571.             ]
  572.         );
  573.         if (!$this->validSession($request)) {
  574.             $this->addFlash('warning','You session expired. Please login once more.');
  575.             return $this->redirectToRoute('feapp_landing');
  576.         }
  577.         if (!$content ) {
  578.             return $this->redirectToRoute('feapp_home');
  579.         }
  580.         return $this->render('genericContent.html.twig', [
  581.             'event'=>$this->currentEvantevent,
  582.             'content'=>$content,
  583.         ]);
  584.     }
  585. }