namespace Rapsys\AirBundle\Controller;
use Rapsys\AirBundle\Entity\Application;
+use Rapsys\AirBundle\Entity\Location;
use Rapsys\AirBundle\Entity\Session;
+use Rapsys\AirBundle\Entity\Slot;
+use Rapsys\AirBundle\Entity\User;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mime\Address;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Translation\TranslatorInterface;
use Rapsys\UserBundle\Utils\Slugger;
+use Symfony\Bundle\FrameworkBundle\Controller\ControllerTrait;
+use Symfony\Component\DependencyInjection\ContainerAwareTrait;
-class DefaultController extends AbstractController {
- //Config array
+
+class DefaultController {
+ use ControllerTrait {
+ //Rename render as _render
+ render as protected _render;
+ }
+
+ ///Config array
protected $config;
- //Context array
+ ///Context array
protected $context;
- //Router instance
+ ///Router instance
protected $router;
- //Slugger instance
- protected $slugger;
-
- //Translator instance
+ ///Translator instance
protected $translator;
+ /**
+ * @var ContainerInterface
+ */
+ protected $container;
+
/**
* Inject container and translator interface
*
* @param ContainerInterface $container The container instance
* @param RouterInterface $router The router instance
- * @param Slugger $slugger The slugger instance
* @param TranslatorInterface $translator The translator instance
*/
- public function __construct(ContainerInterface $container, RouterInterface $router, Slugger $slugger, TranslatorInterface $translator) {
+ public function __construct(ContainerInterface $container, RouterInterface $router, RequestStack $requestStack, TranslatorInterface $translator) {
//Retrieve config
$this->config = $container->getParameter($this->getAlias());
+ //Set the container
+ $this->container = $container;
+
//Set the router
$this->router = $router;
- //Set the slugger
- $this->slugger = $slugger;
-
//Set the translator
$this->translator = $translator;
//Set the context
$this->context = [
- 'copy_long' => $translator->trans($this->config['copy']['long']),
- 'copy_short' => $translator->trans($this->config['copy']['short']),
- 'site_ico' => $this->config['site']['ico'],
- 'site_logo' => $this->config['site']['logo'],
- 'site_png' => $this->config['site']['png'],
- 'site_svg' => $this->config['site']['svg'],
- 'site_title' => $translator->trans($this->config['site']['title']),
- 'site_url' => $router->generate($this->config['site']['url'])
+ 'copy' => [
+ 'by' => $translator->trans($this->config['copy']['by']),
+ 'link' => $this->config['copy']['link'],
+ 'long' => $translator->trans($this->config['copy']['long']),
+ 'short' => $translator->trans($this->config['copy']['short']),
+ 'title' => $this->config['copy']['title']
+ ],
+ 'site' => [
+ 'ico' => $this->config['site']['ico'],
+ 'logo' => $this->config['site']['logo'],
+ 'png' => $this->config['site']['png'],
+ 'svg' => $this->config['site']['svg'],
+ 'title' => $translator->trans($this->config['site']['title']),
+ 'url' => $router->generate($this->config['site']['url']),
+ ],
+ 'canonical' => null,
+ 'alternates' => [],
+ 'forms' => []
];
+
+ //Get current locale
+ #$currentLocale = $router->getContext()->getParameters()['_locale'];
+ $currentLocale = $requestStack->getCurrentRequest()->getLocale();
+
+ //Set translator locale
+ //XXX: allow LocaleSubscriber on the fly locale change for first page
+ $this->translator->setLocale($currentLocale);
+
+ //Iterate on locales excluding current one
+ foreach($this->config['locales'] as $locale) {
+ //Set titles
+ $titles = [];
+
+ //Iterate on other locales
+ foreach(array_diff($this->config['locales'], [$locale]) as $other) {
+ $titles[$other] = $translator->trans($this->config['languages'][$locale], [], null, $other);
+ }
+
+ //Get context path
+ $path = $router->getContext()->getPathInfo();
+
+ //Retrieve route matching path
+ $route = $router->match($path);
+
+ //Get route name
+ $name = $route['_route'];
+
+ //Unset route name
+ unset($route['_route']);
+
+ //With current locale
+ if ($locale == $currentLocale) {
+ //Set locale locales context
+ $this->context['canonical'] = $router->generate($name, ['_locale' => $locale]+$route, UrlGeneratorInterface::ABSOLUTE_URL);
+ } else {
+ //Set locale locales context
+ $this->context['alternates'][] = [
+ 'lang' => $locale,
+ 'absolute' => $router->generate($name, ['_locale' => $locale]+$route, UrlGeneratorInterface::ABSOLUTE_URL),
+ 'relative' => $router->generate($name, ['_locale' => $locale]+$route),
+ 'title' => implode('/', $titles),
+ 'translated' => $translator->trans($this->config['languages'][$locale], [], null, $locale)
+ ];
+ }
+ }
}
/**
*
* @return Response The rendered view or redirection
*/
- public function contact(Request $request, MailerInterface $mailer) {
+ public function contact(Request $request, MailerInterface $mailer): Response {
//Set section
$section = $this->translator->trans('Contact');
+ //Set description
+ $this->context['description'] = $this->translator->trans('Contact Libre Air');
+
+ //Set keywords
+ $this->context['keywords'] = [
+ $this->translator->trans('contact'),
+ $this->translator->trans('Libre Air'),
+ $this->translator->trans('outdoor'),
+ $this->translator->trans('Argentine Tango'),
+ $this->translator->trans('calendar')
+ ];
+
//Set title
- $title = $section.' - '.$this->translator->trans($this->config['site']['title']);
+ $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
//Create the form according to the FormType created previously.
//And give the proper parameters
$form = $this->createForm('Rapsys\AirBundle\Form\ContactType', null, [
- // To set the action use $this->generateUrl('route_identifier')
'action' => $this->generateUrl('rapsys_air_contact'),
'method' => 'POST'
]);
return $this->render('@RapsysAir/form/contact.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView(), 'sent' => $request->query->get('sent', 0)]+$this->context);
}
+
+ /**
+ * The dispute page
+ *
+ * @desc Generate a dispute document
+ *
+ * @param Request $request The request instance
+ * @param MailerInterface $mailer The mailer instance
+ *
+ * @return Response The rendered view or redirection
+ */
+ public function dispute(Request $request, MailerInterface $mailer): Response {
+ //Prevent non-guest to access here
+ $this->denyAccessUnlessGranted('ROLE_USER', null, $this->translator->trans('Unable to access this page without role %role%!', ['%role%' => $this->translator->trans('User')]));
+ //Set section
+ $section = $this->translator->trans('Dispute');
+
+ //Set description
+ $this->context['description'] = $this->translator->trans('Libre Air dispute');
+
+ //Set keywords
+ $this->context['keywords'] = [
+ $this->translator->trans('dispute'),
+ $this->translator->trans('Libre Air'),
+ $this->translator->trans('outdoor'),
+ $this->translator->trans('Argentine Tango'),
+ $this->translator->trans('calendar')
+ ];
+
+ //Set title
+ $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
+
+ //Create the form according to the FormType created previously.
+ //And give the proper parameters
+ $form = $this->createForm('Rapsys\AirBundle\Form\DisputeType', null, [
+ 'action' => $this->generateUrl('rapsys_air_dispute'),
+ 'method' => 'POST'
+ ]);
+
+ if ($request->isMethod('POST')) {
+ // Refill the fields in case the form is not valid.
+ $form->handleRequest($request);
+
+ if ($form->isValid()) {
+ //Get data
+ $data = $form->getData();
+
+ header('Content-Type: text/plain');
+
+ //Infraction
+ var_dump($data['offense']);
+
+ //Numéro d'avis
+ var_dump($data['notice']);
+
+ //Numéro d'agent
+ var_dump($data['agent']);
+
+ //Code service
+ var_dump($data['service']);
+
+ //Masque porté
+ var_dump($data['mask']);
+
+ //Civilité
+ var_dump($this->translator->trans($this->getUser()->getCivility()->getTitle()));
+
+ //Prénom
+ var_dump($this->getUser()->getForename());
+
+ //Nom
+ var_dump($this->getUser()->getSurname());
+
+ //Mail
+ var_dump($this->getUser()->getMail());
+
+ exit;
+
+# //Create message
+# $message = (new TemplatedEmail())
+# //Set sender
+# ->from(new Address($data['mail'], $data['name']))
+# //Set recipient
+# //XXX: remove the debug set in vendor/symfony/mime/Address.php +46
+# ->to(new Address($this->config['contact']['mail'], $this->config['contact']['name']))
+# //Set subject
+# ->subject($data['subject'])
+#
+# //Set path to twig templates
+# ->htmlTemplate('@RapsysAir/mail/contact.html.twig')
+# ->textTemplate('@RapsysAir/mail/contact.text.twig')
+#
+# //Set context
+# ->context(
+# [
+# 'subject' => $data['subject'],
+# 'message' => strip_tags($data['message']),
+# ]+$this->context
+# );
+#
+# //Try sending message
+# //XXX: mail delivery may silently fail
+# try {
+# //Send message
+# $mailer->send($message);
+#
+# //Redirect on the same route with sent=1 to cleanup form
+# return $this->redirectToRoute($request->get('_route'), ['sent' => 1]+$request->get('_route_params'));
+# //Catch obvious transport exception
+# } catch(TransportExceptionInterface $e) {
+# if ($message = $e->getMessage()) {
+# //Add error message mail unreachable
+# $form->get('mail')->addError(new FormError($this->translator->trans('Unable to contact: %mail%: %message%', ['%mail%' => $this->config['contact']['mail'], '%message%' => $this->translator->trans($message)])));
+# } else {
+# //Add error message mail unreachable
+# $form->get('mail')->addError(new FormError($this->translator->trans('Unable to contact: %mail%', ['%mail%' => $this->config['contact']['mail']])));
+# }
+# }
+ }
+ }
+
+ //Render template
+ return $this->render('@RapsysAir/form/dispute.html.twig', ['title' => $title, 'section' => $section, 'form' => $form->createView(), 'sent' => $request->query->get('sent', 0)]+$this->context);
+ }
+
/**
* The index page
*
- * @desc Welcome the user
+ * @desc Display all granted sessions with an application or login form
+ *
+ * @param Request $request The request instance
+ *
+ * @return Response The rendered view
+ */
+ public function index(Request $request): Response {
+ //Fetch doctrine
+ $doctrine = $this->getDoctrine();
+
+ //Set section
+ $section = $this->translator->trans('Argentine Tango in Paris');
+
+ //Set description
+ $this->context['description'] = $this->translator->trans('Outdoor Argentine Tango session calendar in Paris');
+
+ //Set keywords
+ $this->context['keywords'] = [
+ $this->translator->trans('Argentine Tango'),
+ $this->translator->trans('Paris'),
+ $this->translator->trans('outdoor'),
+ $this->translator->trans('calendar'),
+ $this->translator->trans('Libre Air')
+ ];
+
+ //Set title
+ $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
+
+ //Compute period
+ $period = new \DatePeriod(
+ //Start from first monday of week
+ new \DateTime('Monday this week'),
+ //Iterate on each day
+ new \DateInterval('P1D'),
+ //End with next sunday and 4 weeks
+ new \DateTime(
+ $this->isGranted('IS_AUTHENTICATED_REMEMBERED')?'Monday this week + 3 week':'Monday this week + 2 week'
+ )
+ );
+
+ //Fetch calendar
+ $calendar = $doctrine->getRepository(Session::class)->fetchCalendarByDatePeriod($this->translator, $period, null, $request->get('session'), !$this->isGranted('IS_AUTHENTICATED_REMEMBERED'));
+
+ //Fetch locations
+ //XXX: we want to display all active locations anyway
+ $locations = $doctrine->getRepository(Location::class)->findTranslatedSortedByPeriod($this->translator, $period);
+
+ //Render the view
+ return $this->render('@RapsysAir/default/index.html.twig', ['title' => $title, 'section' => $section, 'calendar' => $calendar, 'locations' => $locations]+$this->context);
+
+ //Set Cache-Control must-revalidate directive
+ //TODO: add a javascript forced refresh after 1h ? or header refresh ?
+ #$response->setPublic(true);
+ #$response->setMaxAge(300);
+ #$response->mustRevalidate();
+ ##$response->setCache(['public' => true, 'max_age' => 300]);
+
+ //Return the response
+ #return $response;
+ }
+
+ /**
+ * The organizer regulation page
+ *
+ * @desc Display the organizer regulation policy
+ *
+ * @return Response The rendered view
+ */
+ public function organizerRegulation(): Response {
+ //Set section
+ $section = $this->translator->trans('Organizer regulation');
+
+ //Set description
+ $this->context['description'] = $this->translator->trans('Libre Air organizer regulation');
+
+ //Set keywords
+ $this->context['keywords'] = [
+ $this->translator->trans('organizer regulation'),
+ $this->translator->trans('Libre Air')
+ ];
+
+ //Set title
+ $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
+
+ //Render template
+ return $this->render('@RapsysAir/default/organizer_regulation.html.twig', ['title' => $title, 'section' => $section]+$this->context);
+ }
+
+ /**
+ * The terms of service page
+ *
+ * @desc Display the terms of service policy
*
* @return Response The rendered view
*/
- public function index() {
+ public function termsOfService(): Response {
//Set section
- $section = $this->translator->trans('Index');
+ $section = $this->translator->trans('Terms of service');
+
+ //Set description
+ $this->context['description'] = $this->translator->trans('Libre Air terms of service');
+
+ //Set keywords
+ $this->context['keywords'] = [
+ $this->translator->trans('terms of service'),
+ $this->translator->trans('Libre Air')
+ ];
//Set title
- $title = $section.' - '.$this->context['site_title'];
+ $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
//Render template
- return $this->render('@RapsysAir/default/index.html.twig', ['title' => $title, 'section' => $section]+$this->context);
+ return $this->render('@RapsysAir/default/terms_of_service.html.twig', ['title' => $title, 'section' => $section]+$this->context);
}
/**
- * The regulation page
+ * The frequently asked questions page
*
- * @desc Display the regulation policy
+ * @desc Display the frequently asked questions
*
* @return Response The rendered view
*/
- public function regulation() {
+ public function frequentlyAskedQuestions(): Response {
//Set section
- $section = $this->translator->trans('Regulation');
+ $section = $this->translator->trans('Frequently asked questions');
+
+ //Set description
+ $this->context['description'] = $this->translator->trans('Libre Air frequently asked questions');
+
+ //Set keywords
+ $this->context['keywords'] = [
+ $this->translator->trans('frequently asked questions'),
+ $this->translator->trans('faq'),
+ $this->translator->trans('Libre Air')
+ ];
//Set title
- $title = $section.' - '.$this->context['site_title'];
+ $title = $this->translator->trans($this->config['site']['title']).' - '.$section;
//Render template
- return $this->render('@RapsysAir/default/regulation.html.twig', ['title' => $title, 'section' => $section]+$this->context);
+ return $this->render('@RapsysAir/default/frequently_asked_questions.html.twig', ['title' => $title, 'section' => $section]+$this->context);
}
/**
*
* {@inheritdoc}
*/
- public function getAlias() {
+ public function getAlias(): string {
return 'rapsys_air';
}
+
+ /**
+ * Renders a view
+ *
+ * {@inheritdoc}
+ */
+ protected function render(string $view, array $parameters = [], Response $response = null): Response {
+ //Create application form for role_guest
+ if ($this->isGranted('ROLE_GUEST')) {
+ //Without application form
+ if (empty($parameters['forms']['application'])) {
+ //Fetch doctrine
+ $doctrine = $this->getDoctrine();
+
+ //Create ApplicationType form
+ $application = $this->createForm('Rapsys\AirBundle\Form\ApplicationType', null, [
+ //Set the action
+ 'action' => $this->generateUrl('rapsys_air_application_add'),
+ //Set the form attribute
+ 'attr' => [ 'class' => 'col' ],
+ //Set admin
+ 'admin' => $this->isGranted('ROLE_ADMIN'),
+ //Set default user to current
+ 'user' => $this->getUser()->getId(),
+ //Set default slot to evening
+ //XXX: default to Evening (3)
+ 'slot' => $doctrine->getRepository(Slot::class)->findOneById(3)
+ ]);
+
+ //Add form to context
+ $parameters['forms']['application'] = $application->createView();
+ }
+ //Create login form for anonymous
+ } elseif (!$this->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
+ //Create ApplicationType form
+ $login = $this->createForm('Rapsys\UserBundle\Form\LoginType', null, [
+ //Set the action
+ 'action' => $this->generateUrl('rapsys_user_login'),
+ //Set the form attribute
+ 'attr' => [ 'class' => 'col' ]
+ ]);
+
+ //Add form to context
+ $parameters['forms']['login'] = $login->createView();
+ }
+
+ //Call parent method
+ return $this->_render($view, $parameters, $response);
+ }
}