1 <?php
declare(strict_types
=1);
4 * This file is part of the Rapsys UserBundle 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\UserBundle\Controller
;
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
;
28 use Rapsys\PackBundle\Util\SluggerUtil
;
30 use Rapsys\UserBundle\RapsysUserBundle
;
33 * Provides common features needed in controllers.
37 abstract class AbstractController
extends BaseAbstractController
implements ServiceSubscriberInterface
{
47 ///UserPasswordHasherInterface
56 ///EntityManagerInterface
65 ///Translator instance
66 protected $translator;
72 * Abstract constructor
74 * @param ContainerInterface $container The container instance
75 * @param ManagerRegistry $doctrine The doctrine instance
76 * @param UserPasswordHasherInterface $hasher The password hasher instance
77 * @param LoggerInterface $logger The logger instance
78 * @param MailerInterface $mailer The mailer instance
79 * @param EntityManagerInterface $manager The manager instance
80 * @param RouterInterface $router The router instance
81 * @param SluggerUtil $slugger The slugger instance
82 * @param RequestStack $stack The stack instance
83 * @param TranslatorInterface $translator The translator instance
85 public function __construct(ContainerInterface
$container, ManagerRegistry
$doctrine, UserPasswordHasherInterface
$hasher, LoggerInterface
$logger, MailerInterface
$mailer, EntityManagerInterface
$manager, RouterInterface
$router, SluggerUtil
$slugger, RequestStack
$stack, TranslatorInterface
$translator) {
87 $this->config
= $container->getParameter(RapsysUserBundle
::getAlias());
90 $this->container
= $container;
93 $this->doctrine
= $doctrine;
96 $this->hasher
= $hasher;
99 $this->logger
= $logger;
102 $this->mailer
= $mailer;
105 $this->manager
= $manager;
108 $this->router
= $router;
111 $this->slugger
= $slugger;
114 $this->translator
= $translator;
116 //Get current request
117 $request = $stack->getCurrentRequest();
120 $this->locale
= $request->getLocale();
123 $this->config
['context']['locale'] = str_replace('_', '-', $this->locale
);
125 //Set translate array
128 //Look for keys to translate
129 if (!empty($this->config
['translate'])) {
130 //Iterate on keys to translate
131 foreach($this->config
['translate'] as $translate) {
135 foreach(array_reverse(explode('.', $translate)) as $curkey) {
136 $tmp = array_combine([$curkey], [$tmp]);
139 $translates = array_replace_recursive($translates, $tmp);
143 //Inject every requested route in view and mail context
144 foreach($this->config
as $tag => $current) {
145 //Look for entry with title subkey
146 if (!empty($current['title'])) {
147 //Translate title value
148 $this->config
[$tag]['title'] = $this->translator
->trans($current['title']);
151 //Look for entry with route subkey
152 if (!empty($current['route'])) {
153 //Generate url for both view and mail
154 foreach(['view', 'mail'] as $view) {
155 //Check that context key is usable
156 if (isset($current[$view]['context']) && is_array($current[$view]['context'])) {
157 //Merge with global context
158 $this->config
[$tag][$view]['context'] = array_replace_recursive($this->config
['context'], $this->config
[$tag][$view]['context']);
160 //Process every routes
161 foreach($current['route'] as $route => $key) {
163 if ($route == 'confirm') {
164 //Skip route as it requires some parameters
169 $value = $this->router
->generate(
170 $this->config
['route'][$route]['name'],
171 $this->config
['route'][$route]['context'],
172 //Generate absolute url for mails
173 $view=='mail'?UrlGeneratorInterface
::ABSOLUTE_URL
:UrlGeneratorInterface
::ABSOLUTE_PATH
177 if (strpos($key, '.') !== false) {
182 foreach(array_reverse(explode('.', $key)) as $curkey) {
183 $tmp = array_combine([$curkey], [$tmp]);
187 $this->config
[$tag][$view]['context'] = array_replace_recursive($this->config
[$tag][$view]['context'], $tmp);
191 $this->config
[$tag][$view]['context'][$key] = $value;
195 //Look for successful intersections
196 if (!empty(array_intersect_key($translates, $this->config
[$tag][$view]['context']))) {
197 //Iterate on keys to translate
198 foreach($this->config
['translate'] as $translate) {
200 $keys = explode('.', $translate);
203 $tmp = $this->config
[$tag][$view]['context'];
206 foreach($keys as $curkey) {
208 if (!isset($tmp[$curkey])) {
214 $tmp = $tmp[$curkey];
217 //Translate tmp value
218 $tmp = $this->translator
->trans($tmp);
221 foreach(array_reverse($keys) as $curkey) {
223 $tmp = array_combine([$curkey], [$tmp]);
227 $this->config
[$tag][$view]['context'] = array_replace_recursive($this->config
[$tag][$view]['context'], $tmp);
232 if ($view == 'view') {
234 $pathInfo = $this->router
->getContext()->getPathInfo();
236 //Iterate on locales excluding current one
237 foreach($this->config
['locales'] as $locale) {
241 //Iterate on other locales
242 foreach(array_diff($this->config
['locales'], [$locale]) as $other) {
243 $titles[$other] = $this->translator
->trans($this->config
['languages'][$locale], [], null, $other);
246 //Retrieve route matching path
247 $route = $this->router
->match($pathInfo);
250 $name = $route['_route'];
253 unset($route['_route']);
255 //With current locale
256 if ($locale == $this->locale
) {
257 //Set locale locales context
258 $this->config
[$tag][$view]['context']['canonical'] = $this->router
->generate($name, ['_locale' => $locale]+
$route, UrlGeneratorInterface
::ABSOLUTE_URL
);
260 //Set locale locales context
261 $this->config
[$tag][$view]['context']['alternates'][$locale] = [
262 'absolute' => $this->router
->generate($name, ['_locale' => $locale]+
$route, UrlGeneratorInterface
::ABSOLUTE_URL
),
263 'relative' => $this->router
->generate($name, ['_locale' => $locale]+
$route),
264 'title' => implode('/', $titles),
265 'translated' => $this->translator
->trans($this->config
['languages'][$locale], [], null, $locale)
270 if (empty($this->config
[$tag][$view]['context']['alternates'][$slocale = substr($locale, 0, 2)])) {
272 $this->config
[$tag][$view]['context']['alternates'][$slocale] = [
273 'absolute' => $this->router
->generate($name, ['_locale' => $locale]+
$route, UrlGeneratorInterface
::ABSOLUTE_URL
),
274 'relative' => $this->router
->generate($name, ['_locale' => $locale]+
$route),
275 'title' => implode('/', $titles),
276 'translated' => $this->translator
->trans($this->config
['languages'][$locale], [], null, $locale)
290 * @see vendor/symfony/framework-bundle/Controller/AbstractController.php
292 public static function getSubscribedServices(): array {
293 //Return subscribed services
295 'service_container' => ContainerInterface
::class,
296 'doctrine' => ManagerRegistry
::class,
297 'doctrine.orm.default_entity_manager' => EntityManagerInterface
::class,
298 'logger' => LoggerInterface
::class,
299 'mailer.mailer' => MailerInterface
::class,
300 'rapsys_pack.slugger_util' => SluggerUtil
::class,
301 'request_stack' => RequestStack
::class,
302 'router' => RouterInterface
::class,
303 'security.user_password_hasher' => UserPasswordHasherInterface
::class,
304 'translator' => TranslatorInterface
::class