Skip to content

[Validator] Integrated the Translator in the Validator component #6137

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 9, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions UPGRADE-2.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,26 @@
Symfony\Component\Form\Exception namespace or to create custom exception
classes for your purpose.

* Translating validation errors is now optional. You can still do so
manually if you like, or you can simplify your templates to simply output
the already translated message.

Before:

```
{{
error.messagePluralization is null
? error.messageTemplate|trans(error.messageParameters, 'validators')
: error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'validators')
}}
```

After:

```
{{ error.message }}
```

#### Deprecations

* The methods `getParent()`, `setParent()` and `hasParent()` in
Expand Down Expand Up @@ -186,6 +206,27 @@
}
```

* The sources of the pluralized messages in translation files have changed
from the singular to the pluralized version. If you created custom
translation files for validator errors, you should adapt them.

Before:

<trans-unit id="6">
<source>You must select at least {{ limit }} choices.</source>
<target>Sie müssen mindestens {{ limit }} Möglichkeit wählen.|Sie müssen mindestens {{ limit }} Möglichkeiten wählen.</target>
</trans-unit>

After:

<trans-unit id="6">
<source>You must select at least {{ limit }} choice.|You must select at least {{ limit }} choices.</source>
<target>Sie müssen mindestens {{ limit }} Möglichkeit wählen.|Sie müssen mindestens {{ limit }} Möglichkeiten wählen.</target>
</trans-unit>

Check the file src/Symfony/Component/Validator/Resources/translations/validators.en.xlf
for the new message sources.

#### Deprecations

* The interface `ClassMetadataFactoryInterface` was deprecated and will be
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Bridge\Doctrine\Tests\Validator\Constraints;

use Symfony\Bridge\Doctrine\Tests\DoctrineOrmTestCase;
use Symfony\Component\Validator\DefaultTranslator;
use Symfony\Component\Validator\Tests\Fixtures\FakeMetadataFactory;
use Symfony\Bridge\Doctrine\Tests\Fixtures\SingleIdentEntity;
use Symfony\Bridge\Doctrine\Tests\Fixtures\DoubleIdentEntity;
Expand Down Expand Up @@ -132,7 +133,7 @@ public function createValidator($entityManagerName, $em, $validateClass = null,
$metadataFactory->addMetadata($metadata);
$validatorFactory = $this->createValidatorFactory($uniqueValidator);

return new Validator($metadataFactory, $validatorFactory);
return new Validator($metadataFactory, $validatorFactory, new DefaultTranslator());
}

private function createSchema($em)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,7 @@
{% if errors|length > 0 %}
<ul>
{% for error in errors %}
<li>{{
error.messagePluralization is null
? error.messageTemplate|trans(error.messageParameters, 'validators')
: error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'validators')
}}</li>
<li>{{ error.message }}</li>
{% endfor %}
</ul>
{% endif %}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ public function process(ContainerBuilder $container)
$initializers[] = new Reference($id);
}

$container->getDefinition('validator')->replaceArgument(2, $initializers);
$container->getDefinition('validator')->replaceArgument(4, $initializers);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ private function addValidationSection(ArrayNodeDefinition $rootNode)
->children()
->scalarNode('cache')->end()
->booleanNode('enable_annotations')->defaultFalse()->end()
->scalarNode('translation_domain')->defaultValue('validators')->end()
->end()
->end()
->end()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ private function registerValidationConfiguration(array $config, ContainerBuilder
{
$loader->load('validator.xml');

$container->setParameter('validator.translation_domain', $config['translation_domain']);
$container->setParameter('validator.mapping.loader.xml_files_loader.mapping_files', $this->getValidatorXmlMappingFiles($container));
$container->setParameter('validator.mapping.loader.yaml_files_loader.mapping_files', $this->getValidatorYamlMappingFiles($container));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
<service id="validator" class="%validator.class%">
<argument type="service" id="validator.mapping.class_metadata_factory" />
<argument type="service" id="validator.validator_factory" />
<argument type="service" id="translator.default" />
<argument>%validator.translation_domain%</argument>
<argument type="collection" />
</service>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
<?php if ($errors): ?>
<ul>
<?php foreach ($errors as $error): ?>
<li><?php
if (null === $error->getMessagePluralization()) {
echo $view['translator']->trans(
$error->getMessageTemplate(),
$error->getMessageParameters(),
'validators'
);
} else {
echo $view['translator']->transChoice(
$error->getMessageTemplate(),
$error->getMessagePluralization(),
$error->getMessageParameters(),
'validators'
);
}?></li>
<li><?php echo $error->getMessage() ?></li>
<?php endforeach; ?>
</ul>
<?php endif ?>

This file was deleted.

1 change: 1 addition & 0 deletions src/Symfony/Component/Form/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ CHANGELOG
* deprecated FormException and introduced ExceptionInterface instead
* [BC BREAK] FormException is now an interface
* protected FormBuilder methods from being called when it is turned into a FormConfigInterface with getFormConfig()
* [BC BREAK] inserted argument `$message` in the constructor of `FormError`

2.1.0
-----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ public function mapViolation(ConstraintViolation $violation, FormInterface $form
// Only add the error if the form is synchronized
if ($this->acceptsErrors($scope)) {
$scope->addError(new FormError(
$violation->getMessage(),
$violation->getMessageTemplate(),
$violation->getMessageParameters(),
$violation->getMessagePluralization()
Expand Down
18 changes: 13 additions & 5 deletions src/Symfony/Component/Form/FormError.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
*/
class FormError
{
/**
* @var string
*/
private $message;

/**
* The template for the error message
* @var string
Expand All @@ -41,16 +46,19 @@ class FormError
*
* Any array key in $messageParameters will be used as a placeholder in
* $messageTemplate.
* @see \Symfony\Component\Translation\Translator
*
* @param string $messageTemplate The template for the error message
* @param string $message The translated error message
* @param string|null $messageTemplate The template for the error message
* @param array $messageParameters The parameters that should be
* substituted in the message template.
* @param integer|null $messagePluralization The value for error message pluralization
*
* @see \Symfony\Component\Translation\Translator
*/
public function __construct($messageTemplate, array $messageParameters = array(), $messagePluralization = null)
public function __construct($message, $messageTemplate = null, array $messageParameters = array(), $messagePluralization = null)
{
$this->messageTemplate = $messageTemplate;
$this->message = $message;
$this->messageTemplate = $messageTemplate ?: $message;
$this->messageParameters = $messageParameters;
$this->messagePluralization = $messagePluralization;
}
Expand All @@ -62,7 +70,7 @@ public function __construct($messageTemplate, array $messageParameters = array()
*/
public function getMessage()
{
return strtr($this->messageTemplate, $this->messageParameters);
return $this->message;
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/Symfony/Component/Form/Tests/AbstractDivLayoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ abstract class AbstractDivLayoutTest extends AbstractLayoutTest
public function testRow()
{
$form = $this->factory->createNamed('name', 'text');
$form->addError(new FormError('Error!'));
$form->addError(new FormError('[trans]Error![/trans]'));
$view = $form->createView();
$html = $this->renderRow($view);

Expand Down Expand Up @@ -58,7 +58,7 @@ public function testRowOverrideVariables()
public function testRepeatedRow()
{
$form = $this->factory->createNamed('name', 'repeated');
$form->addError(new FormError('Error!'));
$form->addError(new FormError('[trans]Error![/trans]'));
$view = $form->createView();
$html = $this->renderRow($view);

Expand Down Expand Up @@ -398,7 +398,7 @@ public function testNestedFormError()
)
->getForm();

$form->get('child')->addError(new FormError('Error!'));
$form->get('child')->addError(new FormError('[trans]Error![/trans]'));

$this->assertWidgetMatchesXpath($form->createView(), array(),
'/div
Expand Down
8 changes: 4 additions & 4 deletions src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,8 @@ public function testLabelWithCustomTextAsOptionAndCustomAttributesPassedDirectly
public function testErrors()
{
$form = $this->factory->createNamed('name', 'text');
$form->addError(new FormError('Error 1'));
$form->addError(new FormError('Error 2'));
$form->addError(new FormError('[trans]Error 1[/trans]'));
$form->addError(new FormError('[trans]Error 2[/trans]'));
$view = $form->createView();
$html = $this->renderErrors($view);

Expand Down Expand Up @@ -1151,7 +1151,7 @@ public function testDateErrorBubbling()
{
$child = $this->factory->createNamed('date', 'date');
$form = $this->factory->createNamed('form', 'form')->add($child);
$child->addError(new FormError('Error!'));
$child->addError(new FormError('[trans]Error![/trans]'));
$view = $form->createView();

$this->assertEmpty($this->renderErrors($view));
Expand Down Expand Up @@ -1676,7 +1676,7 @@ public function testTimeErrorBubbling()
{
$child = $this->factory->createNamed('time', 'time');
$form = $this->factory->createNamed('form', 'form')->add($child);
$child->addError(new FormError('Error!'));
$child->addError(new FormError('[trans]Error![/trans]'));
$view = $form->createView();

$this->assertEmpty($this->renderErrors($view));
Expand Down
6 changes: 3 additions & 3 deletions src/Symfony/Component/Form/Tests/AbstractTableLayoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ abstract class AbstractTableLayoutTest extends AbstractLayoutTest
public function testRow()
{
$form = $this->factory->createNamed('name', 'text');
$form->addError(new FormError('Error!'));
$form->addError(new FormError('[trans]Error![/trans]'));
$view = $form->createView();
$html = $this->renderRow($view);

Expand Down Expand Up @@ -91,7 +91,7 @@ public function testRepeatedRow()
public function testRepeatedRowWithErrors()
{
$form = $this->factory->createNamed('name', 'repeated');
$form->addError(new FormError('Error!'));
$form->addError(new FormError('[trans]Error![/trans]'));
$view = $form->createView();
$html = $this->renderRow($view);

Expand Down Expand Up @@ -250,7 +250,7 @@ public function testNestedFormError()
)
->getForm();

$form->get('child')->addError(new FormError('Error!'));
$form->get('child')->addError(new FormError('[trans]Error![/trans]'));

$this->assertWidgetMatchesXpath($form->createView(), array(),
'/table
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class ValidationListenerTest extends \PHPUnit_Framework_TestCase

private $message;

private $messageTemplate;

private $params;

protected function setUp()
Expand All @@ -63,17 +65,13 @@ protected function setUp()
$this->violationMapper = $this->getMock('Symfony\Component\Form\Extension\Validator\ViolationMapper\ViolationMapperInterface');
$this->listener = new ValidationListener($this->validator, $this->violationMapper);
$this->message = 'Message';
$this->messageTemplate = 'Message template';
$this->params = array('foo' => 'bar');
}

private function getConstraintViolation($code = null)
{
return new ConstraintViolation($this->message, $this->params, null, 'prop.path', null, null, $code);
}

private function getFormError()
{
return new FormError($this->message, $this->params);
return new ConstraintViolation($this->message, $this->messageTemplate, $this->params, null, 'prop.path', null, null, $code);
}

private function getBuilder($name = 'name', $propertyPath = null, $dataClass = null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ class ViolationMapperTest extends \PHPUnit_Framework_TestCase
*/
private $message;

/**
* @var string
*/
private $messageTemplate;

/**
* @var array
*/
Expand All @@ -62,6 +67,7 @@ protected function setUp()
$this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface');
$this->mapper = new ViolationMapper();
$this->message = 'Message';
$this->messageTemplate = 'Message template';
$this->params = array('foo' => 'bar');
}

Expand Down Expand Up @@ -101,15 +107,15 @@ private function getDataMapper()
*/
protected function getConstraintViolation($propertyPath)
{
return new ConstraintViolation($this->message, $this->params, null, $propertyPath, null);
return new ConstraintViolation($this->message, $this->messageTemplate, $this->params, null, $propertyPath, null);
}

/**
* @return FormError
*/
protected function getFormError()
{
return new FormError($this->message, $this->params);
return new FormError($this->message, $this->messageTemplate, $this->params);
}

public function testMapToVirtualFormIfDataDoesNotMatch()
Expand Down
11 changes: 11 additions & 0 deletions src/Symfony/Component/Validator/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ 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
* [BC BREAK] inserted argument `$message` in the constructor of `ConstraintViolation`
* [BC BREAK] inserted arguments `$translator` and `$translationDomain` in the constructor of `ExecutionContext`
* [BC BREAK] inserted arguments `$translator` and `$translationDomain` in the constructor of `GraphWalker`
* [BC BREAK] inserted arguments `$translator` and `$translationDomain` in the constructor of `ValidationVisitor`
* [BC BREAK] inserted arguments `$translator` and `$translationDomain` in the constructor of `Validator`
* [BC BREAK] added `setTranslator()` and `setTranslationDomain()` to `ValidatorBuilderInterface`
* improved the Validator to support pluralized messages by default
* [BC BREAK] changed the source of all pluralized messages in the translation files to the pluralized version
* added ExceptionInterface, BadMethodCallException and InvalidArgumentException

2.1.0
-----
Expand Down
Loading