X-Git-Url: https://git.rapsys.eu/treebundle/blobdiff_plain/7c186a8ba6c5a23f7ec0c02d39efb36260593b4f..08adf12f23646afa31a2e1d189d8d710bec88453:/Controller/TreeController.php diff --git a/Controller/TreeController.php b/Controller/TreeController.php index a8f1992..267cffa 100644 --- a/Controller/TreeController.php +++ b/Controller/TreeController.php @@ -15,26 +15,142 @@ use Psr\Container\ContainerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Routing\RouterInterface; +use Symfony\Contracts\Translation\TranslatorInterface; use Twig\Environment; +use Rapsys\TreeBundle\RapsysTreeBundle; + /** * {@inheritdoc} */ class TreeController extends AbstractController { + /** + * Config array + */ + protected array $config; + /** * Context array */ protected array $context = []; + /** + * Locale string + */ + protected string $locale; + + /** + * Request instance + */ + protected Request $request; + + /** + * Route string + */ + protected string $route; + + /** + * Route params array + */ + protected array $routeParams; + /** * Creates a new tree controller * * @param ContainerInterface $container The ContainerInterface instance + * @param RouterInterface $router The router instance + * @param RequestStack $stack The stack instance + * @param TranslatorInterface $translator The translator instance * @param Environment $twig The twig environment instance */ - function __construct(protected ContainerInterface $container, protected Environment $twig) { + function __construct(protected ContainerInterface $container, protected RouterInterface $router, protected RequestStack $stack, protected TranslatorInterface $translator, protected Environment $twig) { + //Retrieve config + $this->config = $container->getParameter(RapsysTreeBundle::getAlias()); + + //Get main request + $this->request = $this->stack->getMainRequest(); + + //Get current locale + $this->locale = $this->request->getLocale(); + + //Set canonical + $canonical = null; + + //Set alternates + $alternates = []; + + //Set route + //TODO: default to not found route ??? + //TODO: pour une url not found, cet attribut n'est pas défini, comment on fait ??? + //XXX: on génère une route bidon par défaut ??? + $this->route = $this->request->attributes->get('_route'); + + //Set route params + $this->routeParams = $this->request->attributes->get('_route_params'); + + //With route and routeParams + if ($this->route !== null && $this->routeParams !== null) { + //Set canonical + $canonical = $this->router->generate($this->route, $this->routeParams, UrlGeneratorInterface::ABSOLUTE_URL); + + //Set alternates + $alternates = [ + substr($this->locale, 0, 2) => [ + 'absolute' => $canonical + ] + ]; + } + + //Set the context + $this->context = [ + 'alternates' => $alternates, + 'canonical' => $canonical, + 'contact' => [ + 'address' => $this->config['contact']['address'], + 'name' => $this->translator->trans($this->config['contact']['name']) + ], + 'copy' => [ + 'by' => $this->translator->trans($this->config['copy']['by']), + 'link' => $this->config['copy']['link'], + 'long' => $this->translator->trans($this->config['copy']['long']), + 'short' => $this->translator->trans($this->config['copy']['short']), + 'title' => $this->config['copy']['title'] + ], + 'description' => null, + 'donate' => $this->config['donate'], + 'facebook' => [ + 'og:type' => 'article', + 'og:site_name' => $title = $this->translator->trans($this->config['title']), + 'og:url' => $canonical, + #'fb:admins' => $this->config['facebook']['admins'], + 'fb:app_id' => $this->config['facebook']['apps'] + ], + //XXX: TODO: only generate it when fb robot request the url ??? + 'fbimage' => [ + 'texts' => [ + $title => [ + 'font' => 'irishgrover', + 'size' => 110 + ] + ] + ], + 'icon' => $this->config['icon'], + 'keywords' => null, + 'locale' => str_replace('_', '-', $this->locale), + 'logo' => $this->config['logo'], + 'forms' => [], + 'root' => $this->router->generate($this->config['root']), + 'title' => [ + 'page' => null, + 'section' => null, + 'site' => $title + ] + ]; } /** @@ -47,7 +163,8 @@ class TreeController extends AbstractController { */ public function index(Request $request, string $path): Response { //Render template - $response = $this->twig->render('@RapsysTree/index.html.twig', $this->context); + $response = $this->render('@RapsysTree/index.html.twig', $this->context); + $response->setEtag(md5($response->getContent())); $response->setPublic(); $response->isNotModified($request); @@ -55,4 +172,114 @@ class TreeController extends AbstractController { //Return response return $response; } + + /** + * Renders a view + * + * {@inheritdoc} + */ + protected function render(string $view, array $parameters = [], Response $response = null): Response { + //Create response when null + $response ??= new Response(); + + //Without alternates + if (count($parameters['alternates']) <= 1) { + //Set routeParams + $routeParams = $this->routeParams; + + //Iterate on locales excluding current one + foreach($this->config['locales'] as $locale) { + //With current locale + if ($locale !== $this->locale) { + //Set titles + $titles = []; + + //Set route params locale + $routeParams['_locale'] = $locale; + + //Iterate on other locales + foreach(array_diff($this->config['locales'], [$locale]) as $other) { + //Set other locale title + $titles[$other] = $this->translator->trans($this->config['languages'][$locale], [], null, $other); + } + + //Set locale locales context + $parameters['alternates'][str_replace('_', '-', $locale)] = [ + 'absolute' => $this->router->generate($this->route, $routeParams, UrlGeneratorInterface::ABSOLUTE_URL), + 'relative' => $this->router->generate($this->route, $routeParams), + 'title' => implode('/', $titles), + 'translated' => $this->translator->trans($this->config['languages'][$locale], [], null, $locale) + ]; + + //Add shorter locale + if (empty($parameters['alternates'][$shortCurrent = substr($locale, 0, 2)])) { + //Set locale locales context + $parameters['alternates'][$shortCurrent] = $parameters['alternates'][str_replace('_', '-', $locale)]; + } + } + } + } + + //With canonical + if (!empty($parameters['canonical'])) { + //Set facebook url + $parameters['facebook']['og:url'] = $parameters['canonical']; + } + + //With empty facebook title and title + if (empty($parameters['facebook']['og:title']) && !empty($parameters['title'])) { + //Set facebook title + $parameters['facebook']['og:title'] = $parameters['title']; + } + + //With empty facebook description and description + if (empty($parameters['facebook']['og:description']) && !empty($parameters['description'])) { + //Set facebook description + $parameters['facebook']['og:description'] = $parameters['description']; + } + + //With locale + if (!empty($this->locale)) { + //Set facebook locale + $parameters['facebook']['og:locale'] = $this->locale; + + //With alternates + //XXX: locale change when fb_locale=xx_xx is provided is done in FacebookSubscriber + //XXX: see https://stackoverflow.com/questions/20827882/in-open-graph-markup-whats-the-use-of-oglocalealternate-without-the-locati + if (!empty($parameters['alternates'])) { + //Iterate on alternates + foreach($parameters['alternates'] as $lang => $alternate) { + if (strlen($lang) == 5) { + //Set facebook locale alternate + $parameters['facebook']['og:locale:alternate'] = str_replace('-', '_', $lang); + } + } + } + } + + //Without facebook image defined and texts + if (empty($parameters['facebook']['og:image']) && !empty($this->request) && !empty($parameters['fbimage']['texts']) && !empty($this->modified)) { + //Get facebook image + $parameters['facebook'] += $this->facebook->getImage($this->request->getPathInfo(), $parameters['fbimage']['texts'], $this->modified->getTimestamp()); + } + + //Call twig render method + $content = $this->twig->render($view, $parameters); + + //Invalidate OK response on invalid form + if (200 === $response->getStatusCode()) { + foreach ($parameters as $v) { + if ($v instanceof FormInterface && $v->isSubmitted() && !$v->isValid()) { + $response->setStatusCode(422); + break; + } + } + } + + //Store content in response + $response->setContent($content); + + //Return response + return $response; + } }