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\Generator\UrlGeneratorInterface;
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;
- //Translator instance
+ ///Router instance
+ protected $router;
+
+ ///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 TranslatorInterface $translator The translator instance
*/
- public function __construct(ContainerInterface $container, TranslatorInterface $translator, RouterInterface $router) {
+ 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 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('rapsys_air_index')
+ '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)
+ ];
+ }
+ }
}
/**
* The contact page
+ *
+ * @desc Send a contact mail to configured contact
+ *
+ * @param Request $request The request instance
+ * @param MailerInterface $mailer The mailer instance
+ *
+ * @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'
]);
/**
* The index page
+ *
+ * @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 policy page
+ * The frequently asked questions page
+ *
+ * @desc Display the frequently asked questions
+ *
+ * @return Response The rendered view
*/
- public function policy() {
+ public function frequentlyAskedQuestions(): Response {
//Set section
- $section = $this->translator->trans('Policy');
+ $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/policy.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);
+ }
}