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