]> Raphaël G. Git Repositories - userbundle/blob - Controller/AbstractController.php
Improve disabled 403 status code response
[userbundle] / Controller / AbstractController.php
1 <?php declare(strict_types=1);
2
3 /*
4 * This file is part of the Rapsys UserBundle 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\UserBundle\Controller;
13
14 use Psr\Log\LoggerInterface;
15 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as BaseAbstractController;
16 use Symfony\Bundle\FrameworkBundle\Controller\ControllerTrait;
17 use Symfony\Component\DependencyInjection\ContainerInterface;
18 use Symfony\Component\HttpFoundation\RequestStack;
19 use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
20 use Symfony\Component\Routing\RouterInterface;
21 use Symfony\Component\Translation\TranslatorInterface;
22 use Symfony\Contracts\Service\ServiceSubscriberInterface;
23
24 use Rapsys\UserBundle\RapsysUserBundle;
25
26 /**
27 * Provides common features needed in controllers.
28 *
29 * {@inheritdoc}
30 */
31 abstract class AbstractController extends BaseAbstractController implements ServiceSubscriberInterface {
32 use ControllerTrait {
33 //Rename render as baseRender
34 render as protected baseRender;
35 }
36
37 ///Config array
38 protected $config;
39
40 ///ContainerInterface instance
41 protected $container;
42
43 ///Context array
44 protected $context;
45
46 ///Router instance
47 protected $router;
48
49 ///Translator instance
50 protected $translator;
51
52 ///Locale
53 protected $locale;
54
55 /**
56 * Common constructor
57 *
58 * Stores container, router and translator interfaces
59 * Stores config
60 * Prepares context tree
61 *
62 * @param ContainerInterface $container The container instance
63 */
64 public function __construct(ContainerInterface $container) {
65 //Retrieve config
66 $this->config = $container->getParameter(RapsysUserBundle::getAlias());
67
68 //Set the container
69 $this->container = $container;
70
71 //Set the router
72 $this->router = $container->get('router');
73
74 //Set the translator
75 $this->translator = $container->get('translator');
76
77 //Get request stack
78 $stack = $this->container->get('request_stack');
79
80 //Get current request
81 $request = $stack->getCurrentRequest();
82
83 //Get current locale
84 $this->locale = $request->getLocale();
85
86 //Set locale
87 $this->config['context']['locale'] = str_replace('_', '-', $this->locale);
88
89 //Set translate array
90 $translates = [];
91
92 //Look for keys to translate
93 if (!empty($this->config['translate'])) {
94 //Iterate on keys to translate
95 foreach($this->config['translate'] as $translate) {
96 //Set tmp
97 $tmp = null;
98 //Iterate on keys
99 foreach(array_reverse(explode('.', $translate)) as $curkey) {
100 $tmp = array_combine([$curkey], [$tmp]);
101 }
102 //Append tree
103 $translates = array_replace_recursive($translates, $tmp);
104 }
105 }
106
107 //Inject every requested route in view and mail context
108 foreach($this->config as $tag => $current) {
109 //Look for entry with title subkey
110 if (!empty($current['title'])) {
111 //Translate title value
112 $this->config[$tag]['title'] = $this->translator->trans($current['title']);
113 }
114
115 //Look for entry with route subkey
116 if (!empty($current['route'])) {
117 //Generate url for both view and mail
118 foreach(['view', 'mail'] as $view) {
119 //Check that context key is usable
120 if (isset($current[$view]['context']) && is_array($current[$view]['context'])) {
121 //Merge with global context
122 $this->config[$tag][$view]['context'] = array_replace_recursive($this->config['context'], $this->config[$tag][$view]['context']);
123
124 //Process every routes
125 foreach($current['route'] as $route => $key) {
126 //With confirm route
127 if ($route == 'confirm') {
128 //Skip route as it requires some parameters
129 continue;
130 }
131
132 //Set value
133 $value = $this->router->generate(
134 $this->config['route'][$route]['name'],
135 $this->config['route'][$route]['context'],
136 //Generate absolute url for mails
137 $view=='mail'?UrlGeneratorInterface::ABSOLUTE_URL:UrlGeneratorInterface::ABSOLUTE_PATH
138 );
139
140 //Multi level key
141 if (strpos($key, '.') !== false) {
142 //Set tmp
143 $tmp = $value;
144
145 //Iterate on key
146 foreach(array_reverse(explode('.', $key)) as $curkey) {
147 $tmp = array_combine([$curkey], [$tmp]);
148 }
149
150 //Set value
151 $this->config[$tag][$view]['context'] = array_replace_recursive($this->config[$tag][$view]['context'], $tmp);
152 //Single level key
153 } else {
154 //Set value
155 $this->config[$tag][$view]['context'][$key] = $value;
156 }
157 }
158
159 //Look for successful intersections
160 if (!empty(array_intersect_key($translates, $this->config[$tag][$view]['context']))) {
161 //Iterate on keys to translate
162 foreach($this->config['translate'] as $translate) {
163 //Set keys
164 $keys = explode('.', $translate);
165
166 //Set tmp
167 $tmp = $this->config[$tag][$view]['context'];
168
169 //Iterate on keys
170 foreach($keys as $curkey) {
171 //Without child key
172 if (!isset($tmp[$curkey])) {
173 //Skip to next key
174 continue(2);
175 }
176
177 //Get child key
178 $tmp = $tmp[$curkey];
179 }
180
181 //Translate tmp value
182 $tmp = $this->translator->trans($tmp);
183
184 //Iterate on keys
185 foreach(array_reverse($keys) as $curkey) {
186 //Set parent key
187 $tmp = array_combine([$curkey], [$tmp]);
188 }
189
190 //Set value
191 $this->config[$tag][$view]['context'] = array_replace_recursive($this->config[$tag][$view]['context'], $tmp);
192 }
193 }
194
195 //With view context
196 if ($view == 'view') {
197 //Get context path
198 $pathInfo = $this->router->getContext()->getPathInfo();
199
200 //Iterate on locales excluding current one
201 foreach($this->config['locales'] as $locale) {
202 //Set titles
203 $titles = [];
204
205 //Iterate on other locales
206 foreach(array_diff($this->config['locales'], [$locale]) as $other) {
207 $titles[$other] = $this->translator->trans($this->config['languages'][$locale], [], null, $other);
208 }
209
210 //Retrieve route matching path
211 $route = $this->router->match($pathInfo);
212
213 //Get route name
214 $name = $route['_route'];
215
216 //Unset route name
217 unset($route['_route']);
218
219 //With current locale
220 if ($locale == $this->locale) {
221 //Set locale locales context
222 $this->config[$tag][$view]['context']['canonical'] = $this->router->generate($name, ['_locale' => $locale]+$route, UrlGeneratorInterface::ABSOLUTE_URL);
223 } else {
224 //Set locale locales context
225 $this->config[$tag][$view]['context']['alternates'][$locale] = [
226 'absolute' => $this->router->generate($name, ['_locale' => $locale]+$route, UrlGeneratorInterface::ABSOLUTE_URL),
227 'relative' => $this->router->generate($name, ['_locale' => $locale]+$route),
228 'title' => implode('/', $titles),
229 'translated' => $this->translator->trans($this->config['languages'][$locale], [], null, $locale)
230 ];
231 }
232
233 //Add shorter locale
234 if (empty($this->config[$tag][$view]['context']['alternates'][$slocale = substr($locale, 0, 2)])) {
235 //Add shorter locale
236 $this->config[$tag][$view]['context']['alternates'][$slocale] = [
237 'absolute' => $this->router->generate($name, ['_locale' => $locale]+$route, UrlGeneratorInterface::ABSOLUTE_URL),
238 'relative' => $this->router->generate($name, ['_locale' => $locale]+$route),
239 'title' => implode('/', $titles),
240 'translated' => $this->translator->trans($this->config['languages'][$locale], [], null, $locale)
241 ];
242 }
243 }
244 }
245 }
246 }
247 }
248 }
249 }
250
251 /**
252 * {@inheritdoc}
253 *
254 * @see vendor/symfony/framework-bundle/Controller/AbstractController.php
255 */
256 public static function getSubscribedServices(): array {
257 //Return subscribed services
258 return [
259 'logger' => LoggerInterface::class,
260 'request_stack' => RequestStack::class,
261 'router' => RouterInterface::class,
262 'translator' => TranslatorInterface::class
263 ];
264 }
265 }