Skip to content

Commit

Permalink
create oneof constraint and add deprecation messages in choice, also …
Browse files Browse the repository at this point in the history
…make choice extend new oneOf constraint to avoid duplicate code
  • Loading branch information
ricardclau committed Dec 15, 2012
1 parent c0507aa commit 9071676
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 112 deletions.
18 changes: 18 additions & 0 deletions UPGRADE-2.2.md
Expand Up @@ -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;
```

1 change: 1 addition & 0 deletions src/Symfony/Component/Validator/CHANGELOG.md
Expand Up @@ -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
-----
Expand Down
26 changes: 7 additions & 19 deletions src/Symfony/Component/Validator/Constraints/Choice.php
Expand Up @@ -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);
}
}
64 changes: 7 additions & 57 deletions src/Symfony/Component/Validator/Constraints/ChoiceValidator.php
Expand Up @@ -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.
*
Expand All @@ -24,60 +19,15 @@
* @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 changes: 41 additions & 0 deletions src/Symfony/Component/Validator/Constraints/OneOf.php
@@ -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';
}
}
83 changes: 83 additions & 0 deletions src/Symfony/Component/Validator/Constraints/OneOfValidator.php
@@ -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));
}
}
}

0 comments on commit 9071676

Please sign in to comment.