3 namespace Rapsys\AirBundle\Controller
;
5 use Doctrine\Bundle\DoctrineBundle\Registry
;
6 use Doctrine\ORM\EntityManagerInterface
;
7 use Symfony\Component\Form\FormError
;
8 use Symfony\Component\HttpFoundation\Request
;
9 use Symfony\Component\HttpFoundation\Response
;
10 use Symfony\Component\Routing\Exception\MethodNotAllowedException
;
11 use Symfony\Component\Routing\Exception\ResourceNotFoundException
;
12 use Symfony\Component\Routing\RequestContext
;
14 use Rapsys\AirBundle\Entity\Application
;
15 use Rapsys\AirBundle\Entity\Location
;
16 use Rapsys\AirBundle\Entity\Session
;
17 use Rapsys\AirBundle\Entity\Slot
;
18 use Rapsys\AirBundle\Entity\User
;
20 class ApplicationController
extends AbstractController
{
24 * @desc Persist application and all required dependencies in database
26 * @param Request $request The request instance
27 * @param Registry $manager The doctrine registry
28 * @param EntityManagerInterface $manager The doctrine entity manager
30 * @return Response The rendered view or redirection
32 * @throws \RuntimeException When user has not at least guest role
34 public function add(Request
$request, Registry
$doctrine, EntityManagerInterface
$manager) {
35 //Prevent non-guest to access here
36 $this->denyAccessUnlessGranted('ROLE_GUEST', null, $this->translator
->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator
->trans('Guest')]));
38 //Get favorites locations
39 $locationFavorites = $doctrine->getRepository(Location
::class)->findByUserId($this->getUser()->getId());
41 //Set location default
42 $locationDefault = current($locationFavorites);
45 if ($this->isGranted('ROLE_ADMIN')) {
47 $locations = $doctrine->getRepository(Location
::class)->findAll();
50 //Restrict to favorite locations
51 $locations = $locationFavorites;
54 $locationFavorites = [];
57 //Create ApplicationType form
58 $form = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [
60 'action' => $this->generateUrl('rapsys_air_application_add'),
61 //Set the form attribute
62 #'attr' => [ 'class' => 'col' ],
63 //Set location choices
64 'location_choices' => $locations,
65 //Set location default
66 'location_default' => $locationDefault,
67 //Set location favorites
68 'location_favorites' => $locationFavorites,
70 'user' => $this->isGranted('ROLE_ADMIN'),
72 'user_choices' => $doctrine->getRepository(User
::class)->findAllWithTranslatedGroupAndCivility($this->translator
),
73 //Set default user to current
74 'user_default' => $this->getUser()->getId(),
75 //Set default slot to evening
76 //XXX: default to Evening (3)
77 'slot_default' => $doctrine->getRepository(Slot
::class)->findOneByTitle('Evening')
80 //Refill the fields in case of invalid form
81 $form->handleRequest($request);
84 if (!$form->isSubmitted() || !$form->isValid()) {
86 $title = $this->translator
->trans('Application add');
89 return $this->render('@RapsysAir/application/add.html.twig', ['title' => $title, 'form' => $form->createView()]+
$this->context
);
93 $data = $form->getData();
95 //Protect session fetching
98 $session = $doctrine->getRepository(Session
::class)->findOneByLocationSlotDate($data['location'], $data['slot'], $data['date']);
99 //Catch no session case
100 } catch (\Doctrine\ORM\NoResultException
$e) {
102 $session = new Session();
103 $session->setLocation($data['location']);
104 $session->setDate($data['date']);
105 $session->setSlot($data['slot']);
106 $session->setCreated(new \
DateTime('now'));
107 $session->setUpdated(new \
DateTime('now'));
110 $short = $data['location']->getShort();
113 $slot = $data['slot']->getTitle();
116 //XXX: premium is stored only for Afternoon and Evening
117 $premium = $session->isPremium();
119 //Set default length at 6h
120 //XXX: date part will be truncated on save
121 $session->setLength(new \
DateTime('06:00:00'));
124 if ($this->isGranted('ROLE_ADMIN')) {
126 if ($slot == 'Morning') {
128 $session->setBegin(new \
DateTime('09:00:00'));
131 $session->setLength(new \
DateTime('05:00:00'));
133 } elseif ($slot == 'Afternoon') {
135 $session->setBegin(new \
DateTime('18:00:00'));
138 $session->setLength(new \
DateTime('05:00:00'));
140 //Check if next day is premium
143 $session->setLength(new \
DateTime('07:00:00'));
146 } elseif ($slot == 'Evening') {
148 $session->setBegin(new \
DateTime('20:00:00'));
150 //Check if next day is premium
153 $session->setLength(new \
DateTime('07:00:00'));
157 #$session->setLength(new \DateTime('04:30:00'));
161 $session->setBegin(new \
DateTime('01:00:00'));
164 $session->setLength(new \
DateTime('04:00:00'));
166 //Check if next day is premium
169 $session->setBegin(new \
DateTime('02:00:00'));
172 $session->setLength(new \
DateTime('03:00:00'));
175 //Docks => 14h -> 19h | 19h -> 01/02h
176 //XXX: remove Garnier from here to switch back to 21h
177 } elseif (in_array($short, ['Docks', 'Garnier']) && in_array($slot, ['Afternoon', 'Evening', 'After'])) {
179 if ($slot == 'Afternoon') {
181 $session->setBegin(new \
DateTime('14:00:00'));
184 $session->setLength(new \
DateTime('05:00:00'));
186 } elseif ($slot == 'Evening') {
188 $session->setBegin(new \
DateTime('19:00:00'));
190 //Check if next day is premium
193 $session->setLength(new \
DateTime('07:00:00'));
198 $session->setBegin(new \
DateTime('01:00:00'));
201 $session->setLength(new \
DateTime('04:00:00'));
203 //Check if next day is premium
206 $session->setBegin(new \
DateTime('02:00:00'));
209 $session->setLength(new \
DateTime('03:00:00'));
212 //Garnier => 21h -> 01/02h
213 } elseif ($short == 'Garnier' && in_array($slot, ['Evening', 'After'])) {
215 if ($slot == 'Evening') {
217 $session->setBegin(new \
DateTime('21:00:00'));
220 $session->setLength(new \
DateTime('05:00:00'));
222 //Check if next day is premium
225 $session->setLength(new \
DateTime('06:00:00'));
230 $session->setBegin(new \
DateTime('01:00:00'));
233 $session->setLength(new \
DateTime('04:00:00'));
235 //Check if next day is premium
238 $session->setBegin(new \
DateTime('02:00:00'));
241 $session->setLength(new \
DateTime('03:00:00'));
244 //Trocadero|Tokyo|Swan|Honore|Orsay => 19h -> 01/02h
245 } elseif (in_array($short, ['Trocadero', 'Tokyo', 'Swan', 'Honore', 'Orsay']) && in_array($slot, ['Evening', 'After'])) {
247 if ($slot == 'Evening') {
249 $session->setBegin(new \
DateTime('19:00:00'));
251 //Check if next day is premium
254 $session->setLength(new \
DateTime('07:00:00'));
259 $session->setBegin(new \
DateTime('01:00:00'));
262 $session->setLength(new \
DateTime('04:00:00'));
264 //Check if next day is premium
267 $session->setBegin(new \
DateTime('02:00:00'));
270 $session->setLength(new \
DateTime('03:00:00'));
273 //La Villette => 14h -> 19h
274 } elseif ($short == 'Villette' && $slot == 'Afternoon') {
276 $session->setBegin(new \
DateTime('14:00:00'));
279 $session->setLength(new \
DateTime('05:00:00'));
280 //Place Colette => 14h -> 21h
281 //TODO: add check here that it's a millegaux account ?
282 } elseif ($short == 'Colette' && $slot == 'Afternoon') {
284 $session->setBegin(new \
DateTime('14:00:00'));
287 $session->setLength(new \
DateTime('07:00:00'));
288 //Galerie d'Orléans => 14h -> 18h
289 } elseif ($short == 'Orleans' && $slot == 'Afternoon') {
291 $session->setBegin(new \
DateTime('14:00:00'));
294 $session->setLength(new \
DateTime('04:00:00'));
295 //Jardin du Monde => 14h -> 15h
296 } elseif ($short == 'Monde' && $slot == 'Morning') {
298 $session->setBegin(new \
DateTime('14:00:00'));
301 $session->setLength(new \
DateTime('01:00:00'));
302 //Combination not supported
304 //Add error in flash message
305 $this->addFlash('error', $this->translator
->trans('Session on %date% %location% %slot% not yet supported', ['%location%' => $this->translator
->trans('at '.$data['location']), '%slot%' => $this->translator
->trans('the '.strtolower($data['slot'])), '%date%' => $data['date']->format('Y-m-d')]));
308 $section = $this->translator
->trans('Application add');
311 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
314 return $this->render('@RapsysAir/application/add.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView()]+
$this->context
);
318 if (!$this->isGranted('ROLE_ADMIN') && $session->getStart() < new \
DateTime('00:00:00')) {
319 //Add error in flash message
320 $this->addFlash('error', $this->translator
->trans('Session in the past on %date% %location% %slot% not yet supported', ['%location%' => $this->translator
->trans('at '.$data['location']), '%slot%' => $this->translator
->trans('the '.strtolower($data['slot'])), '%date%' => $data['date']->format('Y-m-d')]));
323 $section = $this->translator
->trans('Application add');
326 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
329 return $this->render('@RapsysAir/application/add.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView()]+
$this->context
);
333 $manager->persist($session);
335 //Flush to get the ids
338 $this->addFlash('notice', $this->translator
->trans('Session on %date% %location% %slot% created', ['%location%' => $this->translator
->trans('at '.$data['location']), '%slot%' => $this->translator
->trans('the '.strtolower($data['slot'])), '%date%' => $data['date']->format('Y-m-d')]));
342 $user = $this->getUser();
344 //Replace with requested user for admin
345 if ($this->isGranted('ROLE_ADMIN') && !empty($data['user'])) {
346 $user = $this->getDoctrine()->getRepository(User
::class)->findOneById($data['user']);
349 //Protect application fetching
351 //Retrieve application
352 $application = $doctrine->getRepository(Application
::class)->findOneBySessionUser($session, $user);
354 //Add warning in flash message
355 $this->addFlash('warning', $this->translator
->trans('Application on %date% %location% %slot% already exists', ['%location%' => $this->translator
->trans('at '.$data['location']), '%slot%' => $this->translator
->trans('the '.strtolower($data['slot'])), '%date%' => $data['date']->format('Y-m-d')]));
356 //Catch no application and session without identifier (not persisted&flushed) cases
357 } catch (\Doctrine\ORM\NoResultException
|\Doctrine\ORM\ORMInvalidArgumentException
$e) {
358 //Create the application
359 $application = new Application();
360 $application->setSession($session);
361 $application->setUser($user);
362 $application->setCreated(new \
DateTime('now'));
363 $application->setUpdated(new \
DateTime('now'));
365 //Refresh session updated field
366 $session->setUpdated(new \
DateTime('now'));
369 $manager->persist($session);
371 //Queue application save
372 $manager->persist($application);
374 //Flush to get the ids
377 //Add notice in flash message
378 $this->addFlash('notice', $this->translator
->trans('Application on %date% %location% %slot% created', ['%location%' => $this->translator
->trans('at '.$data['location']), '%slot%' => $this->translator
->trans('the '.strtolower($data['slot'])), '%date%' => $data['date']->format('Y-m-d')]));
381 //Extract and process referer
382 if ($referer = $request->headers
->get('referer')) {
383 //Create referer request instance
384 $req = Request
::create($referer);
387 $path = $req->getPathInfo();
389 //Get referer query string
390 $query = $req->getQueryString();
393 $path = str_replace($request->getScriptName(), '', $path);
395 //Try with referer path
398 $oldContext = $this->router
->getContext();
400 //Force clean context
401 //XXX: prevent MethodNotAllowedException because current context method is POST in onevendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php+42
402 $this->router
->setContext(new RequestContext());
404 //Retrieve route matching path
405 $route = $this->router
->match($path);
408 $this->router
->setContext($oldContext);
414 $name = $route['_route'];
416 //Remove route and controller from route defaults
417 unset($route['_route'], $route['_controller']);
419 //Check if session view route
420 if ($name == 'rapsys_air_session_view' && !empty($route['id'])) {
422 $route['id'] = $session->getId();
426 $route['session'] = $session->getId();
430 return $this->redirectToRoute($name, $route);
432 } catch (MethodNotAllowedException
|ResourceNotFoundException
$e) {
433 //Unset referer to fallback to default route
438 //Redirect to cleanup the form
439 return $this->redirectToRoute('rapsys_air', ['session' => $session->getId()]);