]> Raphaël G. Git Repositories - airbundle/blob - Controller/SessionController.php
Protect from infinite remove recursion
[airbundle] / Controller / SessionController.php
1 <?php declare(strict_types=1);
2
3 /*
4 * This file is part of the Rapsys AirBundle package.
5 *
6 * (c) Raphaël Gertz <symfony@rapsys.eu>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Rapsys\AirBundle\Controller;
13
14 use Symfony\Component\Asset\Packages;
15 use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
16 use Symfony\Component\Filesystem\Filesystem;
17 use Symfony\Component\HttpFoundation\BinaryFileResponse;
18 use Symfony\Component\HttpFoundation\Request;
19 use Symfony\Component\HttpFoundation\Response;
20 use Symfony\Component\Routing\Exception\MethodNotAllowedException;
21 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
22 use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
23 use Symfony\Component\Routing\RequestContext;
24
25 use Rapsys\AirBundle\Entity\Application;
26 use Rapsys\AirBundle\Entity\Dance;
27 use Rapsys\AirBundle\Entity\User;
28 use Rapsys\AirBundle\Entity\Slot;
29 use Rapsys\AirBundle\Entity\Session;
30 use Rapsys\AirBundle\Entity\Location;
31
32 class SessionController extends AbstractController {
33 /**
34 * List all sessions
35 *
36 * @desc Display all sessions with an application or login form
37 *
38 * @param Request $request The request instance
39 *
40 * @return Response The rendered view
41 */
42 public function index(Request $request): Response {
43 //Get locations
44 $this->context['locations'] = $this->doctrine->getRepository(Location::class)->findAllAsArray($this->period);
45
46 //Add cities
47 $this->context['cities'] = $this->doctrine->getRepository(Location::class)->findCitiesAsArray($this->period);
48
49 //Add calendar
50 $this->context['calendar'] = $this->doctrine->getRepository(Session::class)->findAllByPeriodAsCalendarArray($this->period, !$this->isGranted('IS_AUTHENTICATED_REMEMBERED'), null, null, 1);
51
52 //Add dances
53 $this->context['dances'] = $this->doctrine->getRepository(Dance::class)->findNamesAsArray();
54
55 //Set modified
56 $this->modified = max(array_map(function ($v) { return $v['modified']; }, array_merge($this->context['calendar'], $this->context['cities'], $this->context['dances'])));
57
58 //Create response
59 $response = new Response();
60
61 //With logged user
62 if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
63 //Set last modified
64 $response->setLastModified(new \DateTime('-1 year'));
65
66 //Set as private
67 $response->setPrivate();
68 //Without logged user
69 } else {
70 //Set etag
71 //XXX: only for public to force revalidation by last modified
72 $response->setEtag(md5(serialize(array_merge($this->context['calendar'], $this->context['cities'], $this->context['dances']))));
73
74 //Set last modified
75 $response->setLastModified($this->modified);
76
77 //Set as public
78 $response->setPublic();
79
80 //Without role and modification
81 if ($response->isNotModified($request)) {
82 //Return 304 response
83 return $response;
84 }
85 }
86
87 //With cities
88 if (!empty($this->context['cities'])) {
89 //Set locations
90 $locations = [];
91
92 //Iterate on each cities
93 foreach($this->context['cities'] as $city) {
94 //Iterate on each locations
95 foreach($city['locations'] as $location) {
96 //Add location
97 $locations[$location['id']] = $location;
98 }
99 }
100
101 //Add multi
102 $this->context['multimap'] = $this->map->getMultiMap($this->translator->trans('Libre Air cities sector map'), $this->modified->getTimestamp(), $locations);
103
104 //Set cities
105 $cities = array_map(function ($v) { return $v['in']; }, $this->context['cities']);
106
107 //Set dances
108 $dances = array_map(function ($v) { return $v['name']; }, $this->context['dances']);
109 } else {
110 //Set cities
111 $cities = [];
112
113 //Set dances
114 $dances = [];
115 }
116
117 //Set keywords
118 //TODO: use splice instead of that shit !!!
119 //TODO: handle smartly indoor and outdoor !!!
120 $this->context['keywords'] = array_values(
121 array_merge(
122 $dances,
123 $cities,
124 [
125 $this->translator->trans('indoor'),
126 $this->translator->trans('outdoor'),
127 $this->translator->trans('sessions'),
128 $this->translator->trans('session list'),
129 $this->translator->trans('listing'),
130 $this->translator->trans('Libre Air')
131 ]
132 )
133 );
134
135 //Get textual cities
136 $cities = implode($this->translator->trans(' and '), array_filter(array_merge([implode(', ', array_slice($cities, 0, -1))], array_slice($cities, -1)), 'strlen'));
137
138 //Get textual dances
139 $dances = implode($this->translator->trans(' and '), array_filter(array_merge([implode(', ', array_slice($dances, 0, -1))], array_slice($dances, -1)), 'strlen'));
140
141 //Set title
142 $this->context['title'] = $this->translator->trans('%dances% %cities% sessions', ['%dances%' => $dances, '%cities%' => $cities]);
143
144 //Set description
145 $this->context['description'] = $this->translator->trans('%dances% indoor and outdoor session calendar %cities%', ['%dances%' => $dances, '%cities%' => $cities]);
146
147 //Render the view
148 return $this->render('@RapsysAir/session/index.html.twig', $this->context);
149 }
150
151 /**
152 * List all sessions for tango argentin
153 *
154 * @desc Display all sessions in tango argentin json format
155 *
156 * @todo Drop it if unused by tangoargentin ???
157 *
158 * @param Request $request The request instance
159 *
160 * @return Response The rendered view or redirection
161 */
162 public function tangoargentin(Request $request): Response {
163 //Retrieve events to update
164 $sessions = $this->doctrine->getRepository(Session::class)->findAllByPeriodAsCalendarArray($this->period);
165
166 //Init return array
167 $ret = [];
168
169 //Flatten sessions tree
170 $sessions = array_reduce($sessions, function ($c, $v) { return array_merge($c, $v['sessions']); }, []);
171
172 //Iterate on sessions
173 foreach($sessions as $sessionId => $session) {
174 //Set route params
175 $routeParams = $this->router->match($session['link']);
176
177 //Set route
178 $route = $routeParams['_route'];
179
180 //Drop _route from route params
181 unset($routeParams['_route']);
182
183 //Add session
184 $ret[$session['id']] = [
185 'start' => $session['start']->format(\DateTime::ISO8601),
186 'stop' => $session['start']->format(\DateTime::ISO8601),
187 'fromto' => $this->translator->trans('from %start% to %stop%', ['%start%' => $session['start']->format('H\hi'), '%stop%' => $session['stop']->format('H\hi')]),
188 'title' => $this->slugger->latin($session['application']['user']['title'])/*.' '.$this->translator->trans('at '.$session['location']['title'])*/,
189 'short' => $session['rate']['short'],
190 'rate' => $session['rate']['title'],
191 'location' => implode(' ', [$session['location']['address'], $session['location']['zipcode'], $session['location']['city']]),
192 'status' => in_array('canceled', $session['class'])?'annulé':'confirmé',
193 'modified' => $session['modified']->format(\DateTime::ISO8601),
194 #'organizer' => $session['application']['user']['title'],
195 #'source' => $this->router->generate('rapsys_air_session_view', ['id' => $sessionId, 'location' => $this->translator->trans($session['l_title'])], UrlGeneratorInterface::ABSOLUTE_URL)
196 'source' => $this->router->generate($route, $routeParams, UrlGeneratorInterface::ABSOLUTE_URL)
197 ];
198 }
199
200 //Set response
201 $response = new Response(json_encode($ret));
202
203 //Set header
204 $response->headers->set('Content-Type', 'application/json');
205
206 //Send response
207 return $response;
208 }
209
210 /**
211 * Display session
212 *
213 * @todo XXX: TODO: add <link rel="prev|next" for sessions or classes ? />
214 * @todo XXX: TODO: like described in: https://www.alsacreations.com/article/lire/1400-attribut-rel-relations.html#xnf-rel-attribute
215 * @todo XXX: TODO: or here: http://microformats.org/wiki/existing-rel-values#HTML5_link_type_extensions
216 *
217 * @todo: generate a background from @RapsysAir/Resources/public/location/<location>.png or @RapsysAir/Resources/public/location/<user>/<location>.png when available
218 *
219 * @todo: generate a share picture @RapsysAir/seance/363/place-saint-sulpice/bal-et-cours-de-tango-argentin/milonga-raphael/share.jpeg ?
220 * (with date, organiser, type, location, times and logo ?)
221 *
222 * @todo: add picture stuff about location ???
223 *
224 * @param Request $request The request instance
225 * @param int $id The session id
226 *
227 * @return Response The rendered view
228 *
229 * @throws NotFoundHttpException When session is not found
230 */
231 public function view(Request $request, int $id): Response {
232 //Fetch session
233 if (empty($this->context['session'] = $this->doctrine->getRepository(Session::class)->findOneByIdAsArray($id))) {
234 //Session not found
235 throw $this->createNotFoundException($this->translator->trans('Unable to find session: %id%', ['%id%' => $id]));
236 }
237
238 //Get locations at less than 1 km
239 $this->context['locations'] = $this->doctrine->getRepository(Location::class)->findAllByLatitudeLongitudeAsArray($this->context['session']['location']['latitude'], $this->context['session']['location']['longitude'], $this->period, 2);
240
241 //Set modified
242 //XXX: dance modified is already computed inside calendar modified
243 $this->modified = max(array_merge([$this->context['session']['modified']], array_map(function ($v) { return $v['modified']; }, $this->context['locations'])));
244
245 //Create response
246 $response = new Response();
247
248 //With logged user
249 if ($this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
250 //Set last modified
251 $response->setLastModified(new \DateTime('-1 year'));
252
253 //Set as private
254 $response->setPrivate();
255 //Without logged user
256 } else {
257 //Set etag
258 //XXX: only for public to force revalidation by last modified
259 $response->setEtag(md5(serialize(array_merge($this->context['session'], $this->context['locations']))));
260
261 //Set last modified
262 $response->setLastModified($this->modified);
263
264 //Set as public
265 $response->setPublic();
266
267 //Without role and modification
268 if ($response->isNotModified($request)) {
269 //Return 304 response
270 return $response;
271 }
272 }
273
274 //Get route
275 $route = $request->attributes->get('_route');
276
277 //Get route params
278 $routeParams = $request->attributes->get('_route_params');
279
280 //Disable redirect
281 $redirect = false;
282
283 //Without location or invalid location
284 if (empty($routeParams['location']) || $this->context['session']['location']['slug'] !== $routeParams['location']) {
285 //Set location
286 $routeParams['location'] = $this->context['session']['location']['slug'];
287
288 //Enable redirect
289 $redirect = true;
290 }
291
292 //With dance slug without dance or invalid dance
293 if (!empty($this->context['session']['application']['dance']['slug']) && (empty($routeParams['dance']) || $this->context['session']['application']['dance']['slug'] !== $routeParams['dance'])) {
294 //Set dance
295 $routeParams['dance'] = $this->context['session']['application']['dance']['slug'];
296
297 //Enable redirect
298 $redirect = true;
299 //Without dance slug with dance
300 } elseif (empty($this->context['session']['application']['dance']['slug']) && !empty($routeParams['dance'])) {
301 //Set dance
302 unset($routeParams['dance']);
303
304 //Enable redirect
305 $redirect = true;
306 }
307
308 //With user slug without user or invalid user
309 if (!empty($this->context['session']['application']['user']['slug']) && (empty($routeParams['user']) || $this->context['session']['application']['user']['slug'] !== $routeParams['user'])) {
310 //Set user
311 $routeParams['user'] = $this->context['session']['application']['user']['slug'];
312
313 //Enable redirect
314 $redirect = true;
315 //Without user slug with user
316 } elseif (empty($this->context['session']['application']['user']['slug']) && !empty($routeParams['user'])) {
317 //Set user
318 unset($routeParams['user']);
319
320 //Enable redirect
321 $redirect = true;
322 }
323
324 //With redirect
325 if ($redirect) {
326 //Redirect to route
327 return $this->redirectToRoute($route, $routeParams, $this->context['session']['stop'] <= new \DateTime('now') ? Response::HTTP_MOVED_PERMANENTLY : Response::HTTP_FOUND);
328 }
329
330 //Add map
331 $this->context['map'] = $this->map->getMap($this->context['session']['location']['map'], $this->modified->getTimestamp(), $this->context['session']['location']['latitude'], $this->context['session']['location']['longitude']);
332
333 //Add multi map
334 $this->context['multimap'] = $this->map->getMultiMap($this->context['session']['location']['multimap'], $this->modified->getTimestamp(), $this->context['locations']);
335
336 //Set canonical
337 $this->context['canonical'] = $this->context['session']['canonical'];
338
339 //Set alternates
340 $this->context['alternates'] = $this->context['session']['alternates'];
341
342 //Set localization date formater
343 $intlDate = new \IntlDateFormatter($this->locale, \IntlDateFormatter::TRADITIONAL, \IntlDateFormatter::NONE);
344
345 //Set localization time formater
346 $intlTime = new \IntlDateFormatter($this->locale, \IntlDateFormatter::NONE, \IntlDateFormatter::SHORT);
347
348 //With application
349 if (!empty($this->context['session']['application'])) {
350 //Set title
351 $this->context['title'] = $this->translator->trans('%dance% %id% by %pseudonym%', ['%id%' => $id, '%dance%' => $this->context['session']['application']['dance']['title'], '%pseudonym%' => $this->context['session']['application']['user']['title']]);
352
353 //Set description
354 $this->context['description'] = ucfirst($this->translator->trans('%dance% %location% %city% %slot% on %date% at %time%', [
355 '%dance%' => $this->context['session']['application']['dance']['title'],
356 '%location%' => $this->context['session']['location']['at'],
357 '%city%' => $this->context['session']['location']['in'],
358 '%slot%' => $this->context['session']['slot']['the'],
359 '%date%' => $intlDate->format($this->context['session']['start']),
360 '%time%' => $intlTime->format($this->context['session']['start']),
361 ]));
362
363 //Set keywords
364 //TODO: readd outdoor ???
365 $this->context['keywords'] = [
366 $this->context['session']['application']['dance']['type'],
367 $this->context['session']['application']['dance']['name'],
368 $this->context['session']['location']['title'],
369 $this->context['session']['application']['user']['title'],
370 $this->translator->trans($this->context['session']['location']['indoor']?'indoor':'outdoor')
371 ];
372 //Without application
373 } else {
374 //Set title
375 $this->context['title'] = $this->translator->trans('Session %id%', ['%id%' => $id]);
376
377 //Set description
378 $this->context['description'] = ucfirst($this->translator->trans('%location% %city% %slot% on %date% at %time%', [
379 '%city%' => ucfirst($this->context['session']['location']['in']),
380 '%location%' => $this->context['session']['location']['at'],
381 '%slot%' => $this->context['session']['slot']['the'],
382 '%date%' => $intlDate->format($this->context['session']['start']),
383 '%time%' => $intlTime->format($this->context['session']['start'])
384 ]));
385
386 //Add dance type
387 //TODO: readd outdoor ???
388 $this->context['keywords'] = [
389 $this->context['session']['location']['title'],
390 $this->translator->trans($this->context['session']['location']['indoor']?'indoor':'outdoor')
391 ];
392 }
393
394 //Set section
395 $this->context['section'] = $this->context['session']['location']['title'];
396
397 //Set facebook title
398 $this->context['facebook']['metas']['og:title'] = $this->context['title'].' '.$this->context['session']['location']['at'];
399
400 //Set facebook image
401 $this->context['facebook'] = [
402 'texts' => [
403 $this->context['session']['application']['user']['title']??$this->context['title'] => [
404 'font' => 'irishgrover',
405 'size' => 110
406 ],
407 ucfirst($intlDate->format($this->context['session']['start']))."\n".$this->translator->trans('Around %start% until %stop%', ['%start%' => $intlTime->format($this->context['session']['start']), '%stop%' => $intlTime->format($this->context['session']['stop'])]) => [
408 'font' => 'irishgrover',
409 'align' => 'left'
410 ],
411 $this->context['session']['location']['at'] => [
412 'align' => 'right',
413 'font' => 'labelleaurore',
414 'size' => 75
415 ]
416 ],
417 'updated' => $this->context['session']['updated']->format('U')
418 ]+$this->context['facebook'];
419
420 //Create application form for role_guest
421 if ($this->isGranted('ROLE_GUEST')) {
422 //Set now
423 $now = new \DateTime('now');
424
425 //Default favorites and dances
426 $danceFavorites = $dances = [];
427 //Default dance
428 $danceDefault = null;
429
430 //With admin
431 if ($this->isGranted('ROLE_ADMIN')) {
432 //Get favorites dances
433 $danceFavorites = $this->doctrine->getRepository(Dance::class)->findByUserId($this->getUser()->getId());
434
435 //Get dances
436 $dances = $this->doctrine->getRepository(Dance::class)->findAllIndexed();
437
438 //Set dance default
439 $danceDefault = !empty($this->context['session']['application'])?$dances[$this->context['session']['application']['dance']['id']]:null;
440 }
441
442 //Create SessionType form
443 //TODO: move to named form ???
444 $sessionForm = $this->createForm('Rapsys\AirBundle\Form\SessionType', null, [
445 //Set the action
446 'action' => $this->generateUrl('rapsys_air_session_view', ['id' => $id, 'location' => $this->context['session']['location']['slug'], 'dance' => $this->context['session']['application']['dance']['slug']??null, 'user' => $this->context['session']['application']['user']['slug']??null]),
447 //Set the form attribute
448 'attr' => [ 'class' => 'col' ],
449 //Set admin
450 'admin' => $this->isGranted('ROLE_ADMIN'),
451 //Set dance choices
452 'dance_choices' => $dances,
453 //Set dance default
454 'dance_default' => $danceDefault,
455 //Set dance favorites
456 'dance_favorites' => $danceFavorites,
457 //Set to session slot or evening by default
458 //XXX: default to Evening (3)
459 'slot_default' => $this->doctrine->getRepository(Slot::class)->findOneById($this->context['session']['slot']['id']??3),
460 //Set default user to current
461 'user' => $this->getUser()->getId(),
462 //Set date
463 'date' => $this->context['session']['date'],
464 //Set begin
465 'begin' => $this->context['session']['begin'],
466 //Set length
467 'length' => $this->context['session']['length'],
468 //Set raincancel
469 'raincancel' => ($this->isGranted('ROLE_ADMIN') || !empty($this->context['session']['application']['user']['id']) && $this->getUser()->getId() == $this->context['session']['application']['user']['id']) && $this->context['session']['rainfall'] >= 2,
470 //Set cancel
471 'cancel' => $this->isGranted('ROLE_ADMIN') || in_array($this->getUser()->getId(), explode("\n", $this->context['session']['sau_id'])),
472 //Set modify
473 'modify' => $this->isGranted('ROLE_ADMIN') || !empty($this->context['session']['application']['user']['id']) && $this->getUser()->getId() == $this->context['session']['application']['user']['id'] && $this->context['session']['stop'] >= $now && $this->isGranted('ROLE_REGULAR'),
474 //Set move
475 'move' => $this->isGranted('ROLE_ADMIN') || !empty($this->context['session']['application']['user']['id']) && $this->getUser()->getId() == $this->context['session']['application']['user']['id'] && $this->context['session']['stop'] >= $now && $this->isGranted('ROLE_SENIOR'),
476 //Set attribute
477 'attribute' => $this->isGranted('ROLE_ADMIN') && $this->context['session']['locked'] === null,
478 //Set session
479 'session' => $this->context['session']['id']
480 ]);
481
482 //Refill the fields in case of invalid form
483 $sessionForm->handleRequest($request);
484
485 //With submitted form
486 if ($sessionForm->isSubmitted() && $sessionForm->isValid()) {
487 //Get data
488 $data = $sessionForm->getData();
489
490 //Fetch session
491 $sessionObject = $this->doctrine->getRepository(Session::class)->findOneById($id);
492
493 //Set user
494 $userObject = $this->getUser();
495
496 //Replace with requested user for admin
497 if ($this->isGranted('ROLE_ADMIN') && !empty($data['user'])) {
498 $userObject = $this->doctrine->getRepository(User::class)->findOneById($data['user']);
499 }
500
501 //Set datetime
502 $datetime = new \DateTime('now');
503
504 //Set canceled time at start minus one day
505 $canceled = (clone $sessionObject->getStart())->sub(new \DateInterval('P1D'));
506
507 //Set action
508 $action = [
509 'raincancel' => $sessionForm->has('raincancel') && $sessionForm->get('raincancel')->isClicked(),
510 'modify' => $sessionForm->has('modify') && $sessionForm->get('modify')->isClicked(),
511 'move' => $sessionForm->has('move') && $sessionForm->get('move')->isClicked(),
512 'cancel' => $sessionForm->has('cancel') && $sessionForm->get('cancel')->isClicked(),
513 'forcecancel' => $sessionForm->has('forcecancel') && $sessionForm->get('forcecancel')->isClicked(),
514 'attribute' => $sessionForm->has('attribute') && $sessionForm->get('attribute')->isClicked(),
515 'autoattribute' => $sessionForm->has('autoattribute') && $sessionForm->get('autoattribute')->isClicked(),
516 'lock' => $sessionForm->has('lock') && $sessionForm->get('lock')->isClicked(),
517 ];
518
519 //With raincancel and application and (rainfall or admin)
520 if ($action['raincancel'] && ($application = $sessionObject->getApplication()) && ($sessionObject->getRainfall() >= 2 || $this->isGranted('ROLE_ADMIN'))) {
521 //Cancel application at start minus one day
522 $application->setCanceled($canceled);
523
524 //Update time
525 $application->setUpdated($datetime);
526
527 //Insufficient rainfall
528 //XXX: is admin
529 if ($sessionObject->getRainfall() < 2) {
530 //Set score
531 //XXX: magic cheat score 42
532 $application->setScore(42);
533 }
534
535 //Queue application save
536 $this->manager->persist($application);
537
538 //Add notice in flash message
539 $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()]));
540
541 //Update time
542 $sessionObject->setUpdated($datetime);
543
544 //Queue session save
545 $this->manager->persist($sessionObject);
546
547 //Add notice in flash message
548 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
549 //With modify
550 } elseif ($action['modify']) {
551 //With admin
552 if ($this->isGranted('ROLE_ADMIN')) {
553 //Get application
554 $application = $this->doctrine->getRepository(Application::class)->findOneBySessionUser($sessionObject, $userObject);
555
556 //Set dance
557 $application->setDance($data['dance']);
558
559 //Queue session save
560 $this->manager->persist($application);
561
562 //Set slot
563 $sessionObject->setSlot($data['slot']);
564
565 //Set date
566 $sessionObject->setDate($data['date']);
567 }
568
569 //Set begin
570 $sessionObject->setBegin($data['begin']);
571
572 //Set length
573 $sessionObject->setLength($data['length']);
574
575 //Update time
576 $sessionObject->setUpdated($datetime);
577
578 //Queue session save
579 $this->manager->persist($sessionObject);
580
581 //Add notice in flash message
582 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
583 //With move
584 } elseif ($action['move']) {
585 //Set location
586 $sessionObject->setLocation($this->doctrine->getRepository(Location::class)->findOneById($data['location']));
587
588 //Update time
589 $sessionObject->setUpdated($datetime);
590
591 //Queue session save
592 $this->manager->persist($sessionObject);
593
594 //Add notice in flash message
595 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
596 //With cancel or forcecancel
597 } elseif ($action['cancel'] || $action['forcecancel']) {
598 //Get application
599 $application = $this->doctrine->getRepository(Application::class)->findOneBySessionUser($sessionObject, $userObject);
600
601 //Not already canceled
602 if ($application->getCanceled() === null) {
603 //Cancel application
604 $application->setCanceled($datetime);
605
606 //Check if application is session application and (canceled 24h before start or forcecancel (as admin))
607 #if ($sessionObject->getApplication() == $application && ($datetime < $canceled || $action['forcecancel'])) {
608 if ($sessionObject->getApplication() == $application && $action['forcecancel']) {
609 //Set score
610 //XXX: magic cheat score 42
611 $application->setScore(42);
612
613 //Unattribute session
614 $sessionObject->setApplication(null);
615
616 //Update time
617 $sessionObject->setUpdated($datetime);
618
619 //Queue session save
620 $this->manager->persist($sessionObject);
621
622 //Add notice in flash message
623 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
624 }
625 //Already canceled
626 } else {
627 //Uncancel application
628 $application->setCanceled(null);
629 }
630
631 //Update time
632 $application->setUpdated($datetime);
633
634 //Queue application save
635 $this->manager->persist($application);
636
637 //Add notice in flash message
638 $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()]));
639 //With attribute
640 } elseif ($action['attribute']) {
641 //Get application
642 $application = $this->doctrine->getRepository(Application::class)->findOneBySessionUser($sessionObject, $userObject);
643
644 //Already canceled
645 if ($application->getCanceled() !== null) {
646 //Uncancel application
647 $application->setCanceled(null);
648 }
649
650 //Set score
651 //XXX: magic cheat score 42
652 $application->setScore(42);
653
654 //Update time
655 $application->setUpdated($datetime);
656
657 //Queue application save
658 $this->manager->persist($application);
659
660 //Add notice in flash message
661 $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()]));
662
663 //Unattribute session
664 $sessionObject->setApplication($application);
665
666 //Update time
667 $sessionObject->setUpdated($datetime);
668
669 //Queue session save
670 $this->manager->persist($sessionObject);
671
672 //Add notice in flash message
673 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
674 //With autoattribute
675 } elseif ($action['autoattribute']) {
676 //Get best application
677 //XXX: best application may not issue result while grace time or bad behaviour
678 if (!empty($application = $this->doctrine->getRepository(Session::class)->findBestApplicationById($id))) {
679 //Attribute session
680 $sessionObject->setApplication($application);
681
682 //Update time
683 $sessionObject->setUpdated($datetime);
684
685 //Queue session save
686 $this->manager->persist($sessionObject);
687
688 //Add notice in flash message
689 $this->addFlash('notice', $this->translator->trans('Session %id% auto attributed', ['%id%' => $id]));
690 //No application
691 } else {
692 //Add warning in flash message
693 $this->addFlash('warning', $this->translator->trans('Session %id% not auto attributed', ['%id%' => $id]));
694 }
695 //With lock
696 } elseif ($action['lock']) {
697 //Already locked
698 if ($sessionObject->getLocked() !== null) {
699 //Set uncanceled
700 $canceled = null;
701
702 //Unlock session
703 $sessionObject->setLocked(null);
704 //Not locked
705 } else {
706 //Get application
707 if ($application = $sessionObject->getApplication()) {
708 //Set score
709 //XXX: magic cheat score 42
710 $application->setScore(42);
711
712 //Update time
713 $application->setUpdated($datetime);
714
715 //Queue application save
716 $this->manager->persist($application);
717
718 //Add notice in flash message
719 $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()]));
720 }
721
722 //Unattribute session
723 $sessionObject->setApplication(null);
724
725 //Lock session
726 $sessionObject->setLocked($datetime);
727 }
728
729 //Update time
730 $sessionObject->setUpdated($datetime);
731
732 //Queue session save
733 $this->manager->persist($sessionObject);
734
735 //Add notice in flash message
736 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
737 //Unknown action
738 } else {
739 //Add warning in flash message
740 $this->addFlash('warning', $this->translator->trans('Session %id% not updated', ['%id%' => $id]));
741 }
742
743 //Flush to get the ids
744 $this->manager->flush();
745
746 //Redirect to cleanup the form
747 return $this->redirectToRoute('rapsys_air_session_view', ['id' => $id, 'location' => $this->context['session']['location']['slug'], 'dance' => $this->context['session']['application']['dance']['slug']??null, 'user' => $this->context['session']['application']['user']['slug']??null]);
748 }
749
750 //Add form to context
751 $this->context['forms']['session'] = $sessionForm->createView();
752 }
753
754 //Render the view
755 return $this->render('@RapsysAir/session/view.html.twig', $this->context, $response);
756 }
757 }