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 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
;
28 class DefaultController
{
30 //Rename render as _render
31 render
as protected _render
;
43 ///Translator instance
44 protected $translator;
47 * @var ContainerInterface
52 * Inject container and translator interface
54 * @param ContainerInterface $container The container instance
55 * @param RouterInterface $router The router instance
56 * @param TranslatorInterface $translator The translator instance
58 public function __construct(ContainerInterface
$container, RouterInterface
$router, RequestStack
$requestStack, TranslatorInterface
$translator) {
60 $this->config
= $container->getParameter($this->getAlias());
63 $this->container
= $container;
66 $this->router
= $router;
69 $this->translator
= $translator;
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']
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']),
94 #$currentLocale = $router->getContext()->getParameters()['_locale'];
95 $currentLocale = $requestStack->getCurrentRequest()->getLocale();
97 //Set translator locale
98 //XXX: allow LocaleSubscriber on the fly locale change for first page
99 $this->translator
->setLocale($currentLocale);
101 //Iterate on locales excluding current one
102 foreach($this->config
['locales'] as $locale) {
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);
112 $path = $router->getContext()->getPathInfo();
114 //Retrieve route matching path
115 $route = $router->match($path);
118 $name = $route['_route'];
121 unset($route['_route']);
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
);
128 //Set locale locales context
129 $this->context
['alternates'][] = [
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)
143 * @desc Send a contact mail to configured contact
145 * @param Request $request The request instance
146 * @param MailerInterface $mailer The mailer instance
148 * @return Response The rendered view or redirection
150 public function contact(Request
$request, MailerInterface
$mailer): Response
{
152 $section = $this->translator
->trans('Contact');
155 $this->context
['description'] = $this->translator
->trans('Contact Libre Air');
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')
167 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
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'),
176 if ($request->isMethod('POST')) {
177 // Refill the fields in case the form is not valid.
178 $form->handleRequest($request);
180 if ($form->isValid()) {
182 $data = $form->getData();
185 $message = (new TemplatedEmail())
187 ->from(new Address($data['mail'], $data['name']))
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']))
192 ->subject($data['subject'])
194 //Set path to twig templates
195 ->htmlTemplate('@RapsysAir/mail/contact.html.twig')
196 ->textTemplate('@RapsysAir/mail/contact.text.twig')
201 'subject' => $data['subject'],
202 'message' => strip_tags($data['message']),
206 //Try sending message
207 //XXX: mail delivery may silently fail
210 $mailer->send($message);
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)])));
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']])));
228 return $this->render('@RapsysAir/form/contact.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView(), 'sent' => $request->query
->get('sent', 0)]+
$this->context
);
234 * @desc Display all granted sessions with an application or login form
236 * @param Request $request The request instance
238 * @return Response The rendered view
240 public function index(Request
$request): Response
{
242 $doctrine = $this->getDoctrine();
245 $section = $this->translator
->trans('Argentine Tango in Paris');
248 $this->context
['description'] = $this->translator
->trans('Outdoor Argentine Tango session calendar in Paris');
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')
260 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
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
270 $this->isGranted('IS_AUTHENTICATED_REMEMBERED')?'Monday this week + 3 week':'Monday this week + 2 week'
275 $calendar = $doctrine->getRepository(Session
::class)->fetchCalendarByDatePeriod($this->translator
, $period, null, $request->get('session'), !$this->isGranted('IS_AUTHENTICATED_REMEMBERED'));
278 //XXX: we want to display all active locations anyway
279 $locations = $doctrine->getRepository(Location
::class)->findTranslatedSortedByPeriod($this->translator
, $period);
282 return $this->render('@RapsysAir/default/index.html.twig', ['title' => $title, 'section' => $section, 'calendar' => $calendar, 'locations' => $locations]+
$this->context
);
284 //Set Cache-Control must-revalidate directive
285 //TODO: add a javascript forced refresh after 1h ? or header refresh ?
286 #$response->setPublic(true);
287 #$response->setMaxAge(300);
288 #$response->mustRevalidate();
289 ##$response->setCache(['public' => true, 'max_age' => 300]);
291 //Return the response
296 * The organizer regulation page
298 * @desc Display the organizer regulation policy
300 * @return Response The rendered view
302 public function organizerRegulation(): Response
{
304 $section = $this->translator
->trans('Organizer regulation');
307 $this->context
['description'] = $this->translator
->trans('Libre Air organizer regulation');
310 $this->context
['keywords'] = [
311 $this->translator
->trans('organizer regulation'),
312 $this->translator
->trans('Libre Air')
316 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
319 return $this->render('@RapsysAir/default/organizer_regulation.html.twig', ['title' => $title, 'section' => $section]+
$this->context
);
323 * The terms of service page
325 * @desc Display the terms of service policy
327 * @return Response The rendered view
329 public function termsOfService(): Response
{
331 $section = $this->translator
->trans('Terms of service');
334 $this->context
['description'] = $this->translator
->trans('Libre Air terms of service');
337 $this->context
['keywords'] = [
338 $this->translator
->trans('terms of service'),
339 $this->translator
->trans('Libre Air')
343 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
346 return $this->render('@RapsysAir/default/terms_of_service.html.twig', ['title' => $title, 'section' => $section]+
$this->context
);
350 * The frequently asked questions page
352 * @desc Display the frequently asked questions
354 * @return Response The rendered view
356 public function frequentlyAskedQuestions(): Response
{
358 $section = $this->translator
->trans('Frequently asked questions');
361 $this->context
['description'] = $this->translator
->trans('Libre Air frequently asked questions');
364 $this->context
['keywords'] = [
365 $this->translator
->trans('frequently asked questions'),
366 $this->translator
->trans('faq'),
367 $this->translator
->trans('Libre Air')
371 $title = $this->translator
->trans($this->config
['site']['title']).' - '.$section;
374 return $this->render('@RapsysAir/default/frequently_asked_questions.html.twig', ['title' => $title, 'section' => $section]+
$this->context
);
378 * Return the bundle alias
382 public function getAlias(): string {
391 protected function render(string $view, array $parameters = [], Response
$response = null): Response
{
392 //Create application form for role_guest
393 if ($this->isGranted('ROLE_GUEST')) {
394 //Without application form
395 if (empty($parameters['forms']['application'])) {
397 $doctrine = $this->getDoctrine();
399 //Create ApplicationType form
400 $application = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [
402 'action' => $this->generateUrl('rapsys_air_application_add'),
403 //Set the form attribute
404 'attr' => [ 'class' => 'col' ],
406 'admin' => $this->isGranted('ROLE_ADMIN'),
407 //Set default user to current
408 'user' => $this->getUser()->getId(),
409 //Set default slot to evening
410 //XXX: default to Evening (3)
411 'slot' => $doctrine->getRepository(Slot
::class)->findOneById(3)
414 //Add form to context
415 $parameters['forms']['application'] = $application->createView();
417 //Create login form for anonymous
418 } elseif (!$this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
419 //Create ApplicationType form
420 $login = $this->createForm('Rapsys\UserBundle\Form\LoginType', null, [
422 'action' => $this->generateUrl('rapsys_user_login'),
423 //Set the form attribute
424 'attr' => [ 'class' => 'col' ]
427 //Add form to context
428 $parameters['forms']['login'] = $login->createView();
432 return $this->_render($view, $parameters, $response);