]> Raphaƫl G. Git Repositories - userbundle/blob - Handler/LogoutSuccessHandler.php
57392ddfac6413e6cb57675078ccac22b1e2c1ac
[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\RequestContext;
10 use Symfony\Component\Routing\RouterInterface;
11 use Symfony\Component\Security\Http\Logout\DefaultLogoutSuccessHandler;
12
13 use Rapsys\UserBundle\RapsysUserBundle;
14
15 /**
16 * {@inheritdoc}
17 */
18 class LogoutSuccessHandler extends DefaultLogoutSuccessHandler {
19 /**
20 * Config array
21 */
22 protected $config;
23
24 /**
25 * {@inheritdoc}
26 */
27 protected $router;
28
29 /**
30 * {@inheritdoc}
31 */
32 protected $targetUrl;
33
34 /**
35 * {@inheritdoc}
36 */
37 public function __construct(ContainerInterface $container, string $targetUrl = '/', RouterInterface $router) {
38 //Set config
39 $this->config = $container->getParameter(self::getAlias());
40
41 //Set target url
42 $this->targetUrl = $targetUrl;
43
44 //Set router
45 $this->router = $router;
46 }
47
48 /**
49 * {@inheritdoc}
50 */
51 public function onLogoutSuccess(Request $request) {
52 //Retrieve logout route
53 $logout = $request->get('_route');
54
55 //Extract and process referer
56 if (($referer = $request->headers->get('referer'))) {
57 //Create referer request instance
58 $req = Request::create($referer);
59
60 //Get referer path
61 $path = $req->getPathInfo();
62
63 //Get referer query string
64 $query = $req->getQueryString();
65
66 //Remove script name
67 $path = str_replace($request->getScriptName(), '', $path);
68
69 //Try with referer path
70 try {
71 //Save old context
72 $oldContext = $this->router->getContext();
73
74 //Force clean context
75 //XXX: prevent MethodNotAllowedException on GET only routes because our context method is POST
76 //XXX: see vendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php +42
77 $this->router->setContext(new RequestContext());
78
79 //Retrieve route matching path
80 $route = $this->router->match($path);
81
82 //Reset context
83 $this->router->setContext($oldContext);
84
85 //Clear old context
86 unset($oldContext);
87
88 //Without logout route name
89 if (($name = $route['_route']) != $logout) {
90 //Remove route and controller from route defaults
91 unset($route['_route'], $route['_controller'], $route['_canonical_route']);
92
93 //Generate url
94 $url = $this->router->generate($name, $route);
95
96 //Return generated route
97 return new RedirectResponse($url, 302);
98 //With logout route name
99 } else {
100 //Unset referer and route
101 unset($referer, $route);
102 }
103 //No route matched
104 } catch (ResourceNotFoundException $e) {
105 //Unset referer and route
106 unset($referer, $route);
107 }
108 }
109
110 //With index route from config
111 if (!empty($name = $this->config['route']['index']['name']) && is_array($context = $this->config['route']['index']['context'])) {
112 //Without logout route name
113 if (($name = $route['_route']) != $logout) {
114 //Try index route
115 try {
116 //Generate url
117 $url = $this->router->generate($name, $context);
118
119 //Return generated route
120 return new RedirectResponse($url, 302);
121 //No route matched
122 } catch (ResourceNotFoundException $e) {
123 //Unset name and context
124 unset($name, $context);
125 }
126 //With logout route name
127 } else {
128 //Unset name and context
129 unset($name, $context);
130 }
131 }
132
133 //Try target url
134 try {
135 //Save old context
136 $oldContext = $this->router->getContext();
137
138 //Force clean context
139 //XXX: prevent MethodNotAllowedException on GET only routes because our context method is POST
140 //XXX: see vendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php +42
141 $this->router->setContext(new RequestContext());
142
143 //Retrieve route matching target url
144 $route = $this->router->match($this->targetUrl);
145
146 //Reset context
147 $this->router->setContext($oldContext);
148
149 //Clear old context
150 unset($oldContext);
151
152 //Without logout route name
153 if (($name = $route['_route']) != $logout) {
154 //Remove route and controller from route defaults
155 unset($route['_route'], $route['_controller'], $route['_canonical_route']);
156
157 //Generate url
158 $url = $this->router->generate($name, $route);
159
160 //Return generated route
161 return new RedirectResponse($url, 302);
162 //With logout route name
163 } else {
164 //Unset name and route
165 unset($name, $route);
166 }
167 //Get first route from route collection if / path was not matched
168 } catch (ResourceNotFoundException $e) {
169 //Unset name and route
170 unset($name, $route);
171 }
172
173 //Throw exception
174 throw new \RuntimeException('You must provide a valid logout target url or route name');
175 }
176
177 /**
178 * {@inheritdoc}
179 */
180 public function getAlias(): string {
181 return RapsysUserBundle::getAlias();
182 }
183 }