EntityUserProvider.php 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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\Common\Persistence\ManagerRegistry;
  12. use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
  13. use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
  14. use Symfony\Component\Security\Core\User\UserProviderInterface;
  15. use Symfony\Component\Security\Core\User\UserInterface;
  16. /**
  17. * Wrapper around a Doctrine ObjectManager.
  18. *
  19. * Provides easy to use provisioning for Doctrine entity users.
  20. *
  21. * @author Fabien Potencier <fabien@symfony.com>
  22. * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  23. */
  24. class EntityUserProvider implements UserProviderInterface
  25. {
  26. private $class;
  27. private $repository;
  28. private $property;
  29. private $metadata;
  30. public function __construct(ManagerRegistry $registry, $class, $property = null, $managerName = null)
  31. {
  32. $em = $registry->getManager($managerName);
  33. $this->class = $class;
  34. $this->metadata = $em->getClassMetadata($class);
  35. if (false !== strpos($this->class, ':')) {
  36. $this->class = $this->metadata->getName();
  37. }
  38. $this->repository = $em->getRepository($class);
  39. $this->property = $property;
  40. }
  41. /**
  42. * {@inheritdoc}
  43. */
  44. public function loadUserByUsername($username)
  45. {
  46. if (null !== $this->property) {
  47. $user = $this->repository->findOneBy(array($this->property => $username));
  48. } else {
  49. if (!$this->repository instanceof UserProviderInterface) {
  50. throw new \InvalidArgumentException(sprintf('The Doctrine repository "%s" must implement UserProviderInterface.', get_class($this->repository)));
  51. }
  52. $user = $this->repository->loadUserByUsername($username);
  53. }
  54. if (null === $user) {
  55. throw new UsernameNotFoundException(sprintf('User "%s" not found.', $username));
  56. }
  57. return $user;
  58. }
  59. /**
  60. * {@inheritDoc}
  61. */
  62. public function refreshUser(UserInterface $user)
  63. {
  64. if (!$user instanceof $this->class) {
  65. throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
  66. }
  67. if ($this->repository instanceof UserProviderInterface) {
  68. $refreshedUser = $this->repository->refreshUser($user);
  69. } else {
  70. // The user must be reloaded via the primary key as all other data
  71. // might have changed without proper persistence in the database.
  72. // That's the case when the user has been changed by a form with
  73. // validation errors.
  74. if (!$id = $this->metadata->getIdentifierValues($user)) {
  75. throw new \InvalidArgumentException("You cannot refresh a user ".
  76. "from the EntityUserProvider that does not contain an identifier. ".
  77. "The user object has to be serialized with its own identifier " .
  78. "mapped by Doctrine."
  79. );
  80. }
  81. if (null === $refreshedUser = $this->repository->find($id)) {
  82. throw new UsernameNotFoundException(sprintf('User with id %s not found', json_encode($id)));
  83. }
  84. }
  85. return $refreshedUser;
  86. }
  87. /**
  88. * {@inheritDoc}
  89. */
  90. public function supportsClass($class)
  91. {
  92. return $class === $this->class || is_subclass_of($class, $this->class);
  93. }
  94. }