vendor/symfony/doctrine-bridge/Security/User/EntityUserProvider.php line 49

  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Bridge\Doctrine\Security\User;
  11. use Doctrine\Persistence\ManagerRegistry;
  12. use Doctrine\Persistence\Mapping\ClassMetadata;
  13. use Doctrine\Persistence\ObjectManager;
  14. use Doctrine\Persistence\ObjectRepository;
  15. use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
  16. use Symfony\Component\Security\Core\Exception\UserNotFoundException;
  17. use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
  18. use Symfony\Component\Security\Core\User\PasswordUpgraderInterface;
  19. use Symfony\Component\Security\Core\User\UserInterface;
  20. use Symfony\Component\Security\Core\User\UserProviderInterface;
  21. /**
  22.  * Wrapper around a Doctrine ObjectManager.
  23.  *
  24.  * Provides provisioning for Doctrine entity users.
  25.  *
  26.  * @author Fabien Potencier <fabien@symfony.com>
  27.  * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  28.  */
  29. class EntityUserProvider implements UserProviderInterfacePasswordUpgraderInterface
  30. {
  31.     private ManagerRegistry $registry;
  32.     private ?string $managerName;
  33.     private string $classOrAlias;
  34.     private string $class;
  35.     private ?string $property;
  36.     public function __construct(ManagerRegistry $registrystring $classOrAliasstring $property nullstring $managerName null)
  37.     {
  38.         $this->registry $registry;
  39.         $this->managerName $managerName;
  40.         $this->classOrAlias $classOrAlias;
  41.         $this->property $property;
  42.     }
  43.     public function loadUserByIdentifier(string $identifier): UserInterface
  44.     {
  45.         $repository $this->getRepository();
  46.         if (null !== $this->property) {
  47.             $user $repository->findOneBy([$this->property => $identifier]);
  48.         } else {
  49.             if (!$repository instanceof UserLoaderInterface) {
  50.                 throw new \InvalidArgumentException(sprintf('You must either make the "%s" entity Doctrine Repository ("%s") implement "Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface" or set the "property" option in the corresponding entity provider configuration.'$this->classOrAliasget_debug_type($repository)));
  51.             }
  52.             $user $repository->loadUserByIdentifier($identifier);
  53.         }
  54.         if (null === $user) {
  55.             $e = new UserNotFoundException(sprintf('User "%s" not found.'$identifier));
  56.             $e->setUserIdentifier($identifier);
  57.             throw $e;
  58.         }
  59.         return $user;
  60.     }
  61.     public function refreshUser(UserInterface $user): UserInterface
  62.     {
  63.         $class $this->getClass();
  64.         if (!$user instanceof $class) {
  65.             throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.'get_debug_type($user)));
  66.         }
  67.         $repository $this->getRepository();
  68.         if ($repository instanceof UserProviderInterface) {
  69.             $refreshedUser $repository->refreshUser($user);
  70.         } else {
  71.             // The user must be reloaded via the primary key as all other data
  72.             // might have changed without proper persistence in the database.
  73.             // That's the case when the user has been changed by a form with
  74.             // validation errors.
  75.             if (!$id $this->getClassMetadata()->getIdentifierValues($user)) {
  76.                 throw new \InvalidArgumentException('You cannot refresh a user from the EntityUserProvider that does not contain an identifier. The user object has to be serialized with its own identifier mapped by Doctrine.');
  77.             }
  78.             $refreshedUser $repository->find($id);
  79.             if (null === $refreshedUser) {
  80.                 $e = new UserNotFoundException('User with id '.json_encode($id).' not found.');
  81.                 $e->setUserIdentifier(json_encode($id));
  82.                 throw $e;
  83.             }
  84.         }
  85.         return $refreshedUser;
  86.     }
  87.     public function supportsClass(string $class): bool
  88.     {
  89.         return $class === $this->getClass() || is_subclass_of($class$this->getClass());
  90.     }
  91.     /**
  92.      * @final
  93.      */
  94.     public function upgradePassword(PasswordAuthenticatedUserInterface $userstring $newHashedPassword): void
  95.     {
  96.         $class $this->getClass();
  97.         if (!$user instanceof $class) {
  98.             throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.'get_debug_type($user)));
  99.         }
  100.         $repository $this->getRepository();
  101.         if ($repository instanceof PasswordUpgraderInterface) {
  102.             $repository->upgradePassword($user$newHashedPassword);
  103.         }
  104.     }
  105.     private function getObjectManager(): ObjectManager
  106.     {
  107.         return $this->registry->getManager($this->managerName);
  108.     }
  109.     private function getRepository(): ObjectRepository
  110.     {
  111.         return $this->getObjectManager()->getRepository($this->classOrAlias);
  112.     }
  113.     private function getClass(): string
  114.     {
  115.         if (!isset($this->class)) {
  116.             $class $this->classOrAlias;
  117.             if (str_contains($class':')) {
  118.                 $class $this->getClassMetadata()->getName();
  119.             }
  120.             $this->class $class;
  121.         }
  122.         return $this->class;
  123.     }
  124.     private function getClassMetadata(): ClassMetadata
  125.     {
  126.         return $this->getObjectManager()->getClassMetadata($this->classOrAlias);
  127.     }
  128. }