Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b3ced86

Browse files
HeahDudedmaicher
authored andcommitted
[DoctrineBridge] Fixed invalid unique value as composite key
Fixed UniqueEntityValidator tests
1 parent 5aadce3 commit b3ced86

File tree

2 files changed

+39
-29
lines changed

2 files changed

+39
-29
lines changed

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

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ public function testValidateUniqueness()
175175
$this->buildViolation('myMessage')
176176
->atPath('property.path.name')
177177
->setParameter('{{ value }}', '"Foo"')
178-
->setInvalidValue('Foo')
178+
->setInvalidValue($entity2)
179179
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
180180
->assertRaised();
181181
}
@@ -200,7 +200,7 @@ public function testValidateCustomErrorPath()
200200
$this->buildViolation('myMessage')
201201
->atPath('property.path.bar')
202202
->setParameter('{{ value }}', '"Foo"')
203-
->setInvalidValue('Foo')
203+
->setInvalidValue($entity2)
204204
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
205205
->assertRaised();
206206
}
@@ -419,7 +419,7 @@ public function testAssociatedEntity()
419419

420420
$this->buildViolation('myMessage')
421421
->atPath('property.path.single')
422-
->setParameter('{{ value }}', $entity1)
422+
->setParameter('{{ value }}', 'object("Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdEntity") identified by (id => 1)')
423423
->setInvalidValue($entity1)
424424
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
425425
->assertRaised();
@@ -452,12 +452,12 @@ public function testValidateUniquenessNotToStringEntityWithAssociatedEntity()
452452

453453
$this->validator->validate($associated2, $constraint);
454454

455-
$expectedValue = 'Object of class "Symfony\Bridge\Doctrine\Tests\Fixtures\AssociationEntity2" identified by "2"';
455+
$expectedValue = 'object("Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity") identified by (id => 1)';
456456

457457
$this->buildViolation('myMessage')
458458
->atPath('property.path.single')
459-
->setParameter('{{ value }}', '"'.$expectedValue.'"')
460-
->setInvalidValue($expectedValue)
459+
->setParameter('{{ value }}', $expectedValue)
460+
->setInvalidValue($entity1)
461461
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
462462
->assertRaised();
463463
}
@@ -574,6 +574,11 @@ public function testValidateUniquenessWithCompositeObjectNoToStringIdEntity()
574574

575575
$objectOne = new SingleIntIdNoToStringEntity(1, 'foo');
576576
$objectTwo = new SingleIntIdNoToStringEntity(2, 'bar');
577+
578+
$this->em->persist($objectOne);
579+
$this->em->persist($objectTwo);
580+
$this->em->flush();
581+
577582
$entity = new CompositeObjectNoToStringIdEntity($objectOne, $objectTwo);
578583

579584
$this->em->persist($entity);
@@ -583,12 +588,12 @@ public function testValidateUniquenessWithCompositeObjectNoToStringIdEntity()
583588

584589
$this->validator->validate($newEntity, $constraint);
585590

586-
$expectedValue = 'Object of class "Symfony\Bridge\Doctrine\Tests\Fixtures\CompositeObjectNoToStringIdEntity" identified by "(Object of class "Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity" identified by "1"), (Object of class "Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity" identified by "2")"';
591+
$expectedValue = 'object("Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIntIdNoToStringEntity") identified by (id => 1)';
587592

588593
$this->buildViolation('myMessage')
589594
->atPath('property.path.objectOne')
590-
->setParameter('{{ value }}', '"'.$expectedValue.'"')
591-
->setInvalidValue($expectedValue)
595+
->setParameter('{{ value }}', $expectedValue)
596+
->setInvalidValue($objectOne)
592597
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
593598
->assertRaised();
594599
}

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

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -129,36 +129,41 @@ public function validate($entity, Constraint $constraint)
129129
$errorPath = null !== $constraint->errorPath ? $constraint->errorPath : $fields[0];
130130
$invalidValue = isset($criteria[$errorPath]) ? $criteria[$errorPath] : $criteria[$fields[0]];
131131

132-
if (is_object($invalidValue) && !method_exists($invalidValue, '__toString')) {
133-
$invalidValue = $this->buildInvalidValueString($em, $class, $entity);
134-
}
135-
136132
$this->context->buildViolation($constraint->message)
137133
->atPath($errorPath)
138-
->setParameter('{{ value }}', $this->formatValue($invalidValue, static::OBJECT_TO_STRING | static::PRETTY_DATE))
134+
->setParameter('{{ value }}', $this->formatWithIdentifiers($em, $class, $invalidValue))
139135
->setInvalidValue($invalidValue)
140136
->setCode(UniqueEntity::NOT_UNIQUE_ERROR)
141137
->addViolation();
142138
}
143139

144-
/**
145-
* @param ObjectManager $em
146-
* @param ClassMetadata $class
147-
* @param object $entity
148-
*
149-
* @return string
150-
*/
151-
private function buildInvalidValueString(ObjectManager $em, ClassMetadata $class, $entity)
140+
private function formatWithIdentifiers(ObjectManager $em, ClassMetadata $class, $value)
152141
{
153-
$identifiers = array_map(function ($identifier) use ($em) {
154-
// identifiers can be objects (without any __toString method) if its a composite PK
155-
if (is_object($identifier) && !method_exists($identifier, '__toString')) {
156-
return sprintf('(%s)', $this->buildInvalidValueString($em, $em->getClassMetadata(get_class($identifier)), $identifier));
142+
if (!is_object($value) || $value instanceof \DateTimeInterface) {
143+
return $this->formatValue($value, self::PRETTY_DATE);
144+
}
145+
146+
// non unique value is a composite PK
147+
if ($class->getName() !== $idClass = get_class($value)) {
148+
$identifiers = $em->getClassMetadata($idClass)->getIdentifierValues($value);
149+
} else {
150+
$identifiers = $class->getIdentifierValues($value);
151+
}
152+
153+
if (!$identifiers) {
154+
return sprintf('object("%s")', $idClass);
155+
}
156+
157+
array_walk($identifiers, function (&$id, $field) {
158+
if (!is_object($id) || $id instanceof \DateTimeInterface) {
159+
$idAsString = $this->formatValue($id, self::PRETTY_DATE);
160+
} else {
161+
$idAsString = sprintf('object("%s")', get_class($id));
157162
}
158163

159-
return $identifier;
160-
}, $class->getIdentifierValues($entity));
164+
$id = sprintf('%s => %s', $field, $idAsString);
165+
});
161166

162-
return sprintf('Object of class "%s" identified by "%s"', get_class($entity), implode(', ', $identifiers));
167+
return sprintf('object("%s") identified by (%s)', $idClass, implode(', ', $identifiers));
163168
}
164169
}

0 commit comments

Comments
 (0)