]> Raphaƫl G. Git Repositories - userbundle/blob - Handler/LogoutSuccessHandler.php
Set civility as optional
[userbundle] / Handler / LogoutSuccessHandler.php
1 <?php
2
3 namespace Rapsys\UserBundle\Handler;
4
5 use Symfony\Component\DependencyInjection\ContainerInterface;
6 use Symfony\Component\HttpFoundation\RedirectResponse;
7 use Symfony\Component\HttpFoundation\Request;
8 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
9 use Symfony\Component\Routing\RouterInterface;
10 use Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface;
11
12 class LogoutSuccessHandler implements LogoutSuccessHandlerInterface {
13 /**
14 * {@inheritdoc}
15 */
16 protected $container;
17
18 /**
19 * {@inheritdoc}
20 */
21 protected $router;
22
23 /**
24 * {@inheritdoc}
25 */
26 public function __construct(ContainerInterface $container, RouterInterface $router) {
27 $this->container = $container;
28 $this->router = $router;
29 }
30
31 /**
32 * {@inheritdoc}
33 */
34 public function onLogoutSuccess(Request $request) {
35 //Retrieve logout route
36 $logout = $request->get('_route');
37
38 //Extract and process referer
39 if ($referer = $request->headers->get('referer')) {
40 //Create referer request instance
41 $req = Request::create($referer);
42
43 //Get referer path
44 $path = $req->getPathInfo();
45
46 //Get referer query string
47 $query = $req->getQueryString();
48
49 //Remove script name
50 $path = str_replace($request->getScriptName(), '', $path);
51
52 //Try with referer path
53 try {
54 //Retrieve route matching path
55 $route = $this->router->match($path);
56
57 //With router differing from logout one
58 if (($name = $route['_route']) == $logout) {
59 #throw new ResourceNotFoundException('Identical referer and logout route');
60 //Unset referer to fallback to default route
61 unset($referer);
62 //With route matching logout
63 } else {
64 //Remove route and controller from route defaults
65 unset($route['_route'], $route['_controller'], $route['_canonical_route']);
66
67 //Generate url
68 $url = $this->router->generate($name, $route);
69 }
70 //No route matched
71 } catch (ResourceNotFoundException $e) {
72 //Unset referer to fallback to default route
73 unset($referer);
74 }
75 }
76
77 //Referer empty or unusable
78 if (empty($referer)) {
79 //Try with / path
80 try {
81 //Retrieve route matching /
82 $route = $this->router->match('/');
83
84 //Verify that it differ from current one
85 if (($name = $route['_route']) == $logout) {
86 throw new ResourceNotFoundException('Identical referer and logout route');
87 }
88
89 //Remove route and controller from route defaults
90 unset($route['_route'], $route['_controller'], $route['_canonical_route']);
91
92 //Generate url
93 $url = $this->router->generate($name, $route);
94 //Get first route from route collection if / path was not matched
95 } catch (ResourceNotFoundException $e) {
96 //Fetch all routes
97 //XXX: this method regenerate the Routing cache making apps very slow
98 //XXX: see https://github.com/symfony/symfony-docs/issues/6710
99 //XXX: it should be fine to call it without referer and a / route
100 foreach ($this->router->getRouteCollection() as $name => $route) {
101 //Return on first public route excluding logout one
102 if (!empty($name) && $name[0] != '_' && $name != $logout) {
103 break;
104 }
105 }
106
107 //Bail out if no route found
108 if (!isset($name) || !isset($route)) {
109 throw new \RuntimeException('Unable to retrieve default route');
110 }
111
112 //Retrieve route defaults
113 $defaults = $route->getDefaults();
114
115 //Remove route and controller from route defaults
116 unset($defaults['_route'], $defaults['_controller'], $defaults['_canonical_route']);
117
118 //Generate url
119 $url = $this->router->generate($name, $defaults);
120 }
121 }
122
123 //Return redirect response
124 return new RedirectResponse($url, 302);
125 }
126 }