]> Raphaël G. Git Repositories - treebundle/blob - Controller/TreeController.php
Add directory roots
[treebundle] / Controller / TreeController.php
1 <?php declare(strict_types=1);
2
3 /*
4 * This file is part of the Rapsys TreeBundle package.
5 *
6 * (c) Raphaël Gertz <symfony@rapsys.eu>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12 namespace Rapsys\TreeBundle\Controller;
13
14 use Psr\Container\ContainerInterface;
15
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;
23
24 use Twig\Environment;
25
26 use Rapsys\TreeBundle\RapsysTreeBundle;
27
28 /**
29 * {@inheritdoc}
30 */
31 class TreeController extends AbstractController {
32 /**
33 * Config array
34 */
35 protected array $config;
36
37 /**
38 * Context array
39 */
40 protected array $context = [];
41
42 /**
43 * Locale string
44 */
45 protected string $locale;
46
47 /**
48 * Request instance
49 */
50 protected Request $request;
51
52 /**
53 * Route string
54 */
55 protected string $route;
56
57 /**
58 * Route params array
59 */
60 protected array $routeParams;
61
62 /**
63 * Creates a new tree controller
64 *
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
70 */
71 function __construct(protected ContainerInterface $container, protected RouterInterface $router, protected RequestStack $stack, protected TranslatorInterface $translator, protected Environment $twig) {
72 //Retrieve config
73 $this->config = $container->getParameter(RapsysTreeBundle::getAlias());
74
75 //Get main request
76 $this->request = $this->stack->getMainRequest();
77
78 //Get current locale
79 $this->locale = $this->request->getLocale();
80
81 //Set canonical
82 $canonical = null;
83
84 //Set alternates
85 $alternates = [];
86
87 //Set route
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');
92
93 //Set route params
94 $this->routeParams = $this->request->attributes->get('_route_params');
95
96 //With route and routeParams
97 if ($this->route !== null && $this->routeParams !== null) {
98 //Set canonical
99 $canonical = $this->router->generate($this->route, $this->routeParams, UrlGeneratorInterface::ABSOLUTE_URL);
100
101 //Set alternates
102 $alternates = [
103 substr($this->locale, 0, 2) => [
104 'absolute' => $canonical
105 ]
106 ];
107 }
108
109 //Set the context
110 $this->context = [
111 'alternates' => $alternates,
112 'canonical' => $canonical,
113 'contact' => [
114 'address' => $this->config['contact']['address'],
115 'name' => $this->translator->trans($this->config['contact']['name'])
116 ],
117 'copy' => [
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']
123 ],
124 'description' => null,
125 'donate' => $this->config['donate'],
126 'facebook' => [
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']
132 ],
133 //XXX: TODO: only generate it when fb robot request the url ???
134 'fbimage' => [
135 'texts' => [
136 $title => [
137 'font' => 'irishgrover',
138 'size' => 110
139 ]
140 ]
141 ],
142 'icon' => $this->config['icon'],
143 'keywords' => null,
144 'locale' => str_replace('_', '-', $this->locale),
145 'logo' => $this->config['logo'],
146 'forms' => [],
147 'root' => $this->router->generate($this->config['root']),
148 'title' => [
149 'page' => null,
150 'section' => null,
151 'site' => $title
152 ]
153 ];
154 }
155
156 /**
157 * The index page
158 *
159 * Display file tree
160 *
161 * @param Request $request The request instance
162 * @return Response The rendered view
163 */
164 public function index(Request $request, string $path): Response {
165 //Render template
166 $response = $this->render('@RapsysTree/index.html.twig', $this->context);
167
168 $response->setEtag(md5($response->getContent()));
169 $response->setPublic();
170 $response->isNotModified($request);
171
172 //Return response
173 return $response;
174 }
175
176 /**
177 * Renders a view
178 *
179 * {@inheritdoc}
180 */
181 protected function render(string $view, array $parameters = [], Response $response = null): Response {
182 //Create response when null
183 $response ??= new Response();
184
185 //Without alternates
186 if (count($parameters['alternates']) <= 1) {
187 //Set routeParams
188 $routeParams = $this->routeParams;
189
190 //Iterate on locales excluding current one
191 foreach($this->config['locales'] as $locale) {
192 //With current locale
193 if ($locale !== $this->locale) {
194 //Set titles
195 $titles = [];
196
197 //Set route params locale
198 $routeParams['_locale'] = $locale;
199
200 //Iterate on other locales
201 foreach(array_diff($this->config['locales'], [$locale]) as $other) {
202 //Set other locale title
203 $titles[$other] = $this->translator->trans($this->config['languages'][$locale], [], null, $other);
204 }
205
206 //Set locale locales context
207 $parameters['alternates'][str_replace('_', '-', $locale)] = [
208 'absolute' => $this->router->generate($this->route, $routeParams, UrlGeneratorInterface::ABSOLUTE_URL),
209 'relative' => $this->router->generate($this->route, $routeParams),
210 'title' => implode('/', $titles),
211 'translated' => $this->translator->trans($this->config['languages'][$locale], [], null, $locale)
212 ];
213
214 //Add shorter locale
215 if (empty($parameters['alternates'][$shortCurrent = substr($locale, 0, 2)])) {
216 //Set locale locales context
217 $parameters['alternates'][$shortCurrent] = $parameters['alternates'][str_replace('_', '-', $locale)];
218 }
219 }
220 }
221 }
222
223 //With canonical
224 if (!empty($parameters['canonical'])) {
225 //Set facebook url
226 $parameters['facebook']['og:url'] = $parameters['canonical'];
227 }
228
229 //With empty facebook title and title
230 if (empty($parameters['facebook']['og:title']) && !empty($parameters['title'])) {
231 //Set facebook title
232 $parameters['facebook']['og:title'] = $parameters['title'];
233 }
234
235 //With empty facebook description and description
236 if (empty($parameters['facebook']['og:description']) && !empty($parameters['description'])) {
237 //Set facebook description
238 $parameters['facebook']['og:description'] = $parameters['description'];
239 }
240
241 //With locale
242 if (!empty($this->locale)) {
243 //Set facebook locale
244 $parameters['facebook']['og:locale'] = $this->locale;
245
246 //With alternates
247 //XXX: locale change when fb_locale=xx_xx is provided is done in FacebookSubscriber
248 //XXX: see https://stackoverflow.com/questions/20827882/in-open-graph-markup-whats-the-use-of-oglocalealternate-without-the-locati
249 if (!empty($parameters['alternates'])) {
250 //Iterate on alternates
251 foreach($parameters['alternates'] as $lang => $alternate) {
252 if (strlen($lang) == 5) {
253 //Set facebook locale alternate
254 $parameters['facebook']['og:locale:alternate'] = str_replace('-', '_', $lang);
255 }
256 }
257 }
258 }
259
260 //Without facebook image defined and texts
261 if (empty($parameters['facebook']['og:image']) && !empty($this->request) && !empty($parameters['fbimage']['texts']) && !empty($this->modified)) {
262 //Get facebook image
263 $parameters['facebook'] += $this->facebook->getImage($this->request->getPathInfo(), $parameters['fbimage']['texts'], $this->modified->getTimestamp());
264 }
265
266 //Call twig render method
267 $content = $this->twig->render($view, $parameters);
268
269 //Invalidate OK response on invalid form
270 if (200 === $response->getStatusCode()) {
271 foreach ($parameters as $v) {
272 if ($v instanceof FormInterface && $v->isSubmitted() && !$v->isValid()) {
273 $response->setStatusCode(422);
274 break;
275 }
276 }
277 }
278
279 //Store content in response
280 $response->setContent($content);
281
282 //Return response
283 return $response;
284 }
285 }