merged branch hason/validator (PR #552)

Commits
-------

f9a486e [Validator] Added support for pluralization of the SizeLengthValidator
c0715f1 [FrameworkBundle], [TwigBundle] added support for form error message pluralization
7a6376e [Form] added support for error message pluralization
345981f [Validator] added support for plural messages

Discussion
----------

[Validator] Added support for plural error messages

Bug fix: no
Feature addition: yes
Backwards compatibility break: no
Symfony2 tests pass: yes
Todo: create translations for en and update others (FrameworkBundle)

[![Build Status](https://secure.travis-ci.org/hason/symfony.png?branch=validator)](http://travis-ci.org/hason/symfony)

---------------------------------------------------------------------------

by fabpot at 2011-05-14T20:41:01Z

@bschussek: What's your opinion?

---------------------------------------------------------------------------

by stof at 2011-09-04T13:14:29Z

@hason could you rebase your branch on top of master and update the PR ?

You also need to change the messages in the constraint that uses the pluralization to a pluralized format.

---------------------------------------------------------------------------

by stof at 2011-10-16T18:06:22Z

@hason ping

---------------------------------------------------------------------------

by stof at 2011-11-11T14:58:19Z

@hason ping again

---------------------------------------------------------------------------

by stof at 2011-12-12T20:39:10Z

@hason ping again. Can you update your PR ?

---------------------------------------------------------------------------

by hason at 2011-12-12T21:29:14Z

@stof I hope that I will update PR this week.

---------------------------------------------------------------------------

by bschussek at 2012-01-15T19:07:32Z

Looks good to me.

---------------------------------------------------------------------------

by canni at 2012-02-02T17:28:54Z

@hason can you update this PR and squash commits, it conflicts with current master

---------------------------------------------------------------------------

by hason at 2012-02-09T07:21:41Z

@stof, @canni Rebased.

What is the best solution for the translation of messages?

1. Change messages in the classes and all xliff files?
2. Keep messages in the classes and change all xliff files?

---------------------------------------------------------------------------

by stof at 2012-02-09T08:19:41Z

The constraints contain the en message so you will need to modify them to update the message

---------------------------------------------------------------------------

by hason at 2012-02-09T08:55:55Z

I prefer second option. The Validator component should be decoupled from the Translation component. The constraints contain the en message which is also the key for Translation component. We should create validators.en.xlf in the FrameworkBundle for en message. I think that this is better solution. What do you think?

---------------------------------------------------------------------------

by stof at 2012-04-04T02:22:02Z

@hason Please rebase your branch. It conflicts with master because of the move of the tests

@fabpot ping
This commit is contained in:
Fabien Potencier 2012-04-11 16:12:39 +02:00
commit cc833b13b6
14 changed files with 86 additions and 34 deletions

View File

@ -259,7 +259,13 @@
{% if errors|length > 0 %}
<ul>
{% for error in errors %}
<li>{{ error.messageTemplate|trans(error.messageParameters, 'validators') }}</li>
<li>{{
error.messagePluralization is null
?
error.messageTemplate|trans(error.messageParameters, 'validators')
:
error.messageTemplate|transchoice(error.messagePluralization, error.messageParameters, 'validators')
}}</li>
{% endfor %}
</ul>
{% endif %}

View File

@ -1,11 +1,21 @@
<?php if ($errors): ?>
<ul>
<?php foreach ($errors as $error): ?>
<li><?php echo $view['translator']->trans(
$error->getMessageTemplate(),
$error->getMessageParameters(),
'validators'
) ?></li>
<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>
<?php endforeach; ?>
</ul>
<?php endif ?>

View File

@ -61,7 +61,8 @@ class DelegatingValidator implements FormValidatorInterface
$propertyPath = new PropertyPath($violation->getPropertyPath());
$template = $violation->getMessageTemplate();
$parameters = $violation->getMessageParameters();
$error = new FormError($template, $parameters);
$pluralization = $violation->getMessagePluralization();
$error = new FormError($template, $parameters, $pluralization);
$child = $form;
foreach ($propertyPath->getElements() as $element) {
@ -82,7 +83,8 @@ class DelegatingValidator implements FormValidatorInterface
$propertyPath = $violation->getPropertyPath();
$template = $violation->getMessageTemplate();
$parameters = $violation->getMessageParameters();
$error = new FormError($template, $parameters);
$pluralization = $violation->getMessagePluralization();
$error = new FormError($template, $parameters, $pluralization);
foreach ($mapping as $mappedPath => $child) {
if (preg_match($mappedPath, $propertyPath)) {

View File

@ -30,6 +30,12 @@ class FormError
*/
protected $messageParameters;
/**
* The value for error message pluralization
* @var integer|null
*/
protected $messagePluralization;
/**
* Constructor
*
@ -37,14 +43,16 @@ class FormError
* $messageTemplate.
* @see Symfony\Component\Translation\Translator
*
* @param string $messageTemplate The template for the error message
* @param array $messageParameters The parameters that should be
* substituted in the message template.
* @param string $messageTemplate The template for the error message
* @param array $messageParameters The parameters that should be
* substituted in the message template.
* @param integer $messagePluralization The value for error message pluralization
*/
public function __construct($messageTemplate, array $messageParameters = array())
public function __construct($messageTemplate, array $messageParameters = array(), $messagePluralization = null)
{
$this->messageTemplate = $messageTemplate;
$this->messageParameters = $messageParameters;
$this->messagePluralization = $messagePluralization;
}
/**
@ -76,4 +84,14 @@ class FormError
{
return $this->messageParameters;
}
/**
* Returns the value for error message pluralization.
*
* @return integer|null
*/
public function getMessagePluralization()
{
return $this->messagePluralization;
}
}

View File

@ -20,14 +20,16 @@ class ConstraintViolation
{
protected $messageTemplate;
protected $messageParameters;
protected $messagePluralization;
protected $root;
protected $propertyPath;
protected $invalidValue;
public function __construct($messageTemplate, array $messageParameters, $root, $propertyPath, $invalidValue)
public function __construct($messageTemplate, array $messageParameters, $root, $propertyPath, $invalidValue, $messagePluralization = null)
{
$this->messageTemplate = $messageTemplate;
$this->messageParameters = $messageParameters;
$this->messagePluralization = $messagePluralization;
$this->root = $root;
$this->propertyPath = $propertyPath;
$this->invalidValue = $invalidValue;
@ -68,6 +70,14 @@ class ConstraintViolation
return $this->messageParameters;
}
/**
* @return integer|null
*/
public function getMessagePluralization()
{
return $this->messagePluralization;
}
/**
* Returns the violation message.
*

View File

@ -75,13 +75,13 @@ class ChoiceValidator extends ConstraintValidator
$count = count($value);
if ($constraint->min !== null && $count < $constraint->min) {
$this->context->addViolation($constraint->minMessage, array('{{ limit }}' => $constraint->min));
$this->context->addViolation($constraint->minMessage, array('{{ limit }}' => $constraint->min), null, (int) $constraint->min);
return false;
}
if ($constraint->max !== null && $count > $constraint->max) {
$this->context->addViolation($constraint->maxMessage, array('{{ limit }}' => $constraint->max));
$this->context->addViolation($constraint->maxMessage, array('{{ limit }}' => $constraint->max), null, (int) $constraint->max);
return false;
}

View File

@ -54,7 +54,7 @@ class MaxLengthValidator extends ConstraintValidator
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $value,
'{{ limit }}' => $constraint->limit,
));
), null, (int) $constraint->limit);
return false;
}

View File

@ -54,7 +54,7 @@ class MinLengthValidator extends ConstraintValidator
$this->context->addViolation($constraint->message, array(
'{{ value }}' => $value,
'{{ limit }}' => $constraint->limit,
));
), null, (int) $constraint->limit);
return false;
}

View File

@ -54,7 +54,7 @@ class SizeLengthValidator extends ConstraintValidator
$this->context->addViolation($constraint->exactMessage, array(
'{{ value }}' => $value,
'{{ limit }}' => $constraint->max,
));
), null, (int) $constraint->max);
return false;
}
@ -63,7 +63,7 @@ class SizeLengthValidator extends ConstraintValidator
$this->context->addViolation($constraint->maxMessage, array(
'{{ value }}' => $value,
'{{ limit }}' => $constraint->max,
));
), null, (int) $constraint->max);
return false;
}
@ -72,7 +72,7 @@ class SizeLengthValidator extends ConstraintValidator
$this->context->addViolation($constraint->minMessage, array(
'{{ value }}' => $value,
'{{ limit }}' => $constraint->min,
));
), null, (int) $constraint->min);
return false;
}

View File

@ -56,10 +56,11 @@ class ExecutionContext
* @param string $message The error message.
* @param array $params The parameters parsed into the error message.
* @param mixed $invalidValue The invalid, validated value.
* @param integer|null $pluralization The number to use to pluralize of the message.
*
* @api
*/
public function addViolation($message, array $params = array(), $invalidValue = null)
public function addViolation($message, array $params = array(), $invalidValue = null, $pluralization = null)
{
$this->globalContext->addViolation(new ConstraintViolation(
$message,
@ -67,7 +68,8 @@ class ExecutionContext
$this->globalContext->getRoot(),
$this->propertyPath,
// check using func_num_args() to allow passing null values
func_num_args() === 3 ? $invalidValue : $this->value
func_num_args() === 3 ? $invalidValue : $this->value,
$pluralization
));
}
@ -79,8 +81,9 @@ class ExecutionContext
* @param string $message The error message.
* @param array $params The parameters parsed into the error message.
* @param mixed $invalidValue The invalid, validated value.
* @param integer|null $pluralization The number to use to pluralize of the message.
*/
public function addViolationAtPath($propertyPath, $message, array $params = array(), $invalidValue = null)
public function addViolationAtPath($propertyPath, $message, array $params = array(), $invalidValue = null, $pluralization = null)
{
$this->globalContext->addViolation(new ConstraintViolation(
$message,
@ -88,7 +91,8 @@ class ExecutionContext
$this->globalContext->getRoot(),
$propertyPath,
// check using func_num_args() to allow passing null values
func_num_args() === 4 ? $invalidValue : $this->value
func_num_args() === 4 ? $invalidValue : $this->value,
$pluralization
));
}
@ -100,8 +104,9 @@ class ExecutionContext
* @param string $message The error message.
* @param array $params The parameters parsed into the error message.
* @param mixed $invalidValue The invalid, validated value.
* @param integer|null $pluralization The number to use to pluralize of the message.
*/
public function addViolationAtSubPath($subPath, $message, array $params = array(), $invalidValue = null)
public function addViolationAtSubPath($subPath, $message, array $params = array(), $invalidValue = null, $pluralization = null)
{
$this->globalContext->addViolation(new ConstraintViolation(
$message,
@ -109,7 +114,8 @@ class ExecutionContext
$this->globalContext->getRoot(),
$this->getPropertyPath($subPath),
// check using func_num_args() to allow passing null values
func_num_args() === 4 ? $invalidValue : $this->value
func_num_args() === 4 ? $invalidValue : $this->value,
$pluralization
));
}

View File

@ -161,7 +161,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
->method('addViolation')
->with('myMessage', array(
'{{ value }}' => 'baz',
));
), null, null);
$this->assertFalse($this->validator->isValid('baz', $constraint));
}
@ -196,7 +196,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
->method('addViolation')
->with('myMessage', array(
'{{ limit }}' => 2,
));
), null, 2);
$this->assertFalse($this->validator->isValid(array('foo'), $constraint));
}
@ -214,7 +214,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
->method('addViolation')
->with('myMessage', array(
'{{ limit }}' => 2,
));
), null, 2);
$this->assertFalse($this->validator->isValid(array('foo', 'bar', 'moo'), $constraint));
}

