diff --git a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php index 6efeebc451818..e23758a5df2e6 100644 --- a/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php +++ b/src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php @@ -455,4 +455,67 @@ public function testEntityManagerNullObject() $this->validator->validate($entity, $constraint); } + + public function testCustomMessageWithOneUniqueField() + { + $constraint = new UniqueEntity(array( + 'message' => 'An entity with name "{{ name }}" already exists.', + 'fields' => array('name'), + 'em' => self::EM_NAME, + )); + + $entity1 = new SingleIntIdEntity(1, 'Foo'); + $entity2 = new SingleIntIdEntity(2, 'Foo'); + + $this->validator->validate($entity1, $constraint); + + $this->assertNoViolation(); + + $this->em->persist($entity1); + $this->em->flush(); + + $this->validator->validate($entity1, $constraint); + + $this->assertNoViolation(); + + $this->validator->validate($entity2, $constraint); + + $this->buildViolation('An entity with name "{{ name }}" already exists.') + ->setParameters(array('{{ name }}' => 'Foo')) + ->atPath('property.path.name') + ->setInvalidValue('Foo') + ->assertRaised(); + } + + public function testCustomMessageWithTwoUniqueFields() + { + $constraint = new UniqueEntity(array( + 'message' => 'An entity with name1 "{{ name }}" and name2 "{{ name2 }}" already exists.', + 'fields' => array('name', 'name2'), + 'em' => self::EM_NAME, + 'errorPath' => 'name2', + )); + + $entity1 = new DoubleNameEntity(1, 'Foo', 'Bar'); + $entity2 = new DoubleNameEntity(2, 'Foo', 'Bar'); + + $this->validator->validate($entity1, $constraint); + + $this->assertNoViolation(); + + $this->em->persist($entity1); + $this->em->flush(); + + $this->validator->validate($entity1, $constraint); + + $this->assertNoViolation(); + + $this->validator->validate($entity2, $constraint); + + $this->buildViolation('An entity with name1 "{{ name }}" and name2 "{{ name2 }}" already exists.') + ->setParameters(array('{{ name }}' => 'Foo', '{{ name2 }}' => 'Bar')) + ->atPath('property.path.name2') + ->setInvalidValue('Bar') + ->assertRaised(); + } } diff --git a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php index a54bb46819636..6e462ab33a682 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntityValidator.php @@ -16,6 +16,7 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException; use Symfony\Component\Validator\Exception\ConstraintDefinitionException; use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\PropertyAccess\PropertyAccess; /** * Unique Entity Validator checks if one or a set of fields contain unique values. @@ -134,7 +135,23 @@ public function validate($entity, Constraint $constraint) $errorPath = null !== $constraint->errorPath ? $constraint->errorPath : $fields[0]; $invalidValue = isset($criteria[$errorPath]) ? $criteria[$errorPath] : $criteria[$fields[0]]; - $this->buildViolation($constraint->message) + $vars = array(); + $paramaters = array(); + + if (preg_match_all('/{{ ([a-zA-Z0-9_]+) }}/', $constraint->message, $vars) > 0) { + + if (!class_exists('Symfony\\Component\\PropertyAccess\\PropertyAccess')) { + throw new \RuntimeException('Unable to access entity property as the Symfony PropertyAccess is not installed.'); + } + + $accessor = PropertyAccess::createPropertyAccessor(); + + foreach ($vars[1] as $var) { + $paramaters[sprintf('{{ %s }}', $var)] = $accessor->getValue($entity, $var); + } + } + + $this->buildViolation($constraint->message, $paramaters) ->atPath($errorPath) ->setInvalidValue($invalidValue) ->addViolation(); diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json index 338b3566ce1d0..cd919fe47a4b4 100644 --- a/src/Symfony/Bridge/Doctrine/composer.json +++ b/src/Symfony/Bridge/Doctrine/composer.json @@ -39,7 +39,8 @@ "symfony/validator": "", "doctrine/data-fixtures": "", "doctrine/dbal": "", - "doctrine/orm": "" + "doctrine/orm": "", + "symfony/property-access": "" }, "autoload": { "psr-0": { "Symfony\\Bridge\\Doctrine\\": "" }