* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Rapsys\TreeBundle\Controller; 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 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 ] ]; } /** * The index page * * Display index * * @param Request $request The request instance * @return Response The rendered view */ public function index(Request $request): Response { //Get roots $this->context['roots'] = $this->config['roots']; //Render template $response = $this->render('@RapsysTree/index.html.twig', $this->context); $response->setEtag(md5($response->getContent())); $response->setPublic(); $response->isNotModified($request); //Return response return $response; } /** * The directory page * * Display directory * * @param Request $request The request instance * @param string $path The directory path * @return Response The rendered view */ public function directory(Request $request, string $path): Response { header('Content-Type: text/plain'); var_dump($path); exit; //Render template $response = $this->render('@RapsysTree/directory.html.twig', $this->context); $response->setEtag(md5($response->getContent())); $response->setPublic(); $response->isNotModified($request); //Return response return $response; } /** * The document page * * Display document * * @param Request $request The request instance * @param string $path The directory path * @return Response The rendered view */ public function document(Request $request, string $path): Response { //Render template $response = $this->render('@RapsysTree/document.html.twig', $this->context); $response->setEtag(md5($response->getContent())); $response->setPublic(); $response->isNotModified($request); //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']['page'])) { //Set facebook title $parameters['facebook']['og:title'] = $parameters['title']['page']; } //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; } }