Skip to content

Commit 312c8a5

Browse files
authored
Merge pull request #3020 from stof/symfony_5
Add support for Symfony 5
2 parents d3a1a8b + 1af6015 commit 312c8a5

36 files changed

+149
-186
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Changelog
88
* [BC break] Change the base class for events to `Symfony\Contracts\EventDispatcher\Event` instead of `Symfony\Component\EventDispatcher\Event`
99
* [BC break] Remove the `Symfony\Component\Security\Core\User\AdvancedUserInterface` methods from our `UserInterface`
1010
* [BC break] Made `\FOS\UserBundle\Model\User::serialize` and `\FOS\UserBundle\Model\User::unserialize` final. Child classes needing to extend the serialization must override `__serialize` and `__unserialize` instead.
11+
* Add support for Symfony 5.
1112

1213
### 2.2.0 (2021-08-26)
1314

CompatibilityUtil.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the FOSUserBundle package.
5+
*
6+
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace FOS\UserBundle;
13+
14+
use Symfony\Component\EventDispatcher\GenericEvent;
15+
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
16+
use Symfony\Contracts\EventDispatcher\Event;
17+
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
18+
19+
/**
20+
* @internal
21+
*/
22+
final class CompatibilityUtil
23+
{
24+
public static function upgradeEventDispatcher(EventDispatcherInterface $eventDispatcher): EventDispatcherInterface
25+
{
26+
// On Symfony 5.0+, the legacy proxy is a no-op and it is deprecated in 5.1+
27+
// Detecting the parent class of GenericEvent (which changed in 5.0) allows to avoid using the deprecated no-op API.
28+
if (is_subclass_of(GenericEvent::class, Event::class)) {
29+
return $eventDispatcher;
30+
}
31+
32+
// BC layer for Symfony 4.4 where we need to apply the decorating proxy in case of non-upgraded dispatcher.
33+
return LegacyEventDispatcherProxy::decorate($eventDispatcher);
34+
}
35+
}

Controller/ChangePasswordController.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace FOS\UserBundle\Controller;
1313

14+
use FOS\UserBundle\CompatibilityUtil;
1415
use FOS\UserBundle\Event\FilterUserResponseEvent;
1516
use FOS\UserBundle\Event\FormEvent;
1617
use FOS\UserBundle\Event\GetResponseUserEvent;
@@ -19,12 +20,11 @@
1920
use FOS\UserBundle\Model\UserInterface;
2021
use FOS\UserBundle\Model\UserManagerInterface;
2122
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
22-
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
23-
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
2423
use Symfony\Component\HttpFoundation\RedirectResponse;
2524
use Symfony\Component\HttpFoundation\Request;
2625
use Symfony\Component\HttpFoundation\Response;
2726
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
27+
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
2828

