]> Raphaƫl G. Git Repositories - airbundle/blob - Controller/LocationController.php
Add add and edit location controller methods
[airbundle] / Controller / LocationController.php
1 <?php
2
3 namespace Rapsys\AirBundle\Controller;
4
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;
13
14 class LocationController extends DefaultController {
15 /**
16 * Add location
17 *
18 * @desc Persist location in database
19 *
20 * @param Request $request The request instance
21 *
22 * @return Response The rendered view or redirection
23 *
24 * @throws \RuntimeException When user has not at least admin role
25 */
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')]));
29
30 //Create LocationType form
31 $form = $this->createForm('Rapsys\AirBundle\Form\LocationType', null, [
32 //Set the action
33 'action' => $this->generateUrl('rapsys_air_location_add'),
34 //Set the form attribute
35 'attr' => []
36 ]);
37
38 //Refill the fields in case of invalid form
39 $form->handleRequest($request);
40
41 //Handle invalid form
42 if (!$form->isSubmitted() || !$form->isValid()) {
43 //Set section
44 $section = $this->translator->trans('Location add');
45
46 //Set title
47 $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
48
49 //Render the view
50 return $this->render('@RapsysAir/location/add.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView()]+$this->context);
51 }
52
53 //Get doctrine
54 $doctrine = $this->getDoctrine();
55
56 //Get manager
57 $manager = $doctrine->getManager();
58
59 //Get location
60 $location = $form->getData();
61
62 //Set created
63 $location->setCreated(new \DateTime('now'));
64
65 //Set updated
66 $location->setUpdated(new \DateTime('now'));
67
68 //Queue location save
69 $manager->persist($location);
70
71 //Flush to get the ids
72 $manager->flush();
73
74 //Add notice
75 $this->addFlash('notice', $this->translator->trans('Location %id% created', ['%id%' => $location->getId()]));
76
77 //Extract and process referer
78 if ($referer = $request->headers->get('referer')) {
79 //Create referer request instance
80 $req = Request::create($referer);
81
82 //Get referer path
83 $path = $req->getPathInfo();
84
85 //Get referer query string
86 $query = $req->getQueryString();
87
88 //Remove script name
89 $path = str_replace($request->getScriptName(), '', $path);
90
91 //Try with referer path
92 try {
93 //Save old context
94 $oldContext = $this->router->getContext();
95
96 //Force clean context
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());
99
100 //Retrieve route matching path
101 $route = $this->router->match($path);
102
103 //Reset context
104 $this->router->setContext($oldContext);
105
106 //Clear old context
107 unset($oldContext);
108
109 //Extract name
110 $name = $route['_route'];
111
112 //Remove route and controller from route defaults
113 unset($route['_route'], $route['_controller']);
114
115 //Check if location view route
116 if ($name == 'rapsys_air_location_view' && !empty($route['id'])) {
117 //Replace id
118 $route['id'] = $location->getId();
119 //Other routes
120 } else {
121 //Set location
122 $route['location'] = $location->getId();
123 }
124
125 //Generate url
126 return $this->redirectToRoute($name, $route);
127 //No route matched
128 } catch(MethodNotAllowedException|ResourceNotFoundException $e) {
129 //Unset referer to fallback to default route
130 unset($referer);
131 }
132 }
133
134 //Redirect to cleanup the form
135 return $this->redirectToRoute('rapsys_air', ['location' => $location->getId()]);
136 }
137
138 /**
139 * Edit location
140 *
141 * @desc Persist location in database
142 *
143 * @param Request $request The request instance
144 *
145 * @return Response The rendered view or redirection
146 *
147 * @throws \RuntimeException When user has not at least guest role
148 */
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')]));
152
153 //Get doctrine
154 $doctrine = $this->getDoctrine();
155
156 //Get location
157 if (empty($location = $doctrine->getRepository(Location::class)->findOneById($id))) {
158 throw $this->createNotFoundException($this->translator->trans('Unable to find location: %id%', ['%id%' => $id]));
159 }
160
161 //Create LocationType form
162 $form = $this->createForm('Rapsys\AirBundle\Form\LocationType', $location, [
163 //Set the action
164 'action' => $this->generateUrl('rapsys_air_location_edit', ['id' => $id]),
165 //Set the form attribute
166 'attr' => []
167 ]);
168
169 //Refill the fields in case of invalid form
170 $form->handleRequest($request);
171
172 //Handle invalid form
173 if (!$form->isSubmitted() || !$form->isValid()) {
174 //Set section
175 $section = $this->translator->trans('Location %id%', ['%id%' => $id]);
176
177 //Set title
178 $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
179
180 //Render the view
181 return $this->render('@RapsysAir/location/edit.html.twig', ['id' => $id, 'title' => $title, 'section' => $section, 'form' => $form->createView()]+$this->context);
182 }
183
184 //Get manager
185 $manager = $doctrine->getManager();
186
187 //Set updated
188 $location->setUpdated(new \DateTime('now'));
189
190 //Queue location save
191 $manager->persist($location);
192
193 //Flush to get the ids
194 $manager->flush();
195
196 //Add notice
197 $this->addFlash('notice', $this->translator->trans('Location %id% updated', ['%id%' => $id]));
198
199 //Extract and process referer
200 if ($referer = $request->headers->get('referer')) {
201 //Create referer request instance
202 $req = Request::create($referer);
203
204 //Get referer path
205 $path = $req->getPathInfo();
206
207 //Get referer query string
208 $query = $req->getQueryString();
209
210 //Remove script name
211 $path = str_replace($request->getScriptName(), '', $path);
212
213 //Try with referer path
214 try {
215 //Save old context
216 $oldContext = $this->router->getContext();
217
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());
221
222 //Retrieve route matching path
223 $route = $this->router->match($path);
224
225 //Reset context
226 $this->router->setContext($oldContext);
227
228 //Clear old context
229 unset($oldContext);
230
231 //Extract name
232 $name = $route['_route'];
233
234 //Remove route and controller from route defaults
235 unset($route['_route'], $route['_controller']);
236
237 //Check if location view route
238 if ($name == 'rapsys_air_location_view' && !empty($route['id'])) {
239 //Replace id
240 $route['id'] = $location->getId();
241 //Other routes
242 } else {
243 //Set location
244 $route['location'] = $location->getId();
245 }
246
247 //Generate url
248 return $this->redirectToRoute($name, $route);
249 //No route matched
250 } catch(MethodNotAllowedException|ResourceNotFoundException $e) {
251 //Unset referer to fallback to default route
252 unset($referer);
253 }
254 }
255
256 //Redirect to cleanup the form
257 return $this->redirectToRoute('rapsys_air', ['location' => $location->getId()]);
258 }
259
260 /**
261 * List all locations
262 *
263 * @desc Display all locations
264 *
265 * @param Request $request The request instance
266 *
267 * @return Response The rendered view
268 */
269 public function index(Request $request): Response {
270 //Fetch doctrine
271 $doctrine = $this->getDoctrine();
272
273 //Set section
274 $section = $this->translator->trans('Libre Air locations');
275
276 //Set description
277 $this->context['description'] = $this->translator->trans('Libre Air location list');
278
279 //Set keywords
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')
285 ];
286
287 //Set title
288 $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
289
290 //Compute period
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
297 new \DateTime(
298 $this->isGranted('IS_AUTHENTICATED_REMEMBERED')?'Monday this week + 4 week':'Monday this week + 2 week'
299 )
300 );
301
302 //Create location forms for role_admin
303 if ($this->isGranted('ROLE_ADMIN')) {
304 //Fetch all locations
305 $locations = $doctrine->getRepository(Location::class)->findAll();
306
307 //Rekey by id
308 $locations = array_reduce($locations, function($carry, $item){$carry[$item->getId()] = $item; return $carry;}, []);
309
310 //Init locations to context
311 $this->context['forms']['locations'] = [];
312
313 //Iterate on locations
314 foreach($locations as $locationId => $location) {
315 //Create LocationType form
316 $form = $this->createForm('Rapsys\AirBundle\Form\LocationType', $location, [
317 //Set the action
318 'action' => $this->generateUrl('rapsys_air_location_edit', ['id' => $location->getId()]),
319 //Set the form attribute
320 'attr' => [],
321 //Set block prefix
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
325 ]);
326
327 //Add form to context
328 $this->context['forms']['locations'][$locationId] = $form->createView();
329 }
330
331 //Create LocationType form
332 $form = $this->createForm('Rapsys\AirBundle\Form\LocationType', null, [
333 //Set the action
334 'action' => $this->generateUrl('rapsys_air_location_add'),
335 //Set the form attribute
336 'attr' => [ 'class' => 'col' ]
337 ]);
338
339 //Add form to context
340 $this->context['forms']['location'] = $form->createView();
341 }
342
343 //Fetch locations
344 //XXX: we want to display all active locations anyway
345 $locations = $doctrine->getRepository(Location::class)->findTranslatedSortedByPeriod($this->translator, $period);
346
347 //Render the view
348 return $this->render('@RapsysAir/location/index.html.twig', ['title' => $title, 'section' => $section, 'locations' => $locations]+$this->context);
349 }
350
351 /**
352 * List all sessions for the location
353 *
354 * @desc Display all sessions for the location with an application or login form
355 *
356 * @param Request $request The request instance
357 * @param int $id The location id
358 *
359 * @return Response The rendered view
360 */
361 public function view(Request $request, $id): Response {
362 //Fetch doctrine
363 $doctrine = $this->getDoctrine();
364
365 //Fetch location
366 if (empty($location = $doctrine->getRepository(Location::class)->findOneById($id))) {
367 throw $this->createNotFoundException($this->translator->trans('Unable to find location: %id%', ['%id%' => $id]));
368 }
369
370 //Set section
371 $section = $this->translator->trans('Argentine Tango at '.$location);
372
373 //Set description
374 $this->context['description'] = $this->translator->trans('Outdoor Argentine Tango session calendar %location%', [ '%location%' => $this->translator->trans('at '.$location) ]);
375
376 //Set keywords
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')
382 ];
383
384 //Set title
385 $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
386
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, [
391 //Set the action
392 'action' => $this->generateUrl('rapsys_air_application_add'),
393 //Set the form attribute
394 'attr' => [ 'class' => 'col' ],
395 //Set admin
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
404 ]);
405
406 //Add form to context
407 $this->context['forms']['application'] = $application->createView();
408 }
409
410 //Compute period
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
417 new \DateTime(
418 $this->isGranted('IS_AUTHENTICATED_REMEMBERED')?'Monday this week + 4 week':'Monday this week + 2 week'
419 )
420 );
421
422 //Fetch calendar
423 $calendar = $doctrine->getRepository(Session::class)->fetchCalendarByDatePeriod($this->translator, $period, $id, $request->get('session'), !$this->isGranted('IS_AUTHENTICATED_REMEMBERED'));
424
425 //Fetch locations
426 //XXX: we want to display all active locations anyway
427 $locations = $doctrine->getRepository(Location::class)->findTranslatedSortedByPeriod($this->translator, $period);
428
429 //Render the view
430 return $this->render('@RapsysAir/location/view.html.twig', ['id' => $id, 'title' => $title, 'section' => $section, 'calendar' => $calendar, 'locations' => $locations]+$this->context);
431 }
432 }