From: Raphaël Gertz <git@rapsys.eu>
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?ds=inline

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 @@
+<?php declare(strict_types=1);
+
+/*
+ * This file is part of the Rapsys UserBundle package.
+ *
+ * (c) Raphaël Gertz <symfony@rapsys.eu>
+ *
+ * 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
+		];
+	}
+}