From b9e5d850a839448a7ffdc1ffcbbe5ae0e24d0428 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rapha=C3=ABl=20Gertz?= Date: Wed, 11 Aug 2021 20:37:54 +0200 Subject: [PATCH] Add LogoutSuccessHandler --- Handler/LogoutSuccessHandler.php | 126 +++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 Handler/LogoutSuccessHandler.php diff --git a/Handler/LogoutSuccessHandler.php b/Handler/LogoutSuccessHandler.php new file mode 100644 index 0000000..34a7b08 --- /dev/null +++ b/Handler/LogoutSuccessHandler.php @@ -0,0 +1,126 @@ +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); + } +} -- 2.41.1