3 namespace Rapsys\AirBundle\Controller
;
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 Rapsys\AirBundle\Pdf\DisputePdf
;
11 use Rapsys\UserBundle\Utils\Slugger
;
12 use Symfony\Bridge\Twig\Mime\TemplatedEmail
;
13 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController
;
14 use Symfony\Component\DependencyInjection\ContainerInterface
;
15 use Symfony\Component\Form\FormError
;
16 use Symfony\Component\HttpFoundation\Request
;
17 use Symfony\Component\HttpFoundation\RequestStack
;
18 use Symfony\Component\HttpFoundation\Response
;
19 use Symfony\Component\Mailer\Exception\TransportExceptionInterface
;
20 use Symfony\Component\Mailer\MailerInterface
;
21 use Symfony\Component\Mime\Address
;
22 use Symfony\Component\Routing\Generator\UrlGeneratorInterface
;
23 use Symfony\Component\Routing\RouterInterface
;
24 use Symfony\Component\Translation\TranslatorInterface
;
25 use Symfony\Bundle\FrameworkBundle\Controller\ControllerTrait
;
26 use Symfony\Component\DependencyInjection\ContainerAwareTrait
;
29 class DefaultController
{
31 //Rename render as _render
32 render
as protected _render
;
44 ///Translator instance
45 protected $translator;
48 * @var ContainerInterface
53 * Inject container and translator interface
55 * @param ContainerInterface $container The container instance
56 * @param RouterInterface $router The router instance
57 * @param TranslatorInterface $translator The translator instance
59 public function __construct(ContainerInterface
$container, RouterInterface
$router, RequestStack
$requestStack, TranslatorInterface
$translator) {
61 $this->config
= $container->getParameter($this->getAlias());
64 $this->container
= $container;
67 $this->router
= $router;
70 $this->translator
= $translator;
75 'by' => $translator->trans($this->config
['copy']['by']),
76 'link' => $this->config
['copy']['link'],
77 'long' => $translator->trans($this->config
['copy']['long']),
78 'short' => $translator->trans($this->config
['copy']['short']),
79 'title' => $this->config
['copy']['title']
82 'ico' => $this->config
['site']['ico'],
83 'logo' => $this->config
['site']['logo'],
84 'png' => $this->config
['site']['png'],
85 'svg' => $this->config
['site']['svg'],
86 'title' => $translator->trans($this->config
['site']['title']),
87 'url' => $router->generate($this->config
['site']['url']),
95 #$currentLocale = $router->getContext()->getParameters()['_locale'];
96 $currentLocale = $requestStack->getCurrentRequest()->getLocale();
98 //Set translator locale
99 //XXX: allow LocaleSubscriber on the fly locale change for first page
100 $this->translator
->setLocale($currentLocale);
102 //Iterate on locales excluding current one
103 foreach($this->config
['locales'] as $locale) {
107 //Iterate on other locales
108 foreach(array_diff($this->config
['locales'], [$locale]) as $other) {
109 $titles[$other] = $translator->trans($this->config
['languages'][$locale], [], null, $other);
113 $path = $router->getContext()->getPathInfo();
115 //Retrieve route matching path
116 $route = $router->match($path);
119 $name = $route['_route'];
122 unset($route['_route']);
124 //With current locale
125 if ($locale == $currentLocale) {
126 //Set locale locales context
127 $this->context
['canonical'] = $router->generate($name, ['_locale' => $locale]+
$route, UrlGeneratorInterface
::ABSOLUTE_URL
);
129 //Set locale locales context
130 $this->context
['alternates'][] = [
132 'absolute' => $router->generate($name, ['_locale' => $locale]+
$route, UrlGeneratorInterface
::ABSOLUTE_URL
),
133 'relative' => $router->generate($name, ['_locale' => $locale]+
$route),
134 'title' => implode('/', $titles),
135 'translated' => $translator->trans($this->config
['languages'][$locale], [], null, $locale)
144 * @desc Send a contact mail to configured contact
146 * @param Request $request The request instance
147 * @param MailerInterface $mailer The mailer instance
149 * @return Response The rendered view or redirection
151 public function contact(Request
$request, MailerInterface
$mailer): Response
{
153 $section = $this->translator
->trans('Contact');
156 $this->context
['description'] = $this->translator
->trans('Contact Libre Air');
159 $this->context
['keywords'] = [
160 $this->translator
->trans('contact'),
161 $this->translator
->trans('Libre Air'),
162 $this->translator
->trans('outdoor'),
163 $this->translator
->trans('Argentine Tango'),
164 $this->translator
->trans('calendar')
168 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
170 //Create the form according to the FormType created previously.
171 //And give the proper parameters
172 $form = $this->createForm('Rapsys\AirBundle\Form\ContactType', null, [
173 'action' => $this->generateUrl('rapsys_air_contact'),
177 if ($request->isMethod('POST')) {
178 // Refill the fields in case the form is not valid.
179 $form->handleRequest($request);
181 if ($form->isValid()) {
183 $data = $form->getData();
186 $message = (new TemplatedEmail())
188 ->from(new Address($data['mail'], $data['name']))
190 //XXX: remove the debug set in vendor/symfony/mime/Address.php +46
191 ->to(new Address($this->config
['contact']['mail'], $this->config
['contact']['name']))
193 ->subject($data['subject'])
195 //Set path to twig templates
196 ->htmlTemplate('@RapsysAir/mail/contact.html.twig')
197 ->textTemplate('@RapsysAir/mail/contact.text.twig')
202 'subject' => $data['subject'],
203 'message' => strip_tags($data['message']),
207 //Try sending message
208 //XXX: mail delivery may silently fail
211 $mailer->send($message);
213 //Redirect on the same route with sent=1 to cleanup form
214 return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+
$request->get('_route_params'));
215 //Catch obvious transport exception
216 } catch(TransportExceptionInterface
$e) {
217 if ($message = $e->getMessage()) {
218 //Add error message mail unreachable
219 $form->get('mail')->addError(new FormError($this->translator
->trans('Unable to contact: %mail%: %message%', ['%mail%' => $this->config
['contact']['mail'], '%message%' => $this->translator
->trans($message)])));
221 //Add error message mail unreachable
222 $form->get('mail')->addError(new FormError($this->translator
->trans('Unable to contact: %mail%', ['%mail%' => $this->config
['contact']['mail']])));
229 return $this->render('@RapsysAir/form/contact.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView(), 'sent' => $request->query
->get('sent', 0)]+
$this->context
);
236 * @desc Generate a dispute document
238 * @param Request $request The request instance
239 * @param MailerInterface $mailer The mailer instance
241 * @return Response The rendered view or redirection
243 public function dispute(Request
$request, MailerInterface
$mailer): Response
{
244 //Prevent non-guest to access here
245 $this->denyAccessUnlessGranted('ROLE_USER', null, $this->translator
->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator
->trans('User')]));
247 $section = $this->translator
->trans('Dispute');
250 $this->context
['description'] = $this->translator
->trans('Libre Air dispute');
253 $this->context
['keywords'] = [
254 $this->translator
->trans('dispute'),
255 $this->translator
->trans('Libre Air'),
256 $this->translator
->trans('outdoor'),
257 $this->translator
->trans('Argentine Tango'),
258 $this->translator
->trans('calendar')
262 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
264 //Create the form according to the FormType created previously.
265 //And give the proper parameters
266 $form = $this->createForm('Rapsys\AirBundle\Form\DisputeType', ['court' => 'Paris', 'abstract' => 'Pour constater cette prĆ©tendue infraction, les agents verbalisateurs ont pĆ©nĆ©trĆ© dans un jardin privatif, sans visibilitĆ© depuis la voie publique, situĆ© derriĆØre un batiment privĆ©, pour ce faire ils ont franchi au moins un grillage de chantier ou des potteaux mĆ©talliques sĆ©parant le terrain privĆ© de la voie publique de l\'autre cĆ“tĆ© du batiment.'], [
267 'action' => $this->generateUrl('rapsys_air_dispute'),
271 if ($request->isMethod('POST')) {
272 // Refill the fields in case the form is not valid.
273 $form->handleRequest($request);
275 if ($form->isValid()) {
277 $data = $form->getData();
280 if (!empty($data['offense']) && $data['offense'] == 'gathering') {
282 $output = DisputePdf
::genGathering($data['court'], $data['notice'], $data['agent'], $data['service'], $data['abstract'], $this->translator
->trans($this->getUser()->getCivility()->getTitle()), $this->getUser()->getForename(), $this->getUser()->getSurname());
284 } elseif (!empty($data['offense'] && $data['offense'] == 'traffic')) {
286 $output = DisputePdf
::genTraffic($data['court'], $data['notice'], $data['agent'], $data['service'], $data['abstract'], $this->translator
->trans($this->getUser()->getCivility()->getTitle()), $this->getUser()->getForename(), $this->getUser()->getSurname());
287 //Unsupported offense
289 header('Content-Type: text/plain');
294 //Send common headers
295 header('Content-Type: application/pdf');
297 //Send remaining headers
298 header('Cache-Control: private, max-age=0, must-revalidate');
299 header('Pragma: public');
301 //Send content-length
302 header('Content-Length: '.strlen($output));
311 # $message = (new TemplatedEmail())
313 # ->from(new Address($data['mail'], $data['name']))
315 # //XXX: remove the debug set in vendor/symfony/mime/Address.php +46
316 # ->to(new Address($this->config['contact']['mail'], $this->config['contact']['name']))
318 # ->subject($data['subject'])
320 # //Set path to twig templates
321 # ->htmlTemplate('@RapsysAir/mail/contact.html.twig')
322 # ->textTemplate('@RapsysAir/mail/contact.text.twig')
327 # 'subject' => $data['subject'],
328 # 'message' => strip_tags($data['message']),
332 # //Try sending message
333 # //XXX: mail delivery may silently fail
336 # $mailer->send($message);
338 # //Redirect on the same route with sent=1 to cleanup form
339 # return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+$request->get('_route_params'));
340 # //Catch obvious transport exception
341 # } catch(TransportExceptionInterface $e) {
342 # if ($message = $e->getMessage()) {
343 # //Add error message mail unreachable
344 # $form->get('mail')->addError(new FormError($this->translator->trans('Unable to contact: %mail%: %message%', ['%mail%' => $this->config['contact']['mail'], '%message%' => $this->translator->trans($message)])));
346 # //Add error message mail unreachable
347 # $form->get('mail')->addError(new FormError($this->translator->trans('Unable to contact: %mail%', ['%mail%' => $this->config['contact']['mail']])));
354 return $this->render('@RapsysAir/form/dispute.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView(), 'sent' => $request->query
->get('sent', 0)]+
$this->context
);
360 * @desc Display all granted sessions with an application or login form
362 * @param Request $request The request instance
364 * @return Response The rendered view
366 public function index(Request
$request): Response
{
368 $doctrine = $this->getDoctrine();
371 $section = $this->translator
->trans('Argentine Tango in Paris');
374 $this->context
['description'] = $this->translator
->trans('Outdoor Argentine Tango session calendar in Paris');
377 $this->context
['keywords'] = [
378 $this->translator
->trans('Argentine Tango'),
379 $this->translator
->trans('Paris'),
380 $this->translator
->trans('outdoor'),
381 $this->translator
->trans('calendar'),
382 $this->translator
->trans('Libre Air')
386 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
389 $period = new \
DatePeriod(
390 //Start from first monday of week
391 new \
DateTime('Monday this week'),
392 //Iterate on each day
393 new \
DateInterval('P1D'),
394 //End with next sunday and 4 weeks
396 $this->isGranted('IS_AUTHENTICATED_REMEMBERED')?'Monday this week + 3 week':'Monday this week + 2 week'
401 $calendar = $doctrine->getRepository(Session
::class)->fetchCalendarByDatePeriod($this->translator
, $period, null, $request->get('session'), !$this->isGranted('IS_AUTHENTICATED_REMEMBERED'));
404 //XXX: we want to display all active locations anyway
405 $locations = $doctrine->getRepository(Location
::class)->findTranslatedSortedByPeriod($this->translator
, $period);
408 return $this->render('@RapsysAir/default/index.html.twig', ['title' => $title, 'section' => $section, 'calendar' => $calendar, 'locations' => $locations]+
$this->context
);
410 //Set Cache-Control must-revalidate directive
411 //TODO: add a javascript forced refresh after 1h ? or header refresh ?
412 #$response->setPublic(true);
413 #$response->setMaxAge(300);
414 #$response->mustRevalidate();
415 ##$response->setCache(['public' => true, 'max_age' => 300]);
417 //Return the response
422 * The organizer regulation page
424 * @desc Display the organizer regulation policy
426 * @return Response The rendered view
428 public function organizerRegulation(): Response
{
430 $section = $this->translator
->trans('Organizer regulation');
433 $this->context
['description'] = $this->translator
->trans('Libre Air organizer regulation');
436 $this->context
['keywords'] = [
437 $this->translator
->trans('organizer regulation'),
438 $this->translator
->trans('Libre Air')
442 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
445 return $this->render('@RapsysAir/default/organizer_regulation.html.twig', ['title' => $title, 'section' => $section]+
$this->context
);
449 * The terms of service page
451 * @desc Display the terms of service policy
453 * @return Response The rendered view
455 public function termsOfService(): Response
{
457 $section = $this->translator
->trans('Terms of service');
460 $this->context
['description'] = $this->translator
->trans('Libre Air terms of service');
463 $this->context
['keywords'] = [
464 $this->translator
->trans('terms of service'),
465 $this->translator
->trans('Libre Air')
469 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
472 return $this->render('@RapsysAir/default/terms_of_service.html.twig', ['title' => $title, 'section' => $section]+
$this->context
);
476 * The frequently asked questions page
478 * @desc Display the frequently asked questions
480 * @return Response The rendered view
482 public function frequentlyAskedQuestions(): Response
{
484 $section = $this->translator
->trans('Frequently asked questions');
487 $this->context
['description'] = $this->translator
->trans('Libre Air frequently asked questions');
490 $this->context
['keywords'] = [
491 $this->translator
->trans('frequently asked questions'),
492 $this->translator
->trans('faq'),
493 $this->translator
->trans('Libre Air')
497 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
500 return $this->render('@RapsysAir/default/frequently_asked_questions.html.twig', ['title' => $title, 'section' => $section]+
$this->context
);
504 * Return the bundle alias
508 public function getAlias(): string {
517 protected function render(string $view, array $parameters = [], Response
$response = null): Response
{
518 //Create application form for role_guest
519 if ($this->isGranted('ROLE_GUEST')) {
520 //Without application form
521 if (empty($parameters['forms']['application'])) {
523 $doctrine = $this->getDoctrine();
525 //Create ApplicationType form
526 $application = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [
528 'action' => $this->generateUrl('rapsys_air_application_add'),
529 //Set the form attribute
530 'attr' => [ 'class' => 'col' ],
532 'admin' => $this->isGranted('ROLE_ADMIN'),
533 //Set default user to current
534 'user' => $this->getUser()->getId(),
535 //Set default slot to evening
536 //XXX: default to Evening (3)
537 'slot' => $doctrine->getRepository(Slot
::class)->findOneById(3)
540 //Add form to context
541 $parameters['forms']['application'] = $application->createView();
543 //Create login form for anonymous
544 } elseif (!$this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
545 //Create ApplicationType form
546 $login = $this->createForm('Rapsys\UserBundle\Form\LoginType', null, [
548 'action' => $this->generateUrl('rapsys_user_login'),
549 //Set the form attribute
550 'attr' => [ 'class' => 'col' ]
553 //Add form to context
554 $parameters['forms']['login'] = $login->createView();
558 return $this->_render($view, $parameters, $response);