Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[Validator] Extracted message interpolation logic of ConstraintViolat…

…ion and used the Translation component for that
  • Loading branch information...
commit 06cf4a4dd34d0b2929c894b102c61214e2e0b899 1 parent ac6ca7b
@webmozart webmozart authored
View
2  CHANGELOG.md
@@ -28,6 +28,8 @@ CHANGELOG
As of Symfony 2.3, this method will be typed against `MetadataFactoryInterface` instead.
* [BC BREAK] the switches `traverse` and `deep` in the `Valid` constraint and in `GraphWalker::walkReference`
are ignored for arrays now. Arrays are always traversed recursively.
+ * added dependency to Translation component
+ * violation messages are now translated with a TranslatorInterface implementation
2.1.0
-----
View
19 ConstraintViolation.php
@@ -21,6 +21,11 @@ class ConstraintViolation implements ConstraintViolationInterface
/**
* @var string
*/
+ private $message;
+
+ /**
+ * @var string
+ */
private $messageTemplate;
/**
@@ -56,6 +61,7 @@ class ConstraintViolation implements ConstraintViolationInterface
/**
* Creates a new constraint violation.
*
+ * @param string $message The violation message.
* @param string $messageTemplate The raw violation message.
* @param array $messageParameters The parameters to substitute
* in the raw message.
@@ -70,8 +76,9 @@ class ConstraintViolation implements ConstraintViolationInterface
* @param mixed $code The error code of the
* violation, if any.
*/
- public function __construct($messageTemplate, array $messageParameters, $root, $propertyPath, $invalidValue, $messagePluralization = null, $code = null)
+ public function __construct($message, $messageTemplate, array $messageParameters, $root, $propertyPath, $invalidValue, $messagePluralization = null, $code = null)
{
+ $this->message = $message;
$this->messageTemplate = $messageTemplate;
$this->messageParameters = $messageParameters;
$this->messagePluralization = $messagePluralization;
@@ -132,15 +139,7 @@ public function getMessagePluralization()
*/
public function getMessage()
{
- $parameters = $this->messageParameters;
-
- foreach ($parameters as $i => $parameter) {
- if (is_array($parameter)) {
- $parameters[$i] = 'Array';
- }
- }
-
- return strtr($this->messageTemplate, $parameters);
+ return $this->message;
}
/**
View
57 DefaultTranslator.php
@@ -0,0 +1,57 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator;
+
+use Symfony\Component\Translation\TranslatorInterface;
+
+/**
+ * Simple translator implementation that simply replaces the parameters in
+ * the message IDs.
+ *
+ * Does not support translation domains or locales.
+ *
+ * @author Bernhard Schussek <bschussek@gmail.com>
+ */
+class DefaultTranslator implements TranslatorInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function trans($id, array $parameters = array(), $domain = null, $locale = null)
+ {
+ return strtr($id, $parameters);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
+ {
+ return strtr($id, $parameters);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setLocale($locale)
+ {
+ throw new \BadMethodCallException('Unsupported method.');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getLocale()
+ {
+ throw new \BadMethodCallException('Unsupported method.');
+ }
+}
View
37 ExecutionContext.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\Validator;
+use Symfony\Component\Translation\TranslatorInterface;
+
/**
* Default implementation of {@link ExecutionContextInterface}.
*
@@ -27,6 +29,16 @@ class ExecutionContext implements ExecutionContextInterface
private $globalContext;
/**
+ * @var TranslatorInterface
+ */
+ private $translator;
+
+ /**
+ * @var null|string
+ */
+ private $translationDomain;
+
+ /**
* @var MetadataInterface
*/
private $metadata;
@@ -49,19 +61,23 @@ class ExecutionContext implements ExecutionContextInterface
/**
* Creates a new execution context.
*
- * @param GlobalExecutionContextInterface $globalContext The global context storing node-independent state.
- * @param MetadataInterface $metadata The metadata of the validated node.
- * @param mixed $value The value of the validated node.
- * @param string $group The current validation group.
- * @param string $propertyPath The property path to the current node.
+ * @param GlobalExecutionContextInterface $globalContext The global context storing node-independent state.
+ * @param TranslatorInterface $translator The translator for translating violation messages.
+ * @param null|string $translationDomain The domain of the validation messages.
+ * @param MetadataInterface $metadata The metadata of the validated node.
+ * @param mixed $value The value of the validated node.
+ * @param string $group The current validation group.
+ * @param string $propertyPath The property path to the current node.
*/
- public function __construct(GlobalExecutionContextInterface $globalContext, MetadataInterface $metadata = null, $value = null, $group = null, $propertyPath = '')
+ public function __construct(GlobalExecutionContextInterface $globalContext, TranslatorInterface $translator, $translationDomain = null, MetadataInterface $metadata = null, $value = null, $group = null, $propertyPath = '')
{
if (null === $group) {
$group = Constraint::DEFAULT_GROUP;
}
$this->globalContext = $globalContext;
+ $this->translator = $translator;
+ $this->translationDomain = $translationDomain;
$this->metadata = $metadata;
$this->value = $value;
$this->propertyPath = $propertyPath;
@@ -74,6 +90,9 @@ public function __construct(GlobalExecutionContextInterface $globalContext, Meta
public function addViolation($message, array $params = array(), $invalidValue = null, $pluralization = null, $code = null)
{
$this->globalContext->getViolations()->add(new ConstraintViolation(
+ null === $pluralization
+ ? $this->translator->trans($message, $params, $this->translationDomain)
+ : $this->translator->transChoice($message, $pluralization, $params, $this->translationDomain),
$message,
$params,
$this->globalContext->getRoot(),
@@ -103,6 +122,9 @@ public function addViolationAtPath($propertyPath, $message, array $params = arra
trigger_error('addViolationAtPath() is deprecated since version 2.2 and will be removed in 2.3.', E_USER_DEPRECATED);
$this->globalContext->getViolations()->add(new ConstraintViolation(
+ null === $pluralization
+ ? $this->translator->trans($message, $params, $this->translationDomain)
+ : $this->translator->transChoice($message, $pluralization, $params, $this->translationDomain),
$message,
$params,
$this->globalContext->getRoot(),
@@ -146,6 +168,9 @@ public function addViolationAtSubPath($subPath, $message, array $params = array(
public function addViolationAt($subPath, $message, array $params = array(), $invalidValue = null, $pluralization = null, $code = null)
{
$this->globalContext->getViolations()->add(new ConstraintViolation(
+ null === $pluralization
+ ? $this->translator->trans($message, $params, $this->translationDomain)
+ : $this->translator->transChoice($message, $pluralization, $params, $this->translationDomain),
$message,
$params,
$this->globalContext->getRoot(),
View
19 GraphWalker.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\Validator;
use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Mapping\MemberMetadata;
@@ -40,6 +41,16 @@ class GraphWalker
private $metadataFactory;
/**
+ * @var TranslatorInterface
+ */
+ private $translator;
+
+ /**
+ * @var null|string
+ */
+ private $translationDomain;
+
+ /**
* @var array
*/
private $validatedObjects;
@@ -49,16 +60,20 @@ class GraphWalker
*
* @param ValidationVisitor $visitor
* @param MetadataFactoryInterface $metadataFactory
+ * @param TranslatorInterface $translator
+ * @param null|string $translationDomain
* @param array $validatedObjects
*
* @deprecated Deprecated since version 2.2, to be removed in 2.3.
*/
- public function __construct(ValidationVisitor $visitor, MetadataFactoryInterface $metadataFactory, array &$validatedObjects = array())
+ public function __construct(ValidationVisitor $visitor, MetadataFactoryInterface $metadataFactory, TranslatorInterface $translator, $translationDomain = null, array &$validatedObjects = array())
{
trigger_error('GraphWalker is deprecated since version 2.2 and will be removed in 2.3. This class has been replaced by ValidationVisitorInterface and MetadataInterface.', E_USER_DEPRECATED);
$this->visitor = $visitor;
$this->metadataFactory = $metadataFactory;
+ $this->translator = $translator;
+ $this->translationDomain = $translationDomain;
$this->validatedObjects = &$validatedObjects;
}
@@ -208,6 +223,8 @@ public function walkConstraint(Constraint $constraint, $value, $group, $property
$context = new ExecutionContext(
$this->visitor,
+ $this->translator,
+ $this->translationDomain,
$metadata,
$value,
$group,
View
2  Tests/ConstraintViolationListTest.php
@@ -129,6 +129,6 @@ public function testToString()
protected function getViolation($message, $root = null, $propertyPath = null)
{
- return new ConstraintViolation($message, array(), $root, $propertyPath, null);
+ return new ConstraintViolation($message, $message, array(), $root, $propertyPath, null);
}
}
View
1  Tests/ConstraintViolationTest.php
@@ -18,6 +18,7 @@ class ConstraintViolationTest extends \PHPUnit_Framework_TestCase
public function testToStringHandlesArrays()
{
$violation = new ConstraintViolation(
+ 'Array',
'{{ value }}',
array('{{ value }}' => array(1, 2, 3)),
'Root',
View
103 Tests/ExecutionContextTest.php
@@ -19,11 +19,14 @@
class ExecutionContextTest extends \PHPUnit_Framework_TestCase
{
+ const TRANS_DOMAIN = 'trans_domain';
+
private $visitor;
private $violations;
private $metadata;
private $metadataFactory;
private $globalContext;
+ private $translator;
/**
* @var ExecutionContext
@@ -51,7 +54,8 @@ protected function setUp()
$this->globalContext->expects($this->any())
->method('getMetadataFactory')
->will($this->returnValue($this->metadataFactory));
- $this->context = new ExecutionContext($this->globalContext, $this->metadata, 'currentValue', 'Group', 'foo.bar');
+ $this->translator = $this->getMock('Symfony\Component\Translation\TranslatorInterface');
+ $this->context = new ExecutionContext($this->globalContext, $this->translator, self::TRANS_DOMAIN, $this->metadata, 'currentValue', 'Group', 'foo.bar');
}
protected function tearDown()
@@ -82,7 +86,7 @@ public function testInitWithClassMetadata()
{
// BC
$this->metadata = new ClassMetadata(__NAMESPACE__ . '\ExecutionContextTest_TestClass');
- $this->context = new ExecutionContext($this->globalContext, $this->metadata, 'currentValue', 'Group', 'foo.bar');
+ $this->context = new ExecutionContext($this->globalContext, $this->translator, self::TRANS_DOMAIN, $this->metadata, 'currentValue', 'Group', 'foo.bar');
$this->assertSame(__NAMESPACE__ . '\ExecutionContextTest_TestClass', $this->context->getCurrentClass());
$this->assertNull($this->context->getCurrentProperty());
@@ -92,7 +96,7 @@ public function testInitWithPropertyMetadata()
{
// BC
$this->metadata = new PropertyMetadata(__NAMESPACE__ . '\ExecutionContextTest_TestClass', 'myProperty');
- $this->context = new ExecutionContext($this->globalContext, $this->metadata, 'currentValue', 'Group', 'foo.bar');
+ $this->context = new ExecutionContext($this->globalContext, $this->translator, self::TRANS_DOMAIN, $this->metadata, 'currentValue', 'Group', 'foo.bar');
$this->assertSame(__NAMESPACE__ . '\ExecutionContextTest_TestClass', $this->context->getCurrentClass());
$this->assertSame('myProperty', $this->context->getCurrentProperty());
@@ -111,10 +115,16 @@ public function testClone()
public function testAddViolation()
{
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array('foo' => 'bar'))
+ ->will($this->returnValue('Translated error'));
+
$this->context->addViolation('Error', array('foo' => 'bar'), 'invalid');
$this->assertEquals(new ConstraintViolationList(array(
new ConstraintViolation(
+ 'Translated error',
'Error',
array('foo' => 'bar'),
'Root',
@@ -126,10 +136,16 @@ public function testAddViolation()
public function testAddViolationUsesPreconfiguredValueIfNotPassed()
{
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array())
+ ->will($this->returnValue('Translated error'));
+
$this->context->addViolation('Error');
$this->assertEquals(new ConstraintViolationList(array(
new ConstraintViolation(
+ 'Translated error',
'Error',
array(),
'Root',
@@ -141,21 +157,32 @@ public function testAddViolationUsesPreconfiguredValueIfNotPassed()
public function testAddViolationUsesPassedNullValue()
{
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array('foo1' => 'bar1'))
+ ->will($this->returnValue('Translated error'));
+ $this->translator->expects($this->once())
+ ->method('transChoice')
+ ->with('Choice error', 1, array('foo2' => 'bar2'))
+ ->will($this->returnValue('Translated choice error'));
+
// passed null value should override preconfigured value "invalid"
- $this->context->addViolation('Error', array('foo' => 'bar'), null);
- $this->context->addViolation('Error', array('foo' => 'bar'), null, 1);
+ $this->context->addViolation('Error', array('foo1' => 'bar1'), null);
+ $this->context->addViolation('Choice error', array('foo2' => 'bar2'), null, 1);
$this->assertEquals(new ConstraintViolationList(array(
new ConstraintViolation(
+ 'Translated error',
'Error',
- array('foo' => 'bar'),
+ array('foo1' => 'bar1'),
'Root',
'foo.bar',
null
),
new ConstraintViolation(
- 'Error',
- array('foo' => 'bar'),
+ 'Translated choice error',
+ 'Choice error',
+ array('foo2' => 'bar2'),
'Root',
'foo.bar',
null,
@@ -166,11 +193,17 @@ public function testAddViolationUsesPassedNullValue()
public function testAddViolationAtPath()
{
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array('foo' => 'bar'))
+ ->will($this->returnValue('Translated error'));
+
// override preconfigured property path
$this->context->addViolationAtPath('bar.baz', 'Error', array('foo' => 'bar'), 'invalid');
$this->assertEquals(new ConstraintViolationList(array(
new ConstraintViolation(
+ 'Translated error',
'Error',
array('foo' => 'bar'),
'Root',
@@ -182,10 +215,16 @@ public function testAddViolationAtPath()
public function testAddViolationAtPathUsesPreconfiguredValueIfNotPassed()
{
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array())
+ ->will($this->returnValue('Translated error'));
+
$this->context->addViolationAtPath('bar.baz', 'Error');
$this->assertEquals(new ConstraintViolationList(array(
new ConstraintViolation(
+ 'Translated error',
'Error',
array(),
'Root',
@@ -197,12 +236,22 @@ public function testAddViolationAtPathUsesPreconfiguredValueIfNotPassed()
public function testAddViolationAtPathUsesPassedNullValue()
{
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array('foo' => 'bar'))
+ ->will($this->returnValue('Translated error'));
+ $this->translator->expects($this->once())
+ ->method('transChoice')
+ ->with('Choice error', 3, array('foo' => 'bar'))
+ ->will($this->returnValue('Translated choice error'));
+
// passed null value should override preconfigured value "invalid"
$this->context->addViolationAtPath('bar.baz', 'Error', array('foo' => 'bar'), null);
- $this->context->addViolationAtPath('bar.baz', 'Error', array('foo' => 'bar'), null, 1);
+ $this->context->addViolationAtPath('bar.baz', 'Choice error', array('foo' => 'bar'), null, 3);
$this->assertEquals(new ConstraintViolationList(array(
new ConstraintViolation(
+ 'Translated error',
'Error',
array('foo' => 'bar'),
'Root',
@@ -210,23 +259,30 @@ public function testAddViolationAtPathUsesPassedNullValue()
null
),
new ConstraintViolation(
- 'Error',
+ 'Translated choice error',
+ 'Choice error',
array('foo' => 'bar'),
'Root',
'bar.baz',
null,
- 1
+ 3
),
)), $this->context->getViolations());
}
public function testAddViolationAt()
{
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array('foo' => 'bar'))
+ ->will($this->returnValue('Translated error'));
+
// override preconfigured property path
$this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), 'invalid');
$this->assertEquals(new ConstraintViolationList(array(
new ConstraintViolation(
+ 'Translated error',
'Error',
array('foo' => 'bar'),
'Root',
@@ -238,10 +294,16 @@ public function testAddViolationAt()
public function testAddViolationAtUsesPreconfiguredValueIfNotPassed()
{
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array())
+ ->will($this->returnValue('Translated error'));
+
$this->context->addViolationAt('bam.baz', 'Error');
$this->assertEquals(new ConstraintViolationList(array(
new ConstraintViolation(
+ 'Translated error',
'Error',
array(),
'Root',
@@ -253,12 +315,22 @@ public function testAddViolationAtUsesPreconfiguredValueIfNotPassed()
public function testAddViolationAtUsesPassedNullValue()
{
+ $this->translator->expects($this->once())
+ ->method('trans')
+ ->with('Error', array('foo' => 'bar'))
+ ->will($this->returnValue('Translated error'));
+ $this->translator->expects($this->once())
+ ->method('transChoice')
+ ->with('Choice error', 2, array('foo' => 'bar'))
+ ->will($this->returnValue('Translated choice error'));
+
// passed null value should override preconfigured value "invalid"
$this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), null);
- $this->context->addViolationAt('bam.baz', 'Error', array('foo' => 'bar'), null, 1);
+ $this->context->addViolationAt('bam.baz', 'Choice error', array('foo' => 'bar'), null, 2);
$this->assertEquals(new ConstraintViolationList(array(
new ConstraintViolation(
+ 'Translated error',
'Error',
array('foo' => 'bar'),
'Root',
@@ -266,12 +338,13 @@ public function testAddViolationAtUsesPassedNullValue()
null
),
new ConstraintViolation(
- 'Error',
+ 'Translated choice error',
+ 'Choice error',
array('foo' => 'bar'),
'Root',
'foo.bar.bam.baz',
null,
- 1
+ 2
),
)), $this->context->getViolations());
}
@@ -293,7 +366,7 @@ public function testGetPropertyPathWithEmptyPath()
public function testGetPropertyPathWithEmptyCurrentPropertyPath()
{
- $this->context = new ExecutionContext($this->globalContext, $this->metadata, 'currentValue', 'Group', '');
+ $this->context = new ExecutionContext($this->globalContext, $this->translator, self::TRANS_DOMAIN, $this->metadata, 'currentValue', 'Group', '');
$this->assertEquals('bam.baz', $this->context->getPropertyPath('bam.baz'));
}
View
11 Tests/GraphWalkerTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\Validator\Tests;
use Symfony\Component\Validator\Tests\Fixtures\ConstraintAValidator;
+use Symfony\Component\Validator\DefaultTranslator;
use Symfony\Component\Validator\ValidationVisitor;
use Symfony\Component\Validator\Tests\Fixtures\Entity;
use Symfony\Component\Validator\Tests\Fixtures\Reference;
@@ -53,7 +54,7 @@ class GraphWalkerTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->metadataFactory = new FakeMetadataFactory();
- $this->visitor = new ValidationVisitor('Root', $this->metadataFactory, new ConstraintValidatorFactory());
+ $this->visitor = new ValidationVisitor('Root', $this->metadataFactory, new ConstraintValidatorFactory(), new DefaultTranslator());
$this->walker = $this->visitor->getGraphWalker();
$this->metadata = new ClassMetadata(self::CLASSNAME);
$this->metadataFactory->addMetadata($this->metadata);
@@ -173,6 +174,7 @@ public function testWalkObjectInDefaultGroupTraversesGroupSequence()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'firstName',
@@ -205,6 +207,7 @@ public function testWalkObjectInGroupSequencePropagatesDefaultGroup()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'reference',
@@ -232,6 +235,7 @@ public function testWalkObjectInOtherGroupTraversesNoGroupSequence()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'lastName',
@@ -286,6 +290,7 @@ public function testWalkCascadedPropertyValidatesReferences()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'path',
@@ -318,6 +323,7 @@ public function testWalkCascadedPropertyValidatesArraysByDefault()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'path[key]',
@@ -351,6 +357,7 @@ public function testWalkCascadedPropertyValidatesTraversableByDefault()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'path[key]',
@@ -450,6 +457,7 @@ public function testWalkCascadedPropertyRecursesIfDeepIsSet()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'path[key][nested]',
@@ -516,6 +524,7 @@ public function testWalkConstraintBuildsAViolationIfFailed()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'message',
+ 'message',
array('param' => 'value'),
'Root',
'firstName.path',
View
16 Tests/ValidationVisitorTest.php
@@ -14,6 +14,7 @@
use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
use Symfony\Component\Validator\Constraints\Valid;
use Symfony\Component\Validator\Tests\Fixtures\Reference;
+use Symfony\Component\Validator\DefaultTranslator;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\Tests\Fixtures\FailingConstraint;
@@ -49,7 +50,7 @@ class ValidationVisitorTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->metadataFactory = new FakeMetadataFactory();
- $this->visitor = new ValidationVisitor('Root', $this->metadataFactory, new ConstraintValidatorFactory());
+ $this->visitor = new ValidationVisitor('Root', $this->metadataFactory, new ConstraintValidatorFactory(), new DefaultTranslator());
$this->metadata = new ClassMetadata(self::CLASS_NAME);
$this->metadataFactory->addMetadata($this->metadata);
}
@@ -155,6 +156,7 @@ public function testValidateInDefaultGroupTraversesGroupSequence()
$violations = new ConstraintViolationList(array(
new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'firstName',
@@ -188,6 +190,7 @@ public function testValidateInGroupSequencePropagatesDefaultGroup()
$violations = new ConstraintViolationList(array(
new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'reference',
@@ -216,6 +219,7 @@ public function testValidateInOtherGroupTraversesNoGroupSequence()
$violations = new ConstraintViolationList(array(
new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'lastName',
@@ -244,6 +248,7 @@ public function testValidateCascadedPropertyValidatesReferences()
// generated by the root object
new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'',
@@ -252,6 +257,7 @@ public function testValidateCascadedPropertyValidatesReferences()
// generated by the reference
new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'reference',
@@ -279,6 +285,7 @@ public function testValidateCascadedPropertyValidatesArraysByDefault()
// generated by the root object
new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'',
@@ -287,6 +294,7 @@ public function testValidateCascadedPropertyValidatesArraysByDefault()
// generated by the reference
new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'reference[key]',
@@ -314,6 +322,7 @@ public function testValidateCascadedPropertyValidatesTraversableByDefault()
// generated by the root object
new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'',
@@ -322,6 +331,7 @@ public function testValidateCascadedPropertyValidatesTraversableByDefault()
// generated by the reference
new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'reference[key]',
@@ -353,6 +363,7 @@ public function testValidateCascadedPropertyDoesNotValidateTraversableIfDisabled
// generated by the root object
new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'',
@@ -415,6 +426,7 @@ public function testValidateCascadedPropertyDoesNotRecurseByDefault()
// generated by the root object
new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'',
@@ -490,6 +502,7 @@ public function testValidateCascadedPropertyRecursesIfDeepIsSet()
// generated by the root object
new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'',
@@ -498,6 +511,7 @@ public function testValidateCascadedPropertyRecursesIfDeepIsSet()
// nothing generated by the reference!
new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'Root',
'reference[key][nested]',
View
16 Tests/ValidatorBuilderTest.php
@@ -96,8 +96,8 @@ public function testSetMetadataFactory()
public function testSetMetadataCache()
{
- $this->assertSame($this->builder, $this->builder->setMetadataCache($this->getMock(
- 'Symfony\Component\Validator\Mapping\Cache\CacheInterface'))
+ $this->assertSame($this->builder, $this->builder->setMetadataCache(
+ $this->getMock('Symfony\Component\Validator\Mapping\Cache\CacheInterface'))
);
}
@@ -107,4 +107,16 @@ public function testSetConstraintValidatorFactory()
$this->getMock('Symfony\Component\Validator\ConstraintValidatorFactoryInterface'))
);
}
+
+ public function testSetTranslator()
+ {
+ $this->assertSame($this->builder, $this->builder->setTranslator(
+ $this->getMock('Symfony\Component\Translation\TranslatorInterface'))
+ );
+ }
+
+ public function testSetTranslationDomain()
+ {
+ $this->assertSame($this->builder, $this->builder->setTranslationDomain('TRANS_DOMAIN'));
+ }
}
View
3  Tests/ValidatorContextTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\Validator\Tests;
use Symfony\Component\Validator\Validator;
+use Symfony\Component\Validator\DefaultTranslator;
use Symfony\Component\Validator\Mapping\ClassMetadataFactoryAdapter;
use Symfony\Component\Validator\ValidatorContext;
@@ -57,6 +58,6 @@ public function testGetValidator()
->setConstraintValidatorFactory($validatorFactory)
->getValidator();
- $this->assertEquals(new Validator(new ClassMetadataFactoryAdapter($metadataFactory), $validatorFactory), $validator);
+ $this->assertEquals(new Validator(new ClassMetadataFactoryAdapter($metadataFactory), $validatorFactory, new DefaultTranslator()), $validator);
}
}
View
3  Tests/ValidatorFactoryTest.php
@@ -14,6 +14,7 @@
use Doctrine\Common\Annotations\AnnotationReader;
use Symfony\Component\Validator\Mapping\ClassMetadataFactoryAdapter;
use Symfony\Component\Validator\Validator;
+use Symfony\Component\Validator\DefaultTranslator;
use Symfony\Component\Validator\ValidatorContext;
use Symfony\Component\Validator\ValidatorFactory;
use Symfony\Component\Validator\ConstraintValidatorFactory;
@@ -78,7 +79,7 @@ public function testGetValidator()
$validator = $this->factory->getValidator();
- $this->assertEquals(new Validator(new ClassMetadataFactoryAdapter($metadataFactory), $validatorFactory), $validator);
+ $this->assertEquals(new Validator(new ClassMetadataFactoryAdapter($metadataFactory), $validatorFactory, new DefaultTranslator()), $validator);
}
public function testBuildDefaultFromAnnotationsWithCustomNamespaces()
View
14 Tests/ValidatorTest.php
@@ -16,6 +16,7 @@
use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
use Symfony\Component\Validator\Tests\Fixtures\FailingConstraint;
use Symfony\Component\Validator\Validator;
+use Symfony\Component\Validator\DefaultTranslator;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Component\Validator\ConstraintValidatorFactory;
@@ -37,7 +38,7 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase
protected function setUp()
{
$this->metadataFactory = new FakeMetadataFactory();
- $this->validator = new Validator($this->metadataFactory, new ConstraintValidatorFactory());
+ $this->validator = new Validator($this->metadataFactory, new ConstraintValidatorFactory(), new DefaultTranslator());
}
protected function tearDown()
@@ -60,6 +61,7 @@ public function testValidate_defaultGroup()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
$entity,
'firstName',
@@ -83,6 +85,7 @@ public function testValidate_oneGroup()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
$entity,
'lastName',
@@ -108,6 +111,7 @@ public function testValidate_multipleGroups()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
$entity,
'firstName',
@@ -115,6 +119,7 @@ public function testValidate_multipleGroups()
));
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
$entity,
'lastName',
@@ -142,6 +147,7 @@ public function testValidate_groupSequenceProvider()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
$entity,
'firstName',
@@ -155,6 +161,7 @@ public function testValidate_groupSequenceProvider()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
$entity,
'lastName',
@@ -199,6 +206,7 @@ public function testValidateValue()
$violations = new ConstraintViolationList();
$violations->add(new ConstraintViolation(
'Failed',
+ 'Failed',
array(),
'',
'',
@@ -232,7 +240,7 @@ public function testValidatePropertyFailsIfPropertiesNotSupported()
->method('getMetadataFor')
->with('VALUE')
->will($this->returnValue($metadata));
- $this->validator = new Validator($this->metadataFactory, new ConstraintValidatorFactory());
+ $this->validator = new Validator($this->metadataFactory, new ConstraintValidatorFactory(), new DefaultTranslator());
$this->validator->validateProperty('VALUE', 'someProperty');
}
@@ -249,7 +257,7 @@ public function testValidatePropertyValueFailsIfPropertiesNotSupported()
->method('getMetadataFor')
->with('VALUE')
->will($this->returnValue($metadata));
- $this->validator = new Validator($this->metadataFactory, new ConstraintValidatorFactory());
+ $this->validator = new Validator($this->metadataFactory, new ConstraintValidatorFactory(), new DefaultTranslator());
$this->validator->validatePropertyValue('VALUE', 'someProperty', 'propertyValue');
}
View
21 ValidationVisitor.php
@@ -13,6 +13,7 @@
use Symfony\Component\Validator\Exception\NoSuchMetadataException;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+use Symfony\Component\Translation\TranslatorInterface;
/**
* Default implementation of {@link ValidationVisitorInterface} and
@@ -38,6 +39,16 @@ class ValidationVisitor implements ValidationVisitorInterface, GlobalExecutionCo
private $validatorFactory;
/**
+ * @var TranslatorInterface
+ */
+ private $translator;
+
+ /**
+ * @var null|string
+ */
+ private $translationDomain;
+
+ /**
* @var array
*/
private $objectInitializers;
@@ -65,11 +76,13 @@ class ValidationVisitor implements ValidationVisitorInterface, GlobalExecutionCo
* @param mixed $root The value passed to the validator.
* @param MetadataFactoryInterface $metadataFactory The factory for obtaining metadata instances.
* @param ConstraintValidatorFactoryInterface $validatorFactory The factory for creating constraint validators.
+ * @param TranslatorInterface $translator The translator for translating violation messages.
+ * @param string|null $translationDomain The domain of the translation messages.
* @param ObjectInitializerInterface[] $objectInitializers The initializers for preparing objects before validation.
*
* @throws UnexpectedTypeException If any of the object initializers is not an instance of ObjectInitializerInterface
*/
- public function __construct($root, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, array $objectInitializers = array())
+ public function __construct($root, MetadataFactoryInterface $metadataFactory, ConstraintValidatorFactoryInterface $validatorFactory, TranslatorInterface $translator, $translationDomain = null, array $objectInitializers = array())
{
foreach ($objectInitializers as $initializer) {
if (!$initializer instanceof ObjectInitializerInterface) {
@@ -80,6 +93,8 @@ public function __construct($root, MetadataFactoryInterface $metadataFactory, Co
$this->root = $root;
$this->metadataFactory = $metadataFactory;
$this->validatorFactory = $validatorFactory;
+ $this->translator = $translator;
+ $this->translationDomain = $translationDomain;
$this->objectInitializers = $objectInitializers;
$this->violations = new ConstraintViolationList();
}
@@ -91,6 +106,8 @@ public function visit(MetadataInterface $metadata, $value, $group, $propertyPath
{
$context = new ExecutionContext(
$this,
+ $this->translator,
+ $this->translationDomain,
$metadata,
$value,
$group,
@@ -161,7 +178,7 @@ public function getGraphWalker()
trigger_error('getGraphWalker() is deprecated since version 2.2 and will be removed in 2.3.', E_USER_DEPRECATED);
if (null === $this->graphWalker) {
- $this->graphWalker = new GraphWalker($this, $this->metadataFactory, $this->validatedObjects);
+ $this->graphWalker = new GraphWalker($this, $this->metadataFactory, $this->translator, $this->translationDomain, $this->validatedObjects);
}
return $this->graphWalker;
View
26 Validator.php
@@ -13,6 +13,7 @@
use Symfony\Component\Validator\Constraints\Valid;
use Symfony\Component\Validator\Exception\ValidatorException;
+use Symfony\Component\Translation\TranslatorInterface;
/**
* Default implementation of {@link ValidatorInterface}.
@@ -33,6 +34,16 @@ class Validator implements ValidatorInterface
private $validatorFactory;
/**
+ * @var TranslatorInterface
+ */
+ private $translator;
+
+ /**
+ * @var null|string
+ */
+ private $translationDomain;
+
+ /**
* @var array
*/
private $objectInitializers;
@@ -40,11 +51,15 @@ class Validator implements ValidatorInterface
public function __construct(
MetadataFactoryInterface $metadataFactory,
ConstraintValidatorFactoryInterface $validatorFactory,
+ TranslatorInterface $translator,
+ $translationDomain = null,
array $objectInitializers = array()
)
{
$this->metadataFactory = $metadataFactory;
$this->validatorFactory = $validatorFactory;
+ $this->translator = $translator;
+ $this->translationDomain = $translationDomain;
$this->objectInitializers = $objectInitializers;
}
@@ -137,7 +152,7 @@ public function validatePropertyValue($containingValue, $property, $value, $grou
*/
public function validateValue($value, $constraints, $groups = null)
{
- $context = new ExecutionContext($this->createVisitor(null));
+ $context = new ExecutionContext($this->createVisitor(null), $this->translator, $this->translationDomain);
$constraints = is_array($constraints) ? $constraints : array($constraints);
@@ -176,7 +191,14 @@ public function validateValue($value, $constraints, $groups = null)
*/
private function createVisitor($root)
{
- return new ValidationVisitor($root, $this->metadataFactory, $this->validatorFactory, $this->objectInitializers);
+ return new ValidationVisitor(
+ $root,
+ $this->metadataFactory,
+ $this->validatorFactory,
+ $this->translator,
+ $this->translationDomain,
+ $this->objectInitializers
+ );
}
/**
View
34 ValidatorBuilder.php
@@ -23,6 +23,7 @@
use Symfony\Component\Validator\Mapping\Loader\YamlFilesLoader;
use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader;
use Symfony\Component\Validator\Mapping\Loader\XmlFilesLoader;
+use Symfony\Component\Translation\TranslatorInterface;
use Doctrine\Common\Annotations\Reader;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\Common\Annotations\CachedReader;
@@ -76,6 +77,16 @@ class ValidatorBuilder implements ValidatorBuilderInterface
private $metadataCache;
/**
+ * @var TranslatorInterface
+ */
+ private $translator;
+
+ /**
+ * @var null|string
+ */
+ private $translationDomain;
+
+ /**
* {@inheritdoc}
*/
public function addObjectInitializer(ObjectInitializerInterface $initializer)
@@ -257,6 +268,26 @@ public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterfac
/**
* {@inheritdoc}
*/
+ public function setTranslator(TranslatorInterface $translator)
+ {
+ $this->translator = $translator;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setTranslationDomain($translationDomain)
+ {
+ $this->translationDomain = $translationDomain;
+
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function getValidator()
{
$metadataFactory = $this->metadataFactory;
@@ -296,7 +327,8 @@ public function getValidator()
}
$validatorFactory = $this->validatorFactory ?: new ConstraintValidatorFactory();
+ $translator = $this->translator ?: new DefaultTranslator();
- return new Validator($metadataFactory, $validatorFactory, $this->initializers);
+ return new Validator($metadataFactory, $validatorFactory, $translator, $this->translationDomain, $this->initializers);
}
}
View
23 ValidatorBuilderInterface.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\Validator;
use Symfony\Component\Validator\Mapping\Cache\CacheInterface;
+use Symfony\Component\Translation\TranslatorInterface;
use Doctrine\Common\Annotations\Reader;
/**
@@ -140,6 +141,28 @@ public function setMetadataCache(CacheInterface $cache);
public function setConstraintValidatorFactory(ConstraintValidatorFactoryInterface $validatorFactory);
/**
+ * Sets the translator used for translating violation messages.
+ *
+ * @param TranslatorInterface $translator The translator instance.
+ *
+ * @return ValidatorBuilderInterface The builder object.
+ */
+ public function setTranslator(TranslatorInterface $translator);
+
+ /**
+ * Sets the default translation domain of violation messages.
+ *
+ * The same message can have different translations in different domains.
+ * Pass the domain that is used for violation messages by default to this
+ * method.
+ *
+ * @param string $translationDomain The translation domain of the violation messages.
+ *
+ * @return ValidatorBuilderInterface The builder object.
+ */
+ public function setTranslationDomain($translationDomain);
+
+ /**
* Builds and returns a new validator object.
*
* @return ValidatorInterface The built validator.
View
3  ValidatorContext.php
@@ -89,7 +89,8 @@ public function getValidator()
return new Validator(
$this->metadataFactory,
- $this->constraintValidatorFactory
+ $this->constraintValidatorFactory,
+ new DefaultTranslator()
);
}
View
3  composer.json
@@ -16,7 +16,8 @@
}
],
"require": {
- "php": ">=5.3.3"
+ "php": ">=5.3.3",
+ "symfony/translation": "2.2.*"
},
"require-dev": {
"symfony/http-foundation": "2.2.*",
Please sign in to comment.
Something went wrong with that request. Please try again.