1 <?php
declare(strict_types
=1);
4 * This file is part of the Rapsys UserBundle package.
6 * (c) Raphaël Gertz <symfony@rapsys.eu>
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
12 namespace Rapsys\UserBundle\Handler
;
14 use Symfony\Component\DependencyInjection\ContainerInterface
;
15 use Symfony\Component\HttpFoundation\RedirectResponse
;
16 use Symfony\Component\HttpFoundation\Request
;
17 use Symfony\Component\HttpFoundation\Response
;
18 use Symfony\Component\Routing\Exception\ResourceNotFoundException
;
19 use Symfony\Component\Routing\RequestContext
;
20 use Symfony\Component\Routing\RouterInterface
;
21 use Symfony\Component\Security\Http\Logout\DefaultLogoutSuccessHandler
;
23 use Rapsys\UserBundle\RapsysUserBundle
;
28 class LogoutSuccessHandler
extends DefaultLogoutSuccessHandler
{
45 * @xxx Second argument will be replaced by security.firewalls.main.logout.target
46 * @see vendor/symfony/security-bundle/DependencyInjection/SecurityExtension.php +360
50 public function __construct(ContainerInterface
$container, string $targetUrl, RouterInterface
$router) {
52 $this->config
= $container->getParameter(self
::getAlias());
55 $this->targetUrl
= $targetUrl;
58 $this->router
= $router;
64 public function onLogoutSuccess(Request
$request): Response
{
65 //Retrieve logout route
66 $logout = $request->get('_route');
68 //Extract and process referer
69 if (($referer = $request->headers
->get('referer'))) {
70 //Create referer request instance
71 $req = Request
::create($referer);
74 $path = $req->getPathInfo();
76 //Get referer query string
77 $query = $req->getQueryString();
80 $path = str_replace($request->getScriptName(), '', $path);
82 //Try with referer path
85 $oldContext = $this->router
->getContext();
88 //XXX: prevent MethodNotAllowedException on GET only routes because our context method is POST
89 //XXX: see vendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php +42
90 $this->router
->setContext(new RequestContext());
92 //Retrieve route matching path
93 $route = $this->router
->match($path);
96 $this->router
->setContext($oldContext);
101 //Without logout route name
102 if (($name = $route['_route']) != $logout) {
103 //Remove route and controller from route defaults
104 unset($route['_route'], $route['_controller'], $route['_canonical_route']);
107 $url = $this->router
->generate($name, $route);
109 //Return generated route
110 return new RedirectResponse($url, 302);
111 //With logout route name
113 //Unset referer and route
114 unset($referer, $route);
117 } catch (ResourceNotFoundException
$e) {
118 //Unset referer and route
119 unset($referer, $route);
123 //With index route from config
124 if (!empty($name = $this->config
['route']['index']['name']) && is_array($context = $this->config
['route']['index']['context'])) {
125 //Without logout route name
126 if ($name != $logout) {
130 $url = $this->router
->generate($name, $context);
132 //Return generated route
133 return new RedirectResponse($url, 302);
135 } catch (ResourceNotFoundException
$e) {
136 //Unset name and context
137 unset($name, $context);
139 //With logout route name
141 //Unset name and context
142 unset($name, $context);
149 $oldContext = $this->router
->getContext();
151 //Force clean context
152 //XXX: prevent MethodNotAllowedException on GET only routes because our context method is POST
153 //XXX: see vendor/symfony/routing/Matcher/Dumper/CompiledUrlMatcherTrait.php +42
154 $this->router
->setContext(new RequestContext());
156 //Retrieve route matching target url
157 $route = $this->router
->match($this->targetUrl
);
160 $this->router
->setContext($oldContext);
165 //Without logout route name
166 if (($name = $route['_route']) != $logout) {
167 //Remove route and controller from route defaults
168 unset($route['_route'], $route['_controller'], $route['_canonical_route']);
171 $url = $this->router
->generate($name, $route);
173 //Return generated route
174 return new RedirectResponse($url, 302);
175 //With logout route name
177 //Unset name and route
178 unset($name, $route);
180 //Get first route from route collection if / path was not matched
181 } catch (ResourceNotFoundException
$e) {
182 //Unset name and route
183 unset($name, $route);
187 throw new \
RuntimeException('You must provide a valid logout target url or route name');
193 public function getAlias(): string {
194 return RapsysUserBundle
::getAlias();