From: Raphaël Gertz Date: Mon, 23 Aug 2021 07:24:30 +0000 (+0200) Subject: Add user abstract controller X-Git-Tag: 0.2.0~38 X-Git-Url: https://git.rapsys.eu/userbundle/commitdiff_plain/07387af34cc2555bf0f626622b9baf405680b7df?hp=ea9b00a8025f8bbe7a1c28399f7538bea6d60a2c Add user abstract controller --- diff --git a/Controller/AbstractController.php b/Controller/AbstractController.php new file mode 100644 index 0000000..c296903 --- /dev/null +++ b/Controller/AbstractController.php @@ -0,0 +1,265 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Rapsys\UserBundle\Controller; + +use Psr\Log\LoggerInterface; +use Symfony\Bundle\FrameworkBundle\Controller\AbstractController as BaseAbstractController; +use Symfony\Bundle\FrameworkBundle\Controller\ControllerTrait; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Symfony\Component\Routing\RouterInterface; +use Symfony\Component\Translation\TranslatorInterface; +use Symfony\Contracts\Service\ServiceSubscriberInterface; + +use Rapsys\UserBundle\RapsysUserBundle; + +/** + * Provides common features needed in controllers. + * + * {@inheritdoc} + */ +abstract class AbstractController extends BaseAbstractController implements ServiceSubscriberInterface { + use ControllerTrait { + //Rename render as baseRender + render as protected baseRender; + } + + ///Config array + protected $config; + + ///ContainerInterface instance + protected $container; + + ///Context array + protected $context; + + ///Router instance + protected $router; + + ///Translator instance + protected $translator; + + ///Locale + protected $locale; + + /** + * Common constructor + * + * Stores container, router and translator interfaces + * Stores config + * Prepares context tree + * + * @param ContainerInterface $container The container instance + */ + public function __construct(ContainerInterface $container) { + //Retrieve config + $this->config = $container->getParameter(RapsysUserBundle::getAlias()); + + //Set the container + $this->container = $container; + + //Set the router + $this->router = $container->get('router'); + + //Set the translator + $this->translator = $container->get('translator'); + + //Get request stack + $stack = $this->container->get('request_stack'); + + //Get current request + $request = $stack->getCurrentRequest(); + + //Get current locale + $this->locale = $request->getLocale(); + + //Set locale + $this->config['context']['locale'] = str_replace('_', '-', $this->locale); + + //Set translate array + $translates = []; + + //Look for keys to translate + if (!empty($this->config['translate'])) { + //Iterate on keys to translate + foreach($this->config['translate'] as $translate) { + //Set tmp + $tmp = null; + //Iterate on keys + foreach(array_reverse(explode('.', $translate)) as $curkey) { + $tmp = array_combine([$curkey], [$tmp]); + } + //Append tree + $translates = array_replace_recursive($translates, $tmp); + } + } + + //Inject every requested route in view and mail context + foreach($this->config as $tag => $current) { + //Look for entry with title subkey + if (!empty($current['title'])) { + //Translate title value + $this->config[$tag]['title'] = $this->translator->trans($current['title']); + } + + //Look for entry with route subkey + if (!empty($current['route'])) { + //Generate url for both view and mail + foreach(['view', 'mail'] as $view) { + //Check that context key is usable + if (isset($current[$view]['context']) && is_array($current[$view]['context'])) { + //Merge with global context + $this->config[$tag][$view]['context'] = array_replace_recursive($this->config['context'], $this->config[$tag][$view]['context']); + + //Process every routes + foreach($current['route'] as $route => $key) { + //With confirm route + if ($route == 'confirm') { + //Skip route as it requires some parameters + continue; + } + + //Set value + $value = $this->router->generate( + $this->config['route'][$route]['name'], + $this->config['route'][$route]['context'], + //Generate absolute url for mails + $view=='mail'?UrlGeneratorInterface::ABSOLUTE_URL:UrlGeneratorInterface::ABSOLUTE_PATH + ); + + //Multi level key + if (strpos($key, '.') !== false) { + //Set tmp + $tmp = $value; + + //Iterate on key + foreach(array_reverse(explode('.', $key)) as $curkey) { + $tmp = array_combine([$curkey], [$tmp]); + } + + //Set value + $this->config[$tag][$view]['context'] = array_replace_recursive($this->config[$tag][$view]['context'], $tmp); + //Single level key + } else { + //Set value + $this->config[$tag][$view]['context'][$key] = $value; + } + } + + //Look for successful intersections + if (!empty(array_intersect_key($translates, $this->config[$tag][$view]['context']))) { + //Iterate on keys to translate + foreach($this->config['translate'] as $translate) { + //Set keys + $keys = explode('.', $translate); + + //Set tmp + $tmp = $this->config[$tag][$view]['context']; + + //Iterate on keys + foreach($keys as $curkey) { + //Without child key + if (!isset($tmp[$curkey])) { + //Skip to next key + continue(2); + } + + //Get child key + $tmp = $tmp[$curkey]; + } + + //Translate tmp value + $tmp = $this->translator->trans($tmp); + + //Iterate on keys + foreach(array_reverse($keys) as $curkey) { + //Set parent key + $tmp = array_combine([$curkey], [$tmp]); + } + + //Set value + $this->config[$tag][$view]['context'] = array_replace_recursive($this->config[$tag][$view]['context'], $tmp); + } + } + + //With view context + if ($view == 'view') { + //Get context path + $pathInfo = $this->router->getContext()->getPathInfo(); + + //Iterate on locales excluding current one + foreach($this->config['locales'] as $locale) { + //Set titles + $titles = []; + + //Iterate on other locales + foreach(array_diff($this->config['locales'], [$locale]) as $other) { + $titles[$other] = $this->translator->trans($this->config['languages'][$locale], [], null, $other); + } + + //Retrieve route matching path + $route = $this->router->match($pathInfo); + + //Get route name + $name = $route['_route']; + + //Unset route name + unset($route['_route']); + + //With current locale + if ($locale == $this->locale) { + //Set locale locales context + $this->config[$tag][$view]['context']['canonical'] = $this->router->generate($name, ['_locale' => $locale]+$route, UrlGeneratorInterface::ABSOLUTE_URL); + } else { + //Set locale locales context + $this->config[$tag][$view]['context']['alternates'][$locale] = [ + 'absolute' => $this->router->generate($name, ['_locale' => $locale]+$route, UrlGeneratorInterface::ABSOLUTE_URL), + 'relative' => $this->router->generate($name, ['_locale' => $locale]+$route), + 'title' => implode('/', $titles), + 'translated' => $this->translator->trans($this->config['languages'][$locale], [], null, $locale) + ]; + } + + //Add shorter locale + if (empty($this->config[$tag][$view]['context']['alternates'][$slocale = substr($locale, 0, 2)])) { + //Add shorter locale + $this->config[$tag][$view]['context']['alternates'][$slocale] = [ + 'absolute' => $this->router->generate($name, ['_locale' => $locale]+$route, UrlGeneratorInterface::ABSOLUTE_URL), + 'relative' => $this->router->generate($name, ['_locale' => $locale]+$route), + 'title' => implode('/', $titles), + 'translated' => $this->translator->trans($this->config['languages'][$locale], [], null, $locale) + ]; + } + } + } + } + } + } + } + } + + /** + * {@inheritdoc} + * + * @see vendor/symfony/framework-bundle/Controller/AbstractController.php + */ + public static function getSubscribedServices(): array { + //Return subscribed services + return [ + 'logger' => LoggerInterface::class, + 'request_stack' => RequestStack::class, + 'router' => RouterInterface::class, + 'translator' => TranslatorInterface::class + ]; + } +}