3 namespace Rapsys\AirBundle\Controller
;
5 use Symfony\Component\HttpFoundation\Request
;
6 use Symfony\Component\HttpFoundation\Response
;
7 use Symfony\Component\Routing\RequestContext
;
8 use Symfony\Component\Routing\Exception\MethodNotAllowedException
;
9 use Symfony\Component\Routing\Exception\ResourceNotFoundException
;
10 use Rapsys\AirBundle\Entity\Slot
;
11 use Rapsys\AirBundle\Entity\Session
;
12 use Rapsys\AirBundle\Entity\Location
;
14 class LocationController
extends DefaultController
{
18 * @desc Persist location in database
20 * @param Request $request The request instance
22 * @return Response The rendered view or redirection
24 * @throws \RuntimeException When user has not at least admin role
26 public function add(Request
$request) {
27 //Prevent non-guest to access here
28 $this->denyAccessUnlessGranted('ROLE_ADMIN', null, $this->translator
->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator
->trans('Admin')]));
30 //Create LocationType form
31 $form = $this->createForm('Rapsys\AirBundle\Form\LocationType', null, [
33 'action' => $this->generateUrl('rapsys_air_location_add'),
34 //Set the form attribute
38 //Refill the fields in case of invalid form
39 $form->handleRequest($request);
42 if (!$form->isSubmitted() || !$form->isValid()) {
44 $section = $this->translator
->trans('Location add');
47 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
50 return $this->render('@RapsysAir/location/add.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView()]+
$this->context
);
54 $doctrine = $this->getDoctrine();
57 $manager = $doctrine->getManager();
60 $location = $form->getData();
63 $location->setCreated(new \
DateTime('now'));
66 $location->setUpdated(new \
DateTime('now'));
69 $manager->persist($location);
71 //Flush to get the ids
75 $this->addFlash('notice', $this->translator
->trans('Location %id% created', ['%id%' => $location->getId()]));
77 //Extract and process referer
78 if ($referer = $request->headers
->get('referer')) {
79 //Create referer request instance
80 $req = Request
::create($referer);
83 $path = $req->getPathInfo();
85 //Get referer query string
86 $query = $req->getQueryString();
89 $path = str_replace($request->getScriptName(), '', $path);
91 //Try with referer path
94 $oldContext = $this->router
->getContext();
97 //XXX: prevent MethodNotAllowedException because current context method is POST in onevendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php+42
98 $this->router
->setContext(new RequestContext());
100 //Retrieve route matching path
101 $route = $this->router
->match($path);
104 $this->router
->setContext($oldContext);
110 $name = $route['_route'];
112 //Remove route and controller from route defaults
113 unset($route['_route'], $route['_controller']);
115 //Check if location view route
116 if ($name == 'rapsys_air_location_view' && !empty($route['id'])) {
118 $route['id'] = $location->getId();
122 $route['location'] = $location->getId();
126 return $this->redirectToRoute($name, $route);
128 } catch(MethodNotAllowedException
|ResourceNotFoundException
$e) {
129 //Unset referer to fallback to default route
134 //Redirect to cleanup the form
135 return $this->redirectToRoute('rapsys_air', ['location' => $location->getId()]);
141 * @desc Persist location in database
143 * @param Request $request The request instance
145 * @return Response The rendered view or redirection
147 * @throws \RuntimeException When user has not at least guest role
149 public function edit(Request
$request, $id) {
150 //Prevent non-admin to access here
151 $this->denyAccessUnlessGranted('ROLE_ADMIN', null, $this->translator
->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator
->trans('Admin')]));
154 $doctrine = $this->getDoctrine();
157 if (empty($location = $doctrine->getRepository(Location
::class)->findOneById($id))) {
158 throw $this->createNotFoundException($this->translator
->trans('Unable to find location: %id%', ['%id%' => $id]));
161 //Create LocationType form
162 $form = $this->createForm('Rapsys\AirBundle\Form\LocationType', $location, [
164 'action' => $this->generateUrl('rapsys_air_location_edit', ['id' => $id]),
165 //Set the form attribute
169 //Refill the fields in case of invalid form
170 $form->handleRequest($request);
172 //Handle invalid form
173 if (!$form->isSubmitted() || !$form->isValid()) {
175 $section = $this->translator
->trans('Location %id%', ['%id%' => $id]);
178 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
181 return $this->render('@RapsysAir/location/edit.html.twig', ['id' => $id, 'title' => $title, 'section' => $section, 'form' => $form->createView()]+
$this->context
);
185 $manager = $doctrine->getManager();
188 $location->setUpdated(new \
DateTime('now'));
190 //Queue location save
191 $manager->persist($location);
193 //Flush to get the ids
197 $this->addFlash('notice', $this->translator
->trans('Location %id% updated', ['%id%' => $id]));
199 //Extract and process referer
200 if ($referer = $request->headers
->get('referer')) {
201 //Create referer request instance
202 $req = Request
::create($referer);
205 $path = $req->getPathInfo();
207 //Get referer query string
208 $query = $req->getQueryString();
211 $path = str_replace($request->getScriptName(), '', $path);
213 //Try with referer path
216 $oldContext = $this->router
->getContext();
218 //Force clean context
219 //XXX: prevent MethodNotAllowedException because current context method is POST in onevendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php+42
220 $this->router
->setContext(new RequestContext());
222 //Retrieve route matching path
223 $route = $this->router
->match($path);
226 $this->router
->setContext($oldContext);
232 $name = $route['_route'];
234 //Remove route and controller from route defaults
235 unset($route['_route'], $route['_controller']);
237 //Check if location view route
238 if ($name == 'rapsys_air_location_view' && !empty($route['id'])) {
240 $route['id'] = $location->getId();
244 $route['location'] = $location->getId();
248 return $this->redirectToRoute($name, $route);
250 } catch(MethodNotAllowedException
|ResourceNotFoundException
$e) {
251 //Unset referer to fallback to default route
256 //Redirect to cleanup the form
257 return $this->redirectToRoute('rapsys_air', ['location' => $location->getId()]);
263 * @desc Display all locations
265 * @param Request $request The request instance
267 * @return Response The rendered view
269 public function index(Request
$request): Response
{
271 $doctrine = $this->getDoctrine();
274 $section = $this->translator
->trans('Libre Air locations');
277 $this->context
['description'] = $this->translator
->trans('Libre Air location list');
280 $this->context
['keywords'] = [
281 $this->translator
->trans('locations'),
282 $this->translator
->trans('location list'),
283 $this->translator
->trans('listing'),
284 $this->translator
->trans('Libre Air')
288 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
291 $period = new \
DatePeriod(
292 //Start from first monday of week
293 new \
DateTime('Monday this week'),
294 //Iterate on each day
295 new \
DateInterval('P1D'),
296 //End with next sunday and 4 weeks
298 $this->isGranted('IS_AUTHENTICATED_REMEMBERED')?'Monday this week + 4 week':'Monday this week + 2 week'
302 //Create location forms for role_admin
303 if ($this->isGranted('ROLE_ADMIN')) {
304 //Fetch all locations
305 $locations = $doctrine->getRepository(Location
::class)->findAll();
308 $locations = array_reduce($locations, function($carry, $item){$carry
[$item
->getId()] = $item
; return $carry
;}, []);
310 //Init locations to context
311 $this->context
['forms']['locations'] = [];
313 //Iterate on locations
314 foreach($locations as $locationId => $location) {
315 //Create LocationType form
316 $form = $this->createForm('Rapsys\AirBundle\Form\LocationType', $location, [
318 'action' => $this->generateUrl('rapsys_air_location_edit', ['id' => $location->getId()]),
319 //Set the form attribute
322 //TODO: make this shit works to prevent label collision
323 //XXX: see https://stackoverflow.com/questions/8703016/adding-a-prefix-to-a-form-label-for-translation
324 'label_prefix' => 'location_'.$locationId
327 //Add form to context
328 $this->context
['forms']['locations'][$locationId] = $form->createView();
331 //Create LocationType form
332 $form = $this->createForm('Rapsys\AirBundle\Form\LocationType', null, [
334 'action' => $this->generateUrl('rapsys_air_location_add'),
335 //Set the form attribute
336 'attr' => [ 'class' => 'col' ]
339 //Add form to context
340 $this->context
['forms']['location'] = $form->createView();
344 //XXX: we want to display all active locations anyway
345 $locations = $doctrine->getRepository(Location
::class)->findTranslatedSortedByPeriod($this->translator
, $period);
348 return $this->render('@RapsysAir/location/index.html.twig', ['title' => $title, 'section' => $section, 'locations' => $locations]+
$this->context
);
352 * List all sessions for the location
354 * @desc Display all sessions for the location with an application or login form
356 * @param Request $request The request instance
357 * @param int $id The location id
359 * @return Response The rendered view
361 public function view(Request
$request, $id): Response
{
363 $doctrine = $this->getDoctrine();
366 if (empty($location = $doctrine->getRepository(Location
::class)->findOneById($id))) {
367 throw $this->createNotFoundException($this->translator
->trans('Unable to find location: %id%', ['%id%' => $id]));
371 $section = $this->translator
->trans('Argentine Tango at '.$location);
374 $this->context
['description'] = $this->translator
->trans('Outdoor Argentine Tango session calendar %location%', [ '%location%' => $this->translator
->trans('at '.$location) ]);
377 $this->context
['keywords'] = [
378 $this->translator
->trans($location),
379 $this->translator
->trans('outdoor'),
380 $this->translator
->trans('Argentine Tango'),
381 $this->translator
->trans('calendar')
385 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
387 //Create application form for role_guest
388 if ($this->isGranted('ROLE_GUEST')) {
389 //Create ApplicationType form
390 $application = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [
392 'action' => $this->generateUrl('rapsys_air_application_add'),
393 //Set the form attribute
394 'attr' => [ 'class' => 'col' ],
396 'admin' => $this->isGranted('ROLE_ADMIN'),
397 //Set default user to current
398 'user' => $this->getUser()->getId(),
399 //Set default slot to evening
400 //XXX: default to Evening (3)
401 'slot' => $doctrine->getRepository(Slot
::class)->findOneById(3),
402 //Set default location to current one
403 'location' => $location
406 //Add form to context
407 $this->context
['forms']['application'] = $application->createView();
411 $period = new \
DatePeriod(
412 //Start from first monday of week
413 new \
DateTime('Monday this week'),
414 //Iterate on each day
415 new \
DateInterval('P1D'),
416 //End with next sunday and 4 weeks
418 $this->isGranted('IS_AUTHENTICATED_REMEMBERED')?'Monday this week + 4 week':'Monday this week + 2 week'
423 $calendar = $doctrine->getRepository(Session
::class)->fetchCalendarByDatePeriod($this->translator
, $period, $id, $request->get('session'), !$this->isGranted('IS_AUTHENTICATED_REMEMBERED'));
426 //XXX: we want to display all active locations anyway
427 $locations = $doctrine->getRepository(Location
::class)->findTranslatedSortedByPeriod($this->translator
, $period);
430 return $this->render('@RapsysAir/location/view.html.twig', ['id' => $id, 'title' => $title, 'section' => $section, 'calendar' => $calendar, 'locations' => $locations]+
$this->context
);