View File

@ -101,7 +101,7 @@ class MaxLengthValidatorTest extends \PHPUnit_Framework_TestCase
->with('myMessage', array(
'{{ value }}' => $value,
'{{ limit }}' => 5,
));
), null, 5);
$this->assertFalse($this->validator->isValid($value, $constraint));
}

View File

@ -101,7 +101,7 @@ class MinLengthValidatorTest extends \PHPUnit_Framework_TestCase
->with('myMessage', array(
'{{ value }}' => $value,
'{{ limit }}' => 5,
));
), null, 5);
$this->assertFalse($this->validator->isValid($value, $constraint));
}

View File

@ -129,7 +129,7 @@ class SizeLengthValidatorTest extends \PHPUnit_Framework_TestCase
->with('myMessage', array(
'{{ value }}' => '1234',
'{{ limit }}' => 5,
));
), null, 5);
$this->assertFalse($this->validator->isValid('1234', $constraint));
}
@ -147,7 +147,7 @@ class SizeLengthValidatorTest extends \PHPUnit_Framework_TestCase
->with('myMessage', array(
'{{ value }}' => '12345678901',
'{{ limit }}' => 10,
));
), null, 10);
$this->assertFalse($this->validator->isValid('12345678901', $constraint));
}
@ -165,7 +165,7 @@ class SizeLengthValidatorTest extends \PHPUnit_Framework_TestCase
->with('myMessage', array(
'{{ value }}' => '1234',
'{{ limit }}' => 5,
));
), null, 5);
$this->assertFalse($this->validator->isValid('1234', $constraint));
}