Skip to content

Commit e7541d9

Browse files
committed
bug #21562 [DoctrineBridge] make sure that null can be the invalid value (xabbuh)
This PR was merged into the 2.7 branch. Discussion ---------- [DoctrineBridge] make sure that null can be the invalid value | Q | A | ------------- | --- | Branch? | 2.7 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #21554 | License | MIT | Doc PR | Commits ------- c3702c2 make sure that null can be the invalid value
2 parents dc4d046 + c3702c2 commit e7541d9

File tree

3 files changed

+78
-1
lines changed

3 files changed

+78
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bridge\Doctrine\Tests\Fixtures;
13+
14+
use Doctrine\ORM\Mapping\Id;
15+
use Doctrine\ORM\Mapping\Column;
16+
use Doctrine\ORM\Mapping\Entity;
17+
18+
/** @Entity */
19+
class DoubleNullableNameEntity
20+
{
21+
/** @Id @Column(type="integer") */
22+
protected $id;
23+
24+
/** @Column(type="string", nullable=true) */
25+
public $name;
26+
27+
/** @Column(type="string", nullable=true) */
28+
public $name2;
29+
30+
public function __construct($id, $name, $name2)
31+
{
32+
$this->id = $id;
33+
$this->name = $name;
34+
$this->name2 = $name2;
35+
}
36+
}

src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php

+31-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Bridge\Doctrine\Test\DoctrineTestHelper;
1919
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity;
2020
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity;
21+
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNullableNameEntity;
2122
use Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity;
2223
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
2324
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator;
@@ -132,6 +133,7 @@ private function createSchema(ObjectManager $em)
132133
$schemaTool->createSchema(array(
133134
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity'),
134135
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNameEntity'),
136+
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleNullableNameEntity'),
135137
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeIntIdEntity'),
136138
$em->getClassMetadata('Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity'),
137139
));
@@ -213,7 +215,7 @@ public function testValidateUniquenessWithNull()
213215
$this->assertNoViolation();
214216
}
215217

216-
public function testValidateUniquenessWithIgnoreNull()
218+
public function testValidateUniquenessWithIgnoreNullDisabled()
217219
{
218220
$constraint = new UniqueEntity(array(
219221
'message' => 'myMessage',
@@ -261,6 +263,34 @@ public function testAllConfiguredFieldsAreCheckedOfBeingMappedByDoctrineWithIgno
261263
$this->validator->validate($entity1, $constraint);
262264
}
263265

266+
public function testNoValidationIfFirstFieldIsNullAndNullValuesAreIgnored()
267+
{
268+
$constraint = new UniqueEntity(array(
269+
'message' => 'myMessage',
270+
'fields' => array('name', 'name2'),
271+
'em' => self::EM_NAME,
272+
'ignoreNull' => true,
273+
));
274+
275+
$entity1 = new DoubleNullableNameEntity(1, null, 'Foo');
276+
$entity2 = new DoubleNullableNameEntity(2, null, 'Foo');
277+
278+
$this->validator->validate($entity1, $constraint);
279+
280+
$this->assertNoViolation();
281+
282+
$this->em->persist($entity1);
283+
$this->em->flush();
284+
285+
$this->validator->validate($entity1, $constraint);
286+
287+
$this->assertNoViolation();
288+
289+
$this->validator->validate($entity2, $constraint);
290+
291+
$this->assertNoViolation();
292+
}
293+
264294
public function testValidateUniquenessWithValidCustomErrorPath()
265295
{
266296
$constraint = new UniqueEntity(array(

src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php

+11
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,19 @@ public function validate($entity, Constraint $constraint)
8080
/* @var $class \Doctrine\Common\Persistence\Mapping\ClassMetadata */
8181

8282
$criteria = array();
83+
$hasNullValue = false;
84+
8385
foreach ($fields as $fieldName) {
8486
if (!$class->hasField($fieldName) && !$class->hasAssociation($fieldName)) {
8587
throw new ConstraintDefinitionException(sprintf('The field "%s" is not mapped by Doctrine, so it cannot be validated for uniqueness.', $fieldName));
8688
}
8789

8890
$fieldValue = $class->reflFields[$fieldName]->getValue($entity);
8991

92+
if (null === $fieldValue) {
93+
$hasNullValue = true;
94+
}
95+
9096
if ($constraint->ignoreNull && null === $fieldValue) {
9197
continue;
9298
}
@@ -102,6 +108,11 @@ public function validate($entity, Constraint $constraint)
102108
}
103109
}
104110

111+
// validation doesn't fail if one of the fields is null and if null values should be ignored
112+
if ($hasNullValue && $constraint->ignoreNull) {
113+
return;
114+
}
115+
105116
// skip validation if there are no criteria (this can happen when the
106117
// "ignoreNull" option is enabled and fields to be checked are null
107118
if (empty($criteria)) {

0 commit comments

Comments
 (0)