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