Merge branch '2.0'
* 2.0: [Doctrine] GH-1635 - UniqueValidator now works with associations
This commit is contained in:
commit
6b3c7ac62d
@ -73,6 +73,17 @@ class UniqueEntityValidator extends ConstraintValidator
|
||||
|
||||
if ($criteria[$fieldName] === null) {
|
||||
return true;
|
||||
} else if (isset($class->associationMappings[$fieldName])) {
|
||||
$relatedClass = $em->getClassMetadata($class->associationMappings[$fieldName]['targetEntity']);
|
||||
$relatedId = $relatedClass->getIdentifierValues($criteria[$fieldName]);
|
||||
|
||||
if (count($relatedId) > 1) {
|
||||
throw new ConstraintDefinitionException(
|
||||
"Associated entities are not allowed have more than one identifier field to be " .
|
||||
"part of a unique constraint in: " . $class->name . "#" . $fieldName
|
||||
);
|
||||
}
|
||||
$criteria[$fieldName] = array_pop($relatedId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Symfony\Tests\Bridge\Doctrine\Form\Fixtures;
|
||||
|
||||
use Doctrine\ORM\Mapping AS ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Entity
|
||||
*/
|
||||
class AssociationEntity
|
||||
{
|
||||
/**
|
||||
* @var int
|
||||
* @ORM\Id @ORM\GeneratedValue
|
||||
* @ORM\Column(type="integer")
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="SingleIdentEntity")
|
||||
* @var \Symfony\Tests\Bridge\Doctrine\Form\Fixtures\SingleIdentEntity
|
||||
*/
|
||||
public $single;
|
||||
|
||||
/**
|
||||
* @ORM\ManyToOne(targetEntity="CompositeIdentEntity")
|
||||
* @ORM\JoinColumns({
|
||||
* @ORM\JoinColumn(name="composite_id1", referencedColumnName="id1"),
|
||||
* @ORM\JoinColumn(name="composite_id2", referencedColumnName="id2")
|
||||
* })
|
||||
* @var \Symfony\Tests\Bridge\Doctrine\Form\Fixtures\CompositeIdentEntity
|
||||
*/
|
||||
public $composite;
|
||||
}
|
@ -13,9 +13,13 @@ namespace Symfony\Tests\Bridge\Doctrine\Validator\Constraints;
|
||||
|
||||
require_once __DIR__.'/../../Form/DoctrineOrmTestCase.php';
|
||||
require_once __DIR__.'/../../Fixtures/SingleIdentEntity.php';
|
||||
require_once __DIR__.'/../../Fixtures/CompositeIdentEntity.php';
|
||||
require_once __DIR__.'/../../Fixtures/AssociationEntity.php';
|
||||
|
||||
use Symfony\Tests\Bridge\Doctrine\Form\DoctrineOrmTestCase;
|
||||
use Symfony\Tests\Bridge\Doctrine\Form\Fixtures\SingleIdentEntity;
|
||||
use Symfony\Tests\Bridge\Doctrine\Form\Fixtures\CompositeIdentEntity;
|
||||
use Symfony\Tests\Bridge\Doctrine\Form\Fixtures\AssociationEntity;
|
||||
use Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
|
||||
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator;
|
||||
@ -58,14 +62,21 @@ class UniqueValidatorTest extends DoctrineOrmTestCase
|
||||
return $validatorFactory;
|
||||
}
|
||||
|
||||
public function createValidator($entityManagerName, $em)
|
||||
public function createValidator($entityManagerName, $em, $validateClass = null, $uniqueFields = null)
|
||||
{
|
||||
if (!$validateClass) {
|
||||
$validateClass = 'Symfony\Tests\Bridge\Doctrine\Form\Fixtures\SingleIdentEntity';
|
||||
}
|
||||
if (!$uniqueFields) {
|
||||
$uniqueFields = array('name');
|
||||
}
|
||||
|
||||
$registry = $this->createRegistryMock($entityManagerName, $em);
|
||||
|
||||
$uniqueValidator = new UniqueEntityValidator($registry);
|
||||
|
||||
$metadata = new ClassMetadata('Symfony\Tests\Bridge\Doctrine\Form\Fixtures\SingleIdentEntity');
|
||||
$metadata->addConstraint(new UniqueEntity(array('fields' => array('name'), 'em' => $entityManagerName)));
|
||||
$metadata = new ClassMetadata($validateClass);
|
||||
$metadata->addConstraint(new UniqueEntity(array('fields' => $uniqueFields, 'em' => $entityManagerName)));
|
||||
|
||||
$metadataFactory = $this->createMetadataFactoryMock($metadata);
|
||||
$validatorFactory = $this->createValidatorFactory($uniqueValidator);
|
||||
@ -77,7 +88,9 @@ class UniqueValidatorTest extends DoctrineOrmTestCase
|
||||
{
|
||||
$schemaTool = new SchemaTool($em);
|
||||
$schemaTool->createSchema(array(
|
||||
$em->getClassMetadata('Symfony\Tests\Bridge\Doctrine\Form\Fixtures\SingleIdentEntity')
|
||||
$em->getClassMetadata('Symfony\Tests\Bridge\Doctrine\Form\Fixtures\SingleIdentEntity'),
|
||||
$em->getClassMetadata('Symfony\Tests\Bridge\Doctrine\Form\Fixtures\CompositeIdentEntity'),
|
||||
$em->getClassMetadata('Symfony\Tests\Bridge\Doctrine\Form\Fixtures\AssociationEntity'),
|
||||
));
|
||||
}
|
||||
|
||||
@ -150,4 +163,60 @@ class UniqueValidatorTest extends DoctrineOrmTestCase
|
||||
$violationsList = $validator->validate($entity2);
|
||||
$this->assertEquals(1, $violationsList->count(), 'Violation found on entity with conflicting entity existing in the database.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @group GH-1635
|
||||
*/
|
||||
public function testAssociatedEntity()
|
||||
{
|
||||
$entityManagerName = "foo";
|
||||
$em = $this->createTestEntityManager();
|
||||
$this->createSchema($em);
|
||||
$validator = $this->createValidator($entityManagerName, $em, 'Symfony\Tests\Bridge\Doctrine\Form\Fixtures\AssociationEntity', array('single'));
|
||||
|
||||
$entity1 = new SingleIdentEntity(1, 'foo');
|
||||
$associated = new AssociationEntity();
|
||||
$associated->single = $entity1;
|
||||
|
||||
$em->persist($entity1);
|
||||
$em->persist($associated);
|
||||
$em->flush();
|
||||
|
||||
$violationsList = $validator->validate($associated);
|
||||
$this->assertEquals(0, $violationsList->count());
|
||||
|
||||
$associated2 = new AssociationEntity();
|
||||
$associated2->single = $entity1;
|
||||
|
||||
$em->persist($associated2);
|
||||
$em->flush();
|
||||
|
||||
$violationsList = $validator->validate($associated2);
|
||||
$this->assertEquals(1, $violationsList->count());
|
||||
}
|
||||
|
||||
/**
|
||||
* @group GH-1635
|
||||
*/
|
||||
public function testAssociatedCompositeEntity()
|
||||
{
|
||||
$entityManagerName = "foo";
|
||||
$em = $this->createTestEntityManager();
|
||||
$this->createSchema($em);
|
||||
$validator = $this->createValidator($entityManagerName, $em, 'Symfony\Tests\Bridge\Doctrine\Form\Fixtures\AssociationEntity', array('composite'));
|
||||
|
||||
$composite = new CompositeIdentEntity(1, 1, "test");
|
||||
$associated = new AssociationEntity();
|
||||
$associated->composite = $composite;
|
||||
|
||||
$em->persist($composite);
|
||||
$em->persist($associated);
|
||||
$em->flush();
|
||||
|
||||
$this->setExpectedException(
|
||||
'Symfony\Component\Validator\Exception\ConstraintDefinitionException',
|
||||
'Associated entities are not allowed have more than one identifier field'
|
||||
);
|
||||
$violationsList = $validator->validate($associated);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user