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