diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php index 878e19ccb5cd..11987179a2f5 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -664,23 +664,6 @@ public function testValidateInheritanceUniqueness() ->assertRaised(); } - /** - * @expectedException \Symfony\Component\Validator\Exception\ConstraintDefinitionException - * @expectedExceptionMessage The "Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity" entity repository does not support the "Symfony\Bridge\Doctrine\Tests\Fixtures\Person" entity. The entity should be an instance of or extend "Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity". - */ - public function testInvalidateRepositoryForInheritance() - { - $constraint = new UniqueEntity(array( - 'message' => 'myMessage', - 'fields' => array('name'), - 'em' => self::EM_NAME, - 'entityClass' => 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleStringIdEntity', - )); - - $entity = new Person(1, 'Foo'); - $this->validator->validate($entity, $constraint); - } - public function testValidateUniquenessWithCompositeObjectNoToStringIdEntity() { $constraint = new UniqueEntity(array( diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php index c9b13dcf5996..55a45a892d28 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php @@ -30,6 +30,7 @@ class UniqueEntity extends Constraint public $em = null; public $entityClass = null; public $repositoryMethod = 'findBy'; + public $isEntityToUpdateMethod = null; public $fields = array(); public $errorPath = null; public $ignoreNull = true; diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php index e03ef3c555b3..80ec1a446bad 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -34,13 +34,13 @@ public function __construct(ManagerRegistry $registry) } /** - * @param object $entity + * @param object $object * @param Constraint $constraint * * @throws UnexpectedTypeException * @throws ConstraintDefinitionException */ - public function validate($entity, Constraint $constraint) + public function validate($object, Constraint $constraint) { if (!$constraint instanceof UniqueEntity) { throw new UnexpectedTypeException($constraint, __NAMESPACE__.'\UniqueEntity'); @@ -60,10 +60,13 @@ public function validate($entity, Constraint $constraint) throw new ConstraintDefinitionException('At least one field has to be specified.'); } - if (null === $entity) { + if (null === $object) { return; } + $objectClass = get_class($object); + $entityClass = $constraint->entityClass ?: $objectClass; + if ($constraint->em) { $em = $this->registry->getManager($constraint->em); @@ -71,25 +74,28 @@ public function validate($entity, Constraint $constraint) throw new ConstraintDefinitionException(sprintf('Object manager "%s" does not exist.', $constraint->em)); } } else { - $em = $this->registry->getManagerForClass(get_class($entity)); + $em = $this->registry->getManagerForClass($entityClass); if (!$em) { - throw new ConstraintDefinitionException(sprintf('Unable to find the object manager associated with an entity of class "%s".', get_class($entity))); + throw new ConstraintDefinitionException(sprintf('Unable to find the object manager associated with an entity of class "%s".', $objectClass)); } } - $class = $em->getClassMetadata(get_class($entity)); - /* @var $class \Doctrine\Common\Persistence\Mapping\ClassMetadata */ + $class = $em->getClassMetadata($entityClass); $criteria = array(); $hasNullValue = false; - foreach ($fields as $fieldName) { - if (!$class->hasField($fieldName) && !$class->hasAssociation($fieldName)) { - throw new ConstraintDefinitionException(sprintf('The field "%s" is not mapped by Doctrine, so it cannot be validated for uniqueness.', $fieldName)); + foreach ($fields as $objectField => $entityField) { + if (!$class->hasField($entityField) && !$class->hasAssociation($entityField)) { + throw new ConstraintDefinitionException(sprintf('The field "%s" is not mapped by Doctrine, so it cannot be validated for uniqueness.', $entityField)); } - $fieldValue = $class->reflFields[$fieldName]->getValue($entity); + $field = new \ReflectionProperty($objectClass, is_int($objectField) ? $entityField : $objectField); + if (!$field->isPublic()) { + $field->setAccessible(true); + } + $fieldValue = $field->getValue($object); if (null === $fieldValue) { $hasNullValue = true; @@ -99,14 +105,14 @@ public function validate($entity, Constraint $constraint) continue; } - $criteria[$fieldName] = $fieldValue; + $criteria[$entityField] = $fieldValue; - if (null !== $criteria[$fieldName] && $class->hasAssociation($fieldName)) { + if (null !== $criteria[$entityField] && $class->hasAssociation($entityField)) { /* Ensure the Proxy is initialized before using reflection to * read its identifiers. This is necessary because the wrapped * getter methods in the Proxy are being bypassed. */ - $em->initializeObject($criteria[$fieldName]); + $em->initializeObject($criteria[$entityField]); } } @@ -121,22 +127,7 @@ public function validate($entity, Constraint $constraint) return; } - if (null !== $constraint->entityClass) { - /* Retrieve repository from given entity name. - * We ensure the retrieved repository can handle the entity - * by checking the entity is the same, or subclass of the supported entity. - */ - $repository = $em->getRepository($constraint->entityClass); - $supportedClass = $repository->getClassName(); - - if (!$entity instanceof $supportedClass) { - throw new ConstraintDefinitionException(sprintf('The "%s" entity repository does not support the "%s" entity. The entity should be an instance of or extend "%s".', $constraint->entityClass, $class->getName(), $supportedClass)); - } - } else { - $repository = $em->getRepository(get_class($entity)); - } - - $result = $repository->{$constraint->repositoryMethod}($criteria); + $result = $em->getRepository($entityClass)->{$constraint->repositoryMethod}($criteria); if ($result instanceof \IteratorAggregate) { $result = $result->getIterator(); @@ -152,14 +143,29 @@ public function validate($entity, Constraint $constraint) reset($result); } - /* If no entity matched the query criteria or a single entity matched, - * which is the same as the entity being validated, the criteria is - * unique. - */ - if (0 === count($result) || (1 === count($result) && $entity === ($result instanceof \Iterator ? $result->current() : current($result)))) { + if (0 === count($result)) { return; } + if (1 === count($result)) { + $entity = $result instanceof \Iterator ? $result->current() : current($result); + + if ($object === $entity) { + return; + } + + $method = $constraint->isEntityToUpdateMethod; + if (null !== $method) { + if (!method_exists($object, $method)) { + throw new ConstraintDefinitionException(sprintf('Method "%s" does not exist in class %s', $method, $objectClass)); + } + + if (call_user_func([$object, $method], $entity)) { + return; + } + } + } + $errorPath = null !== $constraint->errorPath ? $constraint->errorPath : $fields[0]; $invalidValue = isset($criteria[$errorPath]) ? $criteria[$errorPath] : $criteria[$fields[0]]; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy