1 <?php
declare(strict_types
=1);
4 * This file is part of the Rapsys TreeBundle package.
6 * (c) Raphaël Gertz <symfony@rapsys.eu>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Rapsys\TreeBundle\Controller
;
14 use Psr\Container\ContainerInterface
;
16 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController
;
17 use Symfony\Component\HttpFoundation\Request
;
18 use Symfony\Component\HttpFoundation\RequestStack
;
19 use Symfony\Component\HttpFoundation\Response
;
20 use Symfony\Component\Routing\Generator\UrlGeneratorInterface
;
21 use Symfony\Component\Routing\RouterInterface
;
22 use Symfony\Contracts\Translation\TranslatorInterface
;
26 use Rapsys\TreeBundle\RapsysTreeBundle
;
31 class TreeController
extends AbstractController
{
35 protected array $config;
40 protected array $context = [];
45 protected string $locale;
50 protected Request
$request;
55 protected string $route;
60 protected array $routeParams;
63 * Creates a new tree controller
65 * @param ContainerInterface $container The ContainerInterface instance
66 * @param RouterInterface $router The router instance
67 * @param RequestStack $stack The stack instance
68 * @param TranslatorInterface $translator The translator instance
69 * @param Environment $twig The twig environment instance
71 function __construct(protected ContainerInterface
$container, protected RouterInterface
$router, protected RequestStack
$stack, protected TranslatorInterface
$translator, protected Environment
$twig) {
73 $this->config
= $container->getParameter(RapsysTreeBundle
::getAlias());
76 $this->request
= $this->stack
->getMainRequest();
79 $this->locale
= $this->request
->getLocale();
88 //TODO: default to not found route ???
89 //TODO: pour une url not found, cet attribut n'est pas défini, comment on fait ???
90 //XXX: on génère une route bidon par défaut ???
91 $this->route
= $this->request
->attributes
->get('_route');
94 $this->routeParams
= $this->request
->attributes
->get('_route_params');
96 //With route and routeParams
97 if ($this->route
!== null && $this->routeParams
!== null) {
99 $canonical = $this->router
->generate($this->route
, $this->routeParams
, UrlGeneratorInterface
::ABSOLUTE_URL
);
103 substr($this->locale
, 0, 2) => [
104 'absolute' => $canonical
111 'alternates' => $alternates,
112 'canonical' => $canonical,
114 'address' => $this->config
['contact']['address'],
115 'name' => $this->translator
->trans($this->config
['contact']['name'])
118 'by' => $this->translator
->trans($this->config
['copy']['by']),
119 'link' => $this->config
['copy']['link'],
120 'long' => $this->translator
->trans($this->config
['copy']['long']),
121 'short' => $this->translator
->trans($this->config
['copy']['short']),
122 'title' => $this->config
['copy']['title']
124 'description' => null,
125 'donate' => $this->config
['donate'],
127 'og:type' => 'article',
128 'og:site_name' => $title = $this->translator
->trans($this->config
['title']),
129 'og:url' => $canonical,
130 #'fb:admins' => $this->config['facebook']['admins'],
131 'fb:app_id' => $this->config
['facebook']['apps']
133 //XXX: TODO: only generate it when fb robot request the url ???
137 'font' => 'irishgrover',
142 'icon' => $this->config
['icon'],
144 'locale' => str_replace('_', '-', $this->locale
),
145 'logo' => $this->config
['logo'],
147 'root' => $this->router
->generate($this->config
['root']),
161 * @param Request $request The request instance
162 * @return Response The rendered view
164 public function index(Request
$request): Response
{
166 $this->context
['roots'] = $this->config
['roots'];
169 $response = $this->render('@RapsysTree/index.html.twig', $this->context
);
171 $response->setEtag(md5($response->getContent()));
172 $response->setPublic();
173 $response->isNotModified($request);
184 * @param Request $request The request instance
185 * @param string $path The directory path
186 * @return Response The rendered view
188 public function directory(Request
$request, string $path): Response
{
189 header('Content-Type: text/plain');
194 $response = $this->render('@RapsysTree/directory.html.twig', $this->context
);
196 $response->setEtag(md5($response->getContent()));
197 $response->setPublic();
198 $response->isNotModified($request);
209 * @param Request $request The request instance
210 * @param string $path The directory path
211 * @return Response The rendered view
213 public function document(Request
$request, string $path): Response
{
215 $response = $this->render('@RapsysTree/document.html.twig', $this->context
);
217 $response->setEtag(md5($response->getContent()));
218 $response->setPublic();
219 $response->isNotModified($request);
230 protected function render(string $view, array $parameters = [], Response
$response = null): Response
{
231 //Create response when null
232 $response ??= new Response();
235 if (count($parameters['alternates']) <= 1) {
237 $routeParams = $this->routeParams
;
239 //Iterate on locales excluding current one
240 foreach($this->config
['locales'] as $locale) {
241 //With current locale
242 if ($locale !== $this->locale
) {
246 //Set route params locale
247 $routeParams['_locale'] = $locale;
249 //Iterate on other locales
250 foreach(array_diff($this->config
['locales'], [$locale]) as $other) {
251 //Set other locale title
252 $titles[$other] = $this->translator
->trans($this->config
['languages'][$locale], [], null, $other);
255 //Set locale locales context
256 $parameters['alternates'][str_replace('_', '-', $locale)] = [
257 'absolute' => $this->router
->generate($this->route
, $routeParams, UrlGeneratorInterface
::ABSOLUTE_URL
),
258 'relative' => $this->router
->generate($this->route
, $routeParams),
259 'title' => implode('/', $titles),
260 'translated' => $this->translator
->trans($this->config
['languages'][$locale], [], null, $locale)
264 if (empty($parameters['alternates'][$shortCurrent = substr($locale, 0, 2)])) {
265 //Set locale locales context
266 $parameters['alternates'][$shortCurrent] = $parameters['alternates'][str_replace('_', '-', $locale)];
273 if (!empty($parameters['canonical'])) {
275 $parameters['facebook']['og:url'] = $parameters['canonical'];
278 //With empty facebook title and title
279 if (empty($parameters['facebook']['og:title']) && !empty($parameters['title']['page'])) {
281 $parameters['facebook']['og:title'] = $parameters['title']['page'];
284 //With empty facebook description and description
285 if (empty($parameters['facebook']['og:description']) && !empty($parameters['description'])) {
286 //Set facebook description
287 $parameters['facebook']['og:description'] = $parameters['description'];
291 if (!empty($this->locale
)) {
292 //Set facebook locale
293 $parameters['facebook']['og:locale'] = $this->locale
;
296 //XXX: locale change when fb_locale=xx_xx is provided is done in FacebookSubscriber
297 //XXX: see https://stackoverflow.com/questions/20827882/in-open-graph-markup-whats-the-use-of-oglocalealternate-without-the-locati
298 if (!empty($parameters['alternates'])) {
299 //Iterate on alternates
300 foreach($parameters['alternates'] as $lang => $alternate) {
301 if (strlen($lang) == 5) {
302 //Set facebook locale alternate
303 $parameters['facebook']['og:locale:alternate'] = str_replace('-', '_', $lang);
309 //Without facebook image defined and texts
310 if (empty($parameters['facebook']['og:image']) && !empty($this->request
) && !empty($parameters['fbimage']['texts']) && !empty($this->modified
)) {
312 $parameters['facebook'] +
= $this->facebook
->getImage($this->request
->getPathInfo(), $parameters['fbimage']['texts'], $this->modified
->getTimestamp());
315 //Call twig render method
316 $content = $this->twig
->render($view, $parameters);
318 //Invalidate OK response on invalid form
319 if (200 === $response->getStatusCode()) {
320 foreach ($parameters as $v) {
321 if ($v instanceof FormInterface
&& $v->isSubmitted() && !$v->isValid()) {
322 $response->setStatusCode(422);
328 //Store content in response
329 $response->setContent($content);