14
14
use Symfony \Component \DependencyInjection \ContainerInterface ;
15
15
use Symfony \Component \Form \Extension \Csrf \CsrfProvider \CsrfProviderAdapter ;
16
16
use Symfony \Component \Form \Extension \Csrf \CsrfProvider \CsrfProviderInterface ;
17
+ use Symfony \Component \HttpFoundation \RequestStack ;
17
18
use Symfony \Component \Routing \Generator \UrlGeneratorInterface ;
19
+ use Symfony \Component \Security \Core \Authentication \Token \Storage \TokenStorageInterface ;
18
20
use Symfony \Component \Security \Csrf \CsrfTokenManagerInterface ;
19
21
use Symfony \Component \Templating \Helper \Helper ;
20
22
25
27
*/
26
28
class LogoutUrlHelper extends Helper
27
29
{
28
- private $ container ;
30
+ private $ requestStack ;
29
31
private $ listeners = array ();
30
32
private $ router ;
33
+ private $ tokenStorage ;
31
34
32
35
/**
33
36
* Constructor.
34
37
*
35
- * @param ContainerInterface $container A ContainerInterface instance
36
- * @param UrlGeneratorInterface $router A Router instance
38
+ * @param ContainerInterface|RequestStack $requestStack A ContainerInterface instance or RequestStack
39
+ * @param UrlGeneratorInterface $router The router service
40
+ * @param TokenStorageInterface|null $tokenStorage The token storage service
41
+ *
42
+ * @deprecated Passing a ContainerInterface as a first argument is deprecated since 2.7 and will be removed in 3.0.
37
43
*/
38
- public function __construct (ContainerInterface $ container , UrlGeneratorInterface $ router )
44
+ public function __construct ($ requestStack , UrlGeneratorInterface $ router, TokenStorageInterface $ tokenStorage = null )
39
45
{
40
- $ this ->container = $ container ;
46
+ if ($ requestStack instanceof ContainerInterface) {
47
+ $ this ->requestStack = $ requestStack ->get ('request_stack ' );
48
+ trigger_error ('The ' .__CLASS__ .' constructor will require a RequestStack instead of a ContainerInterface instance in 3.0. ' , E_USER_DEPRECATED );
49
+ } elseif ($ requestStack instanceof RequestStack) {
50
+ $ this ->requestStack = $ requestStack ;
51
+ } else {
52
+ throw new \InvalidArgumentException (sprintf ('%s takes either a RequestStack or a ContainerInterface object as its first argument. ' , __METHOD__ ));
53
+ }
54
+
41
55
$ this ->router = $ router ;
56
+ $ this ->tokenStorage = $ tokenStorage ;
42
57
}
43
58
44
59
/**
@@ -64,7 +79,7 @@ public function registerListener($key, $logoutPath, $csrfTokenId, $csrfParameter
64
79
/**
65
80
* Generates the absolute logout path for the firewall.
66
81
*
67
- * @param string $key The firewall key
82
+ * @param string|null $key The firewall key or null to use the current firewall key
68
83
*
69
84
* @return string The logout path
70
85
*/
@@ -76,7 +91,7 @@ public function getLogoutPath($key)
76
91
/**
77
92
* Generates the absolute logout URL for the firewall.
78
93
*
79
- * @param string $key The firewall key
94
+ * @param string|null $key The firewall key or null to use the current firewall key
80
95
*
81
96
* @return string The logout URL
82
97
*/
@@ -88,15 +103,27 @@ public function getLogoutUrl($key)
88
103
/**
89
104
* Generates the logout URL for the firewall.
90
105
*
91
- * @param string $key The firewall key
106
+ * @param string|null $key The firewall key or null to use the current firewall key
92
107
* @param bool|string $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
93
108
*
94
109
* @return string The logout URL
95
110
*
96
- * @throws \InvalidArgumentException if no LogoutListener is registered for the key
111
+ * @throws \InvalidArgumentException if no LogoutListener is registered for the key or the key could not be found automatically.
97
112
*/
98
113
private function generateLogoutUrl ($ key , $ referenceType )
99
114
{
115
+ // Fetch the current provider key from token, if possible
116
+ if (null === $ key && null !== $ this ->tokenStorage ) {
117
+ $ token = $ this ->tokenStorage ->getToken ();
118
+ if (null !== $ token && method_exists ($ token , 'getProviderKey ' )) {
119
+ $ key = $ token ->getProviderKey ();
120
+ }
121
+ }
122
+
123
+ if (null === $ key ) {
124
+ throw new \InvalidArgumentException ('Unable to find the current firewall LogoutListener, please provide the provider key manually. ' );
125
+ }
126
+
100
127
if (!array_key_exists ($ key , $ this ->listeners )) {
101
128
throw new \InvalidArgumentException (sprintf ('No LogoutListener found for firewall key "%s". ' , $ key ));
102
129
}
@@ -106,7 +133,7 @@ private function generateLogoutUrl($key, $referenceType)
106
133
$ parameters = null !== $ csrfTokenManager ? array ($ csrfParameter => (string ) $ csrfTokenManager ->getToken ($ csrfTokenId )) : array ();
107
134
108
135
if ('/ ' === $ logoutPath [0 ]) {
109
- $ request = $ this ->container -> get ( ' request_stack ' ) ->getCurrentRequest ();
136
+ $ request = $ this ->requestStack ->getCurrentRequest ();
110
137
111
138
$ url = UrlGeneratorInterface::ABSOLUTE_URL === $ referenceType ? $ request ->getUriForPath ($ logoutPath ) : $ request ->getBasePath ().$ logoutPath ;
112
139
0 commit comments