2929
/**
3030
* Controller managing the password change.
@@ -42,7 +42,7 @@ class ChangePasswordController extends AbstractController
4242

4343
public function __construct(EventDispatcherInterface $eventDispatcher, FactoryInterface $formFactory, UserManagerInterface $userManager)
4444
{
45-
$this->eventDispatcher = LegacyEventDispatcherProxy::decorate($eventDispatcher);
45+
$this->eventDispatcher = CompatibilityUtil::upgradeEventDispatcher($eventDispatcher);
4646
$this->formFactory = $formFactory;
4747
$this->userManager = $userManager;
4848
}

Controller/ProfileController.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace FOS\UserBundle\Controller;
1313

14+
use FOS\UserBundle\CompatibilityUtil;
1415
use FOS\UserBundle\Event\FilterUserResponseEvent;
1516
use FOS\UserBundle\Event\FormEvent;
1617
use FOS\UserBundle\Event\GetResponseUserEvent;
@@ -19,12 +20,11 @@
1920
use FOS\UserBundle\Model\UserInterface;
2021
use FOS\UserBundle\Model\UserManagerInterface;
2122
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
22-
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
23-
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
2423
use Symfony\Component\HttpFoundation\RedirectResponse;
2524
use Symfony\Component\HttpFoundation\Request;
2625
use Symfony\Component\HttpFoundation\Response;
2726
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
27+
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
2828

2929
/**
3030
* Controller managing the user profile.
@@ -41,7 +41,7 @@ class ProfileController extends AbstractController
4141

4242
public function __construct(EventDispatcherInterface $eventDispatcher, FactoryInterface $formFactory, UserManagerInterface $userManager)
4343
{
44-
$this->eventDispatcher = LegacyEventDispatcherProxy::decorate($eventDispatcher);
44+
$this->eventDispatcher = CompatibilityUtil::upgradeEventDispatcher($eventDispatcher);
4545
$this->formFactory = $formFactory;
4646
$this->userManager = $userManager;
4747
}

Controller/RegistrationController.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace FOS\UserBundle\Controller;
1313

14+
use FOS\UserBundle\CompatibilityUtil;
1415
use FOS\UserBundle\Event\FilterUserResponseEvent;
1516
use FOS\UserBundle\Event\FormEvent;
1617
use FOS\UserBundle\Event\GetResponseUserEvent;
@@ -19,14 +20,13 @@
1920
use FOS\UserBundle\Model\UserInterface;
2021
use FOS\UserBundle\Model\UserManagerInterface;
2122
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
22-
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
23-
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
2423
use Symfony\Component\HttpFoundation\RedirectResponse;
2524
use Symfony\Component\HttpFoundation\Request;
2625
use Symfony\Component\HttpFoundation\Response;
2726
use Symfony\Component\HttpFoundation\Session\SessionInterface;
2827
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
2928
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
29+
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
3030

3131
/**
3232
* Controller managing the registration.
@@ -45,7 +45,7 @@ class RegistrationController extends AbstractController
4545

4646
public function __construct(EventDispatcherInterface $eventDispatcher, FactoryInterface $formFactory, UserManagerInterface $userManager, TokenStorageInterface $tokenStorage)
4747
{
48-
$this->eventDispatcher = LegacyEventDispatcherProxy::decorate($eventDispatcher);
48+
$this->eventDispatcher = CompatibilityUtil::upgradeEventDispatcher($eventDispatcher);
4949
$this->formFactory = $formFactory;
5050
$this->userManager = $userManager;
5151
$this->tokenStorage = $tokenStorage;

Controller/ResettingController.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace FOS\UserBundle\Controller;
1313

14+
use FOS\UserBundle\CompatibilityUtil;
1415
use FOS\UserBundle\Event\FilterUserResponseEvent;
1516
use FOS\UserBundle\Event\FormEvent;
1617
use FOS\UserBundle\Event\GetResponseNullableUserEvent;
@@ -21,11 +22,10 @@
2122
use FOS\UserBundle\Model\UserManagerInterface;
2223
use FOS\UserBundle\Util\TokenGeneratorInterface;
2324
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
24-
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
25-
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
2625
use Symfony\Component\HttpFoundation\RedirectResponse;
2726
use Symfony\Component\HttpFoundation\Request;
2827
use Symfony\Component\HttpFoundation\Response;
28+
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
2929

3030
/**
3131
* Controller managing the resetting of the password.
@@ -53,7 +53,7 @@ class ResettingController extends AbstractController
5353
*/
5454
public function __construct(EventDispatcherInterface $eventDispatcher, FactoryInterface $formFactory, UserManagerInterface $userManager, TokenGeneratorInterface $tokenGenerator, MailerInterface $mailer, $retryTtl)
5555
{
56-
$this->eventDispatcher = LegacyEventDispatcherProxy::decorate($eventDispatcher);
56+
$this->eventDispatcher = CompatibilityUtil::upgradeEventDispatcher($eventDispatcher);
5757
$this->formFactory = $formFactory;
5858
$this->userManager = $userManager;
5959
$this->tokenGenerator = $tokenGenerator;

Controller/SecurityController.php

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,9 @@
1212
namespace FOS\UserBundle\Controller;
1313

1414
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
15-
use Symfony\Component\HttpFoundation\Request;
1615
use Symfony\Component\HttpFoundation\Response;
17-
use Symfony\Component\HttpFoundation\Session\Session;
18-
use Symfony\Component\Security\Core\Exception\AuthenticationException;
19-
use Symfony\Component\Security\Core\Security;
2016
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
17+
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
2118

2219
/**
2320
* Controller managing security.
@@ -29,40 +26,22 @@
2926
*/
3027
class SecurityController extends AbstractController
3128
{
29+
private $authenticationUtils;
3230
private $tokenManager;
3331

34-
public function __construct(CsrfTokenManagerInterface $tokenManager = null)
32+
public function __construct(AuthenticationUtils $authenticationUtils, CsrfTokenManagerInterface $tokenManager = null)
3533
{
34+
$this->authenticationUtils = $authenticationUtils;
3635
$this->tokenManager = $tokenManager;
3736
}
3837

3938
/**
4039
* @return Response
4140
*/
42-
public function loginAction(Request $request)
41+
public function loginAction()
4342
{
44-
/** @var $session Session */
45-
$session = $request->getSession();
46-
47-
$authErrorKey = Security::AUTHENTICATION_ERROR;
48-
$lastUsernameKey = Security::LAST_USERNAME;
49-
50-
// get the error if any (works with forward and redirect -- see below)
51-
if ($request->attributes->has($authErrorKey)) {
52-
$error = $request->attributes->get($authErrorKey);
53-
} elseif (null !== $session && $session->has($authErrorKey)) {
54-
$error = $session->get($authErrorKey);
55-
$session->remove($authErrorKey);
56-
} else {
57-
$error = null;
58-
}
59-
60-
if (!$error instanceof AuthenticationException) {
61-
$error = null; // The value does not come from the security component.
62-
}
63-
64-
// last username entered by the user
65-
$lastUsername = (null === $session) ? '' : $session->get($lastUsernameKey);
43+
$error = $this->authenticationUtils->getLastAuthenticationError();
44+
$lastUsername = $this->authenticationUtils->getLastUsername();
6645

6746
$csrfToken = $this->tokenManager
6847
? $this->tokenManager->getToken('authenticate')->getValue()

DependencyInjection/Compiler/CheckForSessionPass.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ class CheckForSessionPass implements CompilerPassInterface
3030
*/
3131
public function process(ContainerBuilder $container)
3232
{
33-
if ($container->has('fos_user.session') && !$container->has('session')) {
34-
$message = 'FOSUserBundle requires the "session" service to be available.';
33+
if ($container->has('fos_user.session') && !$container->has('session.storage.factory') && !$container->has('session')) {
34+
$message = 'FOSUserBundle requires the "session" to be available for the enabled features.';
3535

3636
if (class_exists(Recipe::class)) {
3737
$message .= ' Uncomment the "session" section in "config/packages/framework.yaml" to activate it.';

EventListener/AuthenticationListener.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111

1212
namespace FOS\UserBundle\EventListener;
1313

14+
use FOS\UserBundle\CompatibilityUtil;
1415
use FOS\UserBundle\Event\FilterUserResponseEvent;
1516
use FOS\UserBundle\Event\UserEvent;
1617
use FOS\UserBundle\FOSUserEvents;
1718
use FOS\UserBundle\Security\LoginManagerInterface;
18-
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
1919
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
20-
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
2120
use Symfony\Component\Security\Core\Exception\AccountStatusException;
21+
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
2222

2323
/**
2424
* @internal
@@ -64,7 +64,7 @@ public static function getSubscribedEvents()
6464
*/
6565
public function authenticate(FilterUserResponseEvent $event, $eventName, EventDispatcherInterface $eventDispatcher)
6666
{
67-
$eventDispatcher = LegacyEventDispatcherProxy::decorate($eventDispatcher);
67+
$eventDispatcher = CompatibilityUtil::upgradeEventDispatcher($eventDispatcher);
6868
try {
6969
$this->loginManager->logInUser($this->firewallName, $event->getUser(), $event->getResponse());
7070

EventListener/FlashListener.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@
1313

1414
use FOS\UserBundle\FOSUserEvents;
1515
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
16-
use Symfony\Component\HttpFoundation\Session\SessionInterface;
17-
use Symfony\Component\Translation\TranslatorInterface;
16+
use Symfony\Component\HttpFoundation\RequestStack;
17+
use Symfony\Component\HttpFoundation\Session\Session;
1818
use Symfony\Contracts\EventDispatcher\Event;
19+
use Symfony\Contracts\Translation\TranslatorInterface;
1920

2021
/**
2122
* @internal
@@ -34,9 +35,9 @@ class FlashListener implements EventSubscriberInterface
3435
];
3536

3637
/**
37-
* @var SessionInterface
38+
* @var RequestStack
3839
*/
39-
private $session;
40+
private $requestStack;
4041

4142
/**
4243
* @var TranslatorInterface
@@ -46,10 +47,10 @@ class FlashListener implements EventSubscriberInterface
4647
/**
4748
* FlashListener constructor.
4849
*/
49-
public function __construct(SessionInterface $session, TranslatorInterface $translator)
50+
public function __construct(RequestStack $requestStack, TranslatorInterface $translator)
5051
{
51-
$this->session = $session;
5252
$this->translator = $translator;
53+
$this->requestStack = $requestStack;
5354
}
5455

5556
/**
@@ -74,11 +75,22 @@ public function addSuccessFlash(Event $event, $eventName)
7475
throw new \InvalidArgumentException('This event does not correspond to a known flash message');
7576
}
7677

77-
$this->session->getFlashBag()->add('success', $this->trans(self::$successMessages[$eventName]));
78+
$this->getSession()->getFlashBag()->add('success', $this->trans(self::$successMessages[$eventName]));
79+
}
80+
81+
private function getSession(): Session
82+
{
83+
$request = $this->requestStack->getCurrentRequest();
84+
85+
if (null === $request) {
86+
throw new \LogicException('Cannot get the session without an active request.');
87+
}
88+
89+
return $request->getSession();
7890
}
7991

8092
/**
81-
* @param string$message
93+
* @param string $message
8294
*
8395
* @return string
8496
*/

0 commit comments

Comments
 (0)