]> Raphaël G. Git Repositories - airbundle/blob - Controller/SessionController.php
Rename "Open Air" reference in "Libre Air"
[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 //Create SessionType form
426 //TODO: move to named form ???
427 $sessionForm = $this->createForm('Rapsys\AirBundle\Form\SessionType', null, [
428 //Set the action
429 '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]),
430 //Set the form attribute
431 'attr' => [ 'class' => 'col' ],
432 //Set admin
433 'admin' => $this->isGranted('ROLE_ADMIN'),
434 //Set default user to current
435 'user' => $this->getUser()->getId(),
436 //Set date
437 'date' => $this->context['session']['date'],
438 //Set begin
439 'begin' => $this->context['session']['begin'],
440 //Set length
441 'length' => $this->context['session']['length'],
442 //Set raincancel
443 '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,
444 //Set cancel
445 'cancel' => $this->isGranted('ROLE_ADMIN') || in_array($this->getUser()->getId(), explode("\n", $this->context['session']['sau_id'])),
446 //Set modify
447 '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'),
448 //Set move
449 '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'),
450 //Set attribute
451 'attribute' => $this->isGranted('ROLE_ADMIN') && $this->context['session']['locked'] === null,
452 //Set session
453 'session' => $this->context['session']['id']
454 ]);
455
456 //Refill the fields in case of invalid form
457 $sessionForm->handleRequest($request);
458
459 //With submitted form
460 if ($sessionForm->isSubmitted() && $sessionForm->isValid()) {
461 //Get data
462 $data = $sessionForm->getData();
463
464 //Fetch session
465 $sessionObject = $this->doctrine->getRepository(Session::class)->findOneById($id);
466
467 //Set user
468 $userObject = $this->getUser();
469
470 //Replace with requested user for admin
471 if ($this->isGranted('ROLE_ADMIN') && !empty($data['user'])) {
472 $userObject = $this->doctrine->getRepository(User::class)->findOneById($data['user']);
473 }
474
475 //Set datetime
476 $datetime = new \DateTime('now');
477
478 //Set canceled time at start minus one day
479 $canceled = (clone $sessionObject->getStart())->sub(new \DateInterval('P1D'));
480
481 //Set action
482 $action = [
483 'raincancel' => $sessionForm->has('raincancel') && $sessionForm->get('raincancel')->isClicked(),
484 'modify' => $sessionForm->has('modify') && $sessionForm->get('modify')->isClicked(),
485 'move' => $sessionForm->has('move') && $sessionForm->get('move')->isClicked(),
486 'cancel' => $sessionForm->has('cancel') && $sessionForm->get('cancel')->isClicked(),
487 'forcecancel' => $sessionForm->has('forcecancel') && $sessionForm->get('forcecancel')->isClicked(),
488 'attribute' => $sessionForm->has('attribute') && $sessionForm->get('attribute')->isClicked(),
489 'autoattribute' => $sessionForm->has('autoattribute') && $sessionForm->get('autoattribute')->isClicked(),
490 'lock' => $sessionForm->has('lock') && $sessionForm->get('lock')->isClicked(),
491 ];
492
493 //With raincancel and application and (rainfall or admin)
494 if ($action['raincancel'] && ($application = $sessionObject->getApplication()) && ($sessionObject->getRainfall() >= 2 || $this->isGranted('ROLE_ADMIN'))) {
495 //Cancel application at start minus one day
496 $application->setCanceled($canceled);
497
498 //Update time
499 $application->setUpdated($datetime);
500
501 //Insufficient rainfall
502 //XXX: is admin
503 if ($sessionObject->getRainfall() < 2) {
504 //Set score
505 //XXX: magic cheat score 42
506 $application->setScore(42);
507 }
508
509 //Queue application save
510 $this->manager->persist($application);
511
512 //Add notice in flash message
513 $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()]));
514
515 //Update time
516 $sessionObject->setUpdated($datetime);
517
518 //Queue session save
519 $this->manager->persist($sessionObject);
520
521 //Add notice in flash message
522 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
523 //With modify
524 } elseif ($action['modify']) {
525 //With admin
526 if ($this->isGranted('ROLE_ADMIN')) {
527 //Set date
528 $sessionObject->setDate($data['date']);
529 }
530
531 //Set begin
532 $sessionObject->setBegin($data['begin']);
533
534 //Set length
535 $sessionObject->setLength($data['length']);
536
537 //Update time
538 $sessionObject->setUpdated($datetime);
539
540 //Queue session save
541 $this->manager->persist($sessionObject);
542
543 //Add notice in flash message
544 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
545 //With move
546 } elseif ($action['move']) {
547 //Set location
548 $sessionObject->setLocation($this->doctrine->getRepository(Location::class)->findOneById($data['location']));
549
550 //Update time
551 $sessionObject->setUpdated($datetime);
552
553 //Queue session save
554 $this->manager->persist($sessionObject);
555
556 //Add notice in flash message
557 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
558 //With cancel or forcecancel
559 } elseif ($action['cancel'] || $action['forcecancel']) {
560 //Get application
561 $application = $this->doctrine->getRepository(Application::class)->findOneBySessionUser($sessionObject, $userObject);
562
563 //Not already canceled
564 if ($application->getCanceled() === null) {
565 //Cancel application
566 $application->setCanceled($datetime);
567
568 //Check if application is session application and (canceled 24h before start or forcecancel (as admin))
569 #if ($sessionObject->getApplication() == $application && ($datetime < $canceled || $action['forcecancel'])) {
570 if ($sessionObject->getApplication() == $application && $action['forcecancel']) {
571 //Set score
572 //XXX: magic cheat score 42
573 $application->setScore(42);
574
575 //Unattribute session
576 $sessionObject->setApplication(null);
577
578 //Update time
579 $sessionObject->setUpdated($datetime);
580
581 //Queue session save
582 $this->manager->persist($sessionObject);
583
584 //Add notice in flash message
585 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
586 }
587 //Already canceled
588 } else {
589 //Uncancel application
590 $application->setCanceled(null);
591 }
592
593 //Update time
594 $application->setUpdated($datetime);
595
596 //Queue application save
597 $this->manager->persist($application);
598
599 //Add notice in flash message
600 $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()]));
601 //With attribute
602 } elseif ($action['attribute']) {
603 //Get application
604 $application = $this->doctrine->getRepository(Application::class)->findOneBySessionUser($sessionObject, $userObject);
605
606 //Already canceled
607 if ($application->getCanceled() !== null) {
608 //Uncancel application
609 $application->setCanceled(null);
610 }
611
612 //Set score
613 //XXX: magic cheat score 42
614 $application->setScore(42);
615
616 //Update time
617 $application->setUpdated($datetime);
618
619 //Queue application save
620 $this->manager->persist($application);
621
622 //Add notice in flash message
623 $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()]));
624
625 //Unattribute session
626 $sessionObject->setApplication($application);
627
628 //Update time
629 $sessionObject->setUpdated($datetime);
630
631 //Queue session save
632 $this->manager->persist($sessionObject);
633
634 //Add notice in flash message
635 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
636 //With autoattribute
637 } elseif ($action['autoattribute']) {
638 //Get best application
639 //XXX: best application may not issue result while grace time or bad behaviour
640 if (!empty($application = $this->doctrine->getRepository(Session::class)->findBestApplicationById($id))) {
641 //Attribute session
642 $sessionObject->setApplication($application);
643
644 //Update time
645 $sessionObject->setUpdated($datetime);
646
647 //Queue session save
648 $this->manager->persist($sessionObject);
649
650 //Add notice in flash message
651 $this->addFlash('notice', $this->translator->trans('Session %id% auto attributed', ['%id%' => $id]));
652 //No application
653 } else {
654 //Add warning in flash message
655 $this->addFlash('warning', $this->translator->trans('Session %id% not auto attributed', ['%id%' => $id]));
656 }
657 //With lock
658 } elseif ($action['lock']) {
659 //Already locked
660 if ($sessionObject->getLocked() !== null) {
661 //Set uncanceled
662 $canceled = null;
663
664 //Unlock session
665 $sessionObject->setLocked(null);
666 //Not locked
667 } else {
668 //Get application
669 if ($application = $sessionObject->getApplication()) {
670 //Set score
671 //XXX: magic cheat score 42
672 $application->setScore(42);
673
674 //Update time
675 $application->setUpdated($datetime);
676
677 //Queue application save
678 $this->manager->persist($application);
679
680 //Add notice in flash message
681 $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()]));
682 }
683
684 //Unattribute session
685 $sessionObject->setApplication(null);
686
687 //Lock session
688 $sessionObject->setLocked($datetime);
689 }
690
691 //Update time
692 $sessionObject->setUpdated($datetime);
693
694 //Queue session save
695 $this->manager->persist($sessionObject);
696
697 //Add notice in flash message
698 $this->addFlash('notice', $this->translator->trans('Session %id% updated', ['%id%' => $id]));
699 //Unknown action
700 } else {
701 //Add warning in flash message
702 $this->addFlash('warning', $this->translator->trans('Session %id% not updated', ['%id%' => $id]));
703 }
704
705 //Flush to get the ids
706 $this->manager->flush();
707
708 //Redirect to cleanup the form
709 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]);
710 }
711
712 //Add form to context
713 $this->context['forms']['session'] = $sessionForm->createView();
714 }
715
716 //Render the view
717 return $this->render('@RapsysAir/session/view.html.twig', $this->context, $response);
718 }
719 }