3 namespace Rapsys\AirBundle\Controller
;
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\Link
;
14 use Rapsys\AirBundle\Entity\Location
;
16 class SessionController
extends DefaultController
{
20 * @desc Persist session and all required dependencies in database
22 * @param Request $request The request instance
24 * @return Response The rendered view or redirection
26 * @throws \RuntimeException When user has not at least guest role
28 public function edit(Request
$request, $id) {
29 //Prevent non-guest to access here
30 $this->denyAccessUnlessGranted('ROLE_GUEST', null, $this->translator
->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator
->trans('Guest')]));
32 //Reject non post requests
33 if (!$request->isMethod('POST')) {
34 throw new \
RuntimeException('Request method MUST be POST');
38 $doctrine = $this->getDoctrine();
41 $session = $doctrine->getRepository(Session
::class)->fetchOneById($id, $request->getLocale());
46 !$this->isGranted('ROLE_ADMIN') &&
48 $this->getUser()->getId() != $session['au_id'] &&
49 //or application without attributed user
50 $session['au_id'] !== null && !in_array($this->getUser()->getId(), explode("\n", $session['sau_id']))
52 //Prevent non admin and non attributed user access
53 throw $this->createAccessDeniedException();
57 $now = new \
DateTime('now');
59 //Create SessionEditType form
60 $form = $this->createForm('Rapsys\AirBundle\Form\SessionEditType', null, [
62 'action' => $this->generateUrl('rapsys_air_session_edit', [ 'id' => $id ]),
63 //Set the form attribute
66 'admin' => $this->isGranted('ROLE_ADMIN'),
67 //Set default user to current
68 'user' => $this->getUser()->getId(),
70 'begin' => $session['begin'],
72 'length' => $session['length'],
74 'raincancel' => ($this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id']) && $session['rainfall'] >= 2,
76 'cancel' => $this->isGranted('ROLE_ADMIN') || in_array($this->getUser()->getId(), explode("\n", $session['sau_id'])),
78 'modify' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['stop'] >= $now && $this->isGranted('ROLE_REGULAR'),
80 'move' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['stop'] >= $now && $this->isGranted('ROLE_SENIOR'),
82 'attribute' => $this->isGranted('ROLE_ADMIN') && $session['locked'] === null,
84 'session' => $session['id']
87 //Refill the fields in case of invalid form
88 $form->handleRequest($request);
91 #if (true) { $form->isValid();
92 //TODO: mettre une contrainte sur un des boutons submit, je sais pas encore comment
93 if (!$form->isValid()) {
95 $section = $this->translator
->trans('Session %id%', ['%id%' => $id]);
98 $title = $section.' - '.$this->translator
->trans($this->config
['site']['title']);
100 //Add session in context
101 $context['session'] = [
103 'title' => $this->translator
->trans('Session %id%', ['%id%' => $id]),
105 'id' => $session['l_id'],
106 'at' => $this->translator
->trans('at '.$session['l_title'])
110 return $this->render('@RapsysAir/session/edit.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView()]+
$context+
$this->context
);
114 $manager = $doctrine->getManager();
117 $data = $form->getData();
120 $session = $doctrine->getRepository(Session
::class)->findOneById($id);
123 $user = $this->getUser();
125 //Replace with requested user for admin
126 if ($this->isGranted('ROLE_ADMIN') && !empty($data['user'])) {
127 $user = $doctrine->getRepository(User
::class)->findOneById($data['user']);
131 $datetime = new \
DateTime('now');
133 //Set canceled time at start minus one day
134 $canceled = (clone $session->getStart())->sub(new \
DateInterval('P1D'));
138 'raincancel' => $form->has('raincancel') && $form->get('raincancel')->isClicked(),
139 'modify' => $form->has('modify') && $form->get('modify')->isClicked(),
140 'move' => $form->has('move') && $form->get('move')->isClicked(),
141 'cancel' => $form->has('cancel') && $form->get('cancel')->isClicked(),
142 'forcecancel' => $form->has('forcecancel') && $form->get('forcecancel')->isClicked(),
143 'attribute' => $form->has('attribute') && $form->get('attribute')->isClicked(),
144 'autoattribute' => $form->has('autoattribute') && $form->get('autoattribute')->isClicked(),
145 'lock' => $form->has('lock') && $form->get('lock')->isClicked(),
148 //With raincancel and application and (rainfall or admin)
149 if ($action['raincancel'] && ($application = $session->getApplication()) && ($session->getRainfall() >= 2 || $this->isGranted('ROLE_ADMIN'))) {
150 //Cancel application at start minus one day
151 $application->setCanceled($canceled);
154 $application->setUpdated($datetime);
156 //Insufficient rainfall
158 if ($session->getRainfall() < 2) {
160 //XXX: magic cheat score 42
161 $application->setScore(42);
164 //Queue application save
165 $manager->persist($application);
167 //Add notice in flash message
168 $this->addFlash('notice', $this->translator
->trans('Application %id% updated', ['%id%' => $application->getId()]));
171 $session->setUpdated($datetime);
174 $manager->persist($session);
176 //Add notice in flash message
177 $this->addFlash('notice', $this->translator
->trans('Session %id% updated', ['%id%' => $id]));
179 } elseif ($action['modify']) {
181 $session->setBegin($data['begin']);
184 $session->setLength($data['length']);
187 $session->setUpdated($datetime);
190 $manager->persist($session);
192 //Add notice in flash message
193 $this->addFlash('notice', $this->translator
->trans('Session %id% updated', ['%id%' => $id]));
195 } elseif ($action['move']) {
197 $session->setLocation($doctrine->getRepository(Location
::class)->findOneById($data['location']));
200 $session->setUpdated($datetime);
203 $manager->persist($session);
205 //Add notice in flash message
206 $this->addFlash('notice', $this->translator
->trans('Session %id% updated', ['%id%' => $id]));
207 //With cancel or forcecancel
208 } elseif ($action['cancel'] || $action['forcecancel']) {
210 $application = $doctrine->getRepository(Application
::class)->findOneBySessionUser($session, $user);
212 //Not already canceled
213 if ($application->getCanceled() === null) {
215 $application->setCanceled($datetime);
217 //Check if application is session application and (canceled 24h before start or forcecancel (as admin))
218 #if ($session->getApplication() == $application && ($datetime < $canceled || $action['forcecancel'])) {
219 if ($session->getApplication() == $application && $action['forcecancel']) {
221 //XXX: magic cheat score 42
222 $application->setScore(42);
224 //Unattribute session
225 $session->setApplication(null);
228 $session->setUpdated($datetime);
231 $manager->persist($session);
233 //Add notice in flash message
234 $this->addFlash('notice', $this->translator
->trans('Session %id% updated', ['%id%' => $id]));
238 //Uncancel application
239 $application->setCanceled(null);
243 $application->setUpdated($datetime);
245 //Queue application save
246 $manager->persist($application);
248 //Add notice in flash message
249 $this->addFlash('notice', $this->translator
->trans('Application %id% updated', ['%id%' => $application->getId()]));
251 } elseif ($action['attribute']) {
253 $application = $doctrine->getRepository(Application
::class)->findOneBySessionUser($session, $user);
256 if ($application->getCanceled() !== null) {
257 //Uncancel application
258 $application->setCanceled(null);
262 //XXX: magic cheat score 42
263 $application->setScore(42);
266 $application->setUpdated($datetime);
268 //Queue application save
269 $manager->persist($application);
271 //Add notice in flash message
272 $this->addFlash('notice', $this->translator
->trans('Application %id% updated', ['%id%' => $application->getId()]));
274 //Unattribute session
275 $session->setApplication($application);
278 $session->setUpdated($datetime);
281 $manager->persist($session);
283 //Add notice in flash message
284 $this->addFlash('notice', $this->translator
->trans('Session %id% updated', ['%id%' => $id]));
286 } elseif ($action['autoattribute']) {
287 //Get best application
288 //XXX: best application may not issue result while grace time or bad behaviour
289 if (!empty($application = $doctrine->getRepository(Session
::class)->findBestApplicationById($id))) {
291 $session->setApplication($application);
294 $session->setUpdated($datetime);
297 $manager->persist($session);
299 //Add notice in flash message
300 $this->addFlash('notice', $this->translator
->trans('Session %id% auto attributed', ['%id%' => $id]));
303 //Add warning in flash message
304 $this->addFlash('warning', $this->translator
->trans('Session %id% not auto attributed', ['%id%' => $id]));
307 } elseif ($action['lock']) {
309 if ($session->getLocked() !== null) {
314 $session->setLocked(null);
318 if ($application = $session->getApplication()) {
320 //XXX: magic cheat score 42
321 $application->setScore(42);
324 $application->setUpdated($datetime);
326 //Queue application save
327 $manager->persist($application);
329 //Add notice in flash message
330 $this->addFlash('notice', $this->translator
->trans('Application %id% updated', ['%id%' => $application->getId()]));
333 //Unattribute session
334 $session->setApplication(null);
337 $session->setLocked($datetime);
341 # $applications = $doctrine->getRepository(Application::class)->findBySession($session);
344 # if (!empty($applications)) {
345 # //Iterate on each applications
346 # foreach($applications as $application) {
347 # //Cancel application
348 # $application->setCanceled($canceled);
351 # $application->setUpdated($datetime);
353 # //Queue application save
354 # $manager->persist($application);
356 # //Add notice in flash message
357 # $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()]));
362 $session->setUpdated($datetime);
365 $manager->persist($session);
367 //Add notice in flash message
368 $this->addFlash('notice', $this->translator
->trans('Session %id% updated', ['%id%' => $id]));
371 //Add warning in flash message
372 $this->addFlash('warning', $this->translator
->trans('Session %id% not updated', ['%id%' => $id]));
375 //Flush to get the ids
378 //Extract and process referer
379 if ($referer = $request->headers
->get('referer')) {
380 //Create referer request instance
381 $req = Request
::create($referer);
384 $path = $req->getPathInfo();
386 //Get referer query string
387 $query = $req->getQueryString();
390 $path = str_replace($request->getScriptName(), '', $path);
392 //Try with referer path
395 $oldContext = $this->router
->getContext();
397 //Force clean context
398 //XXX: prevent MethodNotAllowedException because current context method is POST in onevendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php+42
399 $this->router
->setContext(new RequestContext());
401 //Retrieve route matching path
402 $route = $this->router
->match($path);
405 $this->router
->setContext($oldContext);
411 $name = $route['_route'];
413 //Remove route and controller from route defaults
414 unset($route['_route'], $route['_controller']);
417 return $this->redirectToRoute($name, $route);
419 } catch(MethodNotAllowedException
|ResourceNotFoundException
$e) {
420 //Unset referer to fallback to default route
425 //Redirect to cleanup the form
426 return $this->redirectToRoute('rapsys_air_session_view', ['id' => $id]);
432 * @desc Display all sessions with an application or login form
434 * @param Request $request The request instance
436 * @return Response The rendered view
438 public function index(Request
$request) {
440 $doctrine = $this->getDoctrine();
443 $section = $this->translator
->trans('Sessions');
446 $this->context
['description'] = $this->translator
->trans('Libre Air session list');
449 $this->context
['keywords'] = [
450 $this->translator
->trans('sessions'),
451 $this->translator
->trans('session list'),
452 $this->translator
->trans('listing'),
453 $this->translator
->trans('Libre Air')
457 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
462 //Create application form for role_guest
463 if ($this->isGranted('ROLE_GUEST')) {
464 //Create ApplicationType form
465 $application = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [
467 'action' => $this->generateUrl('rapsys_air_application_add'),
468 //Set the form attribute
469 'attr' => [ 'class' => 'col' ],
471 'admin' => $this->isGranted('ROLE_ADMIN'),
472 //Set default user to current
473 'user' => $this->getUser()->getId(),
474 //Set default slot to evening
475 //XXX: default to Evening (3)
476 'slot' => $doctrine->getRepository(Slot
::class)->findOneById(3)
479 //Add form to context
480 $context['application'] = $application->createView();
481 //Create login form for anonymous
482 } elseif (!$this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
483 //Create ApplicationType form
484 $login = $this->createForm('Rapsys\UserBundle\Form\LoginType', null, [
486 'action' => $this->generateUrl('rapsys_user_login'),
487 //Set the form attribute
488 'attr' => [ 'class' => 'col' ]
491 //Add form to context
492 $context['login'] = $login->createView();
496 $period = new \
DatePeriod(
497 //Start from first monday of week
498 new \
DateTime('Monday this week'),
499 //Iterate on each day
500 new \
DateInterval('P1D'),
501 //End with next sunday and 4 weeks
503 $this->isGranted('IS_AUTHENTICATED_REMEMBERED')?'Monday this week + 4 week':'Monday this week + 2 week'
508 //TODO: highlight with current session route parameter
509 $calendar = $doctrine->getRepository(Session
::class)->fetchCalendarByDatePeriod($this->translator
, $period, null, $request->get('session'), !$this->isGranted('IS_AUTHENTICATED_REMEMBERED'));
512 //XXX: we want to display all active locations anyway
513 $locations = $doctrine->getRepository(Location
::class)->findTranslatedSortedByPeriod($this->translator
, $period);
516 return $this->render('@RapsysAir/session/index.html.twig', ['title' => $title, 'section' => $section, 'calendar' => $calendar, 'locations' => $locations]+
$context+
$this->context
);
522 * @desc Display session by id with an application or login form
524 * @param Request $request The request instance
525 * @param int $id The session id
527 * @return Response The rendered view
529 public function view(Request
$request, $id) {
531 $doctrine = $this->getDoctrine();
534 if (empty($session = $doctrine->getRepository(Session
::class)->fetchOneById($id, $request->getLocale()))) {
535 throw $this->createNotFoundException($this->translator
->trans('Unable to find session: %id%', ['%id%' => $id]));
539 $section = $this->translator
->trans($session['l_title']);
541 //Set localization date formater
542 $intl = new \
IntlDateFormatter($request->getLocale(), \IntlDateFormatter
::GREGORIAN
, \IntlDateFormatter
::SHORT
);
545 $this->context
['description'] = $this->translator
->trans('Outdoor Argentine Tango session the %date%', [ '%date%' => $intl->format($session['start']) ]);
548 $this->context
['keywords'] = [
549 $this->translator
->trans('outdoor'),
550 $this->translator
->trans('Argentine Tango'),
553 //With granted session
554 if (!empty($session['au_id'])) {
555 $this->context
['keywords'][0] = $session['au_pseudonym'];
558 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section.' - '.$this->translator
->trans(!empty($session['au_id'])?'Session %id% by %pseudonym%':'Session %id%', ['%id%' => $id, '%pseudonym%' => $session['au_pseudonym']]);
563 //Create application form for role_guest
564 if ($this->isGranted('ROLE_GUEST')) {
565 //Create ApplicationType form
566 $application = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [
568 'action' => $this->generateUrl('rapsys_air_application_add'),
569 //Set the form attribute
570 'attr' => [ 'class' => 'col' ],
572 'admin' => $this->isGranted('ROLE_ADMIN'),
573 //Set default user to current
574 'user' => $this->getUser()->getId(),
575 //Set default slot to current
576 'slot' => $this->getDoctrine()->getRepository(Slot
::class)->findOneById($session['t_id']),
577 //Set default location to current
578 'location' => $this->getDoctrine()->getRepository(Location
::class)->findOneById($session['l_id']),
581 //Add form to context
582 $context['application'] = $application->createView();
585 $now = new \
DateTime('now');
587 //Create SessionEditType form
588 $session_edit = $this->createForm('Rapsys\AirBundle\Form\SessionEditType', null, [
590 'action' => $this->generateUrl('rapsys_air_session_edit', [ 'id' => $id ]),
591 //Set the form attribute
592 'attr' => [ 'class' => 'col' ],
594 'admin' => $this->isGranted('ROLE_ADMIN'),
595 //Set default user to current
596 'user' => $this->getUser()->getId(),
598 'begin' => $session['begin'],
600 'length' => $session['length'],
602 'raincancel' => ($this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id']) && $session['rainfall'] >= 2,
604 'cancel' => $this->isGranted('ROLE_ADMIN') || in_array($this->getUser()->getId(), explode("\n", $session['sau_id'])),
606 'modify' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['stop'] >= $now && $this->isGranted('ROLE_REGULAR'),
608 'move' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['stop'] >= $now && $this->isGranted('ROLE_SENIOR'),
610 'attribute' => $this->isGranted('ROLE_ADMIN') && $session['locked'] === null,
612 'session' => $session['id']
615 //Add form to context
616 $context['session_edit'] = $session_edit->createView();
617 //Create login form for anonymous
618 } elseif (!$this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
619 //Create ApplicationType form
620 $login = $this->createForm('Rapsys\UserBundle\Form\LoginType', null, [
622 'action' => $this->generateUrl('rapsys_user_login'),
623 //Set the form attribute
624 'attr' => [ 'class' => 'col' ]
627 //Add form to context
628 $context['login'] = $login->createView();
631 //Add session in context
632 $context['session'] = [
634 'date' => $session['date'],
635 'begin' => $session['begin'],
636 'start' => $session['start'],
637 'length' => $session['length'],
638 'stop' => $session['stop'],
639 'rainfall' => $session['rainfall'] !== null ? $session['rainfall'].' mm' : $session['rainfall'],
640 'rainrisk' => $session['rainrisk'] !== null ? ($session['rainrisk']*100).' %' : $session['rainrisk'],
641 'realfeel' => $session['realfeel'] !== null ? $session['realfeel'].' °C' : $session['realfeel'],
642 'realfeelmin' => $session['realfeelmin'] !== null ? $session['realfeelmin'].' °C' : $session['realfeelmin'],
643 'realfeelmax' => $session['realfeelmax'] !== null ? $session['realfeelmax'].' °C' : $session['realfeelmax'],
644 'temperature' => $session['temperature'] !== null ? $session['temperature'].' °C' : $session['temperature'],
645 'temperaturemin' => $session['temperaturemin'] !== null ? $session['temperaturemin'].' °C' : $session['temperaturemin'],
646 'temperaturemax' => $session['temperaturemax'] !== null ? $session['temperaturemax'].' °C' : $session['temperaturemax'],
647 'locked' => $session['locked'],
648 'created' => $session['created'],
649 'updated' => $session['updated'],
650 'title' => $this->translator
->trans('Session %id%', ['%id%' => $id]),
651 'application' => null,
653 'id' => $session['l_id'],
654 'at' => $this->translator
->trans('at '.$session['l_title']),
655 'short' => $this->translator
->trans($session['l_short']),
656 'title' => $this->translator
->trans($session['l_title']),
657 'address' => $session['l_address'],
658 'zipcode' => $session['l_zipcode'],
659 'city' => $session['l_city'],
660 'latitude' => $session['l_latitude'],
661 'longitude' => $session['l_longitude']
664 'id' => $session['t_id'],
665 'title' => $this->translator
->trans($session['t_title'])
668 'id' => $session['p_id'],
669 'description' => $session['p_description']
671 'applications' => null
675 if (!empty($session['a_id'])) {
680 if (!empty($session['i_type']) && !empty($session['i_url'])) {
682 $session['i_type'] = explode("\n", $session['i_type']);
685 $session['i_url'] = explode("\n", $session['i_url']);
690 //Iterate on links type
691 foreach($session['i_type'] as $i => $type) {
692 //Type is contact, donate or link
693 if (in_array($type, [Link
::TYPE_CONTACT
, Link
::TYPE_DONATE
, Link
::TYPE_LINK
])) {
695 $linkTitle = $this->translator
->trans(ucfirst($type));
699 if ($type == Link
::TYPE_CONTACT
) {
701 $description = $this->translator
->trans('Send a message to %pseudonym%', [ '%pseudonym%' => $session['au_pseudonym'] ]);
703 } elseif ($type == Link
::TYPE_DONATE
) {
705 $description = $this->translator
->trans('Donate to %pseudonym%', [ '%pseudonym%' => $session['au_pseudonym'] ]);
707 } elseif ($type == Link
::TYPE_LINK
) {
709 $description = $this->translator
->trans('Link to %pseudonym%', [ '%pseudonym%' => $session['au_pseudonym'] ]);
711 } elseif ($type == Link
::TYPE_SOCIAL
) {
713 $description = $this->translator
->trans('Consult %pseudonym% social profile', [ '%pseudonym%' => $session['au_pseudonym'] ]);
716 $linkTitle = $this->translator
->trans('Social network');
720 throw new \
InvalidArgumentException('Invalid type');
725 'description' => $description,
726 'title' => $linkTitle,
728 'url' => $session['i_url'][$i]
732 $context['session']['application'] = [
734 'id' => $session['au_id'],
735 'by' => $this->translator
->trans('by %pseudonym%', [ '%pseudonym%' => $session['au_pseudonym'] ]),
736 'title' => $session['au_pseudonym'],
739 'id' => $session['a_id'],
740 'title' => $this->translator
->trans('Application %id%', [ '%id%' => $session['a_id'] ]),
745 if (!empty($session['sa_id'])) {
746 //Extract applications id
747 $session['sa_id'] = explode("\n", $session['sa_id']);
748 //Extract applications score
749 //XXX: score may be null before grant or for bad behaviour, replace NULL with 'NULL' to avoid silent drop in mysql
750 $session['sa_score'] = array_map(function($v){return $v
==='NULL'?null:$v
;}, explode("\n", $session['sa_score']));
751 //Extract applications created
752 $session['sa_created'] = array_map(function($v){return new \
DateTime($v
);}, explode("\n", $session['sa_created']));
753 //Extract applications updated
754 $session['sa_updated'] = array_map(function($v){return new \
DateTime($v
);}, explode("\n", $session['sa_updated']));
755 //Extract applications canceled
756 //XXX: canceled is null before cancelation, replace NULL with 'NULL' to avoid silent drop in mysql
757 $session['sa_canceled'] = array_map(function($v){return $v
==='NULL'?null:new \
DateTime($v
);}, explode("\n", $session['sa_canceled']));
759 //Extract applications user id
760 $session['sau_id'] = explode("\n", $session['sau_id']);
761 //Extract applications user pseudonym
762 $session['sau_pseudonym'] = explode("\n", $session['sau_pseudonym']);
765 $context['session']['applications'] = [];
766 foreach($session['sa_id'] as $i => $sa_id) {
767 $context['session']['applications'][$sa_id] = [
769 'score' => $session['sa_score'][$i],
770 'created' => $session['sa_created'][$i],
771 'updated' => $session['sa_updated'][$i],
772 'canceled' => $session['sa_canceled'][$i]
774 if (!empty($session['sau_id'][$i])) {
775 $context['session']['applications'][$sa_id]['user'] = [
776 'id' => $session['sau_id'][$i],
777 'title' => $session['sau_pseudonym'][$i]
784 $period = new \
DatePeriod(
785 //Start from first monday of week
786 new \
DateTime('Monday this week'),
787 //Iterate on each day
788 new \
DateInterval('P1D'),
789 //End with next sunday and 4 weeks
791 $this->isGranted('IS_AUTHENTICATED_REMEMBERED')?'Monday this week + 4 week':'Monday this week + 2 week'
796 //XXX: we want to display all active locations anyway
797 $locations = $doctrine->getRepository(Location
::class)->findTranslatedSortedByPeriod($this->translator
, $period, $session['au_id']);
800 return $this->render('@RapsysAir/session/view.html.twig', ['title' => $title, 'section' => $section, 'locations' => $locations]+
$context+
$this->context
);