--- /dev/null
+<?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);
+ }
+}