From f1c4b8b4156ba6ae9bef4b43c3b9ffef5b0a6a7a Mon Sep 17 00:00:00 2001 From: Bertrand Zuchuat Date: Mon, 23 Jul 2012 10:04:10 +0200 Subject: [PATCH] [Doctrine Bridge] Added a parameter ignoreNull on Unique entity to allow a nullable value on field. Added Test --- .../Tests/Fixtures/DoubleIdentEntity.php | 36 +++++++++++++++++++ .../Constraints/UniqueValidatorTest.php | 36 +++++++++++++++++-- .../Validator/Constraints/UniqueEntity.php | 1 + .../Constraints/UniqueEntityValidator.php | 2 +- 4 files changed, 72 insertions(+), 3 deletions(-) create mode 100644 src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoubleIdentEntity.php diff --git a/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoubleIdentEntity.php b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoubleIdentEntity.php new file mode 100644 index 0000000000..2ac1ad3a85 --- /dev/null +++ b/src/Symfony/Bridge/Doctrine/Tests/Fixtures/DoubleIdentEntity.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bridge\Doctrine\Tests\Fixtures; + +use Doctrine\ORM\Mapping\Id; +use Doctrine\ORM\Mapping\Column; +use Doctrine\ORM\Mapping\Entity; + +/** @Entity */ +class DoubleIdentEntity +{ + /** @Id @Column(type="integer") */ + protected $id; + + /** @Column(type="string") */ + public $name; + + /** @Column(type="string", nullable=true) */ + public $name2; + + public function __construct($id, $name, $name2) + { + $this->id = $id; + $this->name = $name; + $this->name2 = $name2; + } +} diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php index 93bb75cad5..98fd2b9a8d 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueValidatorTest.php @@ -13,6 +13,7 @@ namespace Symfony\Bridge\Doctrine\Tests\Validator\Constraints; use Symfony\Bridge\Doctrine\Tests\DoctrineOrmTestCase; use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity; +use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleIdentEntity; use Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity; use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; @@ -113,7 +114,7 @@ class UniqueValidatorTest extends DoctrineOrmTestCase return $validatorFactory; } - public function createValidator($entityManagerName, $em, $validateClass = null, $uniqueFields = null, $errorPath = null, $repositoryMethod = 'findBy') + public function createValidator($entityManagerName, $em, $validateClass = null, $uniqueFields = null, $errorPath = null, $repositoryMethod = 'findBy', $ignoreNull = true) { if (!$validateClass) { $validateClass = 'Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity'; @@ -131,7 +132,8 @@ class UniqueValidatorTest extends DoctrineOrmTestCase 'fields' => $uniqueFields, 'em' => $entityManagerName, 'errorPath' => $errorPath, - 'repositoryMethod' => $repositoryMethod + 'repositoryMethod' => $repositoryMethod, + 'ignoreNull' => $ignoreNull )); $metadata->addConstraint($constraint); @@ -146,6 +148,7 @@ class UniqueValidatorTest extends DoctrineOrmTestCase $schemaTool = new SchemaTool($em); $schemaTool->createSchema(array( $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity'), + $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleIdentEntity'), $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIdentEntity'), $em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity'), )); @@ -223,6 +226,35 @@ class UniqueValidatorTest extends DoctrineOrmTestCase $this->assertEquals(0, $violationsList->count(), "No violations found on entity having a null value."); } + public function testValidateUniquenessWithIgnoreNull() + { + $entityManagerName = "foo"; + $validateClass = 'Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleIdentEntity'; + $em = $this->createTestEntityManager(); + $this->createSchema($em); + $validator = $this->createValidator($entityManagerName, $em, $validateClass, array('name', 'name2'), 'bar', 'findby', false); + + $entity1 = new DoubleIdentEntity(1, 'Foo', null); + $violationsList = $validator->validate($entity1); + $this->assertEquals(0, $violationsList->count(), "No violations found on entity before it is saved to the database."); + + $em->persist($entity1); + $em->flush(); + + $violationsList = $validator->validate($entity1); + $this->assertEquals(0, $violationsList->count(), "No violations found on entity after it was saved to the database."); + + $entity2 = new DoubleIdentEntity(2, 'Foo', null); + + $violationsList = $validator->validate($entity2); + $this->assertEquals(1, $violationsList->count(), "Violation found on entity with conflicting entity existing in the database."); + + $violation = $violationsList[0]; + $this->assertEquals('This value is already used.', $violation->getMessage()); + $this->assertEquals('bar', $violation->getPropertyPath()); + $this->assertEquals('Foo', $violation->getInvalidValue()); + } + public function testValidateUniquenessAfterConsideringMultipleQueryResults() { $entityManagerName = "foo"; diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php index ae4367fea4..f211f61585 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php @@ -27,6 +27,7 @@ class UniqueEntity extends Constraint public $repositoryMethod = 'findBy'; public $fields = array(); public $errorPath = null; + public $ignoreNull = true; public function getRequiredOptions() { diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php index 81b68a9628..371d1cbe61 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -75,7 +75,7 @@ class UniqueEntityValidator extends ConstraintValidator $criteria[$fieldName] = $class->reflFields[$fieldName]->getValue($entity); - if (null === $criteria[$fieldName]) { + if ($constraint->ignoreNull && null === $criteria[$fieldName]) { return; }