]> Raphaël G. Git Repositories - airbundle/blob - Controller/SessionController.php
Add session edit form
[airbundle] / Controller / SessionController.php
1 <?php
2
3 namespace Rapsys\AirBundle\Controller;
4
5 use Symfony\Component\HttpFoundation\Request;
6 use Symfony\Component\Routing\RequestContext;
7 use Symfony\Component\Routing\Exception\MethodNotAllowedException;
8 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
9 use Rapsys\AirBundle\Entity\Application;
10 use Rapsys\AirBundle\Entity\User;
11 use Rapsys\AirBundle\Entity\Slot;
12 use Rapsys\AirBundle\Entity\Session;
13 use Rapsys\AirBundle\Entity\Location;
14
15 class SessionController extends DefaultController {
16 /**
17 * Edit session
18 *
19 * @desc Persist session and all required dependencies in database
20 *
21 * @param Request $request The request instance
22 *
23 * @return Response The rendered view or redirection
24 *
25 * @throws \RuntimeException When user has not at least guest role
26 */
27 public function edit(Request $request, $id) {
28 //Prevent non-guest to access here
29 $this->denyAccessUnlessGranted('ROLE_GUEST', null, $this->translator->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator->trans('Guest')]));
30
31 //Reject non post requests
32 if (!$request->isMethod('POST')) {
33 throw new \RuntimeException('Request method MUST be POST');
34 }
35
36 //Get doctrine
37 $doctrine = $this->getDoctrine();
38
39 //Fetch session
40 $session = $doctrine->getRepository(Session::class)->fetchOneById($id);
41
42 //Check if
43 if (
44 //we are admin
45 !$this->isGranted('ROLE_ADMIN') &&
46 //or attributed user
47 $this->getUser()->getId() != $session['au_id'] &&
48 //or application without attributed user
49 $session['au_id'] !== null && !in_array($this->getUser()->getId(), explode("\n", $session['sau_id']))
50 ) {
51 //Prevent non admin and non attributed user access
52 throw $this->createAccessDeniedException();
53 }
54
55 //Set now
56 $now = new \DateTime('now');
57
58 //Create SessionEditType form
59 $form = $this->createForm('Rapsys\AirBundle\Form\SessionEditType', null, [
60 //Set the action
61 'action' => $this->generateUrl('rapsys_air_session_edit', [ 'id' => $id ]),
62 //Set the form attribute
63 'attr' => [],
64 //Set admin
65 'admin' => $this->isGranted('ROLE_ADMIN'),
66 //Set default user to current
67 'user' => $this->getUser()->getId(),
68 //Set begin
69 'begin' => $session['begin'],
70 //Set length
71 'length' => $session['length'],
72 //Set raincancel
73 'raincancel' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['rainfall'] >= 2,
74 //Set cancel
75 'cancel' => $this->isGranted('ROLE_ADMIN') || in_array($this->getUser()->getId(), explode("\n", $session['sau_id'])),
76 //Set modify
77 'modify' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['stop'] >= $now && $this->isGranted('ROLE_REGULAR'),
78 //Set move
79 'move' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['stop'] >= $now && $this->isGranted('ROLE_SENIOR'),
80 //Set session
81 'session' => $session['id']
82 ]);
83
84 //Refill the fields in case of invalid form
85 $form->handleRequest($request);
86
87 //Handle invalid data
88 #if (true) { $form->isValid();
89 //TODO: mettre une contrainte sur un des boutons submit, je sais pas encore comment
90 if (!$form->isValid()) {
91 //Set section
92 $section = $this->translator->trans('Session %id%', ['%id%' => $id]);
93
94 //Set title
95 $title = $section.' - '.$this->translator->trans($this->config['site']['title']);
96
97 //Add session in context
98 $context['session'] = [
99 'id' => $id,
100 'title' => $this->translator->trans('Session %id%', ['%id%' => $id]),
101 'location' => [
102 'id' => $session['l_id'],
103 'at' => $this->translator->trans('at '.$session['l_title'])
104 ]
105 ];
106 //Render the view
107 return $this->render('@RapsysAir/session/edit.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView()]+$context+$this->context);
108 }
109
110 //Get manager
111 $manager = $doctrine->getManager();
112
113 //Get data
114 $data = $form->getData();
115
116 //Fetch session
117 $session = $doctrine->getRepository(Session::class)->findOneById($id);
118
119 //Set user
120 $user = $this->getUser();
121
122 //Replace with requested user for admin
123 if ($this->isGranted('ROLE_ADMIN') && !empty($data['user'])) {
124 $user = $doctrine->getRepository(User::class)->findOneById($data['user']);
125 }
126
127 //Set datetime
128 $datetime = new \DateTime('now');
129
130 //With raincancel
131 if ($form->has('raincancel') && $form->get('raincancel')->isClicked()) {
132 //Check rainfall
133 if ($this->isGranted('ROLE_ADMIN') || $session->getRainfall() >= 2) {
134 //Check that application is attributed
135 if (!empty($application = $session->getApplication())) {
136 //Get application
137 $application = $doctrine->getRepository(Application::class)->findOneBySessionUser($session, $application->getUser());
138
139 //Set canceled time at start minus one day
140 $canceled = (clone $session->getStart())->sub(new \DateInterval('P1D'));
141
142 //Cancel application
143 $application->setCanceled($canceled);
144
145 //Update time
146 $application->setUpdated($datetime);
147
148 //Queue application save
149 $manager->persist($application);
150
151 //Add notice in flash message
152 $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()]));
153 //Update time
154 $session->setUpdated($datetime);
155
156 //Queue session save
157 $manager->persist($session);
158
159 //Add notice in flash message
160 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
161 //Not attributed
162 } else {
163 //Add notice in flash message
164 $this->addFlash('warning', $this->translator->trans('Session %id% not updated', ['%id%' => $id]));
165 }
166 //Not enough rainfall
167 } else {
168 //Add notice in flash message
169 $this->addFlash('warning', $this->translator->trans('Session %id% not updated', ['%id%' => $id]));
170 }
171 //With modify
172 } elseif ($form->has('modify') && $form->get('modify')->isClicked()) {
173 //Set begin
174 $session->setBegin($data['begin']);
175
176 //Set length
177 $session->setLength($data['length']);
178
179 //Update time
180 $session->setUpdated($datetime);
181
182 //Queue session save
183 $manager->persist($session);
184
185 //Add notice in flash message
186 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
187 //With move
188 } elseif ($form->has('move') && $form->get('move')->isClicked()) {
189 //Set location
190 $session->setLocation($doctrine->getRepository(Location::class)->findOneById($data['location']));
191
192 //Update time
193 $session->setUpdated($datetime);
194
195 //Queue session save
196 $manager->persist($session);
197
198 //Add notice in flash message
199 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
200 //With cancel
201 } elseif ($form->has('cancel') && $form->get('cancel')->isClicked()) {
202 //Get application
203 $application = $doctrine->getRepository(Application::class)->findOneBySessionUser($session, $user);
204
205 //Not already canceled
206 if ($application->getCanceled() === null) {
207 //Cancel application
208 $application->setCanceled($datetime);
209
210 //Check if application is session application
211 if ($session->getApplication() == $application) {
212 //Unattribute session
213 $session->setApplication(null);
214
215 //Update time
216 $session->setUpdated($datetime);
217
218 //Queue session save
219 $manager->persist($session);
220
221 //Add notice in flash message
222 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
223 }
224 //Already canceled
225 } else {
226 //Uncancel application
227 $application->setCanceled(null);
228 }
229
230 //Update time
231 $application->setUpdated($datetime);
232
233 //Queue application save
234 $manager->persist($application);
235
236 //Add notice in flash message
237 $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()]));
238 //With attribute
239 } elseif ($form->has('attribute') && $form->get('attribute')->isClicked()) {
240 //Get application
241 $application = $doctrine->getRepository(Application::class)->findOneBySessionUser($session, $user);
242
243 //Already canceled
244 if ($application->getCanceled() !== null) {
245 //Uncancel application
246 $application->setCanceled(null);
247 }
248
249 //Set score
250 //XXX: magic cheat score 42
251 $application->setScore(42);
252
253 //Update time
254 $application->setUpdated($datetime);
255
256 //Queue application save
257 $manager->persist($application);
258
259 //Add notice in flash message
260 $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()]));
261
262 //Unattribute session
263 $session->setApplication($application);
264
265 //Update time
266 $session->setUpdated($datetime);
267
268 //Queue session save
269 $manager->persist($session);
270
271 //Add notice in flash message
272 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
273 //With autoattribute
274 } elseif ($form->has('autoattribute') && $form->get('autoattribute')->isClicked()) {
275 //Get best application
276 //XXX: best application may not issue result while grace time or bad behaviour
277 if (!empty($application = $doctrine->getRepository(Session::class)->findBestApplicationById($id))) {
278 //Attribute session
279 $session->setApplication($application);
280
281 //Update time
282 $session->setUpdated($datetime);
283
284 //Queue session save
285 $manager->persist($session);
286
287 //Add notice in flash message
288 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
289 //No application
290 } else {
291 //Add notice in flash message
292 $this->addFlash('warning', $this->translator->trans('Session %id% not updated', ['%id%' => $id]));
293 }
294 //With lock
295 } elseif ($form->has('lock') && $form->get('lock')->isClicked()) {
296 //Already locked
297 if ($session->getLocked() !== null) {
298 //Set uncanceled
299 $canceled = null;
300
301 //Unlock session
302 $session->setLocked(null);
303 //Not locked
304 } else {
305 //Set canceled time at start minus one day
306 $canceled = (clone $session->getStart())->sub(new \DateInterval('P1D'));
307
308 //Unattribute session
309 $session->setApplication(null);
310
311 //Lock session
312 $session->setLocked($datetime);
313 }
314
315 //Get applications
316 $applications = $doctrine->getRepository(Application::class)->findBySession($session);
317
318 //Not empty
319 if (!empty($applications)) {
320 //Iterate on each applications
321 foreach($applications as $application) {
322 //Cancel application
323 $application->setCanceled($canceled);
324
325 //Update time
326 $application->setUpdated($datetime);
327
328 //Queue application save
329 $manager->persist($application);
330
331 //Add notice in flash message
332 $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()]));
333 }
334 }
335
336 //Update time
337 $session->setUpdated($datetime);
338
339 //Queue session save
340 $manager->persist($session);
341
342 //Add notice in flash message
343 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
344 }
345
346 //Flush to get the ids
347 $manager->flush();
348
349 //Extract and process referer
350 if ($referer = $request->headers->get('referer')) {
351 //Create referer request instance
352 $req = Request::create($referer);
353
354 //Get referer path
355 $path = $req->getPathInfo();
356
357 //Get referer query string
358 $query = $req->getQueryString();
359
360 //Remove script name
361 $path = str_replace($request->getScriptName(), '', $path);
362
363 //Try with referer path
364 try {
365 //Save old context
366 $oldContext = $this->router->getContext();
367
368 //Force clean context
369 //XXX: prevent MethodNotAllowedException because current context method is POST in onevendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php+42
370 $this->router->setContext(new RequestContext());
371
372 //Retrieve route matching path
373 $route = $this->router->match($path);
374
375 //Reset context
376 $this->router->setContext($oldContext);
377
378 //Clear old context
379 unset($oldContext);
380
381 //Extract name
382 $name = $route['_route'];
383
384 //Remove route and controller from route defaults
385 unset($route['_route'], $route['_controller']);
386
387 //Generate url
388 return $this->redirectToRoute($name, ['session' => $id]+$route);
389 //No route matched
390 } catch(MethodNotAllowedException|ResourceNotFoundException $e) {
391 //Unset referer to fallback to default route
392 unset($referer);
393 }
394 }
395
396 //Redirect to cleanup the form
397 return $this->redirectToRoute('rapsys_air_session_view', ['id' => $id]);
398
399 //Protect session fetching
400 try {
401 //Fetch session
402 $session = $doctrine->getRepository(Session::class)->findOneById($id);
403
404 //Fetch session
405 $session = $doctrine->getRepository(Session::class)->findOneByLocationSlotDate($data['location'], $data['slot'], $data['date']);
406 //Catch no session case
407 } catch (\Doctrine\ORM\NoResultException $e) {
408 //Create the session
409 $session = new Session();
410 $session->setLocation($data['location']);
411 $session->setDate($data['date']);
412 $session->setSlot($data['slot']);
413 $session->setCreated(new \DateTime('now'));
414 $session->setUpdated(new \DateTime('now'));
415
416 //Get short location
417 $short = $data['location']->getShort();
418
419 //Get slot
420 $slot = $data['slot']->getTitle();
421
422 //Set premium
423 $session->setPremium($premium = false);
424
425 //Check if slot is afternoon
426 //XXX: premium is stored only for Afternoon and Evening
427 if ($slot == 'Afternoon') {
428 //Compute premium
429 //XXX: a session is considered premium a day off
430 $session->setPremium($premium = $this->isPremium($data['date']));
431 //Check if slot is evening
432 //XXX: premium is stored only for Afternoon and Evening
433 } elseif ($slot == 'Evening') {
434 //Compute premium
435 //XXX: a session is considered premium the eve of a day off
436 $session->setPremium($premium = $this->isPremium((clone $data['date'])->add(new \DateInterval('P1D'))));
437 //Check if slot is after
438 } elseif ($slot == 'After') {
439 //Compute premium
440 //XXX: a session is considered premium the eve of a day off
441 $premium = $this->isPremium((clone $data['date'])->add(new \DateInterval('P1D')));
442 }
443
444 //Set default length at 6h
445 //XXX: date part will be truncated on save
446 $session->setLength(new \DateTime('06:00:00'));
447
448 //Check if admin
449 if ($this->isGranted('ROLE_ADMIN')) {
450 //Check if morning
451 if ($slot == 'Morning') {
452 //Set begin at 9h
453 $session->setBegin(new \DateTime('09:00:00'));
454
455 //Set length at 5h
456 $session->setLength(new \DateTime('05:00:00'));
457 //Check if afternoon
458 } elseif ($slot == 'Afternoon') {
459 //Set begin at 14h
460 $session->setBegin(new \DateTime('14:00:00'));
461
462 //Set length at 5h
463 $session->setLength(new \DateTime('05:00:00'));
464 //Check if evening
465 } elseif ($slot == 'Evening') {
466 //Set begin at 19h
467 $session->setBegin(new \DateTime('19:00:00'));
468
469 //Check if next day is premium
470 if ($premium) {
471 //Set length at 7h
472 $session->setLength(new \DateTime('07:00:00'));
473 }
474 //Check if after
475 } else {
476 //Set begin at 1h
477 $session->setBegin(new \DateTime('01:00:00'));
478
479 //Set length at 4h
480 $session->setLength(new \DateTime('04:00:00'));
481
482 //Check if next day is premium
483 if ($premium) {
484 //Set begin at 2h
485 $session->setBegin(new \DateTime('02:00:00'));
486
487 //Set length at 3h
488 $session->setLength(new \DateTime('03:00:00'));
489 }
490 }
491 //Docks => 14h -> 19h | 19h -> 01/02h
492 //XXX: remove Garnier from here to switch back to 21h
493 } elseif (in_array($short, ['Docks', 'Garnier']) && in_array($slot, ['Afternoon', 'Evening', 'After'])) {
494 //Check if afternoon
495 if ($slot == 'Afternoon') {
496 //Set begin at 14h
497 $session->setBegin(new \DateTime('14:00:00'));
498
499 //Set length at 5h
500 $session->setLength(new \DateTime('05:00:00'));
501 //Check if evening
502 } elseif ($slot == 'Evening') {
503 //Set begin at 19h
504 $session->setBegin(new \DateTime('19:00:00'));
505
506 //Check if next day is premium
507 if ($premium) {
508 //Set length at 7h
509 $session->setLength(new \DateTime('07:00:00'));
510 }
511 //Check if after
512 } else {
513 //Set begin at 1h
514 $session->setBegin(new \DateTime('01:00:00'));
515
516 //Set length at 4h
517 $session->setLength(new \DateTime('04:00:00'));
518
519 //Check if next day is premium
520 if ($premium) {
521 //Set begin at 2h
522 $session->setBegin(new \DateTime('02:00:00'));
523
524 //Set length at 3h
525 $session->setLength(new \DateTime('03:00:00'));
526 }
527 }
528 //Garnier => 21h -> 01/02h
529 } elseif ($short == 'Garnier' && in_array($slot, ['Evening', 'After'])) {
530 //Check if evening
531 if ($slot == 'Evening') {
532 //Set begin at 21h
533 $session->setBegin(new \DateTime('21:00:00'));
534
535 //Set length at 5h
536 $session->setLength(new \DateTime('05:00:00'));
537
538 //Check if next day is premium
539 if ($premium) {
540 //Set length at 6h
541 $session->setLength(new \DateTime('06:00:00'));
542 }
543 //Check if after
544 } else {
545 //Set begin at 1h
546 $session->setBegin(new \DateTime('01:00:00'));
547
548 //Set length at 4h
549 $session->setLength(new \DateTime('04:00:00'));
550
551 //Check if next day is premium
552 if ($premium) {
553 //Set begin at 2h
554 $session->setBegin(new \DateTime('02:00:00'));
555
556 //Set length at 3h
557 $session->setLength(new \DateTime('03:00:00'));
558 }
559 }
560 //Trocadero|Tokyo|Swan|Honore|Orsay => 19h -> 01/02h
561 } elseif (in_array($short, ['Trocadero', 'Tokyo', 'Swan', 'Honore', 'Orsay']) && in_array($slot, ['Evening', 'After'])) {
562 //Check if evening
563 if ($slot == 'Evening') {
564 //Set begin at 19h
565 $session->setBegin(new \DateTime('19:00:00'));
566
567 //Check if next day is premium
568 if ($premium) {
569 //Set length at 7h
570 $session->setLength(new \DateTime('07:00:00'));
571 }
572 //Check if after
573 } else {
574 //Set begin at 1h
575 $session->setBegin(new \DateTime('01:00:00'));
576
577 //Set length at 4h
578 $session->setLength(new \DateTime('04:00:00'));
579
580 //Check if next day is premium
581 if ($premium) {
582 //Set begin at 2h
583 $session->setBegin(new \DateTime('02:00:00'));
584
585 //Set length at 3h
586 $session->setLength(new \DateTime('03:00:00'));
587 }
588 }
589 //La Villette => 14h -> 19h
590 } elseif ($short == 'Villette' && $slot == 'Afternoon') {
591 //Set begin at 14h
592 $session->setBegin(new \DateTime('14:00:00'));
593
594 //Set length at 5h
595 $session->setLength(new \DateTime('05:00:00'));
596 //Place Colette => 14h -> 21h
597 //TODO: add check here that it's a millegaux account ?
598 } elseif ($short == 'Colette' && $slot == 'Afternoon') {
599 //Set begin at 14h
600 $session->setBegin(new \DateTime('14:00:00'));
601
602 //Set length at 7h
603 $session->setLength(new \DateTime('07:00:00'));
604 //Galerie d'Orléans => 14h -> 18h
605 } elseif ($short == 'Orleans' && $slot == 'Afternoon') {
606 //Set begin at 14h
607 $session->setBegin(new \DateTime('14:00:00'));
608
609 //Set length at 4h
610 $session->setLength(new \DateTime('04:00:00'));
611 //Combination not supported
612 } else {
613 //Add error in flash message
614 $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')]));
615 }
616
617 //Queue session save
618 $manager->persist($session);
619
620 //Flush to get the ids
621 #$manager->flush();
622
623 $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')]));
624 }
625
626 //Set user
627 $user = $this->getUser();
628
629 //Replace with requested user for admin
630 if ($this->isGranted('ROLE_ADMIN') && !empty($data['user'])) {
631 $user = $this->getDoctrine()->getRepository(User::class)->findOneById($data['user']);
632 }
633
634 //Protect application fetching
635 try {
636 //Retrieve application
637 $application = $doctrine->getRepository(Application::class)->findOneBySessionUser($session, $user);
638
639 //Add warning in flash message
640 $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')]));
641 //Catch no application and session without identifier (not persisted&flushed) cases
642 } catch (\Doctrine\ORM\NoResultException|\Doctrine\ORM\ORMInvalidArgumentException $e) {
643 //Create the application
644 $application = new Application();
645 $application->setSession($session);
646 $application->setUser($user);
647 $application->setCreated(new \DateTime('now'));
648 $application->setUpdated(new \DateTime('now'));
649
650 //Refresh session updated field
651 $session->setUpdated(new \DateTime('now'));
652
653 //Queue session save
654 $manager->persist($session);
655
656 //Queue application save
657 $manager->persist($application);
658
659 //Flush to get the ids
660 $manager->flush();
661
662 //Add notice in flash message
663 $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')]));
664 }
665 }
666
667 /**
668 * List all sessions
669 *
670 * @desc Display all sessions with an application or login form
671 *
672 * @param Request $request The request instance
673 *
674 * @return Response The rendered view
675 */
676 public function index(Request $request = null) {
677 //Fetch doctrine
678 $doctrine = $this->getDoctrine();
679
680 //Set section
681 $section = $this->translator->trans('Sessions');
682
683 //Set title
684 $title = $section.' - '.$this->translator->trans($this->config['site']['title']);
685
686 //Init context
687 $context = [];
688
689 //Create application form for role_guest
690 if ($this->isGranted('ROLE_GUEST')) {
691 //Create ApplicationType form
692 $application = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [
693 //Set the action
694 'action' => $this->generateUrl('rapsys_air_application_add'),
695 //Set the form attribute
696 'attr' => [ 'class' => 'col' ],
697 //Set admin
698 'admin' => $this->isGranted('ROLE_ADMIN'),
699 //Set default user to current
700 'user' => $this->getUser()->getId(),
701 //Set default slot to evening
702 //XXX: default to Evening (3)
703 'slot' => $doctrine->getRepository(Slot::class)->findOneById(3)
704 ]);
705
706 //Add form to context
707 $context['application'] = $application->createView();
708 //Create login form for anonymous
709 } elseif (!$this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
710 //Create ApplicationType form
711 $login = $this->createForm('Rapsys\UserBundle\Form\LoginType', null, [
712 //Set the action
713 'action' => $this->generateUrl('rapsys_user_login'),
714 //Set the form attribute
715 'attr' => [ 'class' => 'col' ]
716 ]);
717
718 //Add form to context
719 $context['login'] = $login->createView();
720 }
721
722 //Compute period
723 $period = new \DatePeriod(
724 //Start from first monday of week
725 new \DateTime('Monday this week'),
726 //Iterate on each day
727 new \DateInterval('P1D'),
728 //End with next sunday and 4 weeks
729 new \DateTime('Monday this week + 5 week')
730 );
731
732 //Fetch calendar
733 //TODO: highlight with current session route parameter
734 $calendar = $doctrine->getRepository(Session::class)->fetchCalendarByDatePeriod($this->translator, $period, null, $request->get('session'), !$this->isGranted('IS_AUTHENTICATED_REMEMBERED'));
735
736 //Fetch locations
737 //XXX: we want to display all active locations anyway
738 $locations = $doctrine->getRepository(Location::class)->fetchTranslatedLocationByDatePeriod($this->translator, $period/*, !$this->isGranted('IS_AUTHENTICATED_REMEMBERED')*/);
739
740 //Render the view
741 return $this->render('@RapsysAir/session/index.html.twig', ['title' => $title, 'section' => $section, 'calendar' => $calendar, 'locations' => $locations]+$context+$this->context);
742 }
743
744 /**
745 * Display session
746 *
747 * @desc Display session by id with an application or login form
748 *
749 * @param Request $request The request instance
750 * @param int $id The session id
751 *
752 * @return Response The rendered view
753 */
754 public function view(Request $request, $id) {
755 //Fetch doctrine
756 $doctrine = $this->getDoctrine();
757
758 //Fetch session
759 $session = $doctrine->getRepository(Session::class)->fetchOneById($id);
760
761 //Set section
762 $section = $this->translator->trans($session['l_title']);
763
764 //Set title
765 $title = $this->translator->trans('Session %id%', ['%id%' => $id]).' - '.$section.' - '.$this->translator->trans($this->config['site']['title']);
766
767 //Init context
768 $context = [];
769
770 //Create application form for role_guest
771 if ($this->isGranted('ROLE_GUEST')) {
772 //Create ApplicationType form
773 $application = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [
774 //Set the action
775 'action' => $this->generateUrl('rapsys_air_application_add'),
776 //Set the form attribute
777 'attr' => [ 'class' => 'col' ],
778 //Set admin
779 'admin' => $this->isGranted('ROLE_ADMIN'),
780 //Set default user to current
781 'user' => $this->getUser()->getId(),
782 //Set default slot to current
783 'slot' => $this->getDoctrine()->getRepository(Slot::class)->findOneById($session['t_id']),
784 //Set default location to current
785 'location' => $this->getDoctrine()->getRepository(Location::class)->findOneById($session['l_id']),
786 ]);
787
788 //Add form to context
789 $context['application'] = $application->createView();
790
791 //Set now
792 $now = new \DateTime('now');
793
794 //Create SessionEditType form
795 $session_edit = $this->createForm('Rapsys\AirBundle\Form\SessionEditType', null, [
796 //Set the action
797 'action' => $this->generateUrl('rapsys_air_session_edit', [ 'id' => $id ]),
798 //Set the form attribute
799 'attr' => [ 'class' => 'col' ],
800 //Set admin
801 'admin' => $this->isGranted('ROLE_ADMIN'),
802 //Set default user to current
803 'user' => $this->getUser()->getId(),
804 //Set begin
805 'begin' => $session['begin'],
806 //Set length
807 'length' => $session['length'],
808 //Set raincancel
809 'raincancel' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['rainfall'] >= 2,
810 //Set cancel
811 'cancel' => $this->isGranted('ROLE_ADMIN') || in_array($this->getUser()->getId(), explode("\n", $session['sau_id'])),
812 //Set modify
813 'modify' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['stop'] >= $now && $this->isGranted('ROLE_REGULAR'),
814 //Set move
815 'move' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['stop'] >= $now && $this->isGranted('ROLE_SENIOR'),
816 //Set session
817 'session' => $session['id']
818 ]);
819
820 //Add form to context
821 $context['session_edit'] = $session_edit->createView();
822 //Create login form for anonymous
823 } elseif (!$this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
824 //Create ApplicationType form
825 $login = $this->createForm('Rapsys\UserBundle\Form\LoginType', null, [
826 //Set the action
827 'action' => $this->generateUrl('rapsys_user_login'),
828 //Set the form attribute
829 'attr' => [ 'class' => 'col' ]
830 ]);
831
832 //Add form to context
833 $context['login'] = $login->createView();
834 }
835
836 //Add session in context
837 $context['session'] = [
838 'id' => $id,
839 'date' => $session['date'],
840 'begin' => $session['begin'],
841 'start' => $session['start'],
842 'length' => $session['length'],
843 'stop' => $session['stop'],
844 'rainfall' => $session['rainfall'] !== null ? $session['rainfall'].' mm' : $session['rainfall'],
845 'rainrisk' => $session['rainrisk'] !== null ? ($session['rainrisk']*100).' %' : $session['rainrisk'],
846 'realfeel' => $session['realfeel'] !== null ? $session['realfeel'].' °C' : $session['realfeel'],
847 'realfeelmin' => $session['realfeelmin'] !== null ? $session['realfeelmin'].' °C' : $session['realfeelmin'],
848 'realfeelmax' => $session['realfeelmax'] !== null ? $session['realfeelmax'].' °C' : $session['realfeelmax'],
849 'temperature' => $session['temperature'] !== null ? $session['temperature'].' °C' : $session['temperature'],
850 'temperaturemin' => $session['temperaturemin'] !== null ? $session['temperaturemin'].' °C' : $session['temperaturemin'],
851 'temperaturemax' => $session['temperaturemax'] !== null ? $session['temperaturemax'].' °C' : $session['temperaturemax'],
852 'locked' => $session['locked'],
853 'created' => $session['created'],
854 'updated' => $session['updated'],
855 'title' => $this->translator->trans('Session %id%', ['%id%' => $id]),
856 'application' => null,
857 'location' => [
858 'id' => $session['l_id'],
859 'at' => $this->translator->trans('at '.$session['l_title']),
860 'short' => $this->translator->trans($session['l_short']),
861 'title' => $this->translator->trans($session['l_title']),
862 'address' => $session['l_address'],
863 'zipcode' => $session['l_zipcode'],
864 'city' => $session['l_city'],
865 'latitude' => $session['l_latitude'],
866 'longitude' => $session['l_longitude']
867 ],
868 'slot' => [
869 'id' => $session['t_id'],
870 'title' => $this->translator->trans($session['t_title'])
871 ],
872 'applications' => null
873 ];
874
875 //With application
876 if (!empty($session['a_id'])) {
877 $context['session']['application'] = [
878 'user' => [
879 'id' => $session['au_id'],
880 'title' => $session['au_pseudonym']
881 ],
882 'id' => $session['a_id'],
883 'title' => $this->translator->trans('Application %id%', [ '%id%' => $session['a_id'] ]),
884 ];
885 }
886
887 //With applications
888 if (!empty($session['sa_id'])) {
889 //Extract applications id
890 $session['sa_id'] = explode("\n", $session['sa_id']);
891 //Extract applications score
892 //XXX: score may be null before grant or for bad behaviour, replace NULL with 'NULL' to avoid silent drop in mysql
893 $session['sa_score'] = array_map(function($v){return $v==='NULL'?null:$v;}, explode("\n", $session['sa_score']));
894 //Extract applications created
895 $session['sa_created'] = array_map(function($v){return new \DateTime($v);}, explode("\n", $session['sa_created']));
896 //Extract applications updated
897 $session['sa_updated'] = array_map(function($v){return new \DateTime($v);}, explode("\n", $session['sa_updated']));
898 //Extract applications canceled
899 //XXX: canceled is null before cancelation, replace NULL with 'NULL' to avoid silent drop in mysql
900 $session['sa_canceled'] = array_map(function($v){return $v==='NULL'?null:new \DateTime($v);}, explode("\n", $session['sa_canceled']));
901
902 //Extract applications user id
903 $session['sau_id'] = explode("\n", $session['sau_id']);
904 //Extract applications user pseudonym
905 $session['sau_pseudonym'] = explode("\n", $session['sau_pseudonym']);
906
907 //Init applications
908 $context['session']['applications'] = [];
909 foreach($session['sa_id'] as $i => $sa_id) {
910 $context['session']['applications'][$sa_id] = [
911 'user' => null,
912 'score' => $session['sa_score'][$i],
913 'created' => $session['sa_created'][$i],
914 'updated' => $session['sa_updated'][$i],
915 'canceled' => $session['sa_canceled'][$i]
916 ];
917 if (!empty($session['sau_id'][$i])) {
918 $context['session']['applications'][$sa_id]['user'] = [
919 'id' => $session['sau_id'][$i],
920 'title' => $session['sau_pseudonym'][$i]
921 ];
922 }
923 }
924 }
925
926 //Render the view
927 return $this->render('@RapsysAir/session/view.html.twig', ['title' => $title, 'section' => $section]+$context+$this->context);
928 }
929 }