create oneof constraint and add deprecation messages in choice, also make choice extend new oneOf constraint to avoid duplicate code
This commit is contained in:
parent
c0507aae90
commit
9071676f0b
@ -319,3 +319,21 @@
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
* The constraint `Choice` was deprecated and will be removed in Symfony 2.3.
|
||||
You should use the new constraint `OneOf` instead.
|
||||
|
||||
Before:
|
||||
|
||||
```
|
||||
/** @Assert\Choice(choices = {"male", "female"}, message = "Choose a valid gender.") */
|
||||
protected $gender;
|
||||
```
|
||||
|
||||
After:
|
||||
|
||||
```
|
||||
/** @Assert\OneOf(choices = {"male", "female"}, message = "Choose a valid gender.") */
|
||||
protected $gender;
|
||||
```
|
||||
|
||||
|
@ -28,6 +28,7 @@ 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.
|
||||
* deprecated `Choice` constraint in favor of the new `OneOf` constraint.
|
||||
|
||||
2.1.0
|
||||
-----
|
||||
|
@ -11,31 +11,19 @@
|
||||
|
||||
namespace Symfony\Component\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated Deprecated since version 2.2, to be removed in 2.3. Use
|
||||
* {@link OneOf} instead.
|
||||
*/
|
||||
class Choice extends Constraint
|
||||
class Choice extends OneOf
|
||||
{
|
||||
public $choices;
|
||||
public $callback;
|
||||
public $multiple = false;
|
||||
public $strict = false;
|
||||
public $min = null;
|
||||
public $max = null;
|
||||
public $message = 'The value you selected is not a valid choice.';
|
||||
public $multipleMessage = 'One or more of the given values is invalid.';
|
||||
public $minMessage = 'You must select at least {{ limit }} choices.';
|
||||
public $maxMessage = 'You must select at most {{ limit }} choices.';
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getDefaultOption()
|
||||
public function __construct($options = null)
|
||||
{
|
||||
return 'choices';
|
||||
trigger_error('Choice constraint is deprecated since version 2.2 and will be removed in 2.3. Use OneOf instead', E_USER_DEPRECATED);
|
||||
parent::__construct($options);
|
||||
}
|
||||
}
|
||||
|
@ -11,11 +11,6 @@
|
||||
|
||||
namespace Symfony\Component\Validator\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
|
||||
/**
|
||||
* ChoiceValidator validates that the value is one of the expected values.
|
||||
*
|
||||
@ -24,60 +19,15 @@ use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*
|
||||
* @deprecated Deprecated since version 2.2, to be removed in 2.3. Use
|
||||
* {@link OneOfValidator} instead.
|
||||
*/
|
||||
class ChoiceValidator extends ConstraintValidator
|
||||
class ChoiceValidator extends OneOfValidator
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function validate($value, Constraint $constraint)
|
||||
public function __construct($options = null)
|
||||
{
|
||||
if (!$constraint->choices && !$constraint->callback) {
|
||||
throw new ConstraintDefinitionException('Either "choices" or "callback" must be specified on constraint Choice');
|
||||
}
|
||||
|
||||
if (null === $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($constraint->multiple && !is_array($value)) {
|
||||
throw new UnexpectedTypeException($value, 'array');
|
||||
}
|
||||
|
||||
if ($constraint->callback) {
|
||||
if (is_callable(array($this->context->getCurrentClass(), $constraint->callback))) {
|
||||
$choices = call_user_func(array($this->context->getCurrentClass(), $constraint->callback));
|
||||
} elseif (is_callable($constraint->callback)) {
|
||||
$choices = call_user_func($constraint->callback);
|
||||
} else {
|
||||
throw new ConstraintDefinitionException('The Choice constraint expects a valid callback');
|
||||
}
|
||||
} else {
|
||||
$choices = $constraint->choices;
|
||||
}
|
||||
|
||||
if ($constraint->multiple) {
|
||||
foreach ($value as $_value) {
|
||||
if (!in_array($_value, $choices, $constraint->strict)) {
|
||||
$this->context->addViolation($constraint->multipleMessage, array('{{ value }}' => $_value));
|
||||
}
|
||||
}
|
||||
|
||||
$count = count($value);
|
||||
|
||||
if ($constraint->min !== null && $count < $constraint->min) {
|
||||
$this->context->addViolation($constraint->minMessage, array('{{ limit }}' => $constraint->min), null, (int) $constraint->min);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($constraint->max !== null && $count > $constraint->max) {
|
||||
$this->context->addViolation($constraint->maxMessage, array('{{ limit }}' => $constraint->max), null, (int) $constraint->max);
|
||||
|
||||
return;
|
||||
}
|
||||
} elseif (!in_array($value, $choices, $constraint->strict)) {
|
||||
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
|
||||
}
|
||||
trigger_error('ChoiceValidator is deprecated since version 2.2 and will be removed in 2.3. Use OneOfValidator instead', E_USER_DEPRECATED);
|
||||
parent::__construct($options);
|
||||
}
|
||||
}
|
||||
|
41
src/Symfony/Component/Validator/Constraints/OneOf.php
Normal file
41
src/Symfony/Component/Validator/Constraints/OneOf.php
Normal file
@ -0,0 +1,41 @@
|
||||
<?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\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
|
||||
/**
|
||||
* @Annotation
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class OneOf extends Constraint
|
||||
{
|
||||
public $choices;
|
||||
public $callback;
|
||||
public $multiple = false;
|
||||
public $strict = false;
|
||||
public $min = null;
|
||||
public $max = null;
|
||||
public $message = 'The value you selected is not a valid choice.';
|
||||
public $multipleMessage = 'One or more of the given values is invalid.';
|
||||
public $minMessage = 'You must select at least {{ limit }} choices.';
|
||||
public $maxMessage = 'You must select at most {{ limit }} choices.';
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function getDefaultOption()
|
||||
{
|
||||
return 'choices';
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
<?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\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\Constraint;
|
||||
use Symfony\Component\Validator\ConstraintValidator;
|
||||
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
|
||||
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
||||
|
||||
/**
|
||||
* ChoiceValidator validates that the value is one of the expected values.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Florian Eckerstorfer <florian@eckerstorfer.org>
|
||||
* @author Bernhard Schussek <bschussek@gmail.com>
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
class OneOfValidator extends ConstraintValidator
|
||||
{
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function validate($value, Constraint $constraint)
|
||||
{
|
||||
if (!$constraint->choices && !$constraint->callback) {
|
||||
throw new ConstraintDefinitionException('Either "choices" or "callback" must be specified on constraint Choice');
|
||||
}
|
||||
|
||||
if (null === $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($constraint->multiple && !is_array($value)) {
|
||||
throw new UnexpectedTypeException($value, 'array');
|
||||
}
|
||||
|
||||
if ($constraint->callback) {
|
||||
if (is_callable(array($this->context->getCurrentClass(), $constraint->callback))) {
|
||||
$choices = call_user_func(array($this->context->getCurrentClass(), $constraint->callback));
|
||||
} elseif (is_callable($constraint->callback)) {
|
||||
$choices = call_user_func($constraint->callback);
|
||||
} else {
|
||||
throw new ConstraintDefinitionException('The OneOf constraint expects a valid callback');
|
||||
}
|
||||
} else {
|
||||
$choices = $constraint->choices;
|
||||
}
|
||||
|
||||
if ($constraint->multiple) {
|
||||
foreach ($value as $_value) {
|
||||
if (!in_array($_value, $choices, $constraint->strict)) {
|
||||
$this->context->addViolation($constraint->multipleMessage, array('{{ value }}' => $_value));
|
||||
}
|
||||
}
|
||||
|
||||
$count = count($value);
|
||||
|
||||
if ($constraint->min !== null && $count < $constraint->min) {
|
||||
$this->context->addViolation($constraint->minMessage, array('{{ limit }}' => $constraint->min), null, (int) $constraint->min);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($constraint->max !== null && $count > $constraint->max) {
|
||||
$this->context->addViolation($constraint->maxMessage, array('{{ limit }}' => $constraint->max), null, (int) $constraint->max);
|
||||
|
||||
return;
|
||||
}
|
||||
} elseif (!in_array($value, $choices, $constraint->strict)) {
|
||||
$this->context->addViolation($constraint->message, array('{{ value }}' => $value));
|
||||
}
|
||||
}
|
||||
}
|
@ -12,15 +12,15 @@
|
||||
namespace Symfony\Component\Validator\Tests\Constraints;
|
||||
|
||||
use Symfony\Component\Validator\ExecutionContext;
|
||||
use Symfony\Component\Validator\Constraints\Choice;
|
||||
use Symfony\Component\Validator\Constraints\ChoiceValidator;
|
||||
use Symfony\Component\Validator\Constraints\OneOf;
|
||||
use Symfony\Component\Validator\Constraints\OneOfValidator;
|
||||
|
||||
function choice_callback()
|
||||
function oneof_callback()
|
||||
{
|
||||
return array('foo', 'bar');
|
||||
}
|
||||
|
||||
class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
class OneOfValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $context;
|
||||
protected $validator;
|
||||
@ -33,7 +33,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
protected function setUp()
|
||||
{
|
||||
$this->context = $this->getMock('Symfony\Component\Validator\ExecutionContext', array(), array(), '', false);
|
||||
$this->validator = new ChoiceValidator();
|
||||
$this->validator = new OneOfValidator();
|
||||
$this->validator->initialize($this->context);
|
||||
|
||||
$this->context->expects($this->any())
|
||||
@ -52,7 +52,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testExpectArrayIfMultipleIsTrue()
|
||||
{
|
||||
$constraint = new Choice(array(
|
||||
$constraint = new OneOf(array(
|
||||
'choices' => array('foo', 'bar'),
|
||||
'multiple' => true,
|
||||
));
|
||||
@ -65,7 +65,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->context->expects($this->never())
|
||||
->method('addViolation');
|
||||
|
||||
$this->validator->validate(null, new Choice(array('choices' => array('foo', 'bar'))));
|
||||
$this->validator->validate(null, new OneOf(array('choices' => array('foo', 'bar'))));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,7 +73,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testChoicesOrCallbackExpected()
|
||||
{
|
||||
$this->validator->validate('foobar', new Choice());
|
||||
$this->validator->validate('foobar', new OneOf());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -81,12 +81,12 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testValidCallbackExpected()
|
||||
{
|
||||
$this->validator->validate('foobar', new Choice(array('callback' => 'abcd')));
|
||||
$this->validator->validate('foobar', new OneOf(array('callback' => 'abcd')));
|
||||
}
|
||||
|
||||
public function testValidChoiceArray()
|
||||
public function testValidOneOfChoicesArray()
|
||||
{
|
||||
$constraint = new Choice(array('choices' => array('foo', 'bar')));
|
||||
$constraint = new OneOf(array('choices' => array('foo', 'bar')));
|
||||
|
||||
$this->context->expects($this->never())
|
||||
->method('addViolation');
|
||||
@ -94,9 +94,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->validator->validate('bar', $constraint);
|
||||
}
|
||||
|
||||
public function testValidChoiceCallbackFunction()
|
||||
public function testValidOneOfCallbackFunction()
|
||||
{
|
||||
$constraint = new Choice(array('callback' => __NAMESPACE__.'\choice_callback'));
|
||||
$constraint = new OneOf(array('callback' => __NAMESPACE__.'\oneof_callback'));
|
||||
|
||||
$this->context->expects($this->never())
|
||||
->method('addViolation');
|
||||
@ -104,9 +104,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->validator->validate('bar', $constraint);
|
||||
}
|
||||
|
||||
public function testValidChoiceCallbackClosure()
|
||||
public function testValidOneOfCallbackClosure()
|
||||
{
|
||||
$constraint = new Choice(array('callback' => function() {
|
||||
$constraint = new OneOf(array('callback' => function() {
|
||||
return array('foo', 'bar');
|
||||
}));
|
||||
|
||||
@ -116,9 +116,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->validator->validate('bar', $constraint);
|
||||
}
|
||||
|
||||
public function testValidChoiceCallbackStaticMethod()
|
||||
public function testValidOneOfCallbackStaticMethod()
|
||||
{
|
||||
$constraint = new Choice(array('callback' => array(__CLASS__, 'staticCallback')));
|
||||
$constraint = new OneOf(array('callback' => array(__CLASS__, 'staticCallback')));
|
||||
|
||||
$this->context->expects($this->never())
|
||||
->method('addViolation');
|
||||
@ -126,9 +126,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->validator->validate('bar', $constraint);
|
||||
}
|
||||
|
||||
public function testValidChoiceCallbackContextMethod()
|
||||
public function testValidOneOfCallbackContextMethod()
|
||||
{
|
||||
$constraint = new Choice(array('callback' => 'staticCallback'));
|
||||
$constraint = new OneOf(array('callback' => 'staticCallback'));
|
||||
|
||||
$this->context->expects($this->never())
|
||||
->method('addViolation');
|
||||
@ -136,9 +136,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->validator->validate('bar', $constraint);
|
||||
}
|
||||
|
||||
public function testMultipleChoices()
|
||||
public function testMultipleOneOfChoices()
|
||||
{
|
||||
$constraint = new Choice(array(
|
||||
$constraint = new OneOf(array(
|
||||
'choices' => array('foo', 'bar', 'baz'),
|
||||
'multiple' => true,
|
||||
));
|
||||
@ -149,9 +149,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->validator->validate(array('baz', 'bar'), $constraint);
|
||||
}
|
||||
|
||||
public function testInvalidChoice()
|
||||
public function testInvalidOneOf()
|
||||
{
|
||||
$constraint = new Choice(array(
|
||||
$constraint = new OneOf(array(
|
||||
'choices' => array('foo', 'bar'),
|
||||
'message' => 'myMessage',
|
||||
));
|
||||
@ -165,9 +165,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->validator->validate('baz', $constraint);
|
||||
}
|
||||
|
||||
public function testInvalidChoiceMultiple()
|
||||
public function testInvalidOneOfMultiple()
|
||||
{
|
||||
$constraint = new Choice(array(
|
||||
$constraint = new OneOf(array(
|
||||
'choices' => array('foo', 'bar'),
|
||||
'multipleMessage' => 'myMessage',
|
||||
'multiple' => true,
|
||||
@ -182,9 +182,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->validator->validate(array('foo', 'baz'), $constraint);
|
||||
}
|
||||
|
||||
public function testTooFewChoices()
|
||||
public function testTooFewOneOfChoices()
|
||||
{
|
||||
$constraint = new Choice(array(
|
||||
$constraint = new OneOf(array(
|
||||
'choices' => array('foo', 'bar', 'moo', 'maa'),
|
||||
'multiple' => true,
|
||||
'min' => 2,
|
||||
@ -200,9 +200,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->validator->validate(array('foo'), $constraint);
|
||||
}
|
||||
|
||||
public function testTooManyChoices()
|
||||
public function testTooManyOneOfChoices()
|
||||
{
|
||||
$constraint = new Choice(array(
|
||||
$constraint = new OneOf(array(
|
||||
'choices' => array('foo', 'bar', 'moo', 'maa'),
|
||||
'multiple' => true,
|
||||
'max' => 2,
|
||||
@ -220,7 +220,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testNonStrict()
|
||||
{
|
||||
$constraint = new Choice(array(
|
||||
$constraint = new OneOf(array(
|
||||
'choices' => array(1, 2),
|
||||
'strict' => false,
|
||||
));
|
||||
@ -234,7 +234,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testStrictAllowsExactValue()
|
||||
{
|
||||
$constraint = new Choice(array(
|
||||
$constraint = new OneOf(array(
|
||||
'choices' => array(1, 2),
|
||||
'strict' => true,
|
||||
));
|
||||
@ -247,7 +247,7 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
public function testStrictDisallowsDifferentType()
|
||||
{
|
||||
$constraint = new Choice(array(
|
||||
$constraint = new OneOf(array(
|
||||
'choices' => array(1, 2),
|
||||
'strict' => true,
|
||||
'message' => 'myMessage'
|
||||
@ -262,9 +262,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->validator->validate('2', $constraint);
|
||||
}
|
||||
|
||||
public function testNonStrictWithMultipleChoices()
|
||||
public function testNonStrictOneOfWithMultipleChoices()
|
||||
{
|
||||
$constraint = new Choice(array(
|
||||
$constraint = new OneOf(array(
|
||||
'choices' => array(1, 2, 3),
|
||||
'multiple' => true,
|
||||
'strict' => false
|
||||
@ -276,9 +276,9 @@ class ChoiceValidatorTest extends \PHPUnit_Framework_TestCase
|
||||
$this->validator->validate(array('2', 3), $constraint);
|
||||
}
|
||||
|
||||
public function testStrictWithMultipleChoices()
|
||||
public function testStrictOneOfWithMultipleChoices()
|
||||
{
|
||||
$constraint = new Choice(array(
|
||||
$constraint = new OneOf(array(
|
||||
'choices' => array(1, 2, 3),
|
||||
'multiple' => true,
|
||||
'strict' => true,
|
Reference in New Issue
Block a user