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/default/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);