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\Location
; 
  15 class SessionController 
extends DefaultController 
{ 
  19          * @desc Persist session and all required dependencies in database 
  21          * @param Request $request The request instance 
  23          * @return Response The rendered view or redirection 
  25          * @throws \RuntimeException When user has not at least guest role 
  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')])); 
  31                 //Reject non post requests 
  32                 if (!$request->isMethod('POST')) { 
  33                         throw new \
RuntimeException('Request method MUST be POST'); 
  37                 $doctrine = $this->getDoctrine(); 
  40                 $session = $doctrine->getRepository(Session
::class)->fetchOneById($id); 
  45                         !$this->isGranted('ROLE_ADMIN') && 
  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'])) 
  51                         //Prevent non admin and non attributed user access 
  52                         throw $this->createAccessDeniedException(); 
  56                 $now = new \
DateTime('now'); 
  58                 //Create SessionEditType form 
  59                 $form = $this->createForm('Rapsys\AirBundle\Form\SessionEditType', null, [ 
  61                         'action' => $this->generateUrl('rapsys_air_session_edit', [ 'id' => $id ]), 
  62                         //Set the form attribute 
  65                         'admin' => $this->isGranted('ROLE_ADMIN'), 
  66                         //Set default user to current 
  67                         'user' => $this->getUser()->getId(), 
  69                         'begin' => $session['begin'], 
  71                         'length' => $session['length'], 
  73                         'raincancel' => ($this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id']) && $session['rainfall'] >= 2, 
  75                         'cancel' => $this->isGranted('ROLE_ADMIN') || in_array($this->getUser()->getId(), explode("\n", $session['sau_id'])), 
  77                         'modify' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['stop'] >= $now && $this->isGranted('ROLE_REGULAR'), 
  79                         'move' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['stop'] >= $now && $this->isGranted('ROLE_SENIOR'), 
  81                         'attribute' => $this->isGranted('ROLE_ADMIN') && $session['locked'] === null, 
  83                         'session' => $session['id'] 
  86                 //Refill the fields in case of invalid form 
  87                 $form->handleRequest($request); 
  90                 #if (true) { $form->isValid(); 
  91                 //TODO: mettre une contrainte sur un des boutons submit, je sais pas encore comment 
  92                 if (!$form->isValid()) { 
  94                         $section = $this->translator
->trans('Session %id%', ['%id%' => $id]); 
  97                         $title = $section.' - '.$this->translator
->trans($this->config
['site']['title']); 
  99                         //Add session in context 
 100                         $context['session'] = [ 
 102                                 'title' => $this->translator
->trans('Session %id%', ['%id%' => $id]), 
 104                                         'id' => $session['l_id'], 
 105                                         'at' => $this->translator
->trans('at '.$session['l_title']) 
 109                         return $this->render('@RapsysAir/session/edit.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView()]+
$context+
$this->context
); 
 113                 $manager = $doctrine->getManager(); 
 116                 $data = $form->getData(); 
 119                 $session = $doctrine->getRepository(Session
::class)->findOneById($id); 
 122                 $user = $this->getUser(); 
 124                 //Replace with requested user for admin 
 125                 if ($this->isGranted('ROLE_ADMIN') && !empty($data['user'])) { 
 126                         $user = $doctrine->getRepository(User
::class)->findOneById($data['user']); 
 130                 $datetime = new \
DateTime('now'); 
 132                 //Set canceled time at start minus one day 
 133                 $canceled = (clone $session->getStart())->sub(new \
DateInterval('P1D')); 
 137                         'raincancel' => $form->has('raincancel') && $form->get('raincancel')->isClicked(), 
 138                         'modify' => $form->has('modify') && $form->get('modify')->isClicked(), 
 139                         'move' => $form->has('move') && $form->get('move')->isClicked(), 
 140                         'cancel' => $form->has('cancel') && $form->get('cancel')->isClicked(), 
 141                         'forcecancel' => $form->has('forcecancel') && $form->get('forcecancel')->isClicked(), 
 142                         'attribute' => $form->has('attribute') && $form->get('attribute')->isClicked(), 
 143                         'autoattribute' => $form->has('autoattribute') && $form->get('autoattribute')->isClicked(), 
 144                         'lock' => $form->has('lock') && $form->get('lock')->isClicked(), 
 147                 //With raincancel and application and (rainfall or admin) 
 148                 if ($action['raincancel'] && ($application = $session->getApplication()) && ($session->getRainfall() >= 2 || $this->isGranted('ROLE_ADMIN'))) { 
 149                         //Cancel application at start minus one day 
 150                         $application->setCanceled($canceled); 
 153                         $application->setUpdated($datetime); 
 155                         //Insufficient rainfall 
 157                         if ($session->getRainfall() < 2) { 
 159                                 //XXX: magic cheat score 42 
 160                                 $application->setScore(42); 
 163                         //Queue application save 
 164                         $manager->persist($application); 
 166                         //Add notice in flash message 
 167                         $this->addFlash('notice', $this->translator
->trans('Application %id% updated', ['%id%' => $application->getId()])); 
 170                         $session->setUpdated($datetime); 
 173                         $manager->persist($session); 
 175                         //Add notice in flash message 
 176                         $this->addFlash('notice', $this->translator
->trans('Session %id% updated', ['%id%' => $id])); 
 178                 } elseif ($action['modify']) { 
 180                         $session->setBegin($data['begin']); 
 183                         $session->setLength($data['length']); 
 186                         $session->setUpdated($datetime); 
 189                         $manager->persist($session); 
 191                         //Add notice in flash message 
 192                         $this->addFlash('notice', $this->translator
->trans('Session %id% updated', ['%id%' => $id])); 
 194                 } elseif ($action['move']) { 
 196                         $session->setLocation($doctrine->getRepository(Location
::class)->findOneById($data['location'])); 
 199                         $session->setUpdated($datetime); 
 202                         $manager->persist($session); 
 204                         //Add notice in flash message 
 205                         $this->addFlash('notice', $this->translator
->trans('Session %id% updated', ['%id%' => $id])); 
 206                 //With cancel or forcecancel 
 207                 } elseif ($action['cancel'] || $action['forcecancel']) { 
 209                         $application = $doctrine->getRepository(Application
::class)->findOneBySessionUser($session, $user); 
 211                         //Not already canceled 
 212                         if ($application->getCanceled() === null) { 
 214                                 $application->setCanceled($datetime); 
 216                                 //Check if application is session application and (canceled 24h before start or forcecancel (as admin)) 
 217                                 #if ($session->getApplication() == $application && ($datetime < $canceled || $action['forcecancel'])) { 
 218                                 if ($session->getApplication() == $application && $action['forcecancel']) { 
 220                                         //XXX: magic cheat score 42 
 221                                         $application->setScore(42); 
 223                                         //Unattribute session 
 224                                         $session->setApplication(null); 
 227                                         $session->setUpdated($datetime); 
 230                                         $manager->persist($session); 
 232                                         //Add notice in flash message 
 233                                         $this->addFlash('notice', $this->translator
->trans('Session %id% updated', ['%id%' => $id])); 
 237                                 //Uncancel application 
 238                                 $application->setCanceled(null); 
 242                         $application->setUpdated($datetime); 
 244                         //Queue application save 
 245                         $manager->persist($application); 
 247                         //Add notice in flash message 
 248                         $this->addFlash('notice', $this->translator
->trans('Application %id% updated', ['%id%' => $application->getId()])); 
 250                 } elseif ($action['attribute']) { 
 252                         $application = $doctrine->getRepository(Application
::class)->findOneBySessionUser($session, $user); 
 255                         if ($application->getCanceled() !== null) { 
 256                                 //Uncancel application 
 257                                 $application->setCanceled(null); 
 261                         //XXX: magic cheat score 42 
 262                         $application->setScore(42); 
 265                         $application->setUpdated($datetime); 
 267                         //Queue application save 
 268                         $manager->persist($application); 
 270                         //Add notice in flash message 
 271                         $this->addFlash('notice', $this->translator
->trans('Application %id% updated', ['%id%' => $application->getId()])); 
 273                         //Unattribute session 
 274                         $session->setApplication($application); 
 277                         $session->setUpdated($datetime); 
 280                         $manager->persist($session); 
 282                         //Add notice in flash message 
 283                         $this->addFlash('notice', $this->translator
->trans('Session %id% updated', ['%id%' => $id])); 
 285                 } elseif ($action['autoattribute']) { 
 286                         //Get best application 
 287                         //XXX: best application may not issue result while grace time or bad behaviour 
 288                         if (!empty($application = $doctrine->getRepository(Session
::class)->findBestApplicationById($id))) { 
 290                                 $session->setApplication($application); 
 293                                 $session->setUpdated($datetime); 
 296                                 $manager->persist($session); 
 298                                 //Add notice in flash message 
 299                                 $this->addFlash('notice', $this->translator
->trans('Session %id% auto attributed', ['%id%' => $id])); 
 302                                 //Add notice in flash message 
 303                                 $this->addFlash('warning', $this->translator
->trans('Session %id% not auto attributed', ['%id%' => $id])); 
 306                 } elseif ($action['lock']) { 
 308                         if ($session->getLocked() !== null) { 
 313                                 $session->setLocked(null); 
 317                                 if ($application = $session->getApplication()) { 
 319                                         //XXX: magic cheat score 42 
 320                                         $application->setScore(42); 
 323                                         $application->setUpdated($datetime); 
 325                                         //Queue application save 
 326                                         $manager->persist($application); 
 328                                         //Add notice in flash message 
 329                                         $this->addFlash('notice', $this->translator
->trans('Application %id% updated', ['%id%' => $application->getId()])); 
 332                                 //Unattribute session 
 333                                 $session->setApplication(null); 
 336                                 $session->setLocked($datetime); 
 340 #                       $applications = $doctrine->getRepository(Application::class)->findBySession($session); 
 343 #                       if (!empty($applications)) { 
 344 #                               //Iterate on each applications 
 345 #                               foreach($applications as $application) { 
 346 #                                       //Cancel application 
 347 #                                       $application->setCanceled($canceled); 
 350 #                                       $application->setUpdated($datetime); 
 352 #                                       //Queue application save 
 353 #                                       $manager->persist($application); 
 355 #                                       //Add notice in flash message 
 356 #                                       $this->addFlash('notice', $this->translator->trans('Application %id% updated', ['%id%' => $application->getId()])); 
 361                         $session->setUpdated($datetime); 
 364                         $manager->persist($session); 
 366                         //Add notice in flash message 
 367                         $this->addFlash('notice', $this->translator
->trans('Session %id% updated', ['%id%' => $id])); 
 370                         //Add notice in flash message 
 371                         $this->addFlash('warning', $this->translator
->trans('Session %id% not updated', ['%id%' => $id])); 
 374                 //Flush to get the ids 
 377                 //Extract and process referer 
 378                 if ($referer = $request->headers
->get('referer')) { 
 379                         //Create referer request instance 
 380                         $req = Request
::create($referer); 
 383                         $path = $req->getPathInfo(); 
 385                         //Get referer query string 
 386                         $query = $req->getQueryString(); 
 389                         $path = str_replace($request->getScriptName(), '', $path); 
 391                         //Try with referer path 
 394                                 $oldContext = $this->router
->getContext(); 
 396                                 //Force clean context 
 397                                 //XXX: prevent MethodNotAllowedException because current context method is POST in onevendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php+42 
 398                                 $this->router
->setContext(new RequestContext()); 
 400                                 //Retrieve route matching path 
 401                                 $route = $this->router
->match($path); 
 404                                 $this->router
->setContext($oldContext); 
 410                                 $name = $route['_route']; 
 412                                 //Remove route and controller from route defaults 
 413                                 unset($route['_route'], $route['_controller']); 
 416                                 return $this->redirectToRoute($name, $route); 
 418                         } catch(MethodNotAllowedException
|ResourceNotFoundException 
$e) { 
 419                                 //Unset referer to fallback to default route 
 424                 //Redirect to cleanup the form 
 425                 return $this->redirectToRoute('rapsys_air_session_view', ['id' => $id]); 
 431          * @desc Display all sessions with an application or login form 
 433          * @param Request $request The request instance 
 435          * @return Response The rendered view 
 437         public function index(Request 
$request = null) { 
 439                 $doctrine = $this->getDoctrine(); 
 442                 $section = $this->translator
->trans('Sessions'); 
 445                 $title = $section.' - '.$this->translator
->trans($this->config
['site']['title']); 
 450                 //Create application form for role_guest 
 451                 if ($this->isGranted('ROLE_GUEST')) { 
 452                         //Create ApplicationType form 
 453                         $application = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [ 
 455                                 'action' => $this->generateUrl('rapsys_air_application_add'), 
 456                                 //Set the form attribute 
 457                                 'attr' => [ 'class' => 'col' ], 
 459                                 'admin' => $this->isGranted('ROLE_ADMIN'), 
 460                                 //Set default user to current 
 461                                 'user' => $this->getUser()->getId(), 
 462                                 //Set default slot to evening 
 463                                 //XXX: default to Evening (3) 
 464                                 'slot' => $doctrine->getRepository(Slot
::class)->findOneById(3) 
 467                         //Add form to context 
 468                         $context['application'] = $application->createView(); 
 469                 //Create login form for anonymous 
 470                 } elseif (!$this->isGranted('IS_AUTHENTICATED_REMEMBERED')) { 
 471                         //Create ApplicationType form 
 472                         $login = $this->createForm('Rapsys\UserBundle\Form\LoginType', null, [ 
 474                                 'action' => $this->generateUrl('rapsys_user_login'), 
 475                                 //Set the form attribute 
 476                                 'attr' => [ 'class' => 'col' ] 
 479                         //Add form to context 
 480                         $context['login'] = $login->createView(); 
 484                 $period = new \
DatePeriod( 
 485                         //Start from first monday of week 
 486                         new \
DateTime('Monday this week'), 
 487                         //Iterate on each day 
 488                         new \
DateInterval('P1D'), 
 489                         //End with next sunday and 4 weeks 
 490                         new \
DateTime('Monday this week + 5 week') 
 494                 //TODO: highlight with current session route parameter 
 495                 $calendar = $doctrine->getRepository(Session
::class)->fetchCalendarByDatePeriod($this->translator
, $period, null, $request->get('session'), !$this->isGranted('IS_AUTHENTICATED_REMEMBERED')); 
 498                 //XXX: we want to display all active locations anyway 
 499                 $locations = $doctrine->getRepository(Location
::class)->fetchTranslatedLocationByDatePeriod($this->translator
, $period/*, !$this->isGranted('IS_AUTHENTICATED_REMEMBERED')*/); 
 502                 return $this->render('@RapsysAir/session/index.html.twig', ['title' => $title, 'section' => $section, 'calendar' => $calendar, 'locations' => $locations]+
$context+
$this->context
); 
 508          * @desc Display session by id with an application or login form 
 510          * @param Request $request The request instance 
 511          * @param int $id The session id 
 513          * @return Response The rendered view 
 515         public function view(Request 
$request, $id) { 
 517                 $doctrine = $this->getDoctrine(); 
 520                 $session = $doctrine->getRepository(Session
::class)->fetchOneById($id); 
 523                 $section = $this->translator
->trans($session['l_title']); 
 526                 $title = $this->translator
->trans('Session %id%', ['%id%' => $id]).' - '.$section.' - '.$this->translator
->trans($this->config
['site']['title']); 
 531                 //Create application form for role_guest 
 532                 if ($this->isGranted('ROLE_GUEST')) { 
 533                         //Create ApplicationType form 
 534                         $application = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [ 
 536                                 'action' => $this->generateUrl('rapsys_air_application_add'), 
 537                                 //Set the form attribute 
 538                                 'attr' => [ 'class' => 'col' ], 
 540                                 'admin' => $this->isGranted('ROLE_ADMIN'), 
 541                                 //Set default user to current 
 542                                 'user' => $this->getUser()->getId(), 
 543                                 //Set default slot to current 
 544                                 'slot' => $this->getDoctrine()->getRepository(Slot
::class)->findOneById($session['t_id']), 
 545                                 //Set default location to current 
 546                                 'location' => $this->getDoctrine()->getRepository(Location
::class)->findOneById($session['l_id']), 
 549                         //Add form to context 
 550                         $context['application'] = $application->createView(); 
 553                         $now = new \
DateTime('now'); 
 555                         //Create SessionEditType form 
 556                         $session_edit = $this->createForm('Rapsys\AirBundle\Form\SessionEditType', null, [ 
 558                                 'action' => $this->generateUrl('rapsys_air_session_edit', [ 'id' => $id ]), 
 559                                 //Set the form attribute 
 560                                 'attr' => [ 'class' => 'col' ], 
 562                                 'admin' => $this->isGranted('ROLE_ADMIN'), 
 563                                 //Set default user to current 
 564                                 'user' => $this->getUser()->getId(), 
 566                                 'begin' => $session['begin'], 
 568                                 'length' => $session['length'], 
 570                                 'raincancel' => ($this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id']) && $session['rainfall'] >= 2, 
 572                                 'cancel' => $this->isGranted('ROLE_ADMIN') || in_array($this->getUser()->getId(), explode("\n", $session['sau_id'])), 
 574                                 'modify' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['stop'] >= $now && $this->isGranted('ROLE_REGULAR'), 
 576                                 'move' => $this->isGranted('ROLE_ADMIN') || $this->getUser()->getId() == $session['au_id'] && $session['stop'] >= $now && $this->isGranted('ROLE_SENIOR'), 
 578                                 'attribute' => $this->isGranted('ROLE_ADMIN') && $session['locked'] === null, 
 580                                 'session' => $session['id'] 
 583                         //Add form to context 
 584                         $context['session_edit'] = $session_edit->createView(); 
 585                 //Create login form for anonymous 
 586                 } elseif (!$this->isGranted('IS_AUTHENTICATED_REMEMBERED')) { 
 587                         //Create ApplicationType form 
 588                         $login = $this->createForm('Rapsys\UserBundle\Form\LoginType', null, [ 
 590                                 'action' => $this->generateUrl('rapsys_user_login'), 
 591                                 //Set the form attribute 
 592                                 'attr' => [ 'class' => 'col' ] 
 595                         //Add form to context 
 596                         $context['login'] = $login->createView(); 
 599                 //Add session in context 
 600                 $context['session'] = [ 
 602                         'date' => $session['date'], 
 603                         'begin' => $session['begin'], 
 604                         'start' => $session['start'], 
 605                         'length' => $session['length'], 
 606                         'stop' => $session['stop'], 
 607                         'rainfall' => $session['rainfall'] !== null ? $session['rainfall'].' mm' : $session['rainfall'], 
 608                         'rainrisk' => $session['rainrisk'] !== null ? ($session['rainrisk']*100).' %' : $session['rainrisk'], 
 609                         'realfeel' => $session['realfeel'] !== null ? $session['realfeel'].' °C' : $session['realfeel'], 
 610                         'realfeelmin' => $session['realfeelmin'] !== null ? $session['realfeelmin'].' °C' : $session['realfeelmin'], 
 611                         'realfeelmax' => $session['realfeelmax'] !== null ? $session['realfeelmax'].' °C' : $session['realfeelmax'], 
 612                         'temperature' => $session['temperature'] !== null ? $session['temperature'].' °C' : $session['temperature'], 
 613                         'temperaturemin' => $session['temperaturemin'] !== null ? $session['temperaturemin'].' °C' : $session['temperaturemin'], 
 614                         'temperaturemax' => $session['temperaturemax'] !== null ? $session['temperaturemax'].' °C' : $session['temperaturemax'], 
 615                         'locked' => $session['locked'], 
 616                         'created' => $session['created'], 
 617                         'updated' => $session['updated'], 
 618                         'title' => $this->translator
->trans('Session %id%', ['%id%' => $id]), 
 619                         'application' => null, 
 621                                 'id' => $session['l_id'], 
 622                                 'at' => $this->translator
->trans('at '.$session['l_title']), 
 623                                 'short' => $this->translator
->trans($session['l_short']), 
 624                                 'title' => $this->translator
->trans($session['l_title']), 
 625                                 'address' => $session['l_address'], 
 626                                 'zipcode' => $session['l_zipcode'], 
 627                                 'city' => $session['l_city'], 
 628                                 'latitude' => $session['l_latitude'], 
 629                                 'longitude' => $session['l_longitude'] 
 632                                 'id' => $session['t_id'], 
 633                                 'title' => $this->translator
->trans($session['t_title']) 
 635                         'applications' => null 
 639                 if (!empty($session['a_id'])) { 
 640                         $context['session']['application'] = [ 
 642                                         'id' => $session['au_id'], 
 643                                         'title' => $session['au_pseudonym'] 
 645                                 'id' => $session['a_id'], 
 646                                 'title' => $this->translator
->trans('Application %id%', [ '%id%' => $session['a_id'] ]), 
 651                 if (!empty($session['sa_id'])) { 
 652                         //Extract applications id 
 653                         $session['sa_id'] = explode("\n", $session['sa_id']); 
 654                         //Extract applications score 
 655                         //XXX: score may be null before grant or for bad behaviour, replace NULL with 'NULL' to avoid silent drop in mysql 
 656                         $session['sa_score'] = array_map(function($v){return $v
==='NULL'?null:$v
;}, explode("\n", $session['sa_score'])); 
 657                         //Extract applications created 
 658                         $session['sa_created'] = array_map(function($v){return new \
DateTime($v
);}, explode("\n", $session['sa_created'])); 
 659                         //Extract applications updated 
 660                         $session['sa_updated'] = array_map(function($v){return new \
DateTime($v
);}, explode("\n", $session['sa_updated'])); 
 661                         //Extract applications canceled 
 662                         //XXX: canceled is null before cancelation, replace NULL with 'NULL' to avoid silent drop in mysql 
 663                         $session['sa_canceled'] = array_map(function($v){return $v
==='NULL'?null:new \
DateTime($v
);}, explode("\n", $session['sa_canceled'])); 
 665                         //Extract applications user id 
 666                         $session['sau_id'] = explode("\n", $session['sau_id']); 
 667                         //Extract applications user pseudonym 
 668                         $session['sau_pseudonym'] = explode("\n", $session['sau_pseudonym']); 
 671                         $context['session']['applications'] = []; 
 672                         foreach($session['sa_id'] as $i => $sa_id) { 
 673                                 $context['session']['applications'][$sa_id] = [ 
 675                                         'score' => $session['sa_score'][$i], 
 676                                         'created' => $session['sa_created'][$i], 
 677                                         'updated' => $session['sa_updated'][$i], 
 678                                         'canceled' => $session['sa_canceled'][$i] 
 680                                 if (!empty($session['sau_id'][$i])) { 
 681                                         $context['session']['applications'][$sa_id]['user'] = [ 
 682                                                 'id' => $session['sau_id'][$i], 
 683                                                 'title' => $session['sau_pseudonym'][$i] 
 690                 return $this->render('@RapsysAir/session/view.html.twig', ['title' => $title, 'section' => $section]+
$context+
$this->context
);