EntityUserProvider.php 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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\ORM\EntityManager;
  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 EntityManager.
  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(EntityManager $em, $class, $property = null)
  31. {
  32. $this->class = $class;
  33. $this->metadata = $em->getClassMetadata($class);
  34. if (false !== strpos($this->class, ':')) {
  35. $this->class = $this->metadata->name;
  36. }
  37. $this->repository = $em->getRepository($class);
  38. $this->property = $property;
  39. }
  40. /**
  41. * {@inheritdoc}
  42. */
  43. public function loadUserByUsername($username)
  44. {
  45. if (null !== $this->property) {
  46. $user = $this->repository->findOneBy(array($this->property => $username));
  47. } else {
  48. if (!$this->repository instanceof UserProviderInterface) {
  49. throw new \InvalidArgumentException(sprintf('The Doctrine repository "%s" must implement UserProviderInterface.', get_class($this->repository)));
  50. }
  51. $user = $this->repository->loadUserByUsername($username);
  52. }
  53. if (null === $user) {
  54. throw new UsernameNotFoundException(sprintf('User "%s" not found.', $username));
  55. }
  56. return $user;
  57. }
  58. /**
  59. * {@inheritDoc}
  60. */
  61. public function refreshUser(UserInterface $user)
  62. {
  63. if (!$user instanceof $this->class) {
  64. throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
  65. }
  66. // The user must be reloaded via the primary key as all other data
  67. // might have changed without proper persistence in the database.
  68. // That's the case when the user has been changed by a form with
  69. // validation errors.
  70. if (!$id = $this->metadata->getIdentifierValues($user)) {
  71. throw new \InvalidArgumentException("You cannot refresh a user ".
  72. "from the EntityUserProvider that does not contain an identifier. ".
  73. "The user object has to be serialized with its own identifier " .
  74. "mapped by Doctrine."
  75. );
  76. }
  77. if (null === $refreshedUser = $this->repository->find($id)) {
  78. throw new UsernameNotFoundException(sprintf('User with id %s not found', json_encode($id)));
  79. }
  80. return $refreshedUser;
  81. }
  82. /**
  83. * {@inheritDoc}
  84. */
  85. public function supportsClass($class)
  86. {
  87. return $class === $this->class || is_subclass_of($class, $this->class);
  88. }
  89. }