merged branch beberlei/DoctrineUniqueValidator (PR #2724)

Commits
-------

59397cf [DoctrineBridge] Generalize EntityValidator to work with any validation service and against any Common ClassMetadata provider

Discussion
----------

[DoctrineBridge] Generalize EntityValidator to work with any validation ...

...service and against any Common ClassMetadata provider. Also decoupled the Bridge from its implicit dependency on the "doctrine.orm.vaildator.unique" service.

Bug fix: no
Feature addition: yes
Backwards compatibility break: no
Symfony2 tests pass: no
This commit is contained in:
Fabien Potencier 2011-12-07 16:09:48 +01:00
commit 7e9d53bc93
2 changed files with 11 additions and 6 deletions

View File

@ -22,6 +22,7 @@ use Symfony\Component\Validator\Constraint;
class UniqueEntity extends Constraint
{
public $message = 'This value is already used';
public $service = 'doctrine.orm.validator.unique';
public $em = null;
public $fields = array();
@ -37,7 +38,7 @@ class UniqueEntity extends Constraint
*/
public function validatedBy()
{
return 'doctrine.orm.validator.unique';
return $this->service;
}
/**

View File

@ -62,11 +62,12 @@ class UniqueEntityValidator extends ConstraintValidator
$className = $this->context->getCurrentClass();
$class = $em->getClassMetadata($className);
/* @var $class \Doctrine\Common\Persistence\Mapping\ClassMetadata */
$criteria = array();
foreach ($fields as $fieldName) {
if (!isset($class->reflFields[$fieldName])) {
throw new ConstraintDefinitionException('Only field names mapped by Doctrine can be validated for uniqueness.');
if (!$class->hasField($fieldName) && !$class->hasAssociation($fieldName)) {
throw new ConstraintDefinitionException("Only field names mapped by Doctrine can be validated for uniqueness.");
}
$criteria[$fieldName] = $class->reflFields[$fieldName]->getValue($entity);
@ -75,12 +76,15 @@ class UniqueEntityValidator extends ConstraintValidator
return true;
}
if (isset($class->associationMappings[$fieldName])) {
$relatedClass = $em->getClassMetadata($class->associationMappings[$fieldName]['targetEntity']);
if ($class->hasAssociation($fieldName)) {
$relatedClass = $em->getClassMetadata($class->getAssociationTargetClass($fieldName));
$relatedId = $relatedClass->getIdentifierValues($criteria[$fieldName]);
if (count($relatedId) > 1) {
throw new ConstraintDefinitionException(sprintf('Associated entities are not allowed to have more than one identifier field to be part of a unique constraint in %s#%s.', $class->name, $fieldName));
throw new ConstraintDefinitionException(
"Associated entities are not allowed to have more than one identifier field to be " .
"part of a unique constraint in: " . $class->getName() . "#" . $fieldName
);
}
$criteria[$fieldName] = array_pop($relatedId);
}