]> Raphaël G. Git Repositories - userbundle/commitdiff
Add LogoutSuccessHandler
authorRaphaël Gertz <git@rapsys.eu>
Wed, 11 Aug 2021 18:37:54 +0000 (20:37 +0200)
committerRaphaël Gertz <git@rapsys.eu>
Wed, 11 Aug 2021 18:37:54 +0000 (20:37 +0200)
Handler/LogoutSuccessHandler.php [new file with mode: 0644]

diff --git a/Handler/LogoutSuccessHandler.php b/Handler/LogoutSuccessHandler.php
new file mode 100644 (file)
index 0000000..34a7b08
--- /dev/null
@@ -0,0 +1,126 @@
+<?php
+
+namespace Rapsys\UserBundle\Handler;
+
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Exception\ResourceNotFoundException;
+use Symfony\Component\Routing\RouterInterface;
+use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
+
+class LogoutSuccessHandler implements LogoutSuccessHandlerInterface {
+       /**
+        * {@inheritdoc}
+        */
+       protected $container;
+
+       /**
+        * {@inheritdoc}
+        */
+       protected $router;
+
+       /**
+        * {@inheritdoc}
+        */
+       public function __construct(ContainerInterface $container, RouterInterface $router) {
+               $this->container = $container;
+               $this->router = $router;
+       }
+
+       /**
+        * {@inheritdoc}
+        */
+       public function onLogoutSuccess(Request $request) {
+               //Retrieve logout route
+               $logout = $request->get('_route');
+
+               //Extract and process referer
+               if ($referer = $request->headers->get('referer')) {
+                       //Create referer request instance
+                       $req = Request::create($referer);
+
+                       //Get referer path
+                       $path = $req->getPathInfo();
+
+                       //Get referer query string
+                       $query = $req->getQueryString();
+
+                       //Remove script name
+                       $path = str_replace($request->getScriptName(), '', $path);
+
+                       //Try with referer path
+                       try {
+                               //Retrieve route matching path
+                               $route = $this->router->match($path);
+
+                               //With router differing from logout one
+                               if (($name = $route['_route']) == $logout) {
+                                       #throw new ResourceNotFoundException('Identical referer and logout route');
+                                       //Unset referer to fallback to default route
+                                       unset($referer);
+                               //With route matching logout
+                               } else {
+                                       //Remove route and controller from route defaults
+                                       unset($route['_route'], $route['_controller'], $route['_canonical_route']);
+
+                                       //Generate url
+                                       $url = $this->router->generate($name, $route);
+                               }
+                       //No route matched
+                       } catch (ResourceNotFoundException $e) {
+                               //Unset referer to fallback to default route
+                               unset($referer);
+                       }
+               }
+
+               //Referer empty or unusable
+               if (empty($referer)) {
+                       //Try with / path
+                       try {
+                               //Retrieve route matching /
+                               $route = $this->router->match('/');
+
+                               //Verify that it differ from current one
+                               if (($name = $route['_route']) == $logout) {
+                                       throw new ResourceNotFoundException('Identical referer and logout route');
+                               }
+
+                               //Remove route and controller from route defaults
+                               unset($route['_route'], $route['_controller'], $route['_canonical_route']);
+
+                               //Generate url
+                               $url = $this->router->generate($name, $route);
+                       //Get first route from route collection if / path was not matched
+                       } catch (ResourceNotFoundException $e) {
+                               //Fetch all routes
+                               //XXX: this method regenerate the Routing cache making apps very slow
+                               //XXX: see https://github.com/symfony/symfony-docs/issues/6710
+                               //XXX: it should be fine to call it without referer and a / route
+                               foreach ($this->router->getRouteCollection() as $name => $route) {
+                                       //Return on first public route excluding logout one
+                                       if (!empty($name) && $name[0] != '_' && $name != $logout) {
+                                               break;
+                                       }
+                               }
+
+                               //Bail out if no route found
+                               if (!isset($name) || !isset($route)) {
+                                       throw new \RuntimeException('Unable to retrieve default route');
+                               }
+
+                               //Retrieve route defaults
+                               $defaults = $route->getDefaults();
+
+                               //Remove route and controller from route defaults
+                               unset($defaults['_route'], $defaults['_controller'], $defaults['_canonical_route']);
+
+                               //Generate url
+                               $url = $this->router->generate($name, $defaults);
+                       }
+               }
+
+               //Return redirect response
+               return new RedirectResponse($url, 302);
+       }
+}