]> Raphaƫl G. Git Repositories - airbundle/blob - Controller/DefaultController.php
Add return types
[airbundle] / Controller / DefaultController.php
1 <?php
2
3 namespace Rapsys\AirBundle\Controller;
4
5 use Rapsys\AirBundle\Entity\Application;
6 use Rapsys\AirBundle\Entity\Location;
7 use Rapsys\AirBundle\Entity\Session;
8 use Rapsys\AirBundle\Entity\Slot;
9 use Rapsys\AirBundle\Entity\User;
10 use Symfony\Bridge\Twig\Mime\TemplatedEmail;
11 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
12 use Symfony\Component\DependencyInjection\ContainerInterface;
13 use Symfony\Component\Form\FormError;
14 use Symfony\Component\HttpFoundation\Request;
15 use Symfony\Component\HttpFoundation\RequestStack;
16 use Symfony\Component\HttpFoundation\Response;
17 use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
18 use Symfony\Component\Mailer\MailerInterface;
19 use Symfony\Component\Mime\Address;
20 use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
21 use Symfony\Component\Routing\RouterInterface;
22 use Symfony\Component\Translation\TranslatorInterface;
23 use Rapsys\UserBundle\Utils\Slugger;
24 use Symfony\Bundle\FrameworkBundle\Controller\ControllerTrait;
25 use Symfony\Component\DependencyInjection\ContainerAwareTrait;
26
27
28 class DefaultController {
29 use ControllerTrait {
30 //Rename render as _render
31 render as protected _render;
32 }
33
34 ///Config array
35 protected $config;
36
37 ///Context array
38 protected $context;
39
40 ///Router instance
41 protected $router;
42
43 ///Translator instance
44 protected $translator;
45
46 /**
47 * @var ContainerInterface
48 */
49 protected $container;
50
51 /**
52 * Inject container and translator interface
53 *
54 * @param ContainerInterface $container The container instance
55 * @param RouterInterface $router The router instance
56 * @param TranslatorInterface $translator The translator instance
57 */
58 public function __construct(ContainerInterface $container, RouterInterface $router, RequestStack $requestStack, TranslatorInterface $translator) {
59 //Retrieve config
60 $this->config = $container->getParameter($this->getAlias());
61
62 //Set the container
63 $this->container = $container;
64
65 //Set the router
66 $this->router = $router;
67
68 //Set the translator
69 $this->translator = $translator;
70
71 //Set the context
72 $this->context = [
73 'copy' => [
74 'by' => $translator->trans($this->config['copy']['by']),
75 'link' => $this->config['copy']['link'],
76 'long' => $translator->trans($this->config['copy']['long']),
77 'short' => $translator->trans($this->config['copy']['short']),
78 'title' => $this->config['copy']['title']
79 ],
80 'site' => [
81 'ico' => $this->config['site']['ico'],
82 'logo' => $this->config['site']['logo'],
83 'png' => $this->config['site']['png'],
84 'svg' => $this->config['site']['svg'],
85 'title' => $translator->trans($this->config['site']['title']),
86 'url' => $router->generate($this->config['site']['url']),
87 ],
88 'canonical' => null,
89 'alternates' => [],
90 'forms' => []
91 ];
92
93 //Get current locale
94 #$currentLocale = $router->getContext()->getParameters()['_locale'];
95 $currentLocale = $requestStack->getCurrentRequest()->getLocale();
96
97 //Set translator locale
98 //XXX: allow LocaleSubscriber on the fly locale change for first page
99 $this->translator->setLocale($currentLocale);
100
101 //Iterate on locales excluding current one
102 foreach($this->config['locales'] as $locale) {
103 //Set titles
104 $titles = [];
105
106 //Iterate on other locales
107 foreach(array_diff($this->config['locales'], [$locale]) as $other) {
108 $titles[$other] = $translator->trans($this->config['languages'][$locale], [], null, $other);
109 }
110
111 //Get context path
112 $path = $router->getContext()->getPathInfo();
113
114 //Retrieve route matching path
115 $route = $router->match($path);
116
117 //Get route name
118 $name = $route['_route'];
119
120 //Unset route name
121 unset($route['_route']);
122
123 //With current locale
124 if ($locale == $currentLocale) {
125 //Set locale locales context
126 $this->context['canonical'] = $router->generate($name, ['_locale' => $locale]+$route, UrlGeneratorInterface::ABSOLUTE_URL);
127 } else {
128 //Set locale locales context
129 $this->context['alternates'][] = [
130 'lang' => $locale,
131 'absolute' => $router->generate($name, ['_locale' => $locale]+$route, UrlGeneratorInterface::ABSOLUTE_URL),
132 'relative' => $router->generate($name, ['_locale' => $locale]+$route),
133 'title' => implode('/', $titles),
134 'translated' => $translator->trans($this->config['languages'][$locale], [], null, $locale)
135 ];
136 }
137 }
138 }
139
140 /**
141 * The contact page
142 *
143 * @desc Send a contact mail to configured contact
144 *
145 * @param Request $request The request instance
146 * @param MailerInterface $mailer The mailer instance
147 *
148 * @return Response The rendered view or redirection
149 */
150 public function contact(Request $request, MailerInterface $mailer): Response {
151 //Set section
152 $section = $this->translator->trans('Contact');
153
154 //Set description
155 $this->context['description'] = $this->translator->trans('Contact Libre Air');
156
157 //Set keywords
158 $this->context['keywords'] = [
159 $this->translator->trans('contact'),
160 $this->translator->trans('Libre Air'),
161 $this->translator->trans('outdoor'),
162 $this->translator->trans('Argentine Tango'),
163 $this->translator->trans('calendar')
164 ];
165
166 //Set title
167 $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
168
169 //Create the form according to the FormType created previously.
170 //And give the proper parameters
171 $form = $this->createForm('Rapsys\AirBundle\Form\ContactType', null, [
172 'action' => $this->generateUrl('rapsys_air_contact'),
173 'method' => 'POST'
174 ]);
175
176 if ($request->isMethod('POST')) {
177 // Refill the fields in case the form is not valid.
178 $form->handleRequest($request);
179
180 if ($form->isValid()) {
181 //Get data
182 $data = $form->getData();
183
184 //Create message
185 $message = (new TemplatedEmail())
186 //Set sender
187 ->from(new Address($data['mail'], $data['name']))
188 //Set recipient
189 //XXX: remove the debug set in vendor/symfony/mime/Address.php +46
190 ->to(new Address($this->config['contact']['mail'], $this->config['contact']['name']))
191 //Set subject
192 ->subject($data['subject'])
193
194 //Set path to twig templates
195 ->htmlTemplate('@RapsysAir/mail/contact.html.twig')
196 ->textTemplate('@RapsysAir/mail/contact.text.twig')
197
198 //Set context
199 ->context(
200 [
201 'subject' => $data['subject'],
202 'message' => strip_tags($data['message']),
203 ]+$this->context
204 );
205
206 //Try sending message
207 //XXX: mail delivery may silently fail
208 try {
209 //Send message
210 $mailer->send($message);
211
212 //Redirect on the same route with sent=1 to cleanup form
213 return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+$request->get('_route_params'));
214 //Catch obvious transport exception
215 } catch(TransportExceptionInterface $e) {
216 if ($message = $e->getMessage()) {
217 //Add error message mail unreachable
218 $form->get('mail')->addError(new FormError($this->translator->trans('Unable to contact: %mail%: %message%', ['%mail%' => $this->config['contact']['mail'], '%message%' => $this->translator->trans($message)])));
219 } else {
220 //Add error message mail unreachable
221 $form->get('mail')->addError(new FormError($this->translator->trans('Unable to contact: %mail%', ['%mail%' => $this->config['contact']['mail']])));
222 }
223 }
224 }
225 }
226
227 //Render template
228 return $this->render('@RapsysAir/form/contact.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView(), 'sent' => $request->query->get('sent', 0)]+$this->context);
229 }
230
231 /**
232 * The index page
233 *
234 * @desc Display all granted sessions with an application or login form
235 *
236 * @param Request $request The request instance
237 *
238 * @return Response The rendered view
239 */
240 public function index(Request $request): Response {
241 //Fetch doctrine
242 $doctrine = $this->getDoctrine();
243
244 //Set section
245 $section = $this->translator->trans('Argentine Tango in Paris');
246
247 //Set description
248 $this->context['description'] = $this->translator->trans('Outdoor Argentine Tango session calendar in Paris');
249
250 //Set keywords
251 $this->context['keywords'] = [
252 $this->translator->trans('Argentine Tango'),
253 $this->translator->trans('Paris'),
254 $this->translator->trans('outdoor'),
255 $this->translator->trans('calendar'),
256 $this->translator->trans('Libre Air')
257 ];
258
259 //Set title
260 $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
261
262 //Compute period
263 $period = new \DatePeriod(
264 //Start from first monday of week
265 new \DateTime('Monday this week'),
266 //Iterate on each day
267 new \DateInterval('P1D'),
268 //End with next sunday and 4 weeks
269 new \DateTime(
270 $this->isGranted('IS_AUTHENTICATED_REMEMBERED')?'Monday this week + 4 week':'Monday this week + 2 week'
271 )
272 );
273
274 //Fetch calendar
275 $calendar = $doctrine->getRepository(Session::class)->fetchCalendarByDatePeriod($this->translator, $period, null, $request->get('session'), !$this->isGranted('IS_AUTHENTICATED_REMEMBERED'));
276
277 //Fetch locations
278 //XXX: we want to display all active locations anyway
279 $locations = $doctrine->getRepository(Location::class)->findTranslatedSortedByPeriod($this->translator, $period);
280
281 //Render the view
282 return $this->render('@RapsysAir/default/index.html.twig', ['title' => $title, 'section' => $section, 'calendar' => $calendar, 'locations' => $locations]+$this->context);
283
284 //Set Cache-Control must-revalidate directive
285 #$response->setPublic(true);
286 #$response->setMaxAge(300);
287 #$response->mustRevalidate();
288 ##$response->setCache(['public' => true, 'max_age' => 300]);
289
290 //Return the response
291 #return $response;
292 }
293
294 /**
295 * The organizer regulation page
296 *
297 * @desc Display the organizer regulation policy
298 *
299 * @return Response The rendered view
300 */
301 public function organizerRegulation(): Response {
302 //Set section
303 $section = $this->translator->trans('Organizer regulation');
304
305 //Set description
306 $this->context['description'] = $this->translator->trans('Libre Air organizer regulation');
307
308 //Set keywords
309 $this->context['keywords'] = [
310 $this->translator->trans('organizer regulation'),
311 $this->translator->trans('Libre Air')
312 ];
313
314 //Set title
315 $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
316
317 //Render template
318 return $this->render('@RapsysAir/default/organizer_regulation.html.twig', ['title' => $title, 'section' => $section]+$this->context);
319 }
320
321 /**
322 * The terms of service page
323 *
324 * @desc Display the terms of service policy
325 *
326 * @return Response The rendered view
327 */
328 public function termsOfService(): Response {
329 //Set section
330 $section = $this->translator->trans('Terms of service');
331
332 //Set description
333 $this->context['description'] = $this->translator->trans('Libre Air terms of service');
334
335 //Set keywords
336 $this->context['keywords'] = [
337 $this->translator->trans('terms of service'),
338 $this->translator->trans('Libre Air')
339 ];
340
341 //Set title
342 $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
343
344 //Render template
345 return $this->render('@RapsysAir/default/terms_of_service.html.twig', ['title' => $title, 'section' => $section]+$this->context);
346 }
347
348 /**
349 * The frequently asked questions page
350 *
351 * @desc Display the frequently asked questions
352 *
353 * @return Response The rendered view
354 */
355 public function frequentlyAskedQuestions(): Response {
356 //Set section
357 $section = $this->translator->trans('Frequently asked questions');
358
359 //Set description
360 $this->context['description'] = $this->translator->trans('Libre Air frequently asked questions');
361
362 //Set keywords
363 $this->context['keywords'] = [
364 $this->translator->trans('frequently asked questions'),
365 $this->translator->trans('faq'),
366 $this->translator->trans('Libre Air')
367 ];
368
369 //Set title
370 $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
371
372 //Render template
373 return $this->render('@RapsysAir/default/frequently_asked_questions.html.twig', ['title' => $title, 'section' => $section]+$this->context);
374 }
375
376 /**
377 * Return the bundle alias
378 *
379 * {@inheritdoc}
380 */
381 public function getAlias(): string {
382 return 'rapsys_air';
383 }
384
385 /**
386 * Renders a view
387 *
388 * {@inheritdoc}
389 */
390 protected function render(string $view, array $parameters = [], Response $response = null): Response {
391 //Create application form for role_guest
392 if ($this->isGranted('ROLE_GUEST')) {
393 //Without application form
394 if (empty($parameters['forms']['application'])) {
395 //Fetch doctrine
396 $doctrine = $this->getDoctrine();
397
398 //Create ApplicationType form
399 $application = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [
400 //Set the action
401 'action' => $this->generateUrl('rapsys_air_application_add'),
402 //Set the form attribute
403 'attr' => [ 'class' => 'col' ],
404 //Set admin
405 'admin' => $this->isGranted('ROLE_ADMIN'),
406 //Set default user to current
407 'user' => $this->getUser()->getId(),
408 //Set default slot to evening
409 //XXX: default to Evening (3)
410 'slot' => $doctrine->getRepository(Slot::class)->findOneById(3)
411 ]);
412
413 //Add form to context
414 $parameters['forms']['application'] = $application->createView();
415 }
416 //Create login form for anonymous
417 } elseif (!$this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
418 //Create ApplicationType form
419 $login = $this->createForm('Rapsys\UserBundle\Form\LoginType', null, [
420 //Set the action
421 'action' => $this->generateUrl('rapsys_user_login'),
422 //Set the form attribute
423 'attr' => [ 'class' => 'col' ]
424 ]);
425
426 //Add form to context
427 $parameters['forms']['login'] = $login->createView();
428 }
429
430 //Call parent method
431 return $this->_render($view, $parameters, $response);
432 }
433 }